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