1/*
2 * Copyright �� 2009
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 * Authors:
24 *    Daniel Vetter <daniel@ffwll.ch>
25 *
26 * Derived from Xorg ddx, xf86-video-intel, src/i830_video.c
27 */
28#include <drm/drmP.h>
29#include <drm/i915_drm.h>
30#include "i915_drv.h"
31#include "i915_reg.h"
32#include "intel_drv.h"
33
34/* Limits for overlay size. According to intel doc, the real limits are:
35 * Y width: 4095, UV width (planar): 2047, Y height: 2047,
36 * UV width (planar): * 1023. But the xorg thinks 2048 for height and width. Use
37 * the mininum of both.  */
38#define IMAGE_MAX_WIDTH		2048
39#define IMAGE_MAX_HEIGHT	2046 /* 2 * 1023 */
40/* on 830 and 845 these large limits result in the card hanging */
41#define IMAGE_MAX_WIDTH_LEGACY	1024
42#define IMAGE_MAX_HEIGHT_LEGACY	1088
43
44/* overlay register definitions */
45/* OCMD register */
46#define OCMD_TILED_SURFACE	(0x1<<19)
47#define OCMD_MIRROR_MASK	(0x3<<17)
48#define OCMD_MIRROR_MODE	(0x3<<17)
49#define OCMD_MIRROR_HORIZONTAL	(0x1<<17)
50#define OCMD_MIRROR_VERTICAL	(0x2<<17)
51#define OCMD_MIRROR_BOTH	(0x3<<17)
52#define OCMD_BYTEORDER_MASK	(0x3<<14) /* zero for YUYV or FOURCC YUY2 */
53#define OCMD_UV_SWAP		(0x1<<14) /* YVYU */
54#define OCMD_Y_SWAP		(0x2<<14) /* UYVY or FOURCC UYVY */
55#define OCMD_Y_AND_UV_SWAP	(0x3<<14) /* VYUY */
56#define OCMD_SOURCE_FORMAT_MASK (0xf<<10)
57#define OCMD_RGB_888		(0x1<<10) /* not in i965 Intel docs */
58#define OCMD_RGB_555		(0x2<<10) /* not in i965 Intel docs */
59#define OCMD_RGB_565		(0x3<<10) /* not in i965 Intel docs */
60#define OCMD_YUV_422_PACKED	(0x8<<10)
61#define OCMD_YUV_411_PACKED	(0x9<<10) /* not in i965 Intel docs */
62#define OCMD_YUV_420_PLANAR	(0xc<<10)
63#define OCMD_YUV_422_PLANAR	(0xd<<10)
64#define OCMD_YUV_410_PLANAR	(0xe<<10) /* also 411 */
65#define OCMD_TVSYNCFLIP_PARITY	(0x1<<9)
66#define OCMD_TVSYNCFLIP_ENABLE	(0x1<<7)
67#define OCMD_BUF_TYPE_MASK	(0x1<<5)
68#define OCMD_BUF_TYPE_FRAME	(0x0<<5)
69#define OCMD_BUF_TYPE_FIELD	(0x1<<5)
70#define OCMD_TEST_MODE		(0x1<<4)
71#define OCMD_BUFFER_SELECT	(0x3<<2)
72#define OCMD_BUFFER0		(0x0<<2)
73#define OCMD_BUFFER1		(0x1<<2)
74#define OCMD_FIELD_SELECT	(0x1<<2)
75#define OCMD_FIELD0		(0x0<<1)
76#define OCMD_FIELD1		(0x1<<1)
77#define OCMD_ENABLE		(0x1<<0)
78
79/* OCONFIG register */
80#define OCONF_PIPE_MASK		(0x1<<18)
81#define OCONF_PIPE_A		(0x0<<18)
82#define OCONF_PIPE_B		(0x1<<18)
83#define OCONF_GAMMA2_ENABLE	(0x1<<16)
84#define OCONF_CSC_MODE_BT601	(0x0<<5)
85#define OCONF_CSC_MODE_BT709	(0x1<<5)
86#define OCONF_CSC_BYPASS	(0x1<<4)
87#define OCONF_CC_OUT_8BIT	(0x1<<3)
88#define OCONF_TEST_MODE		(0x1<<2)
89#define OCONF_THREE_LINE_BUFFER	(0x1<<0)
90#define OCONF_TWO_LINE_BUFFER	(0x0<<0)
91
92/* DCLRKM (dst-key) register */
93#define DST_KEY_ENABLE		(0x1<<31)
94#define CLK_RGB24_MASK		0x0
95#define CLK_RGB16_MASK		0x070307
96#define CLK_RGB15_MASK		0x070707
97#define CLK_RGB8I_MASK		0xffffff
98
99#define RGB16_TO_COLORKEY(c) \
100	(((c & 0xF800) << 8) | ((c & 0x07E0) << 5) | ((c & 0x001F) << 3))
101#define RGB15_TO_COLORKEY(c) \
102	(((c & 0x7c00) << 9) | ((c & 0x03E0) << 6) | ((c & 0x001F) << 3))
103
104/* overlay flip addr flag */
105#define OFC_UPDATE		0x1
106
107/* polyphase filter coefficients */
108#define N_HORIZ_Y_TAPS          5
109#define N_VERT_Y_TAPS           3
110#define N_HORIZ_UV_TAPS         3
111#define N_VERT_UV_TAPS          3
112#define N_PHASES                17
113#define MAX_TAPS                5
114
115/* memory bufferd overlay registers */
116struct overlay_registers {
117	u32 OBUF_0Y;
118	u32 OBUF_1Y;
119	u32 OBUF_0U;
120	u32 OBUF_0V;
121	u32 OBUF_1U;
122	u32 OBUF_1V;
123	u32 OSTRIDE;
124	u32 YRGB_VPH;
125	u32 UV_VPH;
126	u32 HORZ_PH;
127	u32 INIT_PHS;
128	u32 DWINPOS;
129	u32 DWINSZ;
130	u32 SWIDTH;
131	u32 SWIDTHSW;
132	u32 SHEIGHT;
133	u32 YRGBSCALE;
134	u32 UVSCALE;
135	u32 OCLRC0;
136	u32 OCLRC1;
137	u32 DCLRKV;
138	u32 DCLRKM;
139	u32 SCLRKVH;
140	u32 SCLRKVL;
141	u32 SCLRKEN;
142	u32 OCONFIG;
143	u32 OCMD;
144	u32 RESERVED1; /* 0x6C */
145	u32 OSTART_0Y;
146	u32 OSTART_1Y;
147	u32 OSTART_0U;
148	u32 OSTART_0V;
149	u32 OSTART_1U;
150	u32 OSTART_1V;
151	u32 OTILEOFF_0Y;
152	u32 OTILEOFF_1Y;
153	u32 OTILEOFF_0U;
154	u32 OTILEOFF_0V;
155	u32 OTILEOFF_1U;
156	u32 OTILEOFF_1V;
157	u32 FASTHSCALE; /* 0xA0 */
158	u32 UVSCALEV; /* 0xA4 */
159	u32 RESERVEDC[(0x200 - 0xA8) / 4]; /* 0xA8 - 0x1FC */
160	u16 Y_VCOEFS[N_VERT_Y_TAPS * N_PHASES]; /* 0x200 */
161	u16 RESERVEDD[0x100 / 2 - N_VERT_Y_TAPS * N_PHASES];
162	u16 Y_HCOEFS[N_HORIZ_Y_TAPS * N_PHASES]; /* 0x300 */
163	u16 RESERVEDE[0x200 / 2 - N_HORIZ_Y_TAPS * N_PHASES];
164	u16 UV_VCOEFS[N_VERT_UV_TAPS * N_PHASES]; /* 0x500 */
165	u16 RESERVEDF[0x100 / 2 - N_VERT_UV_TAPS * N_PHASES];
166	u16 UV_HCOEFS[N_HORIZ_UV_TAPS * N_PHASES]; /* 0x600 */
167	u16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES];
168};
169
170struct intel_overlay {
171	struct drm_device *dev;
172	struct intel_crtc *crtc;
173	struct drm_i915_gem_object *vid_bo;
174	struct drm_i915_gem_object *old_vid_bo;
175	bool active;
176	bool pfit_active;
177	u32 pfit_vscale_ratio; /* shifted-point number, (1<<12) == 1.0 */
178	u32 color_key:24;
179	u32 color_key_enabled:1;
180	u32 brightness, contrast, saturation;
181	u32 old_xscale, old_yscale;
182	/* register access */
183	u32 flip_addr;
184	struct drm_i915_gem_object *reg_bo;
185	/* flip handling */
186	struct drm_i915_gem_request *last_flip_req;
187	void (*flip_tail)(struct intel_overlay *);
188};
189
190static struct overlay_registers __iomem *
191intel_overlay_map_regs(struct intel_overlay *overlay)
192{
193	struct drm_i915_private *dev_priv = overlay->dev->dev_private;
194	struct overlay_registers __iomem *regs;
195
196	if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
197		regs = (struct overlay_registers __iomem *)overlay->reg_bo->phys_handle->vaddr;
198	else
199		regs = io_mapping_map_wc(dev_priv->gtt.mappable,
200					 i915_gem_obj_ggtt_offset(overlay->reg_bo));
201
202	return regs;
203}
204
205static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
206				     struct overlay_registers __iomem *regs)
207{
208	if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
209		io_mapping_unmap(regs);
210}
211
212static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
213					 struct drm_i915_gem_request *req,
214					 void (*tail)(struct intel_overlay *))
215{
216	int ret;
217
218	WARN_ON(overlay->last_flip_req);
219	i915_gem_request_assign(&overlay->last_flip_req, req);
220	i915_add_request(req);
221
222	overlay->flip_tail = tail;
223	ret = i915_wait_request(overlay->last_flip_req);
224	if (ret)
225		return ret;
226
227	i915_gem_request_assign(&overlay->last_flip_req, NULL);
228	return 0;
229}
230
231/* overlay needs to be disable in OCMD reg */
232static int intel_overlay_on(struct intel_overlay *overlay)
233{
234	struct drm_device *dev = overlay->dev;
235	struct drm_i915_private *dev_priv = dev->dev_private;
236	struct intel_engine_cs *ring = &dev_priv->ring[RCS];
237	struct drm_i915_gem_request *req;
238	int ret;
239
240	WARN_ON(overlay->active);
241	WARN_ON(IS_I830(dev) && !(dev_priv->quirks & QUIRK_PIPEA_FORCE));
242
243	ret = i915_gem_request_alloc(ring, ring->default_context, &req);
244	if (ret)
245		return ret;
246
247	ret = intel_ring_begin(req, 4);
248	if (ret) {
249		i915_gem_request_cancel(req);
250		return ret;
251	}
252
253	overlay->active = true;
254
255	intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_ON);
256	intel_ring_emit(ring, overlay->flip_addr | OFC_UPDATE);
257	intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
258	intel_ring_emit(ring, MI_NOOP);
259	intel_ring_advance(ring);
260
261	return intel_overlay_do_wait_request(overlay, req, NULL);
262}
263
264/* overlay needs to be enabled in OCMD reg */
265static int intel_overlay_continue(struct intel_overlay *overlay,
266				  bool load_polyphase_filter)
267{
268	struct drm_device *dev = overlay->dev;
269	struct drm_i915_private *dev_priv = dev->dev_private;
270	struct intel_engine_cs *ring = &dev_priv->ring[RCS];
271	struct drm_i915_gem_request *req;
272	u32 flip_addr = overlay->flip_addr;
273	u32 tmp;
274	int ret;
275
276	WARN_ON(!overlay->active);
277
278	if (load_polyphase_filter)
279		flip_addr |= OFC_UPDATE;
280
281	/* check for underruns */
282	tmp = I915_READ(DOVSTA);
283	if (tmp & (1 << 17))
284		DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);
285
286	ret = i915_gem_request_alloc(ring, ring->default_context, &req);
287	if (ret)
288		return ret;
289
290	ret = intel_ring_begin(req, 2);
291	if (ret) {
292		i915_gem_request_cancel(req);
293		return ret;
294	}
295
296	intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
297	intel_ring_emit(ring, flip_addr);
298	intel_ring_advance(ring);
299
300	WARN_ON(overlay->last_flip_req);
301	i915_gem_request_assign(&overlay->last_flip_req, req);
302	i915_add_request(req);
303
304	return 0;
305}
306
307static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
308{
309	struct drm_i915_gem_object *obj = overlay->old_vid_bo;
310
311	i915_gem_object_ggtt_unpin(obj);
312	drm_gem_object_unreference(&obj->base);
313
314	overlay->old_vid_bo = NULL;
315}
316
317static void intel_overlay_off_tail(struct intel_overlay *overlay)
318{
319	struct drm_i915_gem_object *obj = overlay->vid_bo;
320
321	/* never have the overlay hw on without showing a frame */
322	if (WARN_ON(!obj))
323		return;
324
325	i915_gem_object_ggtt_unpin(obj);
326	drm_gem_object_unreference(&obj->base);
327	overlay->vid_bo = NULL;
328
329	overlay->crtc->overlay = NULL;
330	overlay->crtc = NULL;
331	overlay->active = false;
332}
333
334/* overlay needs to be disabled in OCMD reg */
335static int intel_overlay_off(struct intel_overlay *overlay)
336{
337	struct drm_device *dev = overlay->dev;
338	struct drm_i915_private *dev_priv = dev->dev_private;
339	struct intel_engine_cs *ring = &dev_priv->ring[RCS];
340	struct drm_i915_gem_request *req;
341	u32 flip_addr = overlay->flip_addr;
342	int ret;
343
344	WARN_ON(!overlay->active);
345
346	/* According to intel docs the overlay hw may hang (when switching
347	 * off) without loading the filter coeffs. It is however unclear whether
348	 * this applies to the disabling of the overlay or to the switching off
349	 * of the hw. Do it in both cases */
350	flip_addr |= OFC_UPDATE;
351
352	ret = i915_gem_request_alloc(ring, ring->default_context, &req);
353	if (ret)
354		return ret;
355
356	ret = intel_ring_begin(req, 6);
357	if (ret) {
358		i915_gem_request_cancel(req);
359		return ret;
360	}
361
362	/* wait for overlay to go idle */
363	intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
364	intel_ring_emit(ring, flip_addr);
365	intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
366	/* turn overlay off */
367	if (IS_I830(dev)) {
368		/* Workaround: Don't disable the overlay fully, since otherwise
369		 * it dies on the next OVERLAY_ON cmd. */
370		intel_ring_emit(ring, MI_NOOP);
371		intel_ring_emit(ring, MI_NOOP);
372		intel_ring_emit(ring, MI_NOOP);
373	} else {
374		intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
375		intel_ring_emit(ring, flip_addr);
376		intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
377	}
378	intel_ring_advance(ring);
379
380	return intel_overlay_do_wait_request(overlay, req, intel_overlay_off_tail);
381}
382
383/* recover from an interruption due to a signal
384 * We have to be careful not to repeat work forever an make forward progess. */
385static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay)
386{
387	int ret;
388
389	if (overlay->last_flip_req == NULL)
390		return 0;
391
392	ret = i915_wait_request(overlay->last_flip_req);
393	if (ret)
394		return ret;
395
396	if (overlay->flip_tail)
397		overlay->flip_tail(overlay);
398
399	i915_gem_request_assign(&overlay->last_flip_req, NULL);
400	return 0;
401}
402
403/* Wait for pending overlay flip and release old frame.
404 * Needs to be called before the overlay register are changed
405 * via intel_overlay_(un)map_regs
406 */
407static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
408{
409	struct drm_device *dev = overlay->dev;
410	struct drm_i915_private *dev_priv = dev->dev_private;
411	struct intel_engine_cs *ring = &dev_priv->ring[RCS];
412	int ret;
413
414	WARN_ON(!mutex_is_locked(&dev->struct_mutex));
415
416	/* Only wait if there is actually an old frame to release to
417	 * guarantee forward progress.
418	 */
419	if (!overlay->old_vid_bo)
420		return 0;
421
422	if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) {
423		/* synchronous slowpath */
424		struct drm_i915_gem_request *req;
425
426		ret = i915_gem_request_alloc(ring, ring->default_context, &req);
427		if (ret)
428			return ret;
429
430		ret = intel_ring_begin(req, 2);
431		if (ret) {
432			i915_gem_request_cancel(req);
433			return ret;
434		}
435
436		intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
437		intel_ring_emit(ring, MI_NOOP);
438		intel_ring_advance(ring);
439
440		ret = intel_overlay_do_wait_request(overlay, req,
441						    intel_overlay_release_old_vid_tail);
442		if (ret)
443			return ret;
444	}
445
446	intel_overlay_release_old_vid_tail(overlay);
447
448
449	i915_gem_track_fb(overlay->old_vid_bo, NULL,
450			  INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe));
451	return 0;
452}
453
454void intel_overlay_reset(struct drm_i915_private *dev_priv)
455{
456	struct intel_overlay *overlay = dev_priv->overlay;
457
458	if (!overlay)
459		return;
460
461	intel_overlay_release_old_vid(overlay);
462
463	overlay->last_flip_req = NULL;
464	overlay->old_xscale = 0;
465	overlay->old_yscale = 0;
466	overlay->crtc = NULL;
467	overlay->active = false;
468}
469
470struct put_image_params {
471	int format;
472	short dst_x;
473	short dst_y;
474	short dst_w;
475	short dst_h;
476	short src_w;
477	short src_scan_h;
478	short src_scan_w;
479	short src_h;
480	short stride_Y;
481	short stride_UV;
482	int offset_Y;
483	int offset_U;
484	int offset_V;
485};
486
487static int packed_depth_bytes(u32 format)
488{
489	switch (format & I915_OVERLAY_DEPTH_MASK) {
490	case I915_OVERLAY_YUV422:
491		return 4;
492	case I915_OVERLAY_YUV411:
493		/* return 6; not implemented */
494	default:
495		return -EINVAL;
496	}
497}
498
499static int packed_width_bytes(u32 format, short width)
500{
501	switch (format & I915_OVERLAY_DEPTH_MASK) {
502	case I915_OVERLAY_YUV422:
503		return width << 1;
504	default:
505		return -EINVAL;
506	}
507}
508
509static int uv_hsubsampling(u32 format)
510{
511	switch (format & I915_OVERLAY_DEPTH_MASK) {
512	case I915_OVERLAY_YUV422:
513	case I915_OVERLAY_YUV420:
514		return 2;
515	case I915_OVERLAY_YUV411:
516	case I915_OVERLAY_YUV410:
517		return 4;
518	default:
519		return -EINVAL;
520	}
521}
522
523static int uv_vsubsampling(u32 format)
524{
525	switch (format & I915_OVERLAY_DEPTH_MASK) {
526	case I915_OVERLAY_YUV420:
527	case I915_OVERLAY_YUV410:
528		return 2;
529	case I915_OVERLAY_YUV422:
530	case I915_OVERLAY_YUV411:
531		return 1;
532	default:
533		return -EINVAL;
534	}
535}
536
537static u32 calc_swidthsw(struct drm_device *dev, u32 offset, u32 width)
538{
539	u32 mask, shift, ret;
540	if (IS_GEN2(dev)) {
541		mask = 0x1f;
542		shift = 5;
543	} else {
544		mask = 0x3f;
545		shift = 6;
546	}
547	ret = ((offset + width + mask) >> shift) - (offset >> shift);
548	if (!IS_GEN2(dev))
549		ret <<= 1;
550	ret -= 1;
551	return ret << 2;
552}
553
554static const u16 y_static_hcoeffs[N_HORIZ_Y_TAPS * N_PHASES] = {
555	0x3000, 0xb4a0, 0x1930, 0x1920, 0xb4a0,
556	0x3000, 0xb500, 0x19d0, 0x1880, 0xb440,
557	0x3000, 0xb540, 0x1a88, 0x2f80, 0xb3e0,
558	0x3000, 0xb580, 0x1b30, 0x2e20, 0xb380,
559	0x3000, 0xb5c0, 0x1bd8, 0x2cc0, 0xb320,
560	0x3020, 0xb5e0, 0x1c60, 0x2b80, 0xb2c0,
561	0x3020, 0xb5e0, 0x1cf8, 0x2a20, 0xb260,
562	0x3020, 0xb5e0, 0x1d80, 0x28e0, 0xb200,
563	0x3020, 0xb5c0, 0x1e08, 0x3f40, 0xb1c0,
564	0x3020, 0xb580, 0x1e78, 0x3ce0, 0xb160,
565	0x3040, 0xb520, 0x1ed8, 0x3aa0, 0xb120,
566	0x3040, 0xb4a0, 0x1f30, 0x3880, 0xb0e0,
567	0x3040, 0xb400, 0x1f78, 0x3680, 0xb0a0,
568	0x3020, 0xb340, 0x1fb8, 0x34a0, 0xb060,
569	0x3020, 0xb240, 0x1fe0, 0x32e0, 0xb040,
570	0x3020, 0xb140, 0x1ff8, 0x3160, 0xb020,
571	0xb000, 0x3000, 0x0800, 0x3000, 0xb000
572};
573
574static const u16 uv_static_hcoeffs[N_HORIZ_UV_TAPS * N_PHASES] = {
575	0x3000, 0x1800, 0x1800, 0xb000, 0x18d0, 0x2e60,
576	0xb000, 0x1990, 0x2ce0, 0xb020, 0x1a68, 0x2b40,
577	0xb040, 0x1b20, 0x29e0, 0xb060, 0x1bd8, 0x2880,
578	0xb080, 0x1c88, 0x3e60, 0xb0a0, 0x1d28, 0x3c00,
579	0xb0c0, 0x1db8, 0x39e0, 0xb0e0, 0x1e40, 0x37e0,
580	0xb100, 0x1eb8, 0x3620, 0xb100, 0x1f18, 0x34a0,
581	0xb100, 0x1f68, 0x3360, 0xb0e0, 0x1fa8, 0x3240,
582	0xb0c0, 0x1fe0, 0x3140, 0xb060, 0x1ff0, 0x30a0,
583	0x3000, 0x0800, 0x3000
584};
585
586static void update_polyphase_filter(struct overlay_registers __iomem *regs)
587{
588	memcpy_toio(regs->Y_HCOEFS, y_static_hcoeffs, sizeof(y_static_hcoeffs));
589	memcpy_toio(regs->UV_HCOEFS, uv_static_hcoeffs,
590		    sizeof(uv_static_hcoeffs));
591}
592
593static bool update_scaling_factors(struct intel_overlay *overlay,
594				   struct overlay_registers __iomem *regs,
595				   struct put_image_params *params)
596{
597	/* fixed point with a 12 bit shift */
598	u32 xscale, yscale, xscale_UV, yscale_UV;
599#define FP_SHIFT 12
600#define FRACT_MASK 0xfff
601	bool scale_changed = false;
602	int uv_hscale = uv_hsubsampling(params->format);
603	int uv_vscale = uv_vsubsampling(params->format);
604
605	if (params->dst_w > 1)
606		xscale = ((params->src_scan_w - 1) << FP_SHIFT)
607			/(params->dst_w);
608	else
609		xscale = 1 << FP_SHIFT;
610
611	if (params->dst_h > 1)
612		yscale = ((params->src_scan_h - 1) << FP_SHIFT)
613			/(params->dst_h);
614	else
615		yscale = 1 << FP_SHIFT;
616
617	/*if (params->format & I915_OVERLAY_YUV_PLANAR) {*/
618	xscale_UV = xscale/uv_hscale;
619	yscale_UV = yscale/uv_vscale;
620	/* make the Y scale to UV scale ratio an exact multiply */
621	xscale = xscale_UV * uv_hscale;
622	yscale = yscale_UV * uv_vscale;
623	/*} else {
624	  xscale_UV = 0;
625	  yscale_UV = 0;
626	  }*/
627
628	if (xscale != overlay->old_xscale || yscale != overlay->old_yscale)
629		scale_changed = true;
630	overlay->old_xscale = xscale;
631	overlay->old_yscale = yscale;
632
633	iowrite32(((yscale & FRACT_MASK) << 20) |
634		  ((xscale >> FP_SHIFT)  << 16) |
635		  ((xscale & FRACT_MASK) << 3),
636		 &regs->YRGBSCALE);
637
638	iowrite32(((yscale_UV & FRACT_MASK) << 20) |
639		  ((xscale_UV >> FP_SHIFT)  << 16) |
640		  ((xscale_UV & FRACT_MASK) << 3),
641		 &regs->UVSCALE);
642
643	iowrite32((((yscale    >> FP_SHIFT) << 16) |
644		   ((yscale_UV >> FP_SHIFT) << 0)),
645		 &regs->UVSCALEV);
646
647	if (scale_changed)
648		update_polyphase_filter(regs);
649
650	return scale_changed;
651}
652
653static void update_colorkey(struct intel_overlay *overlay,
654			    struct overlay_registers __iomem *regs)
655{
656	u32 key = overlay->color_key;
657	u32 flags;
658
659	flags = 0;
660	if (overlay->color_key_enabled)
661		flags |= DST_KEY_ENABLE;
662
663	switch (overlay->crtc->base.primary->fb->bits_per_pixel) {
664	case 8:
665		key = 0;
666		flags |= CLK_RGB8I_MASK;
667		break;
668
669	case 16:
670		if (overlay->crtc->base.primary->fb->depth == 15) {
671			key = RGB15_TO_COLORKEY(key);
672			flags |= CLK_RGB15_MASK;
673		} else {
674			key = RGB16_TO_COLORKEY(key);
675			flags |= CLK_RGB16_MASK;
676		}
677		break;
678
679	case 24:
680	case 32:
681		flags |= CLK_RGB24_MASK;
682		break;
683	}
684
685	iowrite32(key, &regs->DCLRKV);
686	iowrite32(flags, &regs->DCLRKM);
687}
688
689static u32 overlay_cmd_reg(struct put_image_params *params)
690{
691	u32 cmd = OCMD_ENABLE | OCMD_BUF_TYPE_FRAME | OCMD_BUFFER0;
692
693	if (params->format & I915_OVERLAY_YUV_PLANAR) {
694		switch (params->format & I915_OVERLAY_DEPTH_MASK) {
695		case I915_OVERLAY_YUV422:
696			cmd |= OCMD_YUV_422_PLANAR;
697			break;
698		case I915_OVERLAY_YUV420:
699			cmd |= OCMD_YUV_420_PLANAR;
700			break;
701		case I915_OVERLAY_YUV411:
702		case I915_OVERLAY_YUV410:
703			cmd |= OCMD_YUV_410_PLANAR;
704			break;
705		}
706	} else { /* YUV packed */
707		switch (params->format & I915_OVERLAY_DEPTH_MASK) {
708		case I915_OVERLAY_YUV422:
709			cmd |= OCMD_YUV_422_PACKED;
710			break;
711		case I915_OVERLAY_YUV411:
712			cmd |= OCMD_YUV_411_PACKED;
713			break;
714		}
715
716		switch (params->format & I915_OVERLAY_SWAP_MASK) {
717		case I915_OVERLAY_NO_SWAP:
718			break;
719		case I915_OVERLAY_UV_SWAP:
720			cmd |= OCMD_UV_SWAP;
721			break;
722		case I915_OVERLAY_Y_SWAP:
723			cmd |= OCMD_Y_SWAP;
724			break;
725		case I915_OVERLAY_Y_AND_UV_SWAP:
726			cmd |= OCMD_Y_AND_UV_SWAP;
727			break;
728		}
729	}
730
731	return cmd;
732}
733
734static int intel_overlay_do_put_image(struct intel_overlay *overlay,
735				      struct drm_i915_gem_object *new_bo,
736				      struct put_image_params *params)
737{
738	int ret, tmp_width;
739	struct overlay_registers __iomem *regs;
740	bool scale_changed = false;
741	struct drm_device *dev = overlay->dev;
742	u32 swidth, swidthsw, sheight, ostride;
743	enum pipe pipe = overlay->crtc->pipe;
744
745	WARN_ON(!mutex_is_locked(&dev->struct_mutex));
746	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
747
748	ret = intel_overlay_release_old_vid(overlay);
749	if (ret != 0)
750		return ret;
751
752	ret = i915_gem_object_pin_to_display_plane(new_bo, 0, NULL, NULL,
753						   &i915_ggtt_view_normal);
754	if (ret != 0)
755		return ret;
756
757	ret = i915_gem_object_put_fence(new_bo);
758	if (ret)
759		goto out_unpin;
760
761	if (!overlay->active) {
762		u32 oconfig;
763		regs = intel_overlay_map_regs(overlay);
764		if (!regs) {
765			ret = -ENOMEM;
766			goto out_unpin;
767		}
768		oconfig = OCONF_CC_OUT_8BIT;
769		if (IS_GEN4(overlay->dev))
770			oconfig |= OCONF_CSC_MODE_BT709;
771		oconfig |= pipe == 0 ?
772			OCONF_PIPE_A : OCONF_PIPE_B;
773		iowrite32(oconfig, &regs->OCONFIG);
774		intel_overlay_unmap_regs(overlay, regs);
775
776		ret = intel_overlay_on(overlay);
777		if (ret != 0)
778			goto out_unpin;
779	}
780
781	regs = intel_overlay_map_regs(overlay);
782	if (!regs) {
783		ret = -ENOMEM;
784		goto out_unpin;
785	}
786
787	iowrite32((params->dst_y << 16) | params->dst_x, &regs->DWINPOS);
788	iowrite32((params->dst_h << 16) | params->dst_w, &regs->DWINSZ);
789
790	if (params->format & I915_OVERLAY_YUV_PACKED)
791		tmp_width = packed_width_bytes(params->format, params->src_w);
792	else
793		tmp_width = params->src_w;
794
795	swidth = params->src_w;
796	swidthsw = calc_swidthsw(overlay->dev, params->offset_Y, tmp_width);
797	sheight = params->src_h;
798	iowrite32(i915_gem_obj_ggtt_offset(new_bo) + params->offset_Y, &regs->OBUF_0Y);
799	ostride = params->stride_Y;
800
801	if (params->format & I915_OVERLAY_YUV_PLANAR) {
802		int uv_hscale = uv_hsubsampling(params->format);
803		int uv_vscale = uv_vsubsampling(params->format);
804		u32 tmp_U, tmp_V;
805		swidth |= (params->src_w/uv_hscale) << 16;
806		tmp_U = calc_swidthsw(overlay->dev, params->offset_U,
807				      params->src_w/uv_hscale);
808		tmp_V = calc_swidthsw(overlay->dev, params->offset_V,
809				      params->src_w/uv_hscale);
810		swidthsw |= max_t(u32, tmp_U, tmp_V) << 16;
811		sheight |= (params->src_h/uv_vscale) << 16;
812		iowrite32(i915_gem_obj_ggtt_offset(new_bo) + params->offset_U, &regs->OBUF_0U);
813		iowrite32(i915_gem_obj_ggtt_offset(new_bo) + params->offset_V, &regs->OBUF_0V);
814		ostride |= params->stride_UV << 16;
815	}
816
817	iowrite32(swidth, &regs->SWIDTH);
818	iowrite32(swidthsw, &regs->SWIDTHSW);
819	iowrite32(sheight, &regs->SHEIGHT);
820	iowrite32(ostride, &regs->OSTRIDE);
821
822	scale_changed = update_scaling_factors(overlay, regs, params);
823
824	update_colorkey(overlay, regs);
825
826	iowrite32(overlay_cmd_reg(params), &regs->OCMD);
827
828	intel_overlay_unmap_regs(overlay, regs);
829
830	ret = intel_overlay_continue(overlay, scale_changed);
831	if (ret)
832		goto out_unpin;
833
834	i915_gem_track_fb(overlay->vid_bo, new_bo,
835			  INTEL_FRONTBUFFER_OVERLAY(pipe));
836
837	overlay->old_vid_bo = overlay->vid_bo;
838	overlay->vid_bo = new_bo;
839
840	intel_frontbuffer_flip(dev,
841			       INTEL_FRONTBUFFER_OVERLAY(pipe));
842
843	return 0;
844
845out_unpin:
846	i915_gem_object_ggtt_unpin(new_bo);
847	return ret;
848}
849
850int intel_overlay_switch_off(struct intel_overlay *overlay)
851{
852	struct overlay_registers __iomem *regs;
853	struct drm_device *dev = overlay->dev;
854	int ret;
855
856	WARN_ON(!mutex_is_locked(&dev->struct_mutex));
857	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
858
859	ret = intel_overlay_recover_from_interrupt(overlay);
860	if (ret != 0)
861		return ret;
862
863	if (!overlay->active)
864		return 0;
865
866	ret = intel_overlay_release_old_vid(overlay);
867	if (ret != 0)
868		return ret;
869
870	regs = intel_overlay_map_regs(overlay);
871	iowrite32(0, &regs->OCMD);
872	intel_overlay_unmap_regs(overlay, regs);
873
874	ret = intel_overlay_off(overlay);
875	if (ret != 0)
876		return ret;
877
878	intel_overlay_off_tail(overlay);
879	return 0;
880}
881
882static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
883					  struct intel_crtc *crtc)
884{
885	if (!crtc->active)
886		return -EINVAL;
887
888	/* can't use the overlay with double wide pipe */
889	if (crtc->config->double_wide)
890		return -EINVAL;
891
892	return 0;
893}
894
895static void update_pfit_vscale_ratio(struct intel_overlay *overlay)
896{
897	struct drm_device *dev = overlay->dev;
898	struct drm_i915_private *dev_priv = dev->dev_private;
899	u32 pfit_control = I915_READ(PFIT_CONTROL);
900	u32 ratio;
901
902	/* XXX: This is not the same logic as in the xorg driver, but more in
903	 * line with the intel documentation for the i965
904	 */
905	if (INTEL_INFO(dev)->gen >= 4) {
906		/* on i965 use the PGM reg to read out the autoscaler values */
907		ratio = I915_READ(PFIT_PGM_RATIOS) >> PFIT_VERT_SCALE_SHIFT_965;
908	} else {
909		if (pfit_control & VERT_AUTO_SCALE)
910			ratio = I915_READ(PFIT_AUTO_RATIOS);
911		else
912			ratio = I915_READ(PFIT_PGM_RATIOS);
913		ratio >>= PFIT_VERT_SCALE_SHIFT;
914	}
915
916	overlay->pfit_vscale_ratio = ratio;
917}
918
919static int check_overlay_dst(struct intel_overlay *overlay,
920			     struct drm_intel_overlay_put_image *rec)
921{
922	struct drm_display_mode *mode = &overlay->crtc->base.mode;
923
924	if (rec->dst_x < mode->hdisplay &&
925	    rec->dst_x + rec->dst_width <= mode->hdisplay &&
926	    rec->dst_y < mode->vdisplay &&
927	    rec->dst_y + rec->dst_height <= mode->vdisplay)
928		return 0;
929	else
930		return -EINVAL;
931}
932
933static int check_overlay_scaling(struct put_image_params *rec)
934{
935	u32 tmp;
936
937	/* downscaling limit is 8.0 */
938	tmp = ((rec->src_scan_h << 16) / rec->dst_h) >> 16;
939	if (tmp > 7)
940		return -EINVAL;
941	tmp = ((rec->src_scan_w << 16) / rec->dst_w) >> 16;
942	if (tmp > 7)
943		return -EINVAL;
944
945	return 0;
946}
947
948static int check_overlay_src(struct drm_device *dev,
949			     struct drm_intel_overlay_put_image *rec,
950			     struct drm_i915_gem_object *new_bo)
951{
952	int uv_hscale = uv_hsubsampling(rec->flags);
953	int uv_vscale = uv_vsubsampling(rec->flags);
954	u32 stride_mask;
955	int depth;
956	u32 tmp;
957
958	/* check src dimensions */
959	if (IS_845G(dev) || IS_I830(dev)) {
960		if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY ||
961		    rec->src_width  > IMAGE_MAX_WIDTH_LEGACY)
962			return -EINVAL;
963	} else {
964		if (rec->src_height > IMAGE_MAX_HEIGHT ||
965		    rec->src_width  > IMAGE_MAX_WIDTH)
966			return -EINVAL;
967	}
968
969	/* better safe than sorry, use 4 as the maximal subsampling ratio */
970	if (rec->src_height < N_VERT_Y_TAPS*4 ||
971	    rec->src_width  < N_HORIZ_Y_TAPS*4)
972		return -EINVAL;
973
974	/* check alignment constraints */
975	switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
976	case I915_OVERLAY_RGB:
977		/* not implemented */
978		return -EINVAL;
979
980	case I915_OVERLAY_YUV_PACKED:
981		if (uv_vscale != 1)
982			return -EINVAL;
983
984		depth = packed_depth_bytes(rec->flags);
985		if (depth < 0)
986			return depth;
987
988		/* ignore UV planes */
989		rec->stride_UV = 0;
990		rec->offset_U = 0;
991		rec->offset_V = 0;
992		/* check pixel alignment */
993		if (rec->offset_Y % depth)
994			return -EINVAL;
995		break;
996
997	case I915_OVERLAY_YUV_PLANAR:
998		if (uv_vscale < 0 || uv_hscale < 0)
999			return -EINVAL;
1000		/* no offset restrictions for planar formats */
1001		break;
1002
1003	default:
1004		return -EINVAL;
1005	}
1006
1007	if (rec->src_width % uv_hscale)
1008		return -EINVAL;
1009
1010	/* stride checking */
1011	if (IS_I830(dev) || IS_845G(dev))
1012		stride_mask = 255;
1013	else
1014		stride_mask = 63;
1015
1016	if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask)
1017		return -EINVAL;
1018	if (IS_GEN4(dev) && rec->stride_Y < 512)
1019		return -EINVAL;
1020
1021	tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ?
1022		4096 : 8192;
1023	if (rec->stride_Y > tmp || rec->stride_UV > 2*1024)
1024		return -EINVAL;
1025
1026	/* check buffer dimensions */
1027	switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
1028	case I915_OVERLAY_RGB:
1029	case I915_OVERLAY_YUV_PACKED:
1030		/* always 4 Y values per depth pixels */
1031		if (packed_width_bytes(rec->flags, rec->src_width) > rec->stride_Y)
1032			return -EINVAL;
1033
1034		tmp = rec->stride_Y*rec->src_height;
1035		if (rec->offset_Y + tmp > new_bo->base.size)
1036			return -EINVAL;
1037		break;
1038
1039	case I915_OVERLAY_YUV_PLANAR:
1040		if (rec->src_width > rec->stride_Y)
1041			return -EINVAL;
1042		if (rec->src_width/uv_hscale > rec->stride_UV)
1043			return -EINVAL;
1044
1045		tmp = rec->stride_Y * rec->src_height;
1046		if (rec->offset_Y + tmp > new_bo->base.size)
1047			return -EINVAL;
1048
1049		tmp = rec->stride_UV * (rec->src_height / uv_vscale);
1050		if (rec->offset_U + tmp > new_bo->base.size ||
1051		    rec->offset_V + tmp > new_bo->base.size)
1052			return -EINVAL;
1053		break;
1054	}
1055
1056	return 0;
1057}
1058
1059/**
1060 * Return the pipe currently connected to the panel fitter,
1061 * or -1 if the panel fitter is not present or not in use
1062 */
1063static int intel_panel_fitter_pipe(struct drm_device *dev)
1064{
1065	struct drm_i915_private *dev_priv = dev->dev_private;
1066	u32  pfit_control;
1067
1068	/* i830 doesn't have a panel fitter */
1069	if (INTEL_INFO(dev)->gen <= 3 && (IS_I830(dev) || !IS_MOBILE(dev)))
1070		return -1;
1071
1072	pfit_control = I915_READ(PFIT_CONTROL);
1073
1074	/* See if the panel fitter is in use */
1075	if ((pfit_control & PFIT_ENABLE) == 0)
1076		return -1;
1077
1078	/* 965 can place panel fitter on either pipe */
1079	if (IS_GEN4(dev))
1080		return (pfit_control >> 29) & 0x3;
1081
1082	/* older chips can only use pipe 1 */
1083	return 1;
1084}
1085
1086int intel_overlay_put_image(struct drm_device *dev, void *data,
1087			    struct drm_file *file_priv)
1088{
1089	struct drm_intel_overlay_put_image *put_image_rec = data;
1090	struct drm_i915_private *dev_priv = dev->dev_private;
1091	struct intel_overlay *overlay;
1092	struct drm_crtc *drmmode_crtc;
1093	struct intel_crtc *crtc;
1094	struct drm_i915_gem_object *new_bo;
1095	struct put_image_params *params;
1096	int ret;
1097
1098	overlay = dev_priv->overlay;
1099	if (!overlay) {
1100		DRM_DEBUG("userspace bug: no overlay\n");
1101		return -ENODEV;
1102	}
1103
1104	if (!(put_image_rec->flags & I915_OVERLAY_ENABLE)) {
1105		drm_modeset_lock_all(dev);
1106		mutex_lock(&dev->struct_mutex);
1107
1108		ret = intel_overlay_switch_off(overlay);
1109
1110		mutex_unlock(&dev->struct_mutex);
1111		drm_modeset_unlock_all(dev);
1112
1113		return ret;
1114	}
1115
1116	params = kmalloc(sizeof(*params), GFP_KERNEL);
1117	if (!params)
1118		return -ENOMEM;
1119
1120	drmmode_crtc = drm_crtc_find(dev, put_image_rec->crtc_id);
1121	if (!drmmode_crtc) {
1122		ret = -ENOENT;
1123		goto out_free;
1124	}
1125	crtc = to_intel_crtc(drmmode_crtc);
1126
1127	new_bo = to_intel_bo(drm_gem_object_lookup(dev, file_priv,
1128						   put_image_rec->bo_handle));
1129	if (&new_bo->base == NULL) {
1130		ret = -ENOENT;
1131		goto out_free;
1132	}
1133
1134	drm_modeset_lock_all(dev);
1135	mutex_lock(&dev->struct_mutex);
1136
1137	if (new_bo->tiling_mode) {
1138		DRM_DEBUG_KMS("buffer used for overlay image can not be tiled\n");
1139		ret = -EINVAL;
1140		goto out_unlock;
1141	}
1142
1143	ret = intel_overlay_recover_from_interrupt(overlay);
1144	if (ret != 0)
1145		goto out_unlock;
1146
1147	if (overlay->crtc != crtc) {
1148		struct drm_display_mode *mode = &crtc->base.mode;
1149		ret = intel_overlay_switch_off(overlay);
1150		if (ret != 0)
1151			goto out_unlock;
1152
1153		ret = check_overlay_possible_on_crtc(overlay, crtc);
1154		if (ret != 0)
1155			goto out_unlock;
1156
1157		overlay->crtc = crtc;
1158		crtc->overlay = overlay;
1159
1160		/* line too wide, i.e. one-line-mode */
1161		if (mode->hdisplay > 1024 &&
1162		    intel_panel_fitter_pipe(dev) == crtc->pipe) {
1163			overlay->pfit_active = true;
1164			update_pfit_vscale_ratio(overlay);
1165		} else
1166			overlay->pfit_active = false;
1167	}
1168
1169	ret = check_overlay_dst(overlay, put_image_rec);
1170	if (ret != 0)
1171		goto out_unlock;
1172
1173	if (overlay->pfit_active) {
1174		params->dst_y = ((((u32)put_image_rec->dst_y) << 12) /
1175				 overlay->pfit_vscale_ratio);
1176		/* shifting right rounds downwards, so add 1 */
1177		params->dst_h = ((((u32)put_image_rec->dst_height) << 12) /
1178				 overlay->pfit_vscale_ratio) + 1;
1179	} else {
1180		params->dst_y = put_image_rec->dst_y;
1181		params->dst_h = put_image_rec->dst_height;
1182	}
1183	params->dst_x = put_image_rec->dst_x;
1184	params->dst_w = put_image_rec->dst_width;
1185
1186	params->src_w = put_image_rec->src_width;
1187	params->src_h = put_image_rec->src_height;
1188	params->src_scan_w = put_image_rec->src_scan_width;
1189	params->src_scan_h = put_image_rec->src_scan_height;
1190	if (params->src_scan_h > params->src_h ||
1191	    params->src_scan_w > params->src_w) {
1192		ret = -EINVAL;
1193		goto out_unlock;
1194	}
1195
1196	ret = check_overlay_src(dev, put_image_rec, new_bo);
1197	if (ret != 0)
1198		goto out_unlock;
1199	params->format = put_image_rec->flags & ~I915_OVERLAY_FLAGS_MASK;
1200	params->stride_Y = put_image_rec->stride_Y;
1201	params->stride_UV = put_image_rec->stride_UV;
1202	params->offset_Y = put_image_rec->offset_Y;
1203	params->offset_U = put_image_rec->offset_U;
1204	params->offset_V = put_image_rec->offset_V;
1205
1206	/* Check scaling after src size to prevent a divide-by-zero. */
1207	ret = check_overlay_scaling(params);
1208	if (ret != 0)
1209		goto out_unlock;
1210
1211	ret = intel_overlay_do_put_image(overlay, new_bo, params);
1212	if (ret != 0)
1213		goto out_unlock;
1214
1215	mutex_unlock(&dev->struct_mutex);
1216	drm_modeset_unlock_all(dev);
1217
1218	kfree(params);
1219
1220	return 0;
1221
1222out_unlock:
1223	mutex_unlock(&dev->struct_mutex);
1224	drm_modeset_unlock_all(dev);
1225	drm_gem_object_unreference_unlocked(&new_bo->base);
1226out_free:
1227	kfree(params);
1228
1229	return ret;
1230}
1231
1232static void update_reg_attrs(struct intel_overlay *overlay,
1233			     struct overlay_registers __iomem *regs)
1234{
1235	iowrite32((overlay->contrast << 18) | (overlay->brightness & 0xff),
1236		  &regs->OCLRC0);
1237	iowrite32(overlay->saturation, &regs->OCLRC1);
1238}
1239
1240static bool check_gamma_bounds(u32 gamma1, u32 gamma2)
1241{
1242	int i;
1243
1244	if (gamma1 & 0xff000000 || gamma2 & 0xff000000)
1245		return false;
1246
1247	for (i = 0; i < 3; i++) {
1248		if (((gamma1 >> i*8) & 0xff) >= ((gamma2 >> i*8) & 0xff))
1249			return false;
1250	}
1251
1252	return true;
1253}
1254
1255static bool check_gamma5_errata(u32 gamma5)
1256{
1257	int i;
1258
1259	for (i = 0; i < 3; i++) {
1260		if (((gamma5 >> i*8) & 0xff) == 0x80)
1261			return false;
1262	}
1263
1264	return true;
1265}
1266
1267static int check_gamma(struct drm_intel_overlay_attrs *attrs)
1268{
1269	if (!check_gamma_bounds(0, attrs->gamma0) ||
1270	    !check_gamma_bounds(attrs->gamma0, attrs->gamma1) ||
1271	    !check_gamma_bounds(attrs->gamma1, attrs->gamma2) ||
1272	    !check_gamma_bounds(attrs->gamma2, attrs->gamma3) ||
1273	    !check_gamma_bounds(attrs->gamma3, attrs->gamma4) ||
1274	    !check_gamma_bounds(attrs->gamma4, attrs->gamma5) ||
1275	    !check_gamma_bounds(attrs->gamma5, 0x00ffffff))
1276		return -EINVAL;
1277
1278	if (!check_gamma5_errata(attrs->gamma5))
1279		return -EINVAL;
1280
1281	return 0;
1282}
1283
1284int intel_overlay_attrs(struct drm_device *dev, void *data,
1285			struct drm_file *file_priv)
1286{
1287	struct drm_intel_overlay_attrs *attrs = data;
1288	struct drm_i915_private *dev_priv = dev->dev_private;
1289	struct intel_overlay *overlay;
1290	struct overlay_registers __iomem *regs;
1291	int ret;
1292
1293	overlay = dev_priv->overlay;
1294	if (!overlay) {
1295		DRM_DEBUG("userspace bug: no overlay\n");
1296		return -ENODEV;
1297	}
1298
1299	drm_modeset_lock_all(dev);
1300	mutex_lock(&dev->struct_mutex);
1301
1302	ret = -EINVAL;
1303	if (!(attrs->flags & I915_OVERLAY_UPDATE_ATTRS)) {
1304		attrs->color_key  = overlay->color_key;
1305		attrs->brightness = overlay->brightness;
1306		attrs->contrast   = overlay->contrast;
1307		attrs->saturation = overlay->saturation;
1308
1309		if (!IS_GEN2(dev)) {
1310			attrs->gamma0 = I915_READ(OGAMC0);
1311			attrs->gamma1 = I915_READ(OGAMC1);
1312			attrs->gamma2 = I915_READ(OGAMC2);
1313			attrs->gamma3 = I915_READ(OGAMC3);
1314			attrs->gamma4 = I915_READ(OGAMC4);
1315			attrs->gamma5 = I915_READ(OGAMC5);
1316		}
1317	} else {
1318		if (attrs->brightness < -128 || attrs->brightness > 127)
1319			goto out_unlock;
1320		if (attrs->contrast > 255)
1321			goto out_unlock;
1322		if (attrs->saturation > 1023)
1323			goto out_unlock;
1324
1325		overlay->color_key  = attrs->color_key;
1326		overlay->brightness = attrs->brightness;
1327		overlay->contrast   = attrs->contrast;
1328		overlay->saturation = attrs->saturation;
1329
1330		regs = intel_overlay_map_regs(overlay);
1331		if (!regs) {
1332			ret = -ENOMEM;
1333			goto out_unlock;
1334		}
1335
1336		update_reg_attrs(overlay, regs);
1337
1338		intel_overlay_unmap_regs(overlay, regs);
1339
1340		if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) {
1341			if (IS_GEN2(dev))
1342				goto out_unlock;
1343
1344			if (overlay->active) {
1345				ret = -EBUSY;
1346				goto out_unlock;
1347			}
1348
1349			ret = check_gamma(attrs);
1350			if (ret)
1351				goto out_unlock;
1352
1353			I915_WRITE(OGAMC0, attrs->gamma0);
1354			I915_WRITE(OGAMC1, attrs->gamma1);
1355			I915_WRITE(OGAMC2, attrs->gamma2);
1356			I915_WRITE(OGAMC3, attrs->gamma3);
1357			I915_WRITE(OGAMC4, attrs->gamma4);
1358			I915_WRITE(OGAMC5, attrs->gamma5);
1359		}
1360	}
1361	overlay->color_key_enabled = (attrs->flags & I915_OVERLAY_DISABLE_DEST_COLORKEY) == 0;
1362
1363	ret = 0;
1364out_unlock:
1365	mutex_unlock(&dev->struct_mutex);
1366	drm_modeset_unlock_all(dev);
1367
1368	return ret;
1369}
1370
1371void intel_setup_overlay(struct drm_device *dev)
1372{
1373	struct drm_i915_private *dev_priv = dev->dev_private;
1374	struct intel_overlay *overlay;
1375	struct drm_i915_gem_object *reg_bo;
1376	struct overlay_registers __iomem *regs;
1377	int ret;
1378
1379	if (!HAS_OVERLAY(dev))
1380		return;
1381
1382	overlay = kzalloc(sizeof(*overlay), GFP_KERNEL);
1383	if (!overlay)
1384		return;
1385
1386	mutex_lock(&dev->struct_mutex);
1387	if (WARN_ON(dev_priv->overlay))
1388		goto out_free;
1389
1390	overlay->dev = dev;
1391
1392	reg_bo = NULL;
1393	if (!OVERLAY_NEEDS_PHYSICAL(dev))
1394		reg_bo = i915_gem_object_create_stolen(dev, PAGE_SIZE);
1395	if (reg_bo == NULL)
1396		reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE);
1397	if (reg_bo == NULL)
1398		goto out_free;
1399	overlay->reg_bo = reg_bo;
1400
1401	if (OVERLAY_NEEDS_PHYSICAL(dev)) {
1402		ret = i915_gem_object_attach_phys(reg_bo, PAGE_SIZE);
1403		if (ret) {
1404			DRM_ERROR("failed to attach phys overlay regs\n");
1405			goto out_free_bo;
1406		}
1407		overlay->flip_addr = reg_bo->phys_handle->busaddr;
1408	} else {
1409		ret = i915_gem_obj_ggtt_pin(reg_bo, PAGE_SIZE, PIN_MAPPABLE);
1410		if (ret) {
1411			DRM_ERROR("failed to pin overlay register bo\n");
1412			goto out_free_bo;
1413		}
1414		overlay->flip_addr = i915_gem_obj_ggtt_offset(reg_bo);
1415
1416		ret = i915_gem_object_set_to_gtt_domain(reg_bo, true);
1417		if (ret) {
1418			DRM_ERROR("failed to move overlay register bo into the GTT\n");
1419			goto out_unpin_bo;
1420		}
1421	}
1422
1423	/* init all values */
1424	overlay->color_key = 0x0101fe;
1425	overlay->color_key_enabled = true;
1426	overlay->brightness = -19;
1427	overlay->contrast = 75;
1428	overlay->saturation = 146;
1429
1430	regs = intel_overlay_map_regs(overlay);
1431	if (!regs)
1432		goto out_unpin_bo;
1433
1434	memset_io(regs, 0, sizeof(struct overlay_registers));
1435	update_polyphase_filter(regs);
1436	update_reg_attrs(overlay, regs);
1437
1438	intel_overlay_unmap_regs(overlay, regs);
1439
1440	dev_priv->overlay = overlay;
1441	mutex_unlock(&dev->struct_mutex);
1442	DRM_INFO("initialized overlay support\n");
1443	return;
1444
1445out_unpin_bo:
1446	if (!OVERLAY_NEEDS_PHYSICAL(dev))
1447		i915_gem_object_ggtt_unpin(reg_bo);
1448out_free_bo:
1449	drm_gem_object_unreference(&reg_bo->base);
1450out_free:
1451	mutex_unlock(&dev->struct_mutex);
1452	kfree(overlay);
1453	return;
1454}
1455
1456void intel_cleanup_overlay(struct drm_device *dev)
1457{
1458	struct drm_i915_private *dev_priv = dev->dev_private;
1459
1460	if (!dev_priv->overlay)
1461		return;
1462
1463	/* The bo's should be free'd by the generic code already.
1464	 * Furthermore modesetting teardown happens beforehand so the
1465	 * hardware should be off already */
1466	WARN_ON(dev_priv->overlay->active);
1467
1468	drm_gem_object_unreference_unlocked(&dev_priv->overlay->reg_bo->base);
1469	kfree(dev_priv->overlay);
1470}
1471
1472struct intel_overlay_error_state {
1473	struct overlay_registers regs;
1474	unsigned long base;
1475	u32 dovsta;
1476	u32 isr;
1477};
1478
1479static struct overlay_registers __iomem *
1480intel_overlay_map_regs_atomic(struct intel_overlay *overlay)
1481{
1482	struct drm_i915_private *dev_priv = overlay->dev->dev_private;
1483	struct overlay_registers __iomem *regs;
1484
1485	if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
1486		/* Cast to make sparse happy, but it's wc memory anyway, so
1487		 * equivalent to the wc io mapping on X86. */
1488		regs = (struct overlay_registers __iomem *)
1489			overlay->reg_bo->phys_handle->vaddr;
1490	else
1491		regs = io_mapping_map_atomic_wc(dev_priv->gtt.mappable,
1492						i915_gem_obj_ggtt_offset(overlay->reg_bo));
1493
1494	return regs;
1495}
1496
1497static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay,
1498					struct overlay_registers __iomem *regs)
1499{
1500	if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
1501		io_mapping_unmap_atomic(regs);
1502}
1503
1504
1505struct intel_overlay_error_state *
1506intel_overlay_capture_error_state(struct drm_device *dev)
1507{
1508	struct drm_i915_private *dev_priv = dev->dev_private;
1509	struct intel_overlay *overlay = dev_priv->overlay;
1510	struct intel_overlay_error_state *error;
1511	struct overlay_registers __iomem *regs;
1512
1513	if (!overlay || !overlay->active)
1514		return NULL;
1515
1516	error = kmalloc(sizeof(*error), GFP_ATOMIC);
1517	if (error == NULL)
1518		return NULL;
1519
1520	error->dovsta = I915_READ(DOVSTA);
1521	error->isr = I915_READ(ISR);
1522	if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
1523		error->base = (__force long)overlay->reg_bo->phys_handle->vaddr;
1524	else
1525		error->base = i915_gem_obj_ggtt_offset(overlay->reg_bo);
1526
1527	regs = intel_overlay_map_regs_atomic(overlay);
1528	if (!regs)
1529		goto err;
1530
1531	memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers));
1532	intel_overlay_unmap_regs_atomic(overlay, regs);
1533
1534	return error;
1535
1536err:
1537	kfree(error);
1538	return NULL;
1539}
1540
1541void
1542intel_overlay_print_error_state(struct drm_i915_error_state_buf *m,
1543				struct intel_overlay_error_state *error)
1544{
1545	i915_error_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
1546			  error->dovsta, error->isr);
1547	i915_error_printf(m, "  Register file at 0x%08lx:\n",
1548			  error->base);
1549
1550#define P(x) i915_error_printf(m, "    " #x ":	0x%08x\n", error->regs.x)
1551	P(OBUF_0Y);
1552	P(OBUF_1Y);
1553	P(OBUF_0U);
1554	P(OBUF_0V);
1555	P(OBUF_1U);
1556	P(OBUF_1V);
1557	P(OSTRIDE);
1558	P(YRGB_VPH);
1559	P(UV_VPH);
1560	P(HORZ_PH);
1561	P(INIT_PHS);
1562	P(DWINPOS);
1563	P(DWINSZ);
1564	P(SWIDTH);
1565	P(SWIDTHSW);
1566	P(SHEIGHT);
1567	P(YRGBSCALE);
1568	P(UVSCALE);
1569	P(OCLRC0);
1570	P(OCLRC1);
1571	P(DCLRKV);
1572	P(DCLRKM);
1573	P(SCLRKVH);
1574	P(SCLRKVL);
1575	P(SCLRKEN);
1576	P(OCONFIG);
1577	P(OCMD);
1578	P(OSTART_0Y);
1579	P(OSTART_1Y);
1580	P(OSTART_0U);
1581	P(OSTART_0V);
1582	P(OSTART_1U);
1583	P(OSTART_1V);
1584	P(OTILEOFF_0Y);
1585	P(OTILEOFF_1Y);
1586	P(OTILEOFF_0U);
1587	P(OTILEOFF_0V);
1588	P(OTILEOFF_1U);
1589	P(OTILEOFF_1V);
1590	P(FASTHSCALE);
1591	P(UVSCALEV);
1592#undef P
1593}
1594