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