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