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