xref: /dragonfly/sys/dev/drm/i915/intel_overlay.c (revision 9348a738)
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 */
116 struct 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 
170 struct 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 
190 static struct overlay_registers __iomem *
191 intel_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 
205 static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
206 				     struct overlay_registers __iomem *regs)
207 {
208 	if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
209 		pmap_unmapdev((vm_offset_t)regs, PAGE_SIZE);
210 }
211 
212 static 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 */
232 static 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 	req = i915_gem_request_alloc(ring, NULL);
244 	if (IS_ERR(req))
245 		return PTR_ERR(req);
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 */
265 static 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 	req = i915_gem_request_alloc(ring, NULL);
287 	if (IS_ERR(req))
288 		return PTR_ERR(req);
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 
307 static 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 
317 static 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 */
335 static 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 	req = i915_gem_request_alloc(ring, NULL);
353 	if (IS_ERR(req))
354 		return PTR_ERR(req);
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. */
385 static 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  */
407 static 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 		req = i915_gem_request_alloc(ring, NULL);
427 		if (IS_ERR(req))
428 			return PTR_ERR(req);
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 
454 void 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 
470 struct 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 
487 static 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 
499 static 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 
509 static 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 
523 static 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 
537 static 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 
554 static 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 
574 static 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 
586 static 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 
593 static 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 
653 static 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 
689 static 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 
734 static 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 i915_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,
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 
845 out_unpin:
846 	i915_gem_object_ggtt_unpin(new_bo);
847 	return ret;
848 }
849 
850 int 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 
882 static 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 
895 static 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 
919 static 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 
933 static 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 
948 static 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  */
1063 static 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 
1086 int 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), M_DRM, M_WAITOK);
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 
1222 out_unlock:
1223 	mutex_unlock(&dev->struct_mutex);
1224 	drm_modeset_unlock_all(dev);
1225 	drm_gem_object_unreference_unlocked(&new_bo->base);
1226 out_free:
1227 	kfree(params);
1228 
1229 	return ret;
1230 }
1231 
1232 static 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 
1240 static 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 
1255 static 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 
1267 static 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 
1284 int 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;
1364 out_unlock:
1365 	mutex_unlock(&dev->struct_mutex);
1366 	drm_modeset_unlock_all(dev);
1367 
1368 	return ret;
1369 }
1370 
1371 void 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 
1445 out_unpin_bo:
1446 	if (!OVERLAY_NEEDS_PHYSICAL(dev))
1447 		i915_gem_object_ggtt_unpin(reg_bo);
1448 out_free_bo:
1449 	drm_gem_object_unreference(&reg_bo->base);
1450 out_free:
1451 	mutex_unlock(&dev->struct_mutex);
1452 	kfree(overlay);
1453 	return;
1454 }
1455 
1456 void 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 
1472 struct intel_overlay_error_state {
1473 	struct overlay_registers regs;
1474 	unsigned long base;
1475 	u32 dovsta;
1476 	u32 isr;
1477 };
1478 
1479 #if 0
1480 static struct overlay_registers __iomem *
1481 intel_overlay_map_regs_atomic(struct intel_overlay *overlay)
1482 {
1483 	struct drm_i915_private *dev_priv = overlay->dev->dev_private;
1484 	struct overlay_registers __iomem *regs;
1485 
1486 	if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
1487 		/* Cast to make sparse happy, but it's wc memory anyway, so
1488 		 * equivalent to the wc io mapping on X86. */
1489 		regs = (struct overlay_registers __iomem *)
1490 			overlay->reg_bo->phys_handle->vaddr;
1491 	else
1492 		regs = io_mapping_map_atomic_wc(dev_priv->gtt.mappable,
1493 						i915_gem_obj_ggtt_offset(overlay->reg_bo));
1494 
1495 	return regs;
1496 }
1497 
1498 static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay,
1499 					struct overlay_registers __iomem *regs)
1500 {
1501 	if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
1502 		io_mapping_unmap_atomic(regs);
1503 }
1504 
1505 
1506 struct intel_overlay_error_state *
1507 intel_overlay_capture_error_state(struct drm_device *dev)
1508 {
1509 	struct drm_i915_private *dev_priv = dev->dev_private;
1510 	struct intel_overlay *overlay = dev_priv->overlay;
1511 	struct intel_overlay_error_state *error;
1512 	struct overlay_registers __iomem *regs;
1513 
1514 	if (!overlay || !overlay->active)
1515 		return NULL;
1516 
1517 	error = kmalloc(sizeof(*error), GFP_ATOMIC);
1518 	if (error == NULL)
1519 		return NULL;
1520 
1521 	error->dovsta = I915_READ(DOVSTA);
1522 	error->isr = I915_READ(ISR);
1523 	if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
1524 		error->base = (__force long)overlay->reg_bo->phys_handle->vaddr;
1525 	else
1526 		error->base = i915_gem_obj_ggtt_offset(overlay->reg_bo);
1527 
1528 	regs = intel_overlay_map_regs_atomic(overlay);
1529 	if (!regs)
1530 		goto err;
1531 
1532 	memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers));
1533 	intel_overlay_unmap_regs_atomic(overlay, regs);
1534 
1535 	return error;
1536 
1537 err:
1538 	kfree(error);
1539 	return NULL;
1540 }
1541 
1542 void
1543 intel_overlay_print_error_state(struct drm_i915_error_state_buf *m,
1544 				struct intel_overlay_error_state *error)
1545 {
1546 	i915_error_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
1547 			  error->dovsta, error->isr);
1548 	i915_error_printf(m, "  Register file at 0x%08lx:\n",
1549 			  error->base);
1550 
1551 #define P(x) i915_error_printf(m, "    " #x ":	0x%08x\n", error->regs.x)
1552 	P(OBUF_0Y);
1553 	P(OBUF_1Y);
1554 	P(OBUF_0U);
1555 	P(OBUF_0V);
1556 	P(OBUF_1U);
1557 	P(OBUF_1V);
1558 	P(OSTRIDE);
1559 	P(YRGB_VPH);
1560 	P(UV_VPH);
1561 	P(HORZ_PH);
1562 	P(INIT_PHS);
1563 	P(DWINPOS);
1564 	P(DWINSZ);
1565 	P(SWIDTH);
1566 	P(SWIDTHSW);
1567 	P(SHEIGHT);
1568 	P(YRGBSCALE);
1569 	P(UVSCALE);
1570 	P(OCLRC0);
1571 	P(OCLRC1);
1572 	P(DCLRKV);
1573 	P(DCLRKM);
1574 	P(SCLRKVH);
1575 	P(SCLRKVL);
1576 	P(SCLRKEN);
1577 	P(OCONFIG);
1578 	P(OCMD);
1579 	P(OSTART_0Y);
1580 	P(OSTART_1Y);
1581 	P(OSTART_0U);
1582 	P(OSTART_0V);
1583 	P(OSTART_1U);
1584 	P(OSTART_1V);
1585 	P(OTILEOFF_0Y);
1586 	P(OTILEOFF_1Y);
1587 	P(OTILEOFF_0U);
1588 	P(OTILEOFF_0V);
1589 	P(OTILEOFF_1U);
1590 	P(OTILEOFF_1V);
1591 	P(FASTHSCALE);
1592 	P(UVSCALEV);
1593 #undef P
1594 }
1595 #endif
1596