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