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