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