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