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