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