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