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