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