xref: /dragonfly/sys/dev/drm/i915/intel_overlay.c (revision 2513f15e)
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 
768 	ret = intel_overlay_release_old_vid(overlay);
769 	if (ret != 0)
770 		return ret;
771 
772 	ret = i915_gem_object_pin_to_display_plane(new_bo, 0, NULL);
773 	if (ret != 0)
774 		goto out_unpin;
775 
776 	ret = i915_gem_object_put_fence(new_bo);
777 	if (ret)
778 		goto out_unpin;
779 
780 	if (!overlay->active) {
781 		regs = intel_overlay_map_regs(overlay);
782 		if (!regs) {
783 			ret = -ENOMEM;
784 			goto out_unpin;
785 		}
786 		regs->OCONFIG = OCONF_CC_OUT_8BIT;
787 		if (IS_GEN4(overlay->dev))
788 			regs->OCONFIG |= OCONF_CSC_MODE_BT709;
789 		regs->OCONFIG |= overlay->crtc->pipe == 0 ?
790 			OCONF_PIPE_A : OCONF_PIPE_B;
791 		intel_overlay_unmap_regs(overlay, regs);
792 
793 		ret = intel_overlay_on(overlay);
794 		if (ret != 0)
795 			goto out_unpin;
796 	}
797 
798 	regs = intel_overlay_map_regs(overlay);
799 	if (!regs) {
800 		ret = -ENOMEM;
801 		goto out_unpin;
802 	}
803 
804 	regs->DWINPOS = (params->dst_y << 16) | params->dst_x;
805 	regs->DWINSZ = (params->dst_h << 16) | params->dst_w;
806 
807 	if (params->format & I915_OVERLAY_YUV_PACKED)
808 		tmp_width = packed_width_bytes(params->format, params->src_w);
809 	else
810 		tmp_width = params->src_w;
811 
812 	regs->SWIDTH = params->src_w;
813 	regs->SWIDTHSW = calc_swidthsw(overlay->dev,
814 				       params->offset_Y, tmp_width);
815 	regs->SHEIGHT = params->src_h;
816 	regs->OBUF_0Y = new_bo->gtt_offset + params->offset_Y;
817 	regs->OSTRIDE = params->stride_Y;
818 
819 	if (params->format & I915_OVERLAY_YUV_PLANAR) {
820 		int uv_hscale = uv_hsubsampling(params->format);
821 		int uv_vscale = uv_vsubsampling(params->format);
822 		u32 tmp_U, tmp_V;
823 		regs->SWIDTH |= (params->src_w/uv_hscale) << 16;
824 		tmp_U = calc_swidthsw(overlay->dev, params->offset_U,
825 				      params->src_w/uv_hscale);
826 		tmp_V = calc_swidthsw(overlay->dev, params->offset_V,
827 				      params->src_w/uv_hscale);
828 		regs->SWIDTHSW |= max_u32(tmp_U, tmp_V) << 16;
829 		regs->SHEIGHT |= (params->src_h/uv_vscale) << 16;
830 		regs->OBUF_0U = new_bo->gtt_offset + params->offset_U;
831 		regs->OBUF_0V = new_bo->gtt_offset + params->offset_V;
832 		regs->OSTRIDE |= params->stride_UV << 16;
833 	}
834 
835 	scale_changed = update_scaling_factors(overlay, regs, params);
836 
837 	update_colorkey(overlay, regs);
838 
839 	regs->OCMD = overlay_cmd_reg(params);
840 
841 	intel_overlay_unmap_regs(overlay, regs);
842 
843 	ret = intel_overlay_continue(overlay, scale_changed);
844 	if (ret)
845 		goto out_unpin;
846 
847 	overlay->old_vid_bo = overlay->vid_bo;
848 	overlay->vid_bo = new_bo;
849 
850 	return 0;
851 
852 out_unpin:
853 	i915_gem_object_unpin(new_bo);
854 	return ret;
855 }
856 
857 int intel_overlay_switch_off(struct intel_overlay *overlay)
858 {
859 	struct overlay_registers *regs;
860 	int ret;
861 
862 	DRM_LOCK_ASSERT(overlay->dev);
863 
864 	ret = intel_overlay_recover_from_interrupt(overlay);
865 	if (ret != 0)
866 		return ret;
867 
868 	if (!overlay->active)
869 		return 0;
870 
871 	ret = intel_overlay_release_old_vid(overlay);
872 	if (ret != 0)
873 		return ret;
874 
875 	regs = intel_overlay_map_regs(overlay);
876 	regs->OCMD = 0;
877 	intel_overlay_unmap_regs(overlay, regs);
878 
879 	ret = intel_overlay_off(overlay);
880 	if (ret != 0)
881 		return ret;
882 
883 	intel_overlay_off_tail(overlay);
884 	return 0;
885 }
886 
887 static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
888 					  struct intel_crtc *crtc)
889 {
890 	drm_i915_private_t *dev_priv = overlay->dev->dev_private;
891 
892 	if (!crtc->active)
893 		return -EINVAL;
894 
895 	/* can't use the overlay with double wide pipe */
896 	if (INTEL_INFO(overlay->dev)->gen < 4 &&
897 	    (I915_READ(PIPECONF(crtc->pipe)) & (PIPECONF_DOUBLE_WIDE | PIPECONF_ENABLE)) != PIPECONF_ENABLE)
898 		return -EINVAL;
899 
900 	return 0;
901 }
902 
903 static void update_pfit_vscale_ratio(struct intel_overlay *overlay)
904 {
905 	struct drm_device *dev = overlay->dev;
906 	drm_i915_private_t *dev_priv = dev->dev_private;
907 	u32 pfit_control = I915_READ(PFIT_CONTROL);
908 	u32 ratio;
909 
910 	/* XXX: This is not the same logic as in the xorg driver, but more in
911 	 * line with the intel documentation for the i965
912 	 */
913 	if (INTEL_INFO(dev)->gen >= 4) {
914 		/* on i965 use the PGM reg to read out the autoscaler values */
915 		ratio = I915_READ(PFIT_PGM_RATIOS) >> PFIT_VERT_SCALE_SHIFT_965;
916 	} else {
917 		if (pfit_control & VERT_AUTO_SCALE)
918 			ratio = I915_READ(PFIT_AUTO_RATIOS);
919 		else
920 			ratio = I915_READ(PFIT_PGM_RATIOS);
921 		ratio >>= PFIT_VERT_SCALE_SHIFT;
922 	}
923 
924 	overlay->pfit_vscale_ratio = ratio;
925 }
926 
927 static int check_overlay_dst(struct intel_overlay *overlay,
928 			     struct drm_intel_overlay_put_image *rec)
929 {
930 	struct drm_display_mode *mode = &overlay->crtc->base.mode;
931 
932 	if (rec->dst_x < mode->hdisplay &&
933 	    rec->dst_x + rec->dst_width <= mode->hdisplay &&
934 	    rec->dst_y < mode->vdisplay &&
935 	    rec->dst_y + rec->dst_height <= mode->vdisplay)
936 		return 0;
937 	else
938 		return -EINVAL;
939 }
940 
941 static int check_overlay_scaling(struct put_image_params *rec)
942 {
943 	u32 tmp;
944 
945 	/* downscaling limit is 8.0 */
946 	tmp = ((rec->src_scan_h << 16) / rec->dst_h) >> 16;
947 	if (tmp > 7)
948 		return -EINVAL;
949 	tmp = ((rec->src_scan_w << 16) / rec->dst_w) >> 16;
950 	if (tmp > 7)
951 		return -EINVAL;
952 
953 	return 0;
954 }
955 
956 static int check_overlay_src(struct drm_device *dev,
957 			     struct drm_intel_overlay_put_image *rec,
958 			     struct drm_i915_gem_object *new_bo)
959 {
960 	int uv_hscale = uv_hsubsampling(rec->flags);
961 	int uv_vscale = uv_vsubsampling(rec->flags);
962 	u32 stride_mask;
963 	int depth;
964 	u32 tmp;
965 
966 	/* check src dimensions */
967 	if (IS_845G(dev) || IS_I830(dev)) {
968 		if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY ||
969 		    rec->src_width  > IMAGE_MAX_WIDTH_LEGACY)
970 			return -EINVAL;
971 	} else {
972 		if (rec->src_height > IMAGE_MAX_HEIGHT ||
973 		    rec->src_width  > IMAGE_MAX_WIDTH)
974 			return -EINVAL;
975 	}
976 
977 	/* better safe than sorry, use 4 as the maximal subsampling ratio */
978 	if (rec->src_height < N_VERT_Y_TAPS*4 ||
979 	    rec->src_width  < N_HORIZ_Y_TAPS*4)
980 		return -EINVAL;
981 
982 	/* check alignment constraints */
983 	switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
984 	case I915_OVERLAY_RGB:
985 		/* not implemented */
986 		return -EINVAL;
987 
988 	case I915_OVERLAY_YUV_PACKED:
989 		if (uv_vscale != 1)
990 			return -EINVAL;
991 
992 		depth = packed_depth_bytes(rec->flags);
993 		if (depth < 0)
994 			return depth;
995 
996 		/* ignore UV planes */
997 		rec->stride_UV = 0;
998 		rec->offset_U = 0;
999 		rec->offset_V = 0;
1000 		/* check pixel alignment */
1001 		if (rec->offset_Y % depth)
1002 			return -EINVAL;
1003 		break;
1004 
1005 	case I915_OVERLAY_YUV_PLANAR:
1006 		if (uv_vscale < 0 || uv_hscale < 0)
1007 			return -EINVAL;
1008 		/* no offset restrictions for planar formats */
1009 		break;
1010 
1011 	default:
1012 		return -EINVAL;
1013 	}
1014 
1015 	if (rec->src_width % uv_hscale)
1016 		return -EINVAL;
1017 
1018 	/* stride checking */
1019 	if (IS_I830(dev) || IS_845G(dev))
1020 		stride_mask = 255;
1021 	else
1022 		stride_mask = 63;
1023 
1024 	if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask)
1025 		return -EINVAL;
1026 	if (IS_GEN4(dev) && rec->stride_Y < 512)
1027 		return -EINVAL;
1028 
1029 	tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ?
1030 		4096 : 8192;
1031 	if (rec->stride_Y > tmp || rec->stride_UV > 2*1024)
1032 		return -EINVAL;
1033 
1034 	/* check buffer dimensions */
1035 	switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
1036 	case I915_OVERLAY_RGB:
1037 	case I915_OVERLAY_YUV_PACKED:
1038 		/* always 4 Y values per depth pixels */
1039 		if (packed_width_bytes(rec->flags, rec->src_width) > rec->stride_Y)
1040 			return -EINVAL;
1041 
1042 		tmp = rec->stride_Y*rec->src_height;
1043 		if (rec->offset_Y + tmp > new_bo->base.size)
1044 			return -EINVAL;
1045 		break;
1046 
1047 	case I915_OVERLAY_YUV_PLANAR:
1048 		if (rec->src_width > rec->stride_Y)
1049 			return -EINVAL;
1050 		if (rec->src_width/uv_hscale > rec->stride_UV)
1051 			return -EINVAL;
1052 
1053 		tmp = rec->stride_Y * rec->src_height;
1054 		if (rec->offset_Y + tmp > new_bo->base.size)
1055 			return -EINVAL;
1056 
1057 		tmp = rec->stride_UV * (rec->src_height / uv_vscale);
1058 		if (rec->offset_U + tmp > new_bo->base.size ||
1059 		    rec->offset_V + tmp > new_bo->base.size)
1060 			return -EINVAL;
1061 		break;
1062 	}
1063 
1064 	return 0;
1065 }
1066 
1067 /**
1068  * Return the pipe currently connected to the panel fitter,
1069  * or -1 if the panel fitter is not present or not in use
1070  */
1071 static int intel_panel_fitter_pipe(struct drm_device *dev)
1072 {
1073 	struct drm_i915_private *dev_priv = dev->dev_private;
1074 	u32  pfit_control;
1075 
1076 	/* i830 doesn't have a panel fitter */
1077 	if (IS_I830(dev))
1078 		return -1;
1079 
1080 	pfit_control = I915_READ(PFIT_CONTROL);
1081 
1082 	/* See if the panel fitter is in use */
1083 	if ((pfit_control & PFIT_ENABLE) == 0)
1084 		return -1;
1085 
1086 	/* 965 can place panel fitter on either pipe */
1087 	if (IS_GEN4(dev))
1088 		return (pfit_control >> 29) & 0x3;
1089 
1090 	/* older chips can only use pipe 1 */
1091 	return 1;
1092 }
1093 
1094 int intel_overlay_put_image(struct drm_device *dev, void *data,
1095 			    struct drm_file *file_priv)
1096 {
1097 	struct drm_intel_overlay_put_image *put_image_rec = data;
1098 	drm_i915_private_t *dev_priv = dev->dev_private;
1099 	struct intel_overlay *overlay;
1100 	struct drm_mode_object *drmmode_obj;
1101 	struct intel_crtc *crtc;
1102 	struct drm_i915_gem_object *new_bo;
1103 	struct put_image_params *params;
1104 	int ret;
1105 
1106 	if (!dev_priv) {
1107 		DRM_ERROR("called with no initialization\n");
1108 		return -EINVAL;
1109 	}
1110 
1111 	overlay = dev_priv->overlay;
1112 	if (!overlay) {
1113 		DRM_DEBUG("userspace bug: no overlay\n");
1114 		return -ENODEV;
1115 	}
1116 
1117 	if (!(put_image_rec->flags & I915_OVERLAY_ENABLE)) {
1118 		lockmgr(&dev->mode_config.mutex, LK_EXCLUSIVE);
1119 		DRM_LOCK(dev);
1120 
1121 		ret = intel_overlay_switch_off(overlay);
1122 
1123 		DRM_UNLOCK(dev);
1124 		lockmgr(&dev->mode_config.mutex, LK_RELEASE);
1125 
1126 		return ret;
1127 	}
1128 
1129 	params = kmalloc(sizeof(struct put_image_params), DRM_I915_GEM,
1130 	    M_WAITOK | M_ZERO);
1131 
1132 	drmmode_obj = drm_mode_object_find(dev, put_image_rec->crtc_id,
1133 					   DRM_MODE_OBJECT_CRTC);
1134 	if (!drmmode_obj) {
1135 		ret = -ENOENT;
1136 		goto out_free;
1137 	}
1138 	crtc = to_intel_crtc(obj_to_crtc(drmmode_obj));
1139 
1140 	new_bo = to_intel_bo(drm_gem_object_lookup(dev, file_priv,
1141 						   put_image_rec->bo_handle));
1142 	if (&new_bo->base == NULL) {
1143 		ret = -ENOENT;
1144 		goto out_free;
1145 	}
1146 
1147 	lockmgr(&dev->mode_config.mutex, LK_EXCLUSIVE);
1148 	DRM_LOCK(dev);
1149 
1150 	if (new_bo->tiling_mode) {
1151 		DRM_ERROR("buffer used for overlay image can not be tiled\n");
1152 		ret = -EINVAL;
1153 		goto out_unlock;
1154 	}
1155 
1156 	ret = intel_overlay_recover_from_interrupt(overlay);
1157 	if (ret != 0)
1158 		goto out_unlock;
1159 
1160 	if (overlay->crtc != crtc) {
1161 		struct drm_display_mode *mode = &crtc->base.mode;
1162 		ret = intel_overlay_switch_off(overlay);
1163 		if (ret != 0)
1164 			goto out_unlock;
1165 
1166 		ret = check_overlay_possible_on_crtc(overlay, crtc);
1167 		if (ret != 0)
1168 			goto out_unlock;
1169 
1170 		overlay->crtc = crtc;
1171 		crtc->overlay = overlay;
1172 
1173 		/* line too wide, i.e. one-line-mode */
1174 		if (mode->hdisplay > 1024 &&
1175 		    intel_panel_fitter_pipe(dev) == crtc->pipe) {
1176 			overlay->pfit_active = 1;
1177 			update_pfit_vscale_ratio(overlay);
1178 		} else
1179 			overlay->pfit_active = 0;
1180 	}
1181 
1182 	ret = check_overlay_dst(overlay, put_image_rec);
1183 	if (ret != 0)
1184 		goto out_unlock;
1185 
1186 	if (overlay->pfit_active) {
1187 		params->dst_y = ((((u32)put_image_rec->dst_y) << 12) /
1188 				 overlay->pfit_vscale_ratio);
1189 		/* shifting right rounds downwards, so add 1 */
1190 		params->dst_h = ((((u32)put_image_rec->dst_height) << 12) /
1191 				 overlay->pfit_vscale_ratio) + 1;
1192 	} else {
1193 		params->dst_y = put_image_rec->dst_y;
1194 		params->dst_h = put_image_rec->dst_height;
1195 	}
1196 	params->dst_x = put_image_rec->dst_x;
1197 	params->dst_w = put_image_rec->dst_width;
1198 
1199 	params->src_w = put_image_rec->src_width;
1200 	params->src_h = put_image_rec->src_height;
1201 	params->src_scan_w = put_image_rec->src_scan_width;
1202 	params->src_scan_h = put_image_rec->src_scan_height;
1203 	if (params->src_scan_h > params->src_h ||
1204 	    params->src_scan_w > params->src_w) {
1205 		ret = -EINVAL;
1206 		goto out_unlock;
1207 	}
1208 
1209 	ret = check_overlay_src(dev, put_image_rec, new_bo);
1210 	if (ret != 0)
1211 		goto out_unlock;
1212 	params->format = put_image_rec->flags & ~I915_OVERLAY_FLAGS_MASK;
1213 	params->stride_Y = put_image_rec->stride_Y;
1214 	params->stride_UV = put_image_rec->stride_UV;
1215 	params->offset_Y = put_image_rec->offset_Y;
1216 	params->offset_U = put_image_rec->offset_U;
1217 	params->offset_V = put_image_rec->offset_V;
1218 
1219 	/* Check scaling after src size to prevent a divide-by-zero. */
1220 	ret = check_overlay_scaling(params);
1221 	if (ret != 0)
1222 		goto out_unlock;
1223 
1224 	ret = intel_overlay_do_put_image(overlay, new_bo, params);
1225 	if (ret != 0)
1226 		goto out_unlock;
1227 
1228 	DRM_UNLOCK(dev);
1229 	lockmgr(&dev->mode_config.mutex, LK_RELEASE);
1230 
1231 	drm_free(params, DRM_I915_GEM);
1232 
1233 	return 0;
1234 
1235 out_unlock:
1236 	DRM_UNLOCK(dev);
1237 	lockmgr(&dev->mode_config.mutex, LK_RELEASE);
1238 	drm_gem_object_unreference_unlocked(&new_bo->base);
1239 out_free:
1240 	drm_free(params, DRM_I915_GEM);
1241 
1242 	return ret;
1243 }
1244 
1245 static void update_reg_attrs(struct intel_overlay *overlay,
1246 			     struct overlay_registers *regs)
1247 {
1248 	regs->OCLRC0 = (overlay->contrast << 18) | (overlay->brightness & 0xff);
1249 	regs->OCLRC1 = overlay->saturation;
1250 }
1251 
1252 static bool check_gamma_bounds(u32 gamma1, u32 gamma2)
1253 {
1254 	int i;
1255 
1256 	if (gamma1 & 0xff000000 || gamma2 & 0xff000000)
1257 		return false;
1258 
1259 	for (i = 0; i < 3; i++) {
1260 		if (((gamma1 >> i*8) & 0xff) >= ((gamma2 >> i*8) & 0xff))
1261 			return false;
1262 	}
1263 
1264 	return true;
1265 }
1266 
1267 static bool check_gamma5_errata(u32 gamma5)
1268 {
1269 	int i;
1270 
1271 	for (i = 0; i < 3; i++) {
1272 		if (((gamma5 >> i*8) & 0xff) == 0x80)
1273 			return false;
1274 	}
1275 
1276 	return true;
1277 }
1278 
1279 static int check_gamma(struct drm_intel_overlay_attrs *attrs)
1280 {
1281 	if (!check_gamma_bounds(0, attrs->gamma0) ||
1282 	    !check_gamma_bounds(attrs->gamma0, attrs->gamma1) ||
1283 	    !check_gamma_bounds(attrs->gamma1, attrs->gamma2) ||
1284 	    !check_gamma_bounds(attrs->gamma2, attrs->gamma3) ||
1285 	    !check_gamma_bounds(attrs->gamma3, attrs->gamma4) ||
1286 	    !check_gamma_bounds(attrs->gamma4, attrs->gamma5) ||
1287 	    !check_gamma_bounds(attrs->gamma5, 0x00ffffff))
1288 		return -EINVAL;
1289 
1290 	if (!check_gamma5_errata(attrs->gamma5))
1291 		return -EINVAL;
1292 
1293 	return 0;
1294 }
1295 
1296 int intel_overlay_attrs(struct drm_device *dev, void *data,
1297 			struct drm_file *file_priv)
1298 {
1299 	struct drm_intel_overlay_attrs *attrs = data;
1300 	drm_i915_private_t *dev_priv = dev->dev_private;
1301 	struct intel_overlay *overlay;
1302 	struct overlay_registers *regs;
1303 	int ret;
1304 
1305 	if (!dev_priv) {
1306 		DRM_ERROR("called with no initialization\n");
1307 		return -EINVAL;
1308 	}
1309 
1310 	overlay = dev_priv->overlay;
1311 	if (!overlay) {
1312 		DRM_DEBUG("userspace bug: no overlay\n");
1313 		return -ENODEV;
1314 	}
1315 
1316 	lockmgr(&dev->mode_config.mutex, LK_EXCLUSIVE);
1317 	DRM_LOCK(dev);
1318 
1319 	ret = -EINVAL;
1320 	if (!(attrs->flags & I915_OVERLAY_UPDATE_ATTRS)) {
1321 		attrs->color_key  = overlay->color_key;
1322 		attrs->brightness = overlay->brightness;
1323 		attrs->contrast   = overlay->contrast;
1324 		attrs->saturation = overlay->saturation;
1325 
1326 		if (!IS_GEN2(dev)) {
1327 			attrs->gamma0 = I915_READ(OGAMC0);
1328 			attrs->gamma1 = I915_READ(OGAMC1);
1329 			attrs->gamma2 = I915_READ(OGAMC2);
1330 			attrs->gamma3 = I915_READ(OGAMC3);
1331 			attrs->gamma4 = I915_READ(OGAMC4);
1332 			attrs->gamma5 = I915_READ(OGAMC5);
1333 		}
1334 	} else {
1335 		if (attrs->brightness < -128 || attrs->brightness > 127)
1336 			goto out_unlock;
1337 		if (attrs->contrast > 255)
1338 			goto out_unlock;
1339 		if (attrs->saturation > 1023)
1340 			goto out_unlock;
1341 
1342 		overlay->color_key  = attrs->color_key;
1343 		overlay->brightness = attrs->brightness;
1344 		overlay->contrast   = attrs->contrast;
1345 		overlay->saturation = attrs->saturation;
1346 
1347 		regs = intel_overlay_map_regs(overlay);
1348 		if (!regs) {
1349 			ret = -ENOMEM;
1350 			goto out_unlock;
1351 		}
1352 
1353 		update_reg_attrs(overlay, regs);
1354 
1355 		intel_overlay_unmap_regs(overlay, regs);
1356 
1357 		if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) {
1358 			if (IS_GEN2(dev))
1359 				goto out_unlock;
1360 
1361 			if (overlay->active) {
1362 				ret = -EBUSY;
1363 				goto out_unlock;
1364 			}
1365 
1366 			ret = check_gamma(attrs);
1367 			if (ret)
1368 				goto out_unlock;
1369 
1370 			I915_WRITE(OGAMC0, attrs->gamma0);
1371 			I915_WRITE(OGAMC1, attrs->gamma1);
1372 			I915_WRITE(OGAMC2, attrs->gamma2);
1373 			I915_WRITE(OGAMC3, attrs->gamma3);
1374 			I915_WRITE(OGAMC4, attrs->gamma4);
1375 			I915_WRITE(OGAMC5, attrs->gamma5);
1376 		}
1377 	}
1378 
1379 	ret = 0;
1380 out_unlock:
1381 	DRM_UNLOCK(dev);
1382 	lockmgr(&dev->mode_config.mutex, LK_RELEASE);
1383 
1384 	return ret;
1385 }
1386 
1387 void intel_setup_overlay(struct drm_device *dev)
1388 {
1389 	drm_i915_private_t *dev_priv = dev->dev_private;
1390 	struct intel_overlay *overlay;
1391 	struct drm_i915_gem_object *reg_bo;
1392 	struct overlay_registers *regs;
1393 	int ret;
1394 
1395 	if (!HAS_OVERLAY(dev))
1396 		return;
1397 
1398 	overlay = kmalloc(sizeof(struct intel_overlay), DRM_I915_GEM,
1399 	    M_WAITOK | M_ZERO);
1400 	DRM_LOCK(dev);
1401 	if (dev_priv->overlay != NULL)
1402 		goto out_free;
1403 	overlay->dev = dev;
1404 
1405 	reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE);
1406 	if (!reg_bo)
1407 		goto out_free;
1408 	overlay->reg_bo = reg_bo;
1409 
1410 	if (OVERLAY_NEEDS_PHYSICAL(dev)) {
1411 		ret = i915_gem_attach_phys_object(dev, reg_bo,
1412 						  I915_GEM_PHYS_OVERLAY_REGS,
1413 						  PAGE_SIZE);
1414 		if (ret) {
1415 			DRM_ERROR("failed to attach phys overlay regs\n");
1416 			goto out_free_bo;
1417 		}
1418 		overlay->flip_addr = reg_bo->phys_obj->handle->busaddr;
1419 	} else {
1420 		ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true);
1421 		if (ret) {
1422 			DRM_ERROR("failed to pin overlay register bo\n");
1423 			goto out_free_bo;
1424 		}
1425 		overlay->flip_addr = reg_bo->gtt_offset;
1426 
1427 		ret = i915_gem_object_set_to_gtt_domain(reg_bo, true);
1428 		if (ret) {
1429 			DRM_ERROR("failed to move overlay register bo into the GTT\n");
1430 			goto out_unpin_bo;
1431 		}
1432 	}
1433 
1434 	/* init all values */
1435 	overlay->color_key = 0x0101fe;
1436 	overlay->brightness = -19;
1437 	overlay->contrast = 75;
1438 	overlay->saturation = 146;
1439 
1440 	regs = intel_overlay_map_regs(overlay);
1441 	if (!regs)
1442 		goto out_unpin_bo;
1443 
1444 	memset(regs, 0, sizeof(struct overlay_registers));
1445 	update_polyphase_filter(regs);
1446 	update_reg_attrs(overlay, regs);
1447 
1448 	intel_overlay_unmap_regs(overlay, regs);
1449 
1450 	dev_priv->overlay = overlay;
1451 	DRM_INFO("initialized overlay support\n");
1452 	DRM_UNLOCK(dev);
1453 	return;
1454 
1455 out_unpin_bo:
1456 	if (!OVERLAY_NEEDS_PHYSICAL(dev))
1457 		i915_gem_object_unpin(reg_bo);
1458 out_free_bo:
1459 	drm_gem_object_unreference(&reg_bo->base);
1460 out_free:
1461 	DRM_UNLOCK(dev);
1462 	drm_free(overlay, DRM_I915_GEM);
1463 	return;
1464 }
1465 
1466 void intel_cleanup_overlay(struct drm_device *dev)
1467 {
1468 	drm_i915_private_t *dev_priv = dev->dev_private;
1469 
1470 	if (!dev_priv->overlay)
1471 		return;
1472 
1473 	/* The bo's should be free'd by the generic code already.
1474 	 * Furthermore modesetting teardown happens beforehand so the
1475 	 * hardware should be off already */
1476 	KASSERT(!dev_priv->overlay->active, ("Overlay still active"));
1477 
1478 	drm_gem_object_unreference_unlocked(&dev_priv->overlay->reg_bo->base);
1479 	drm_free(dev_priv->overlay, DRM_I915_GEM);
1480 }
1481 
1482 struct intel_overlay_error_state {
1483 	struct overlay_registers regs;
1484 	unsigned long base;
1485 	u32 dovsta;
1486 	u32 isr;
1487 };
1488 
1489 struct intel_overlay_error_state *
1490 intel_overlay_capture_error_state(struct drm_device *dev)
1491 {
1492 	drm_i915_private_t *dev_priv = dev->dev_private;
1493 	struct intel_overlay *overlay = dev_priv->overlay;
1494 	struct intel_overlay_error_state *error;
1495 	struct overlay_registers __iomem *regs;
1496 
1497 	if (!overlay || !overlay->active)
1498 		return NULL;
1499 
1500 	error = kmalloc(sizeof(*error), DRM_I915_GEM, M_NOWAIT);
1501 	if (error == NULL)
1502 		return NULL;
1503 
1504 	error->dovsta = I915_READ(DOVSTA);
1505 	error->isr = I915_READ(ISR);
1506 	if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
1507 		error->base = (long) overlay->reg_bo->phys_obj->handle->vaddr;
1508 	else
1509 		error->base = (long) overlay->reg_bo->gtt_offset;
1510 
1511 	regs = intel_overlay_map_regs(overlay);
1512 	if (!regs)
1513 		goto err;
1514 
1515 	memcpy(&error->regs, regs, sizeof(struct overlay_registers));
1516 	intel_overlay_unmap_regs(overlay, regs);
1517 
1518 	return (error);
1519 
1520 err:
1521 	drm_free(error, DRM_I915_GEM);
1522 	return (NULL);
1523 }
1524 
1525 void
1526 intel_overlay_print_error_state(struct sbuf *m,
1527     struct intel_overlay_error_state *error)
1528 {
1529 	sbuf_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
1530 	    error->dovsta, error->isr);
1531 	sbuf_printf(m, "  Register file at 0x%08lx:\n",
1532 	    error->base);
1533 
1534 #define P(x) sbuf_printf(m, "    " #x ":	0x%08x\n", error->regs.x)
1535 	P(OBUF_0Y);
1536 	P(OBUF_1Y);
1537 	P(OBUF_0U);
1538 	P(OBUF_0V);
1539 	P(OBUF_1U);
1540 	P(OBUF_1V);
1541 	P(OSTRIDE);
1542 	P(YRGB_VPH);
1543 	P(UV_VPH);
1544 	P(HORZ_PH);
1545 	P(INIT_PHS);
1546 	P(DWINPOS);
1547 	P(DWINSZ);
1548 	P(SWIDTH);
1549 	P(SWIDTHSW);
1550 	P(SHEIGHT);
1551 	P(YRGBSCALE);
1552 	P(UVSCALE);
1553 	P(OCLRC0);
1554 	P(OCLRC1);
1555 	P(DCLRKV);
1556 	P(DCLRKM);
1557 	P(SCLRKVH);
1558 	P(SCLRKVL);
1559 	P(SCLRKEN);
1560 	P(OCONFIG);
1561 	P(OCMD);
1562 	P(OSTART_0Y);
1563 	P(OSTART_1Y);
1564 	P(OSTART_0U);
1565 	P(OSTART_0V);
1566 	P(OSTART_1U);
1567 	P(OSTART_1V);
1568 	P(OTILEOFF_0Y);
1569 	P(OTILEOFF_1Y);
1570 	P(OTILEOFF_0U);
1571 	P(OTILEOFF_0V);
1572 	P(OTILEOFF_1U);
1573 	P(OTILEOFF_1V);
1574 	P(FASTHSCALE);
1575 	P(UVSCALEV);
1576 #undef P
1577 }
1578