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