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