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:
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
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
24 * Daniel Vetter <daniel@ffwll.ch>
26 * Derived from Xorg ddx, xf86-video-intel, src/i830_video.c
29 #include <drm/i915_drm.h>
32 #include "intel_drv.h"
34 /* Limits for overlay size. According to intel doc, the real limits are:
35 * Y width: 4095, UV width (planar): 2047, Y height: 2047,
36 * UV width (planar): * 1023. But the xorg thinks 2048 for height and width. Use
37 * the mininum of both. */
38 #define IMAGE_MAX_WIDTH 2048
39 #define IMAGE_MAX_HEIGHT 2046 /* 2 * 1023 */
40 /* on 830 and 845 these large limits result in the card hanging */
41 #define IMAGE_MAX_WIDTH_LEGACY 1024
42 #define IMAGE_MAX_HEIGHT_LEGACY 1088
44 /* overlay register definitions */
46 #define OCMD_TILED_SURFACE (0x1<<19)
47 #define OCMD_MIRROR_MASK (0x3<<17)
48 #define OCMD_MIRROR_MODE (0x3<<17)
49 #define OCMD_MIRROR_HORIZONTAL (0x1<<17)
50 #define OCMD_MIRROR_VERTICAL (0x2<<17)
51 #define OCMD_MIRROR_BOTH (0x3<<17)
52 #define OCMD_BYTEORDER_MASK (0x3<<14) /* zero for YUYV or FOURCC YUY2 */
53 #define OCMD_UV_SWAP (0x1<<14) /* YVYU */
54 #define OCMD_Y_SWAP (0x2<<14) /* UYVY or FOURCC UYVY */
55 #define OCMD_Y_AND_UV_SWAP (0x3<<14) /* VYUY */
56 #define OCMD_SOURCE_FORMAT_MASK (0xf<<10)
57 #define OCMD_RGB_888 (0x1<<10) /* not in i965 Intel docs */
58 #define OCMD_RGB_555 (0x2<<10) /* not in i965 Intel docs */
59 #define OCMD_RGB_565 (0x3<<10) /* not in i965 Intel docs */
60 #define OCMD_YUV_422_PACKED (0x8<<10)
61 #define OCMD_YUV_411_PACKED (0x9<<10) /* not in i965 Intel docs */
62 #define OCMD_YUV_420_PLANAR (0xc<<10)
63 #define OCMD_YUV_422_PLANAR (0xd<<10)
64 #define OCMD_YUV_410_PLANAR (0xe<<10) /* also 411 */
65 #define OCMD_TVSYNCFLIP_PARITY (0x1<<9)
66 #define OCMD_TVSYNCFLIP_ENABLE (0x1<<7)
67 #define OCMD_BUF_TYPE_MASK (0x1<<5)
68 #define OCMD_BUF_TYPE_FRAME (0x0<<5)
69 #define OCMD_BUF_TYPE_FIELD (0x1<<5)
70 #define OCMD_TEST_MODE (0x1<<4)
71 #define OCMD_BUFFER_SELECT (0x3<<2)
72 #define OCMD_BUFFER0 (0x0<<2)
73 #define OCMD_BUFFER1 (0x1<<2)
74 #define OCMD_FIELD_SELECT (0x1<<2)
75 #define OCMD_FIELD0 (0x0<<1)
76 #define OCMD_FIELD1 (0x1<<1)
77 #define OCMD_ENABLE (0x1<<0)
79 /* OCONFIG register */
80 #define OCONF_PIPE_MASK (0x1<<18)
81 #define OCONF_PIPE_A (0x0<<18)
82 #define OCONF_PIPE_B (0x1<<18)
83 #define OCONF_GAMMA2_ENABLE (0x1<<16)
84 #define OCONF_CSC_MODE_BT601 (0x0<<5)
85 #define OCONF_CSC_MODE_BT709 (0x1<<5)
86 #define OCONF_CSC_BYPASS (0x1<<4)
87 #define OCONF_CC_OUT_8BIT (0x1<<3)
88 #define OCONF_TEST_MODE (0x1<<2)
89 #define OCONF_THREE_LINE_BUFFER (0x1<<0)
90 #define OCONF_TWO_LINE_BUFFER (0x0<<0)
92 /* DCLRKM (dst-key) register */
93 #define DST_KEY_ENABLE (0x1<<31)
94 #define CLK_RGB24_MASK 0x0
95 #define CLK_RGB16_MASK 0x070307
96 #define CLK_RGB15_MASK 0x070707
97 #define CLK_RGB8I_MASK 0xffffff
99 #define RGB16_TO_COLORKEY(c) \
100 (((c & 0xF800) << 8) | ((c & 0x07E0) << 5) | ((c & 0x001F) << 3))
101 #define RGB15_TO_COLORKEY(c) \
102 (((c & 0x7c00) << 9) | ((c & 0x03E0) << 6) | ((c & 0x001F) << 3))
104 /* overlay flip addr flag */
105 #define OFC_UPDATE 0x1
107 /* polyphase filter coefficients */
108 #define N_HORIZ_Y_TAPS 5
109 #define N_VERT_Y_TAPS 3
110 #define N_HORIZ_UV_TAPS 3
111 #define N_VERT_UV_TAPS 3
115 /* memory bufferd overlay registers */
116 struct overlay_registers
{
144 u32 RESERVED1
; /* 0x6C */
157 u32 FASTHSCALE
; /* 0xA0 */
158 u32 UVSCALEV
; /* 0xA4 */
159 u32 RESERVEDC
[(0x200 - 0xA8) / 4]; /* 0xA8 - 0x1FC */
160 u16 Y_VCOEFS
[N_VERT_Y_TAPS
* N_PHASES
]; /* 0x200 */
161 u16 RESERVEDD
[0x100 / 2 - N_VERT_Y_TAPS
* N_PHASES
];
162 u16 Y_HCOEFS
[N_HORIZ_Y_TAPS
* N_PHASES
]; /* 0x300 */
163 u16 RESERVEDE
[0x200 / 2 - N_HORIZ_Y_TAPS
* N_PHASES
];
164 u16 UV_VCOEFS
[N_VERT_UV_TAPS
* N_PHASES
]; /* 0x500 */
165 u16 RESERVEDF
[0x100 / 2 - N_VERT_UV_TAPS
* N_PHASES
];
166 u16 UV_HCOEFS
[N_HORIZ_UV_TAPS
* N_PHASES
]; /* 0x600 */
167 u16 RESERVEDG
[0x100 / 2 - N_HORIZ_UV_TAPS
* N_PHASES
];
170 struct intel_overlay
{
171 struct drm_device
*dev
;
172 struct intel_crtc
*crtc
;
173 struct drm_i915_gem_object
*vid_bo
;
174 struct drm_i915_gem_object
*old_vid_bo
;
177 u32 pfit_vscale_ratio
; /* shifted-point number, (1<<12) == 1.0 */
179 u32 brightness
, contrast
, saturation
;
180 u32 old_xscale
, old_yscale
;
181 /* register access */
183 struct drm_i915_gem_object
*reg_bo
;
185 uint32_t last_flip_req
;
186 void (*flip_tail
)(struct intel_overlay
*);
189 static struct overlay_registers __iomem
*
190 intel_overlay_map_regs(struct intel_overlay
*overlay
)
192 drm_i915_private_t
*dev_priv
= overlay
->dev
->dev_private
;
193 struct overlay_registers __iomem
*regs
;
195 if (OVERLAY_NEEDS_PHYSICAL(overlay
->dev
))
196 regs
= (struct overlay_registers __iomem
*)overlay
->reg_bo
->phys_obj
->handle
->vaddr
;
198 regs
= io_mapping_map_wc(dev_priv
->mm
.gtt_mapping
,
199 overlay
->reg_bo
->gtt_offset
);
204 static void intel_overlay_unmap_regs(struct intel_overlay
*overlay
,
205 struct overlay_registers __iomem
*regs
)
207 if (!OVERLAY_NEEDS_PHYSICAL(overlay
->dev
))
208 io_mapping_unmap(regs
);
211 static int intel_overlay_do_wait_request(struct intel_overlay
*overlay
,
212 struct drm_i915_gem_request
*request
,
213 void (*tail
)(struct intel_overlay
*))
215 struct drm_device
*dev
= overlay
->dev
;
216 drm_i915_private_t
*dev_priv
= dev
->dev_private
;
217 struct intel_ring_buffer
*ring
= &dev_priv
->ring
[RCS
];
220 BUG_ON(overlay
->last_flip_req
);
221 ret
= i915_add_request(ring
, NULL
, request
);
226 overlay
->last_flip_req
= request
->seqno
;
227 overlay
->flip_tail
= tail
;
228 ret
= i915_wait_seqno(ring
, overlay
->last_flip_req
);
231 i915_gem_retire_requests(dev
);
233 overlay
->last_flip_req
= 0;
237 /* overlay needs to be disable in OCMD reg */
238 static int intel_overlay_on(struct intel_overlay
*overlay
)
240 struct drm_device
*dev
= overlay
->dev
;
241 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
242 struct intel_ring_buffer
*ring
= &dev_priv
->ring
[RCS
];
243 struct drm_i915_gem_request
*request
;
246 BUG_ON(overlay
->active
);
249 WARN_ON(IS_I830(dev
) && !(dev_priv
->quirks
& QUIRK_PIPEA_FORCE
));
251 request
= kzalloc(sizeof(*request
), GFP_KERNEL
);
252 if (request
== NULL
) {
257 ret
= intel_ring_begin(ring
, 4);
263 intel_ring_emit(ring
, MI_OVERLAY_FLIP
| MI_OVERLAY_ON
);
264 intel_ring_emit(ring
, overlay
->flip_addr
| OFC_UPDATE
);
265 intel_ring_emit(ring
, MI_WAIT_FOR_EVENT
| MI_WAIT_FOR_OVERLAY_FLIP
);
266 intel_ring_emit(ring
, MI_NOOP
);
267 intel_ring_advance(ring
);
269 ret
= intel_overlay_do_wait_request(overlay
, request
, NULL
);
274 /* overlay needs to be enabled in OCMD reg */
275 static int intel_overlay_continue(struct intel_overlay
*overlay
,
276 bool load_polyphase_filter
)
278 struct drm_device
*dev
= overlay
->dev
;
279 drm_i915_private_t
*dev_priv
= dev
->dev_private
;
280 struct intel_ring_buffer
*ring
= &dev_priv
->ring
[RCS
];
281 struct drm_i915_gem_request
*request
;
282 u32 flip_addr
= overlay
->flip_addr
;
286 BUG_ON(!overlay
->active
);
288 request
= kzalloc(sizeof(*request
), GFP_KERNEL
);
292 if (load_polyphase_filter
)
293 flip_addr
|= OFC_UPDATE
;
295 /* check for underruns */
296 tmp
= I915_READ(DOVSTA
);
298 DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp
);
300 ret
= intel_ring_begin(ring
, 2);
305 intel_ring_emit(ring
, MI_OVERLAY_FLIP
| MI_OVERLAY_CONTINUE
);
306 intel_ring_emit(ring
, flip_addr
);
307 intel_ring_advance(ring
);
309 ret
= i915_add_request(ring
, NULL
, request
);
315 overlay
->last_flip_req
= request
->seqno
;
319 static void intel_overlay_release_old_vid_tail(struct intel_overlay
*overlay
)
321 struct drm_i915_gem_object
*obj
= overlay
->old_vid_bo
;
323 i915_gem_object_unpin(obj
);
324 drm_gem_object_unreference(&obj
->base
);
326 overlay
->old_vid_bo
= NULL
;
329 static void intel_overlay_off_tail(struct intel_overlay
*overlay
)
331 struct drm_i915_gem_object
*obj
= overlay
->vid_bo
;
333 /* never have the overlay hw on without showing a frame */
334 BUG_ON(!overlay
->vid_bo
);
336 i915_gem_object_unpin(obj
);
337 drm_gem_object_unreference(&obj
->base
);
338 overlay
->vid_bo
= NULL
;
340 overlay
->crtc
->overlay
= NULL
;
341 overlay
->crtc
= NULL
;
345 /* overlay needs to be disabled in OCMD reg */
346 static int intel_overlay_off(struct intel_overlay
*overlay
)
348 struct drm_device
*dev
= overlay
->dev
;
349 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
350 struct intel_ring_buffer
*ring
= &dev_priv
->ring
[RCS
];
351 u32 flip_addr
= overlay
->flip_addr
;
352 struct drm_i915_gem_request
*request
;
355 BUG_ON(!overlay
->active
);
357 request
= kzalloc(sizeof(*request
), GFP_KERNEL
);
361 /* According to intel docs the overlay hw may hang (when switching
362 * off) without loading the filter coeffs. It is however unclear whether
363 * this applies to the disabling of the overlay or to the switching off
364 * of the hw. Do it in both cases */
365 flip_addr
|= OFC_UPDATE
;
367 ret
= intel_ring_begin(ring
, 6);
372 /* wait for overlay to go idle */
373 intel_ring_emit(ring
, MI_OVERLAY_FLIP
| MI_OVERLAY_CONTINUE
);
374 intel_ring_emit(ring
, flip_addr
);
375 intel_ring_emit(ring
, MI_WAIT_FOR_EVENT
| MI_WAIT_FOR_OVERLAY_FLIP
);
376 /* turn overlay off */
377 intel_ring_emit(ring
, MI_OVERLAY_FLIP
| MI_OVERLAY_OFF
);
378 intel_ring_emit(ring
, flip_addr
);
379 intel_ring_emit(ring
, MI_WAIT_FOR_EVENT
| MI_WAIT_FOR_OVERLAY_FLIP
);
380 intel_ring_advance(ring
);
382 return intel_overlay_do_wait_request(overlay
, request
,
383 intel_overlay_off_tail
);
386 /* recover from an interruption due to a signal
387 * We have to be careful not to repeat work forever an make forward progess. */
388 static int intel_overlay_recover_from_interrupt(struct intel_overlay
*overlay
)
390 struct drm_device
*dev
= overlay
->dev
;
391 drm_i915_private_t
*dev_priv
= dev
->dev_private
;
392 struct intel_ring_buffer
*ring
= &dev_priv
->ring
[RCS
];
395 if (overlay
->last_flip_req
== 0)
398 ret
= i915_wait_seqno(ring
, overlay
->last_flip_req
);
401 i915_gem_retire_requests(dev
);
403 if (overlay
->flip_tail
)
404 overlay
->flip_tail(overlay
);
406 overlay
->last_flip_req
= 0;
410 /* Wait for pending overlay flip and release old frame.
411 * Needs to be called before the overlay register are changed
412 * via intel_overlay_(un)map_regs
414 static int intel_overlay_release_old_vid(struct intel_overlay
*overlay
)
416 struct drm_device
*dev
= overlay
->dev
;
417 drm_i915_private_t
*dev_priv
= dev
->dev_private
;
418 struct intel_ring_buffer
*ring
= &dev_priv
->ring
[RCS
];
421 /* Only wait if there is actually an old frame to release to
422 * guarantee forward progress.
424 if (!overlay
->old_vid_bo
)
427 if (I915_READ(ISR
) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT
) {
428 struct drm_i915_gem_request
*request
;
430 /* synchronous slowpath */
431 request
= kzalloc(sizeof(*request
), GFP_KERNEL
);
435 ret
= intel_ring_begin(ring
, 2);
441 intel_ring_emit(ring
, MI_WAIT_FOR_EVENT
| MI_WAIT_FOR_OVERLAY_FLIP
);
442 intel_ring_emit(ring
, MI_NOOP
);
443 intel_ring_advance(ring
);
445 ret
= intel_overlay_do_wait_request(overlay
, request
,
446 intel_overlay_release_old_vid_tail
);
451 intel_overlay_release_old_vid_tail(overlay
);
455 struct put_image_params
{
472 static int packed_depth_bytes(u32 format
)
474 switch (format
& I915_OVERLAY_DEPTH_MASK
) {
475 case I915_OVERLAY_YUV422
:
477 case I915_OVERLAY_YUV411
:
478 /* return 6; not implemented */
484 static int packed_width_bytes(u32 format
, short width
)
486 switch (format
& I915_OVERLAY_DEPTH_MASK
) {
487 case I915_OVERLAY_YUV422
:
494 static int uv_hsubsampling(u32 format
)
496 switch (format
& I915_OVERLAY_DEPTH_MASK
) {
497 case I915_OVERLAY_YUV422
:
498 case I915_OVERLAY_YUV420
:
500 case I915_OVERLAY_YUV411
:
501 case I915_OVERLAY_YUV410
:
508 static int uv_vsubsampling(u32 format
)
510 switch (format
& I915_OVERLAY_DEPTH_MASK
) {
511 case I915_OVERLAY_YUV420
:
512 case I915_OVERLAY_YUV410
:
514 case I915_OVERLAY_YUV422
:
515 case I915_OVERLAY_YUV411
:
522 static u32
calc_swidthsw(struct drm_device
*dev
, u32 offset
, u32 width
)
524 u32 mask
, shift
, ret
;
532 ret
= ((offset
+ width
+ mask
) >> shift
) - (offset
>> shift
);
539 static const u16 y_static_hcoeffs
[N_HORIZ_Y_TAPS
* N_PHASES
] = {
540 0x3000, 0xb4a0, 0x1930, 0x1920, 0xb4a0,
541 0x3000, 0xb500, 0x19d0, 0x1880, 0xb440,
542 0x3000, 0xb540, 0x1a88, 0x2f80, 0xb3e0,
543 0x3000, 0xb580, 0x1b30, 0x2e20, 0xb380,
544 0x3000, 0xb5c0, 0x1bd8, 0x2cc0, 0xb320,
545 0x3020, 0xb5e0, 0x1c60, 0x2b80, 0xb2c0,
546 0x3020, 0xb5e0, 0x1cf8, 0x2a20, 0xb260,
547 0x3020, 0xb5e0, 0x1d80, 0x28e0, 0xb200,
548 0x3020, 0xb5c0, 0x1e08, 0x3f40, 0xb1c0,
549 0x3020, 0xb580, 0x1e78, 0x3ce0, 0xb160,
550 0x3040, 0xb520, 0x1ed8, 0x3aa0, 0xb120,
551 0x3040, 0xb4a0, 0x1f30, 0x3880, 0xb0e0,
552 0x3040, 0xb400, 0x1f78, 0x3680, 0xb0a0,
553 0x3020, 0xb340, 0x1fb8, 0x34a0, 0xb060,
554 0x3020, 0xb240, 0x1fe0, 0x32e0, 0xb040,
555 0x3020, 0xb140, 0x1ff8, 0x3160, 0xb020,
556 0xb000, 0x3000, 0x0800, 0x3000, 0xb000
559 static const u16 uv_static_hcoeffs
[N_HORIZ_UV_TAPS
* N_PHASES
] = {
560 0x3000, 0x1800, 0x1800, 0xb000, 0x18d0, 0x2e60,
561 0xb000, 0x1990, 0x2ce0, 0xb020, 0x1a68, 0x2b40,
562 0xb040, 0x1b20, 0x29e0, 0xb060, 0x1bd8, 0x2880,
563 0xb080, 0x1c88, 0x3e60, 0xb0a0, 0x1d28, 0x3c00,
564 0xb0c0, 0x1db8, 0x39e0, 0xb0e0, 0x1e40, 0x37e0,
565 0xb100, 0x1eb8, 0x3620, 0xb100, 0x1f18, 0x34a0,
566 0xb100, 0x1f68, 0x3360, 0xb0e0, 0x1fa8, 0x3240,
567 0xb0c0, 0x1fe0, 0x3140, 0xb060, 0x1ff0, 0x30a0,
568 0x3000, 0x0800, 0x3000
571 static void update_polyphase_filter(struct overlay_registers __iomem
*regs
)
573 memcpy_toio(regs
->Y_HCOEFS
, y_static_hcoeffs
, sizeof(y_static_hcoeffs
));
574 memcpy_toio(regs
->UV_HCOEFS
, uv_static_hcoeffs
,
575 sizeof(uv_static_hcoeffs
));
578 static bool update_scaling_factors(struct intel_overlay
*overlay
,
579 struct overlay_registers __iomem
*regs
,
580 struct put_image_params
*params
)
582 /* fixed point with a 12 bit shift */
583 u32 xscale
, yscale
, xscale_UV
, yscale_UV
;
585 #define FRACT_MASK 0xfff
586 bool scale_changed
= false;
587 int uv_hscale
= uv_hsubsampling(params
->format
);
588 int uv_vscale
= uv_vsubsampling(params
->format
);
590 if (params
->dst_w
> 1)
591 xscale
= ((params
->src_scan_w
- 1) << FP_SHIFT
)
594 xscale
= 1 << FP_SHIFT
;
596 if (params
->dst_h
> 1)
597 yscale
= ((params
->src_scan_h
- 1) << FP_SHIFT
)
600 yscale
= 1 << FP_SHIFT
;
602 /*if (params->format & I915_OVERLAY_YUV_PLANAR) {*/
603 xscale_UV
= xscale
/uv_hscale
;
604 yscale_UV
= yscale
/uv_vscale
;
605 /* make the Y scale to UV scale ratio an exact multiply */
606 xscale
= xscale_UV
* uv_hscale
;
607 yscale
= yscale_UV
* uv_vscale
;
613 if (xscale
!= overlay
->old_xscale
|| yscale
!= overlay
->old_yscale
)
614 scale_changed
= true;
615 overlay
->old_xscale
= xscale
;
616 overlay
->old_yscale
= yscale
;
618 iowrite32(((yscale
& FRACT_MASK
) << 20) |
619 ((xscale
>> FP_SHIFT
) << 16) |
620 ((xscale
& FRACT_MASK
) << 3),
623 iowrite32(((yscale_UV
& FRACT_MASK
) << 20) |
624 ((xscale_UV
>> FP_SHIFT
) << 16) |
625 ((xscale_UV
& FRACT_MASK
) << 3),
628 iowrite32((((yscale
>> FP_SHIFT
) << 16) |
629 ((yscale_UV
>> FP_SHIFT
) << 0)),
633 update_polyphase_filter(regs
);
635 return scale_changed
;
638 static void update_colorkey(struct intel_overlay
*overlay
,
639 struct overlay_registers __iomem
*regs
)
641 u32 key
= overlay
->color_key
;
643 switch (overlay
->crtc
->base
.fb
->bits_per_pixel
) {
645 iowrite32(0, ®s
->DCLRKV
);
646 iowrite32(CLK_RGB8I_MASK
| DST_KEY_ENABLE
, ®s
->DCLRKM
);
650 if (overlay
->crtc
->base
.fb
->depth
== 15) {
651 iowrite32(RGB15_TO_COLORKEY(key
), ®s
->DCLRKV
);
652 iowrite32(CLK_RGB15_MASK
| DST_KEY_ENABLE
,
655 iowrite32(RGB16_TO_COLORKEY(key
), ®s
->DCLRKV
);
656 iowrite32(CLK_RGB16_MASK
| DST_KEY_ENABLE
,
663 iowrite32(key
, ®s
->DCLRKV
);
664 iowrite32(CLK_RGB24_MASK
| DST_KEY_ENABLE
, ®s
->DCLRKM
);
669 static u32
overlay_cmd_reg(struct put_image_params
*params
)
671 u32 cmd
= OCMD_ENABLE
| OCMD_BUF_TYPE_FRAME
| OCMD_BUFFER0
;
673 if (params
->format
& I915_OVERLAY_YUV_PLANAR
) {
674 switch (params
->format
& I915_OVERLAY_DEPTH_MASK
) {
675 case I915_OVERLAY_YUV422
:
676 cmd
|= OCMD_YUV_422_PLANAR
;
678 case I915_OVERLAY_YUV420
:
679 cmd
|= OCMD_YUV_420_PLANAR
;
681 case I915_OVERLAY_YUV411
:
682 case I915_OVERLAY_YUV410
:
683 cmd
|= OCMD_YUV_410_PLANAR
;
686 } else { /* YUV packed */
687 switch (params
->format
& I915_OVERLAY_DEPTH_MASK
) {
688 case I915_OVERLAY_YUV422
:
689 cmd
|= OCMD_YUV_422_PACKED
;
691 case I915_OVERLAY_YUV411
:
692 cmd
|= OCMD_YUV_411_PACKED
;
696 switch (params
->format
& I915_OVERLAY_SWAP_MASK
) {
697 case I915_OVERLAY_NO_SWAP
:
699 case I915_OVERLAY_UV_SWAP
:
702 case I915_OVERLAY_Y_SWAP
:
705 case I915_OVERLAY_Y_AND_UV_SWAP
:
706 cmd
|= OCMD_Y_AND_UV_SWAP
;
714 static int intel_overlay_do_put_image(struct intel_overlay
*overlay
,
715 struct drm_i915_gem_object
*new_bo
,
716 struct put_image_params
*params
)
719 struct overlay_registers __iomem
*regs
;
720 bool scale_changed
= false;
721 struct drm_device
*dev
= overlay
->dev
;
722 u32 swidth
, swidthsw
, sheight
, ostride
;
724 BUG_ON(!mutex_is_locked(&dev
->struct_mutex
));
725 BUG_ON(!mutex_is_locked(&dev
->mode_config
.mutex
));
728 ret
= intel_overlay_release_old_vid(overlay
);
732 ret
= i915_gem_object_pin_to_display_plane(new_bo
, 0, NULL
);
736 ret
= i915_gem_object_put_fence(new_bo
);
740 if (!overlay
->active
) {
742 regs
= intel_overlay_map_regs(overlay
);
747 oconfig
= OCONF_CC_OUT_8BIT
;
748 if (IS_GEN4(overlay
->dev
))
749 oconfig
|= OCONF_CSC_MODE_BT709
;
750 oconfig
|= overlay
->crtc
->pipe
== 0 ?
751 OCONF_PIPE_A
: OCONF_PIPE_B
;
752 iowrite32(oconfig
, ®s
->OCONFIG
);
753 intel_overlay_unmap_regs(overlay
, regs
);
755 ret
= intel_overlay_on(overlay
);
760 regs
= intel_overlay_map_regs(overlay
);
766 iowrite32((params
->dst_y
<< 16) | params
->dst_x
, ®s
->DWINPOS
);
767 iowrite32((params
->dst_h
<< 16) | params
->dst_w
, ®s
->DWINSZ
);
769 if (params
->format
& I915_OVERLAY_YUV_PACKED
)
770 tmp_width
= packed_width_bytes(params
->format
, params
->src_w
);
772 tmp_width
= params
->src_w
;
774 swidth
= params
->src_w
;
775 swidthsw
= calc_swidthsw(overlay
->dev
, params
->offset_Y
, tmp_width
);
776 sheight
= params
->src_h
;
777 iowrite32(new_bo
->gtt_offset
+ params
->offset_Y
, ®s
->OBUF_0Y
);
778 ostride
= params
->stride_Y
;
780 if (params
->format
& I915_OVERLAY_YUV_PLANAR
) {
781 int uv_hscale
= uv_hsubsampling(params
->format
);
782 int uv_vscale
= uv_vsubsampling(params
->format
);
784 swidth
|= (params
->src_w
/uv_hscale
) << 16;
785 tmp_U
= calc_swidthsw(overlay
->dev
, params
->offset_U
,
786 params
->src_w
/uv_hscale
);
787 tmp_V
= calc_swidthsw(overlay
->dev
, params
->offset_V
,
788 params
->src_w
/uv_hscale
);
789 swidthsw
|= max_t(u32
, tmp_U
, tmp_V
) << 16;
790 sheight
|= (params
->src_h
/uv_vscale
) << 16;
791 iowrite32(new_bo
->gtt_offset
+ params
->offset_U
, ®s
->OBUF_0U
);
792 iowrite32(new_bo
->gtt_offset
+ params
->offset_V
, ®s
->OBUF_0V
);
793 ostride
|= params
->stride_UV
<< 16;
796 iowrite32(swidth
, ®s
->SWIDTH
);
797 iowrite32(swidthsw
, ®s
->SWIDTHSW
);
798 iowrite32(sheight
, ®s
->SHEIGHT
);
799 iowrite32(ostride
, ®s
->OSTRIDE
);
801 scale_changed
= update_scaling_factors(overlay
, regs
, params
);
803 update_colorkey(overlay
, regs
);
805 iowrite32(overlay_cmd_reg(params
), ®s
->OCMD
);
807 intel_overlay_unmap_regs(overlay
, regs
);
809 ret
= intel_overlay_continue(overlay
, scale_changed
);
813 overlay
->old_vid_bo
= overlay
->vid_bo
;
814 overlay
->vid_bo
= new_bo
;
819 i915_gem_object_unpin(new_bo
);
823 int intel_overlay_switch_off(struct intel_overlay
*overlay
)
825 struct overlay_registers __iomem
*regs
;
826 struct drm_device
*dev
= overlay
->dev
;
829 BUG_ON(!mutex_is_locked(&dev
->struct_mutex
));
830 BUG_ON(!mutex_is_locked(&dev
->mode_config
.mutex
));
832 ret
= intel_overlay_recover_from_interrupt(overlay
);
836 if (!overlay
->active
)
839 ret
= intel_overlay_release_old_vid(overlay
);
843 regs
= intel_overlay_map_regs(overlay
);
844 iowrite32(0, ®s
->OCMD
);
845 intel_overlay_unmap_regs(overlay
, regs
);
847 ret
= intel_overlay_off(overlay
);
851 intel_overlay_off_tail(overlay
);
855 static int check_overlay_possible_on_crtc(struct intel_overlay
*overlay
,
856 struct intel_crtc
*crtc
)
858 drm_i915_private_t
*dev_priv
= overlay
->dev
->dev_private
;
863 /* can't use the overlay with double wide pipe */
864 if (INTEL_INFO(overlay
->dev
)->gen
< 4 &&
865 (I915_READ(PIPECONF(crtc
->pipe
)) & (PIPECONF_DOUBLE_WIDE
| PIPECONF_ENABLE
)) != PIPECONF_ENABLE
)
871 static void update_pfit_vscale_ratio(struct intel_overlay
*overlay
)
873 struct drm_device
*dev
= overlay
->dev
;
874 drm_i915_private_t
*dev_priv
= dev
->dev_private
;
875 u32 pfit_control
= I915_READ(PFIT_CONTROL
);
878 /* XXX: This is not the same logic as in the xorg driver, but more in
879 * line with the intel documentation for the i965
881 if (INTEL_INFO(dev
)->gen
>= 4) {
882 /* on i965 use the PGM reg to read out the autoscaler values */
883 ratio
= I915_READ(PFIT_PGM_RATIOS
) >> PFIT_VERT_SCALE_SHIFT_965
;
885 if (pfit_control
& VERT_AUTO_SCALE
)
886 ratio
= I915_READ(PFIT_AUTO_RATIOS
);
888 ratio
= I915_READ(PFIT_PGM_RATIOS
);
889 ratio
>>= PFIT_VERT_SCALE_SHIFT
;
892 overlay
->pfit_vscale_ratio
= ratio
;
895 static int check_overlay_dst(struct intel_overlay
*overlay
,
896 struct drm_intel_overlay_put_image
*rec
)
898 struct drm_display_mode
*mode
= &overlay
->crtc
->base
.mode
;
900 if (rec
->dst_x
< mode
->hdisplay
&&
901 rec
->dst_x
+ rec
->dst_width
<= mode
->hdisplay
&&
902 rec
->dst_y
< mode
->vdisplay
&&
903 rec
->dst_y
+ rec
->dst_height
<= mode
->vdisplay
)
909 static int check_overlay_scaling(struct put_image_params
*rec
)
913 /* downscaling limit is 8.0 */
914 tmp
= ((rec
->src_scan_h
<< 16) / rec
->dst_h
) >> 16;
917 tmp
= ((rec
->src_scan_w
<< 16) / rec
->dst_w
) >> 16;
924 static int check_overlay_src(struct drm_device
*dev
,
925 struct drm_intel_overlay_put_image
*rec
,
926 struct drm_i915_gem_object
*new_bo
)
928 int uv_hscale
= uv_hsubsampling(rec
->flags
);
929 int uv_vscale
= uv_vsubsampling(rec
->flags
);
934 /* check src dimensions */
935 if (IS_845G(dev
) || IS_I830(dev
)) {
936 if (rec
->src_height
> IMAGE_MAX_HEIGHT_LEGACY
||
937 rec
->src_width
> IMAGE_MAX_WIDTH_LEGACY
)
940 if (rec
->src_height
> IMAGE_MAX_HEIGHT
||
941 rec
->src_width
> IMAGE_MAX_WIDTH
)
945 /* better safe than sorry, use 4 as the maximal subsampling ratio */
946 if (rec
->src_height
< N_VERT_Y_TAPS
*4 ||
947 rec
->src_width
< N_HORIZ_Y_TAPS
*4)
950 /* check alignment constraints */
951 switch (rec
->flags
& I915_OVERLAY_TYPE_MASK
) {
952 case I915_OVERLAY_RGB
:
953 /* not implemented */
956 case I915_OVERLAY_YUV_PACKED
:
960 depth
= packed_depth_bytes(rec
->flags
);
964 /* ignore UV planes */
968 /* check pixel alignment */
969 if (rec
->offset_Y
% depth
)
973 case I915_OVERLAY_YUV_PLANAR
:
974 if (uv_vscale
< 0 || uv_hscale
< 0)
976 /* no offset restrictions for planar formats */
983 if (rec
->src_width
% uv_hscale
)
986 /* stride checking */
987 if (IS_I830(dev
) || IS_845G(dev
))
992 if (rec
->stride_Y
& stride_mask
|| rec
->stride_UV
& stride_mask
)
994 if (IS_GEN4(dev
) && rec
->stride_Y
< 512)
997 tmp
= (rec
->flags
& I915_OVERLAY_TYPE_MASK
) == I915_OVERLAY_YUV_PLANAR
?
999 if (rec
->stride_Y
> tmp
|| rec
->stride_UV
> 2*1024)
1002 /* check buffer dimensions */
1003 switch (rec
->flags
& I915_OVERLAY_TYPE_MASK
) {
1004 case I915_OVERLAY_RGB
:
1005 case I915_OVERLAY_YUV_PACKED
:
1006 /* always 4 Y values per depth pixels */
1007 if (packed_width_bytes(rec
->flags
, rec
->src_width
) > rec
->stride_Y
)
1010 tmp
= rec
->stride_Y
*rec
->src_height
;
1011 if (rec
->offset_Y
+ tmp
> new_bo
->base
.size
)
1015 case I915_OVERLAY_YUV_PLANAR
:
1016 if (rec
->src_width
> rec
->stride_Y
)
1018 if (rec
->src_width
/uv_hscale
> rec
->stride_UV
)
1021 tmp
= rec
->stride_Y
* rec
->src_height
;
1022 if (rec
->offset_Y
+ tmp
> new_bo
->base
.size
)
1025 tmp
= rec
->stride_UV
* (rec
->src_height
/ uv_vscale
);
1026 if (rec
->offset_U
+ tmp
> new_bo
->base
.size
||
1027 rec
->offset_V
+ tmp
> new_bo
->base
.size
)
1036 * Return the pipe currently connected to the panel fitter,
1037 * or -1 if the panel fitter is not present or not in use
1039 static int intel_panel_fitter_pipe(struct drm_device
*dev
)
1041 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
1044 /* i830 doesn't have a panel fitter */
1048 pfit_control
= I915_READ(PFIT_CONTROL
);
1050 /* See if the panel fitter is in use */
1051 if ((pfit_control
& PFIT_ENABLE
) == 0)
1054 /* 965 can place panel fitter on either pipe */
1056 return (pfit_control
>> 29) & 0x3;
1058 /* older chips can only use pipe 1 */
1062 int intel_overlay_put_image(struct drm_device
*dev
, void *data
,
1063 struct drm_file
*file_priv
)
1065 struct drm_intel_overlay_put_image
*put_image_rec
= data
;
1066 drm_i915_private_t
*dev_priv
= dev
->dev_private
;
1067 struct intel_overlay
*overlay
;
1068 struct drm_mode_object
*drmmode_obj
;
1069 struct intel_crtc
*crtc
;
1070 struct drm_i915_gem_object
*new_bo
;
1071 struct put_image_params
*params
;
1074 /* No need to check for DRIVER_MODESET - we don't set it up then. */
1075 overlay
= dev_priv
->overlay
;
1077 DRM_DEBUG("userspace bug: no overlay\n");
1081 if (!(put_image_rec
->flags
& I915_OVERLAY_ENABLE
)) {
1082 mutex_lock(&dev
->mode_config
.mutex
);
1083 mutex_lock(&dev
->struct_mutex
);
1085 ret
= intel_overlay_switch_off(overlay
);
1087 mutex_unlock(&dev
->struct_mutex
);
1088 mutex_unlock(&dev
->mode_config
.mutex
);
1093 params
= kmalloc(sizeof(struct put_image_params
), GFP_KERNEL
);
1097 drmmode_obj
= drm_mode_object_find(dev
, put_image_rec
->crtc_id
,
1098 DRM_MODE_OBJECT_CRTC
);
1103 crtc
= to_intel_crtc(obj_to_crtc(drmmode_obj
));
1105 new_bo
= to_intel_bo(drm_gem_object_lookup(dev
, file_priv
,
1106 put_image_rec
->bo_handle
));
1107 if (&new_bo
->base
== NULL
) {
1112 mutex_lock(&dev
->mode_config
.mutex
);
1113 mutex_lock(&dev
->struct_mutex
);
1115 if (new_bo
->tiling_mode
) {
1116 DRM_ERROR("buffer used for overlay image can not be tiled\n");
1121 ret
= intel_overlay_recover_from_interrupt(overlay
);
1125 if (overlay
->crtc
!= crtc
) {
1126 struct drm_display_mode
*mode
= &crtc
->base
.mode
;
1127 ret
= intel_overlay_switch_off(overlay
);
1131 ret
= check_overlay_possible_on_crtc(overlay
, crtc
);
1135 overlay
->crtc
= crtc
;
1136 crtc
->overlay
= overlay
;
1138 /* line too wide, i.e. one-line-mode */
1139 if (mode
->hdisplay
> 1024 &&
1140 intel_panel_fitter_pipe(dev
) == crtc
->pipe
) {
1141 overlay
->pfit_active
= 1;
1142 update_pfit_vscale_ratio(overlay
);
1144 overlay
->pfit_active
= 0;
1147 ret
= check_overlay_dst(overlay
, put_image_rec
);
1151 if (overlay
->pfit_active
) {
1152 params
->dst_y
= ((((u32
)put_image_rec
->dst_y
) << 12) /
1153 overlay
->pfit_vscale_ratio
);
1154 /* shifting right rounds downwards, so add 1 */
1155 params
->dst_h
= ((((u32
)put_image_rec
->dst_height
) << 12) /
1156 overlay
->pfit_vscale_ratio
) + 1;
1158 params
->dst_y
= put_image_rec
->dst_y
;
1159 params
->dst_h
= put_image_rec
->dst_height
;
1161 params
->dst_x
= put_image_rec
->dst_x
;
1162 params
->dst_w
= put_image_rec
->dst_width
;
1164 params
->src_w
= put_image_rec
->src_width
;
1165 params
->src_h
= put_image_rec
->src_height
;
1166 params
->src_scan_w
= put_image_rec
->src_scan_width
;
1167 params
->src_scan_h
= put_image_rec
->src_scan_height
;
1168 if (params
->src_scan_h
> params
->src_h
||
1169 params
->src_scan_w
> params
->src_w
) {
1174 ret
= check_overlay_src(dev
, put_image_rec
, new_bo
);
1177 params
->format
= put_image_rec
->flags
& ~I915_OVERLAY_FLAGS_MASK
;
1178 params
->stride_Y
= put_image_rec
->stride_Y
;
1179 params
->stride_UV
= put_image_rec
->stride_UV
;
1180 params
->offset_Y
= put_image_rec
->offset_Y
;
1181 params
->offset_U
= put_image_rec
->offset_U
;
1182 params
->offset_V
= put_image_rec
->offset_V
;
1184 /* Check scaling after src size to prevent a divide-by-zero. */
1185 ret
= check_overlay_scaling(params
);
1189 ret
= intel_overlay_do_put_image(overlay
, new_bo
, params
);
1193 mutex_unlock(&dev
->struct_mutex
);
1194 mutex_unlock(&dev
->mode_config
.mutex
);
1201 mutex_unlock(&dev
->struct_mutex
);
1202 mutex_unlock(&dev
->mode_config
.mutex
);
1203 drm_gem_object_unreference_unlocked(&new_bo
->base
);
1210 static void update_reg_attrs(struct intel_overlay
*overlay
,
1211 struct overlay_registers __iomem
*regs
)
1213 iowrite32((overlay
->contrast
<< 18) | (overlay
->brightness
& 0xff),
1215 iowrite32(overlay
->saturation
, ®s
->OCLRC1
);
1218 static bool check_gamma_bounds(u32 gamma1
, u32 gamma2
)
1222 if (gamma1
& 0xff000000 || gamma2
& 0xff000000)
1225 for (i
= 0; i
< 3; i
++) {
1226 if (((gamma1
>> i
*8) & 0xff) >= ((gamma2
>> i
*8) & 0xff))
1233 static bool check_gamma5_errata(u32 gamma5
)
1237 for (i
= 0; i
< 3; i
++) {
1238 if (((gamma5
>> i
*8) & 0xff) == 0x80)
1245 static int check_gamma(struct drm_intel_overlay_attrs
*attrs
)
1247 if (!check_gamma_bounds(0, attrs
->gamma0
) ||
1248 !check_gamma_bounds(attrs
->gamma0
, attrs
->gamma1
) ||
1249 !check_gamma_bounds(attrs
->gamma1
, attrs
->gamma2
) ||
1250 !check_gamma_bounds(attrs
->gamma2
, attrs
->gamma3
) ||
1251 !check_gamma_bounds(attrs
->gamma3
, attrs
->gamma4
) ||
1252 !check_gamma_bounds(attrs
->gamma4
, attrs
->gamma5
) ||
1253 !check_gamma_bounds(attrs
->gamma5
, 0x00ffffff))
1256 if (!check_gamma5_errata(attrs
->gamma5
))
1262 int intel_overlay_attrs(struct drm_device
*dev
, void *data
,
1263 struct drm_file
*file_priv
)
1265 struct drm_intel_overlay_attrs
*attrs
= data
;
1266 drm_i915_private_t
*dev_priv
= dev
->dev_private
;
1267 struct intel_overlay
*overlay
;
1268 struct overlay_registers __iomem
*regs
;
1271 /* No need to check for DRIVER_MODESET - we don't set it up then. */
1272 overlay
= dev_priv
->overlay
;
1274 DRM_DEBUG("userspace bug: no overlay\n");
1278 mutex_lock(&dev
->mode_config
.mutex
);
1279 mutex_lock(&dev
->struct_mutex
);
1282 if (!(attrs
->flags
& I915_OVERLAY_UPDATE_ATTRS
)) {
1283 attrs
->color_key
= overlay
->color_key
;
1284 attrs
->brightness
= overlay
->brightness
;
1285 attrs
->contrast
= overlay
->contrast
;
1286 attrs
->saturation
= overlay
->saturation
;
1288 if (!IS_GEN2(dev
)) {
1289 attrs
->gamma0
= I915_READ(OGAMC0
);
1290 attrs
->gamma1
= I915_READ(OGAMC1
);
1291 attrs
->gamma2
= I915_READ(OGAMC2
);
1292 attrs
->gamma3
= I915_READ(OGAMC3
);
1293 attrs
->gamma4
= I915_READ(OGAMC4
);
1294 attrs
->gamma5
= I915_READ(OGAMC5
);
1297 if (attrs
->brightness
< -128 || attrs
->brightness
> 127)
1299 if (attrs
->contrast
> 255)
1301 if (attrs
->saturation
> 1023)
1304 overlay
->color_key
= attrs
->color_key
;
1305 overlay
->brightness
= attrs
->brightness
;
1306 overlay
->contrast
= attrs
->contrast
;
1307 overlay
->saturation
= attrs
->saturation
;
1309 regs
= intel_overlay_map_regs(overlay
);
1315 update_reg_attrs(overlay
, regs
);
1317 intel_overlay_unmap_regs(overlay
, regs
);
1319 if (attrs
->flags
& I915_OVERLAY_UPDATE_GAMMA
) {
1323 if (overlay
->active
) {
1328 ret
= check_gamma(attrs
);
1332 I915_WRITE(OGAMC0
, attrs
->gamma0
);
1333 I915_WRITE(OGAMC1
, attrs
->gamma1
);
1334 I915_WRITE(OGAMC2
, attrs
->gamma2
);
1335 I915_WRITE(OGAMC3
, attrs
->gamma3
);
1336 I915_WRITE(OGAMC4
, attrs
->gamma4
);
1337 I915_WRITE(OGAMC5
, attrs
->gamma5
);
1343 mutex_unlock(&dev
->struct_mutex
);
1344 mutex_unlock(&dev
->mode_config
.mutex
);
1349 void intel_setup_overlay(struct drm_device
*dev
)
1351 drm_i915_private_t
*dev_priv
= dev
->dev_private
;
1352 struct intel_overlay
*overlay
;
1353 struct drm_i915_gem_object
*reg_bo
;
1354 struct overlay_registers __iomem
*regs
;
1357 if (!HAS_OVERLAY(dev
))
1360 overlay
= kzalloc(sizeof(struct intel_overlay
), GFP_KERNEL
);
1364 mutex_lock(&dev
->struct_mutex
);
1365 if (WARN_ON(dev_priv
->overlay
))
1370 reg_bo
= i915_gem_alloc_object(dev
, PAGE_SIZE
);
1373 overlay
->reg_bo
= reg_bo
;
1375 if (OVERLAY_NEEDS_PHYSICAL(dev
)) {
1376 ret
= i915_gem_attach_phys_object(dev
, reg_bo
,
1377 I915_GEM_PHYS_OVERLAY_REGS
,
1380 DRM_ERROR("failed to attach phys overlay regs\n");
1383 overlay
->flip_addr
= reg_bo
->phys_obj
->handle
->busaddr
;
1385 ret
= i915_gem_object_pin(reg_bo
, PAGE_SIZE
, true, false);
1387 DRM_ERROR("failed to pin overlay register bo\n");
1390 overlay
->flip_addr
= reg_bo
->gtt_offset
;
1392 ret
= i915_gem_object_set_to_gtt_domain(reg_bo
, true);
1394 DRM_ERROR("failed to move overlay register bo into the GTT\n");
1399 /* init all values */
1400 overlay
->color_key
= 0x0101fe;
1401 overlay
->brightness
= -19;
1402 overlay
->contrast
= 75;
1403 overlay
->saturation
= 146;
1405 regs
= intel_overlay_map_regs(overlay
);
1409 memset_io(regs
, 0, sizeof(struct overlay_registers
));
1410 update_polyphase_filter(regs
);
1411 update_reg_attrs(overlay
, regs
);
1413 intel_overlay_unmap_regs(overlay
, regs
);
1415 dev_priv
->overlay
= overlay
;
1416 mutex_unlock(&dev
->struct_mutex
);
1417 DRM_INFO("initialized overlay support\n");
1421 if (!OVERLAY_NEEDS_PHYSICAL(dev
))
1422 i915_gem_object_unpin(reg_bo
);
1424 drm_gem_object_unreference(®_bo
->base
);
1426 mutex_unlock(&dev
->struct_mutex
);
1431 void intel_cleanup_overlay(struct drm_device
*dev
)
1433 drm_i915_private_t
*dev_priv
= dev
->dev_private
;
1435 if (!dev_priv
->overlay
)
1438 /* The bo's should be free'd by the generic code already.
1439 * Furthermore modesetting teardown happens beforehand so the
1440 * hardware should be off already */
1441 BUG_ON(dev_priv
->overlay
->active
);
1443 drm_gem_object_unreference_unlocked(&dev_priv
->overlay
->reg_bo
->base
);
1444 kfree(dev_priv
->overlay
);
1447 #ifdef CONFIG_DEBUG_FS
1448 #include <linux/seq_file.h>
1450 struct intel_overlay_error_state
{
1451 struct overlay_registers regs
;
1457 static struct overlay_registers __iomem
*
1458 intel_overlay_map_regs_atomic(struct intel_overlay
*overlay
)
1460 drm_i915_private_t
*dev_priv
= overlay
->dev
->dev_private
;
1461 struct overlay_registers __iomem
*regs
;
1463 if (OVERLAY_NEEDS_PHYSICAL(overlay
->dev
))
1464 /* Cast to make sparse happy, but it's wc memory anyway, so
1465 * equivalent to the wc io mapping on X86. */
1466 regs
= (struct overlay_registers __iomem
*)
1467 overlay
->reg_bo
->phys_obj
->handle
->vaddr
;
1469 regs
= io_mapping_map_atomic_wc(dev_priv
->mm
.gtt_mapping
,
1470 overlay
->reg_bo
->gtt_offset
);
1475 static void intel_overlay_unmap_regs_atomic(struct intel_overlay
*overlay
,
1476 struct overlay_registers __iomem
*regs
)
1478 if (!OVERLAY_NEEDS_PHYSICAL(overlay
->dev
))
1479 io_mapping_unmap_atomic(regs
);
1483 struct intel_overlay_error_state
*
1484 intel_overlay_capture_error_state(struct drm_device
*dev
)
1486 drm_i915_private_t
*dev_priv
= dev
->dev_private
;
1487 struct intel_overlay
*overlay
= dev_priv
->overlay
;
1488 struct intel_overlay_error_state
*error
;
1489 struct overlay_registers __iomem
*regs
;
1491 if (!overlay
|| !overlay
->active
)
1494 error
= kmalloc(sizeof(*error
), GFP_ATOMIC
);
1498 error
->dovsta
= I915_READ(DOVSTA
);
1499 error
->isr
= I915_READ(ISR
);
1500 if (OVERLAY_NEEDS_PHYSICAL(overlay
->dev
))
1501 error
->base
= (__force
long)overlay
->reg_bo
->phys_obj
->handle
->vaddr
;
1503 error
->base
= overlay
->reg_bo
->gtt_offset
;
1505 regs
= intel_overlay_map_regs_atomic(overlay
);
1509 memcpy_fromio(&error
->regs
, regs
, sizeof(struct overlay_registers
));
1510 intel_overlay_unmap_regs_atomic(overlay
, regs
);
1520 intel_overlay_print_error_state(struct seq_file
*m
, struct intel_overlay_error_state
*error
)
1522 seq_printf(m
, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
1523 error
->dovsta
, error
->isr
);
1524 seq_printf(m
, " Register file at 0x%08lx:\n",
1527 #define P(x) seq_printf(m, " " #x ": 0x%08x\n", error->regs.x)