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