kref.h: Adapt to Linux 3.8's drm
[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         DRM_MODE_CONFIG_ASSERT_LOCKED(overlay->dev);
768
769         ret = intel_overlay_release_old_vid(overlay);
770         if (ret != 0)
771                 return ret;
772
773         ret = i915_gem_object_pin_to_display_plane(new_bo, 0, NULL);
774         if (ret != 0)
775                 goto out_unpin;
776
777         ret = i915_gem_object_put_fence(new_bo);
778         if (ret)
779                 goto out_unpin;
780
781         if (!overlay->active) {
782                 regs = intel_overlay_map_regs(overlay);
783                 if (!regs) {
784                         ret = -ENOMEM;
785                         goto out_unpin;
786                 }
787                 regs->OCONFIG = OCONF_CC_OUT_8BIT;
788                 if (IS_GEN4(overlay->dev))
789                         regs->OCONFIG |= OCONF_CSC_MODE_BT709;
790                 regs->OCONFIG |= overlay->crtc->pipe == 0 ?
791                         OCONF_PIPE_A : OCONF_PIPE_B;
792                 intel_overlay_unmap_regs(overlay, regs);
793
794                 ret = intel_overlay_on(overlay);
795                 if (ret != 0)
796                         goto out_unpin;
797         }
798
799         regs = intel_overlay_map_regs(overlay);
800         if (!regs) {
801                 ret = -ENOMEM;
802                 goto out_unpin;
803         }
804
805         regs->DWINPOS = (params->dst_y << 16) | params->dst_x;
806         regs->DWINSZ = (params->dst_h << 16) | params->dst_w;
807
808         if (params->format & I915_OVERLAY_YUV_PACKED)
809                 tmp_width = packed_width_bytes(params->format, params->src_w);
810         else
811                 tmp_width = params->src_w;
812
813         regs->SWIDTH = params->src_w;
814         regs->SWIDTHSW = calc_swidthsw(overlay->dev,
815                                        params->offset_Y, tmp_width);
816         regs->SHEIGHT = params->src_h;
817         regs->OBUF_0Y = new_bo->gtt_offset + params->offset_Y;
818         regs->OSTRIDE = params->stride_Y;
819
820         if (params->format & I915_OVERLAY_YUV_PLANAR) {
821                 int uv_hscale = uv_hsubsampling(params->format);
822                 int uv_vscale = uv_vsubsampling(params->format);
823                 u32 tmp_U, tmp_V;
824                 regs->SWIDTH |= (params->src_w/uv_hscale) << 16;
825                 tmp_U = calc_swidthsw(overlay->dev, params->offset_U,
826                                       params->src_w/uv_hscale);
827                 tmp_V = calc_swidthsw(overlay->dev, params->offset_V,
828                                       params->src_w/uv_hscale);
829                 regs->SWIDTHSW |= max_u32(tmp_U, tmp_V) << 16;
830                 regs->SHEIGHT |= (params->src_h/uv_vscale) << 16;
831                 regs->OBUF_0U = new_bo->gtt_offset + params->offset_U;
832                 regs->OBUF_0V = new_bo->gtt_offset + params->offset_V;
833                 regs->OSTRIDE |= params->stride_UV << 16;
834         }
835
836         scale_changed = update_scaling_factors(overlay, regs, params);
837
838         update_colorkey(overlay, regs);
839
840         regs->OCMD = overlay_cmd_reg(params);
841
842         intel_overlay_unmap_regs(overlay, regs);
843
844         ret = intel_overlay_continue(overlay, scale_changed);
845         if (ret)
846                 goto out_unpin;
847
848         overlay->old_vid_bo = overlay->vid_bo;
849         overlay->vid_bo = new_bo;
850
851         return 0;
852
853 out_unpin:
854         i915_gem_object_unpin(new_bo);
855         return ret;
856 }
857
858 int intel_overlay_switch_off(struct intel_overlay *overlay)
859 {
860         struct overlay_registers *regs;
861         int ret;
862
863         DRM_LOCK_ASSERT(overlay->dev);
864         DRM_MODE_CONFIG_ASSERT_LOCKED(overlay->dev);
865
866         ret = intel_overlay_recover_from_interrupt(overlay);
867         if (ret != 0)
868                 return ret;
869
870         if (!overlay->active)
871                 return 0;
872
873         ret = intel_overlay_release_old_vid(overlay);
874         if (ret != 0)
875                 return ret;
876
877         regs = intel_overlay_map_regs(overlay);
878         regs->OCMD = 0;
879         intel_overlay_unmap_regs(overlay, regs);
880
881         ret = intel_overlay_off(overlay);
882         if (ret != 0)
883                 return ret;
884
885         intel_overlay_off_tail(overlay);
886         return 0;
887 }
888
889 static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
890                                           struct intel_crtc *crtc)
891 {
892         drm_i915_private_t *dev_priv = overlay->dev->dev_private;
893
894         if (!crtc->active)
895                 return -EINVAL;
896
897         /* can't use the overlay with double wide pipe */
898         if (INTEL_INFO(overlay->dev)->gen < 4 &&
899             (I915_READ(PIPECONF(crtc->pipe)) & (PIPECONF_DOUBLE_WIDE | PIPECONF_ENABLE)) != PIPECONF_ENABLE)
900                 return -EINVAL;
901
902         return 0;
903 }
904
905 static void update_pfit_vscale_ratio(struct intel_overlay *overlay)
906 {
907         struct drm_device *dev = overlay->dev;
908         drm_i915_private_t *dev_priv = dev->dev_private;
909         u32 pfit_control = I915_READ(PFIT_CONTROL);
910         u32 ratio;
911
912         /* XXX: This is not the same logic as in the xorg driver, but more in
913          * line with the intel documentation for the i965
914          */
915         if (INTEL_INFO(dev)->gen >= 4) {
916                 /* on i965 use the PGM reg to read out the autoscaler values */
917                 ratio = I915_READ(PFIT_PGM_RATIOS) >> PFIT_VERT_SCALE_SHIFT_965;
918         } else {
919                 if (pfit_control & VERT_AUTO_SCALE)
920                         ratio = I915_READ(PFIT_AUTO_RATIOS);
921                 else
922                         ratio = I915_READ(PFIT_PGM_RATIOS);
923                 ratio >>= PFIT_VERT_SCALE_SHIFT;
924         }
925
926         overlay->pfit_vscale_ratio = ratio;
927 }
928
929 static int check_overlay_dst(struct intel_overlay *overlay,
930                              struct drm_intel_overlay_put_image *rec)
931 {
932         struct drm_display_mode *mode = &overlay->crtc->base.mode;
933
934         if (rec->dst_x < mode->hdisplay &&
935             rec->dst_x + rec->dst_width <= mode->hdisplay &&
936             rec->dst_y < mode->vdisplay &&
937             rec->dst_y + rec->dst_height <= mode->vdisplay)
938                 return 0;
939         else
940                 return -EINVAL;
941 }
942
943 static int check_overlay_scaling(struct put_image_params *rec)
944 {
945         u32 tmp;
946
947         /* downscaling limit is 8.0 */
948         tmp = ((rec->src_scan_h << 16) / rec->dst_h) >> 16;
949         if (tmp > 7)
950                 return -EINVAL;
951         tmp = ((rec->src_scan_w << 16) / rec->dst_w) >> 16;
952         if (tmp > 7)
953                 return -EINVAL;
954
955         return 0;
956 }
957
958 static int check_overlay_src(struct drm_device *dev,
959                              struct drm_intel_overlay_put_image *rec,
960                              struct drm_i915_gem_object *new_bo)
961 {
962         int uv_hscale = uv_hsubsampling(rec->flags);
963         int uv_vscale = uv_vsubsampling(rec->flags);
964         u32 stride_mask;
965         int depth;
966         u32 tmp;
967
968         /* check src dimensions */
969         if (IS_845G(dev) || IS_I830(dev)) {
970                 if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY ||
971                     rec->src_width  > IMAGE_MAX_WIDTH_LEGACY)
972                         return -EINVAL;
973         } else {
974                 if (rec->src_height > IMAGE_MAX_HEIGHT ||
975                     rec->src_width  > IMAGE_MAX_WIDTH)
976                         return -EINVAL;
977         }
978
979         /* better safe than sorry, use 4 as the maximal subsampling ratio */
980         if (rec->src_height < N_VERT_Y_TAPS*4 ||
981             rec->src_width  < N_HORIZ_Y_TAPS*4)
982                 return -EINVAL;
983
984         /* check alignment constraints */
985         switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
986         case I915_OVERLAY_RGB:
987                 /* not implemented */
988                 return -EINVAL;
989
990         case I915_OVERLAY_YUV_PACKED:
991                 if (uv_vscale != 1)
992                         return -EINVAL;
993
994                 depth = packed_depth_bytes(rec->flags);
995                 if (depth < 0)
996                         return depth;
997
998                 /* ignore UV planes */
999                 rec->stride_UV = 0;
1000                 rec->offset_U = 0;
1001                 rec->offset_V = 0;
1002                 /* check pixel alignment */
1003                 if (rec->offset_Y % depth)
1004                         return -EINVAL;
1005                 break;
1006
1007         case I915_OVERLAY_YUV_PLANAR:
1008                 if (uv_vscale < 0 || uv_hscale < 0)
1009                         return -EINVAL;
1010                 /* no offset restrictions for planar formats */
1011                 break;
1012
1013         default:
1014                 return -EINVAL;
1015         }
1016
1017         if (rec->src_width % uv_hscale)
1018                 return -EINVAL;
1019
1020         /* stride checking */
1021         if (IS_I830(dev) || IS_845G(dev))
1022                 stride_mask = 255;
1023         else
1024                 stride_mask = 63;
1025
1026         if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask)
1027                 return -EINVAL;
1028         if (IS_GEN4(dev) && rec->stride_Y < 512)
1029                 return -EINVAL;
1030
1031         tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ?
1032                 4096 : 8192;
1033         if (rec->stride_Y > tmp || rec->stride_UV > 2*1024)
1034                 return -EINVAL;
1035
1036         /* check buffer dimensions */
1037         switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
1038         case I915_OVERLAY_RGB:
1039         case I915_OVERLAY_YUV_PACKED:
1040                 /* always 4 Y values per depth pixels */
1041                 if (packed_width_bytes(rec->flags, rec->src_width) > rec->stride_Y)
1042                         return -EINVAL;
1043
1044                 tmp = rec->stride_Y*rec->src_height;
1045                 if (rec->offset_Y + tmp > new_bo->base.size)
1046                         return -EINVAL;
1047                 break;
1048
1049         case I915_OVERLAY_YUV_PLANAR:
1050                 if (rec->src_width > rec->stride_Y)
1051                         return -EINVAL;
1052                 if (rec->src_width/uv_hscale > rec->stride_UV)
1053                         return -EINVAL;
1054
1055                 tmp = rec->stride_Y * rec->src_height;
1056                 if (rec->offset_Y + tmp > new_bo->base.size)
1057                         return -EINVAL;
1058
1059                 tmp = rec->stride_UV * (rec->src_height / uv_vscale);
1060                 if (rec->offset_U + tmp > new_bo->base.size ||
1061                     rec->offset_V + tmp > new_bo->base.size)
1062                         return -EINVAL;
1063                 break;
1064         }
1065
1066         return 0;
1067 }
1068
1069 /**
1070  * Return the pipe currently connected to the panel fitter,
1071  * or -1 if the panel fitter is not present or not in use
1072  */
1073 static int intel_panel_fitter_pipe(struct drm_device *dev)
1074 {
1075         struct drm_i915_private *dev_priv = dev->dev_private;
1076         u32  pfit_control;
1077
1078         /* i830 doesn't have a panel fitter */
1079         if (IS_I830(dev))
1080                 return -1;
1081
1082         pfit_control = I915_READ(PFIT_CONTROL);
1083
1084         /* See if the panel fitter is in use */
1085         if ((pfit_control & PFIT_ENABLE) == 0)
1086                 return -1;
1087
1088         /* 965 can place panel fitter on either pipe */
1089         if (IS_GEN4(dev))
1090                 return (pfit_control >> 29) & 0x3;
1091
1092         /* older chips can only use pipe 1 */
1093         return 1;
1094 }
1095
1096 int intel_overlay_put_image(struct drm_device *dev, void *data,
1097                             struct drm_file *file_priv)
1098 {
1099         struct drm_intel_overlay_put_image *put_image_rec = data;
1100         drm_i915_private_t *dev_priv = dev->dev_private;
1101         struct intel_overlay *overlay;
1102         struct drm_mode_object *drmmode_obj;
1103         struct intel_crtc *crtc;
1104         struct drm_i915_gem_object *new_bo;
1105         struct put_image_params *params;
1106         int ret;
1107
1108         if (!dev_priv) {
1109                 DRM_ERROR("called with no initialization\n");
1110                 return -EINVAL;
1111         }
1112
1113         overlay = dev_priv->overlay;
1114         if (!overlay) {
1115                 DRM_DEBUG("userspace bug: no overlay\n");
1116                 return -ENODEV;
1117         }
1118
1119         if (!(put_image_rec->flags & I915_OVERLAY_ENABLE)) {
1120                 lockmgr(&dev->mode_config.lock, LK_EXCLUSIVE);
1121                 DRM_LOCK(dev);
1122
1123                 ret = intel_overlay_switch_off(overlay);
1124
1125                 DRM_UNLOCK(dev);
1126                 lockmgr(&dev->mode_config.lock, LK_RELEASE);
1127
1128                 return ret;
1129         }
1130
1131         params = kmalloc(sizeof(struct put_image_params), DRM_I915_GEM,
1132             M_WAITOK | M_ZERO);
1133
1134         drmmode_obj = drm_mode_object_find(dev, put_image_rec->crtc_id,
1135                                            DRM_MODE_OBJECT_CRTC);
1136         if (!drmmode_obj) {
1137                 ret = -ENOENT;
1138                 goto out_free;
1139         }
1140         crtc = to_intel_crtc(obj_to_crtc(drmmode_obj));
1141
1142         new_bo = to_intel_bo(drm_gem_object_lookup(dev, file_priv,
1143                                                    put_image_rec->bo_handle));
1144         if (&new_bo->base == NULL) {
1145                 ret = -ENOENT;
1146                 goto out_free;
1147         }
1148
1149         lockmgr(&dev->mode_config.lock, LK_EXCLUSIVE);
1150         DRM_LOCK(dev);
1151
1152         if (new_bo->tiling_mode) {
1153                 DRM_ERROR("buffer used for overlay image can not be tiled\n");
1154                 ret = -EINVAL;
1155                 goto out_unlock;
1156         }
1157
1158         ret = intel_overlay_recover_from_interrupt(overlay);
1159         if (ret != 0)
1160                 goto out_unlock;
1161
1162         if (overlay->crtc != crtc) {
1163                 struct drm_display_mode *mode = &crtc->base.mode;
1164                 ret = intel_overlay_switch_off(overlay);
1165                 if (ret != 0)
1166                         goto out_unlock;
1167
1168                 ret = check_overlay_possible_on_crtc(overlay, crtc);
1169                 if (ret != 0)
1170                         goto out_unlock;
1171
1172                 overlay->crtc = crtc;
1173                 crtc->overlay = overlay;
1174
1175                 /* line too wide, i.e. one-line-mode */
1176                 if (mode->hdisplay > 1024 &&
1177                     intel_panel_fitter_pipe(dev) == crtc->pipe) {
1178                         overlay->pfit_active = 1;
1179                         update_pfit_vscale_ratio(overlay);
1180                 } else
1181                         overlay->pfit_active = 0;
1182         }
1183
1184         ret = check_overlay_dst(overlay, put_image_rec);
1185         if (ret != 0)
1186                 goto out_unlock;
1187
1188         if (overlay->pfit_active) {
1189                 params->dst_y = ((((u32)put_image_rec->dst_y) << 12) /
1190                                  overlay->pfit_vscale_ratio);
1191                 /* shifting right rounds downwards, so add 1 */
1192                 params->dst_h = ((((u32)put_image_rec->dst_height) << 12) /
1193                                  overlay->pfit_vscale_ratio) + 1;
1194         } else {
1195                 params->dst_y = put_image_rec->dst_y;
1196                 params->dst_h = put_image_rec->dst_height;
1197         }
1198         params->dst_x = put_image_rec->dst_x;
1199         params->dst_w = put_image_rec->dst_width;
1200
1201         params->src_w = put_image_rec->src_width;
1202         params->src_h = put_image_rec->src_height;
1203         params->src_scan_w = put_image_rec->src_scan_width;
1204         params->src_scan_h = put_image_rec->src_scan_height;
1205         if (params->src_scan_h > params->src_h ||
1206             params->src_scan_w > params->src_w) {
1207                 ret = -EINVAL;
1208                 goto out_unlock;
1209         }
1210
1211         ret = check_overlay_src(dev, put_image_rec, new_bo);
1212         if (ret != 0)
1213                 goto out_unlock;
1214         params->format = put_image_rec->flags & ~I915_OVERLAY_FLAGS_MASK;
1215         params->stride_Y = put_image_rec->stride_Y;
1216         params->stride_UV = put_image_rec->stride_UV;
1217         params->offset_Y = put_image_rec->offset_Y;
1218         params->offset_U = put_image_rec->offset_U;
1219         params->offset_V = put_image_rec->offset_V;
1220
1221         /* Check scaling after src size to prevent a divide-by-zero. */
1222         ret = check_overlay_scaling(params);
1223         if (ret != 0)
1224                 goto out_unlock;
1225
1226         ret = intel_overlay_do_put_image(overlay, new_bo, params);
1227         if (ret != 0)
1228                 goto out_unlock;
1229
1230         DRM_UNLOCK(dev);
1231         lockmgr(&dev->mode_config.lock, LK_RELEASE);
1232
1233         drm_free(params, DRM_I915_GEM);
1234
1235         return 0;
1236
1237 out_unlock:
1238         DRM_UNLOCK(dev);
1239         lockmgr(&dev->mode_config.lock, LK_RELEASE);
1240         drm_gem_object_unreference_unlocked(&new_bo->base);
1241 out_free:
1242         drm_free(params, DRM_I915_GEM);
1243
1244         return ret;
1245 }
1246
1247 static void update_reg_attrs(struct intel_overlay *overlay,
1248                              struct overlay_registers *regs)
1249 {
1250         regs->OCLRC0 = (overlay->contrast << 18) | (overlay->brightness & 0xff);
1251         regs->OCLRC1 = overlay->saturation;
1252 }
1253
1254 static bool check_gamma_bounds(u32 gamma1, u32 gamma2)
1255 {
1256         int i;
1257
1258         if (gamma1 & 0xff000000 || gamma2 & 0xff000000)
1259                 return false;
1260
1261         for (i = 0; i < 3; i++) {
1262                 if (((gamma1 >> i*8) & 0xff) >= ((gamma2 >> i*8) & 0xff))
1263                         return false;
1264         }
1265
1266         return true;
1267 }
1268
1269 static bool check_gamma5_errata(u32 gamma5)
1270 {
1271         int i;
1272
1273         for (i = 0; i < 3; i++) {
1274                 if (((gamma5 >> i*8) & 0xff) == 0x80)
1275                         return false;
1276         }
1277
1278         return true;
1279 }
1280
1281 static int check_gamma(struct drm_intel_overlay_attrs *attrs)
1282 {
1283         if (!check_gamma_bounds(0, attrs->gamma0) ||
1284             !check_gamma_bounds(attrs->gamma0, attrs->gamma1) ||
1285             !check_gamma_bounds(attrs->gamma1, attrs->gamma2) ||
1286             !check_gamma_bounds(attrs->gamma2, attrs->gamma3) ||
1287             !check_gamma_bounds(attrs->gamma3, attrs->gamma4) ||
1288             !check_gamma_bounds(attrs->gamma4, attrs->gamma5) ||
1289             !check_gamma_bounds(attrs->gamma5, 0x00ffffff))
1290                 return -EINVAL;
1291
1292         if (!check_gamma5_errata(attrs->gamma5))
1293                 return -EINVAL;
1294
1295         return 0;
1296 }
1297
1298 int intel_overlay_attrs(struct drm_device *dev, void *data,
1299                         struct drm_file *file_priv)
1300 {
1301         struct drm_intel_overlay_attrs *attrs = data;
1302         drm_i915_private_t *dev_priv = dev->dev_private;
1303         struct intel_overlay *overlay;
1304         struct overlay_registers *regs;
1305         int ret;
1306
1307         if (!dev_priv) {
1308                 DRM_ERROR("called with no initialization\n");
1309                 return -EINVAL;
1310         }
1311
1312         overlay = dev_priv->overlay;
1313         if (!overlay) {
1314                 DRM_DEBUG("userspace bug: no overlay\n");
1315                 return -ENODEV;
1316         }
1317
1318         lockmgr(&dev->mode_config.lock, LK_EXCLUSIVE);
1319         DRM_LOCK(dev);
1320
1321         ret = -EINVAL;
1322         if (!(attrs->flags & I915_OVERLAY_UPDATE_ATTRS)) {
1323                 attrs->color_key  = overlay->color_key;
1324                 attrs->brightness = overlay->brightness;
1325                 attrs->contrast   = overlay->contrast;
1326                 attrs->saturation = overlay->saturation;
1327
1328                 if (!IS_GEN2(dev)) {
1329                         attrs->gamma0 = I915_READ(OGAMC0);
1330                         attrs->gamma1 = I915_READ(OGAMC1);
1331                         attrs->gamma2 = I915_READ(OGAMC2);
1332                         attrs->gamma3 = I915_READ(OGAMC3);
1333                         attrs->gamma4 = I915_READ(OGAMC4);
1334                         attrs->gamma5 = I915_READ(OGAMC5);
1335                 }
1336         } else {
1337                 if (attrs->brightness < -128 || attrs->brightness > 127)
1338                         goto out_unlock;
1339                 if (attrs->contrast > 255)
1340                         goto out_unlock;
1341                 if (attrs->saturation > 1023)
1342                         goto out_unlock;
1343
1344                 overlay->color_key  = attrs->color_key;
1345                 overlay->brightness = attrs->brightness;
1346                 overlay->contrast   = attrs->contrast;
1347                 overlay->saturation = attrs->saturation;
1348
1349                 regs = intel_overlay_map_regs(overlay);
1350                 if (!regs) {
1351                         ret = -ENOMEM;
1352                         goto out_unlock;
1353                 }
1354
1355                 update_reg_attrs(overlay, regs);
1356
1357                 intel_overlay_unmap_regs(overlay, regs);
1358
1359                 if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) {
1360                         if (IS_GEN2(dev))
1361                                 goto out_unlock;
1362
1363                         if (overlay->active) {
1364                                 ret = -EBUSY;
1365                                 goto out_unlock;
1366                         }
1367
1368                         ret = check_gamma(attrs);
1369                         if (ret)
1370                                 goto out_unlock;
1371
1372                         I915_WRITE(OGAMC0, attrs->gamma0);
1373                         I915_WRITE(OGAMC1, attrs->gamma1);
1374                         I915_WRITE(OGAMC2, attrs->gamma2);
1375                         I915_WRITE(OGAMC3, attrs->gamma3);
1376                         I915_WRITE(OGAMC4, attrs->gamma4);
1377                         I915_WRITE(OGAMC5, attrs->gamma5);
1378                 }
1379         }
1380
1381         ret = 0;
1382 out_unlock:
1383         DRM_UNLOCK(dev);
1384         lockmgr(&dev->mode_config.lock, LK_RELEASE);
1385
1386         return ret;
1387 }
1388
1389 void intel_setup_overlay(struct drm_device *dev)
1390 {
1391         drm_i915_private_t *dev_priv = dev->dev_private;
1392         struct intel_overlay *overlay;
1393         struct drm_i915_gem_object *reg_bo;
1394         struct overlay_registers *regs;
1395         int ret;
1396
1397         if (!HAS_OVERLAY(dev))
1398                 return;
1399
1400         overlay = kmalloc(sizeof(struct intel_overlay), DRM_I915_GEM,
1401             M_WAITOK | M_ZERO);
1402         DRM_LOCK(dev);
1403         if (dev_priv->overlay != NULL)
1404                 goto out_free;
1405         overlay->dev = dev;
1406
1407         reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE);
1408         if (!reg_bo)
1409                 goto out_free;
1410         overlay->reg_bo = reg_bo;
1411
1412         if (OVERLAY_NEEDS_PHYSICAL(dev)) {
1413                 ret = i915_gem_attach_phys_object(dev, reg_bo,
1414                                                   I915_GEM_PHYS_OVERLAY_REGS,
1415                                                   PAGE_SIZE);
1416                 if (ret) {
1417                         DRM_ERROR("failed to attach phys overlay regs\n");
1418                         goto out_free_bo;
1419                 }
1420                 overlay->flip_addr = reg_bo->phys_obj->handle->busaddr;
1421         } else {
1422                 ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true);
1423                 if (ret) {
1424                         DRM_ERROR("failed to pin overlay register bo\n");
1425                         goto out_free_bo;
1426                 }
1427                 overlay->flip_addr = reg_bo->gtt_offset;
1428
1429                 ret = i915_gem_object_set_to_gtt_domain(reg_bo, true);
1430                 if (ret) {
1431                         DRM_ERROR("failed to move overlay register bo into the GTT\n");
1432                         goto out_unpin_bo;
1433                 }
1434         }
1435
1436         /* init all values */
1437         overlay->color_key = 0x0101fe;
1438         overlay->brightness = -19;
1439         overlay->contrast = 75;
1440         overlay->saturation = 146;
1441
1442         regs = intel_overlay_map_regs(overlay);
1443         if (!regs)
1444                 goto out_unpin_bo;
1445
1446         memset(regs, 0, sizeof(struct overlay_registers));
1447         update_polyphase_filter(regs);
1448         update_reg_attrs(overlay, regs);
1449
1450         intel_overlay_unmap_regs(overlay, regs);
1451
1452         dev_priv->overlay = overlay;
1453         DRM_INFO("initialized overlay support\n");
1454         DRM_UNLOCK(dev);
1455         return;
1456
1457 out_unpin_bo:
1458         if (!OVERLAY_NEEDS_PHYSICAL(dev))
1459                 i915_gem_object_unpin(reg_bo);
1460 out_free_bo:
1461         drm_gem_object_unreference(&reg_bo->base);
1462 out_free:
1463         DRM_UNLOCK(dev);
1464         drm_free(overlay, DRM_I915_GEM);
1465         return;
1466 }
1467
1468 void intel_cleanup_overlay(struct drm_device *dev)
1469 {
1470         drm_i915_private_t *dev_priv = dev->dev_private;
1471
1472         if (!dev_priv->overlay)
1473                 return;
1474
1475         /* The bo's should be free'd by the generic code already.
1476          * Furthermore modesetting teardown happens beforehand so the
1477          * hardware should be off already */
1478         KASSERT(!dev_priv->overlay->active, ("Overlay still active"));
1479
1480         drm_gem_object_unreference_unlocked(&dev_priv->overlay->reg_bo->base);
1481         drm_free(dev_priv->overlay, DRM_I915_GEM);
1482 }
1483
1484 struct intel_overlay_error_state {
1485         struct overlay_registers regs;
1486         unsigned long base;
1487         u32 dovsta;
1488         u32 isr;
1489 };
1490
1491 struct intel_overlay_error_state *
1492 intel_overlay_capture_error_state(struct drm_device *dev)
1493 {
1494         drm_i915_private_t *dev_priv = dev->dev_private;
1495         struct intel_overlay *overlay = dev_priv->overlay;
1496         struct intel_overlay_error_state *error;
1497         struct overlay_registers __iomem *regs;
1498
1499         if (!overlay || !overlay->active)
1500                 return NULL;
1501
1502         error = kmalloc(sizeof(*error), DRM_I915_GEM, M_NOWAIT);
1503         if (error == NULL)
1504                 return NULL;
1505
1506         error->dovsta = I915_READ(DOVSTA);
1507         error->isr = I915_READ(ISR);
1508         if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
1509                 error->base = (long) overlay->reg_bo->phys_obj->handle->vaddr;
1510         else
1511                 error->base = (long) overlay->reg_bo->gtt_offset;
1512
1513         regs = intel_overlay_map_regs(overlay);
1514         if (!regs)
1515                 goto err;
1516
1517         memcpy(&error->regs, regs, sizeof(struct overlay_registers));
1518         intel_overlay_unmap_regs(overlay, regs);
1519
1520         return (error);
1521
1522 err:
1523         drm_free(error, DRM_I915_GEM);
1524         return (NULL);
1525 }
1526
1527 void
1528 intel_overlay_print_error_state(struct sbuf *m,
1529     struct intel_overlay_error_state *error)
1530 {
1531         sbuf_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
1532             error->dovsta, error->isr);
1533         sbuf_printf(m, "  Register file at 0x%08lx:\n",
1534             error->base);
1535
1536 #define P(x) sbuf_printf(m, "    " #x ":        0x%08x\n", error->regs.x)
1537         P(OBUF_0Y);
1538         P(OBUF_1Y);
1539         P(OBUF_0U);
1540         P(OBUF_0V);
1541         P(OBUF_1U);
1542         P(OBUF_1V);
1543         P(OSTRIDE);
1544         P(YRGB_VPH);
1545         P(UV_VPH);
1546         P(HORZ_PH);
1547         P(INIT_PHS);
1548         P(DWINPOS);
1549         P(DWINSZ);
1550         P(SWIDTH);
1551         P(SWIDTHSW);
1552         P(SHEIGHT);
1553         P(YRGBSCALE);
1554         P(UVSCALE);
1555         P(OCLRC0);
1556         P(OCLRC1);
1557         P(DCLRKV);
1558         P(DCLRKM);
1559         P(SCLRKVH);
1560         P(SCLRKVL);
1561         P(SCLRKEN);
1562         P(OCONFIG);
1563         P(OCMD);
1564         P(OSTART_0Y);
1565         P(OSTART_1Y);
1566         P(OSTART_0U);
1567         P(OSTART_0V);
1568         P(OSTART_1U);
1569         P(OSTART_1V);
1570         P(OTILEOFF_0Y);
1571         P(OTILEOFF_1Y);
1572         P(OTILEOFF_0U);
1573         P(OTILEOFF_0V);
1574         P(OTILEOFF_1U);
1575         P(OTILEOFF_1V);
1576         P(FASTHSCALE);
1577         P(UVSCALEV);
1578 #undef P
1579 }