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