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(®_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