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