2 * Copyright © 2011 Intel Corporation
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 * Jesse Barnes <jbarnes@virtuousgeek.org>
26 * New plane/sprite handling.
28 * The older chips had a separate interface for programming plane related
29 * registers; newer ones are much simpler and we can use the new DRM plane
33 #include <drm/drm_crtc.h>
34 #include <drm/drm_fourcc.h>
35 #include <drm/drm_rect.h>
36 #include "intel_drv.h"
37 #include <drm/i915_drm.h>
40 static int usecs_to_scanlines(const struct drm_display_mode
*mode
, int usecs
)
43 if (!mode
->crtc_htotal
)
46 return DIV_ROUND_UP(usecs
* mode
->crtc_clock
, 1000 * mode
->crtc_htotal
);
49 static bool intel_pipe_update_start(struct intel_crtc
*crtc
, uint32_t *start_vbl_count
)
51 struct drm_device
*dev
= crtc
->base
.dev
;
52 const struct drm_display_mode
*mode
= &crtc
->config
.adjusted_mode
;
53 enum pipe pipe
= crtc
->pipe
;
54 long timeout
= msecs_to_jiffies_timeout(1);
55 int scanline
, min
, max
, vblank_start
;
56 wait_queue_head_t
*wq
= drm_crtc_vblank_waitqueue(&crtc
->base
);
59 WARN_ON(!drm_modeset_is_locked(&crtc
->base
.mutex
));
61 vblank_start
= mode
->crtc_vblank_start
;
62 if (mode
->flags
& DRM_MODE_FLAG_INTERLACE
)
63 vblank_start
= DIV_ROUND_UP(vblank_start
, 2);
65 /* FIXME needs to be calibrated sensibly */
66 min
= vblank_start
- usecs_to_scanlines(mode
, 100);
67 max
= vblank_start
- 1;
69 if (min
<= 0 || max
<= 0)
72 if (WARN_ON(drm_vblank_get(dev
, pipe
)))
77 trace_i915_pipe_update_start(crtc
, min
, max
);
81 * prepare_to_wait() has a memory barrier, which guarantees
82 * other CPUs can see the task state update by the time we
85 prepare_to_wait(wq
, &wait
, TASK_UNINTERRUPTIBLE
);
87 scanline
= intel_get_crtc_scanline(crtc
);
88 if (scanline
< min
|| scanline
> max
)
92 DRM_ERROR("Potential atomic update failure on pipe %c\n",
93 pipe_name(crtc
->pipe
));
99 timeout
= schedule_timeout(timeout
);
104 finish_wait(wq
, &wait
);
106 drm_vblank_put(dev
, pipe
);
108 *start_vbl_count
= dev
->driver
->get_vblank_counter(dev
, pipe
);
110 trace_i915_pipe_update_vblank_evaded(crtc
, min
, max
, *start_vbl_count
);
115 static void intel_pipe_update_end(struct intel_crtc
*crtc
, u32 start_vbl_count
)
117 struct drm_device
*dev
= crtc
->base
.dev
;
118 enum pipe pipe
= crtc
->pipe
;
119 u32 end_vbl_count
= dev
->driver
->get_vblank_counter(dev
, pipe
);
121 trace_i915_pipe_update_end(crtc
, end_vbl_count
);
125 if (start_vbl_count
!= end_vbl_count
)
126 DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u)\n",
127 pipe_name(pipe
), start_vbl_count
, end_vbl_count
);
130 static void intel_update_primary_plane(struct intel_crtc
*crtc
)
132 struct drm_i915_private
*dev_priv
= crtc
->base
.dev
->dev_private
;
133 int reg
= DSPCNTR(crtc
->plane
);
135 if (crtc
->primary_enabled
)
136 I915_WRITE(reg
, I915_READ(reg
) | DISPLAY_PLANE_ENABLE
);
138 I915_WRITE(reg
, I915_READ(reg
) & ~DISPLAY_PLANE_ENABLE
);
142 vlv_update_plane(struct drm_plane
*dplane
, struct drm_crtc
*crtc
,
143 struct drm_framebuffer
*fb
,
144 struct drm_i915_gem_object
*obj
, int crtc_x
, int crtc_y
,
145 unsigned int crtc_w
, unsigned int crtc_h
,
146 uint32_t x
, uint32_t y
,
147 uint32_t src_w
, uint32_t src_h
)
149 struct drm_device
*dev
= dplane
->dev
;
150 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
151 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
152 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
153 int pipe
= intel_plane
->pipe
;
154 int plane
= intel_plane
->plane
;
156 unsigned long sprsurf_offset
, linear_offset
;
157 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
161 sprctl
= I915_READ(SPCNTR(pipe
, plane
));
163 /* Mask out pixel format bits in case we change it */
164 sprctl
&= ~SP_PIXFORMAT_MASK
;
165 sprctl
&= ~SP_YUV_BYTE_ORDER_MASK
;
168 switch (fb
->pixel_format
) {
169 case DRM_FORMAT_YUYV
:
170 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_YUYV
;
172 case DRM_FORMAT_YVYU
:
173 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_YVYU
;
175 case DRM_FORMAT_UYVY
:
176 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_UYVY
;
178 case DRM_FORMAT_VYUY
:
179 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_VYUY
;
181 case DRM_FORMAT_RGB565
:
182 sprctl
|= SP_FORMAT_BGR565
;
184 case DRM_FORMAT_XRGB8888
:
185 sprctl
|= SP_FORMAT_BGRX8888
;
187 case DRM_FORMAT_ARGB8888
:
188 sprctl
|= SP_FORMAT_BGRA8888
;
190 case DRM_FORMAT_XBGR2101010
:
191 sprctl
|= SP_FORMAT_RGBX1010102
;
193 case DRM_FORMAT_ABGR2101010
:
194 sprctl
|= SP_FORMAT_RGBA1010102
;
196 case DRM_FORMAT_XBGR8888
:
197 sprctl
|= SP_FORMAT_RGBX8888
;
199 case DRM_FORMAT_ABGR8888
:
200 sprctl
|= SP_FORMAT_RGBA8888
;
204 * If we get here one of the upper layers failed to filter
205 * out the unsupported plane formats
212 * Enable gamma to match primary/cursor plane behaviour.
213 * FIXME should be user controllable via propertiesa.
215 sprctl
|= SP_GAMMA_ENABLE
;
217 if (obj
->tiling_mode
!= I915_TILING_NONE
)
222 intel_update_sprite_watermarks(dplane
, crtc
, src_w
, src_h
,
224 src_w
!= crtc_w
|| src_h
!= crtc_h
);
226 /* Sizes are 0 based */
232 linear_offset
= y
* fb
->pitches
[0] + x
* pixel_size
;
233 sprsurf_offset
= intel_gen4_compute_page_offset(&x
, &y
,
237 linear_offset
-= sprsurf_offset
;
239 atomic_update
= intel_pipe_update_start(intel_crtc
, &start_vbl_count
);
241 intel_update_primary_plane(intel_crtc
);
243 I915_WRITE(SPSTRIDE(pipe
, plane
), fb
->pitches
[0]);
244 I915_WRITE(SPPOS(pipe
, plane
), (crtc_y
<< 16) | crtc_x
);
246 if (obj
->tiling_mode
!= I915_TILING_NONE
)
247 I915_WRITE(SPTILEOFF(pipe
, plane
), (y
<< 16) | x
);
249 I915_WRITE(SPLINOFF(pipe
, plane
), linear_offset
);
251 I915_WRITE(SPSIZE(pipe
, plane
), (crtc_h
<< 16) | crtc_w
);
252 I915_WRITE(SPCNTR(pipe
, plane
), sprctl
);
253 I915_WRITE(SPSURF(pipe
, plane
), i915_gem_obj_ggtt_offset(obj
) +
256 intel_flush_primary_plane(dev_priv
, intel_crtc
->plane
);
259 intel_pipe_update_end(intel_crtc
, start_vbl_count
);
263 vlv_disable_plane(struct drm_plane
*dplane
, struct drm_crtc
*crtc
)
265 struct drm_device
*dev
= dplane
->dev
;
266 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
267 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
268 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
269 int pipe
= intel_plane
->pipe
;
270 int plane
= intel_plane
->plane
;
274 atomic_update
= intel_pipe_update_start(intel_crtc
, &start_vbl_count
);
276 intel_update_primary_plane(intel_crtc
);
278 I915_WRITE(SPCNTR(pipe
, plane
), I915_READ(SPCNTR(pipe
, plane
)) &
280 /* Activate double buffered register update */
281 I915_WRITE(SPSURF(pipe
, plane
), 0);
283 intel_flush_primary_plane(dev_priv
, intel_crtc
->plane
);
286 intel_pipe_update_end(intel_crtc
, start_vbl_count
);
288 intel_update_sprite_watermarks(dplane
, crtc
, 0, 0, 0, false, false);
292 vlv_update_colorkey(struct drm_plane
*dplane
,
293 struct drm_intel_sprite_colorkey
*key
)
295 struct drm_device
*dev
= dplane
->dev
;
296 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
297 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
298 int pipe
= intel_plane
->pipe
;
299 int plane
= intel_plane
->plane
;
302 if (key
->flags
& I915_SET_COLORKEY_DESTINATION
)
305 I915_WRITE(SPKEYMINVAL(pipe
, plane
), key
->min_value
);
306 I915_WRITE(SPKEYMAXVAL(pipe
, plane
), key
->max_value
);
307 I915_WRITE(SPKEYMSK(pipe
, plane
), key
->channel_mask
);
309 sprctl
= I915_READ(SPCNTR(pipe
, plane
));
310 sprctl
&= ~SP_SOURCE_KEY
;
311 if (key
->flags
& I915_SET_COLORKEY_SOURCE
)
312 sprctl
|= SP_SOURCE_KEY
;
313 I915_WRITE(SPCNTR(pipe
, plane
), sprctl
);
315 POSTING_READ(SPKEYMSK(pipe
, plane
));
321 vlv_get_colorkey(struct drm_plane
*dplane
,
322 struct drm_intel_sprite_colorkey
*key
)
324 struct drm_device
*dev
= dplane
->dev
;
325 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
326 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
327 int pipe
= intel_plane
->pipe
;
328 int plane
= intel_plane
->plane
;
331 key
->min_value
= I915_READ(SPKEYMINVAL(pipe
, plane
));
332 key
->max_value
= I915_READ(SPKEYMAXVAL(pipe
, plane
));
333 key
->channel_mask
= I915_READ(SPKEYMSK(pipe
, plane
));
335 sprctl
= I915_READ(SPCNTR(pipe
, plane
));
336 if (sprctl
& SP_SOURCE_KEY
)
337 key
->flags
= I915_SET_COLORKEY_SOURCE
;
339 key
->flags
= I915_SET_COLORKEY_NONE
;
343 ivb_update_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
,
344 struct drm_framebuffer
*fb
,
345 struct drm_i915_gem_object
*obj
, int crtc_x
, int crtc_y
,
346 unsigned int crtc_w
, unsigned int crtc_h
,
347 uint32_t x
, uint32_t y
,
348 uint32_t src_w
, uint32_t src_h
)
350 struct drm_device
*dev
= plane
->dev
;
351 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
352 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
353 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
354 int pipe
= intel_plane
->pipe
;
355 u32 sprctl
, sprscale
= 0;
356 unsigned long sprsurf_offset
, linear_offset
;
357 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
361 sprctl
= I915_READ(SPRCTL(pipe
));
363 /* Mask out pixel format bits in case we change it */
364 sprctl
&= ~SPRITE_PIXFORMAT_MASK
;
365 sprctl
&= ~SPRITE_RGB_ORDER_RGBX
;
366 sprctl
&= ~SPRITE_YUV_BYTE_ORDER_MASK
;
367 sprctl
&= ~SPRITE_TILED
;
369 switch (fb
->pixel_format
) {
370 case DRM_FORMAT_XBGR8888
:
371 sprctl
|= SPRITE_FORMAT_RGBX888
| SPRITE_RGB_ORDER_RGBX
;
373 case DRM_FORMAT_XRGB8888
:
374 sprctl
|= SPRITE_FORMAT_RGBX888
;
376 case DRM_FORMAT_YUYV
:
377 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_YUYV
;
379 case DRM_FORMAT_YVYU
:
380 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_YVYU
;
382 case DRM_FORMAT_UYVY
:
383 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_UYVY
;
385 case DRM_FORMAT_VYUY
:
386 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_VYUY
;
393 * Enable gamma to match primary/cursor plane behaviour.
394 * FIXME should be user controllable via propertiesa.
396 sprctl
|= SPRITE_GAMMA_ENABLE
;
398 if (obj
->tiling_mode
!= I915_TILING_NONE
)
399 sprctl
|= SPRITE_TILED
;
401 if (IS_HASWELL(dev
) || IS_BROADWELL(dev
))
402 sprctl
&= ~SPRITE_TRICKLE_FEED_DISABLE
;
404 sprctl
|= SPRITE_TRICKLE_FEED_DISABLE
;
406 sprctl
|= SPRITE_ENABLE
;
408 if (IS_HASWELL(dev
) || IS_BROADWELL(dev
))
409 sprctl
|= SPRITE_PIPE_CSC_ENABLE
;
411 intel_update_sprite_watermarks(plane
, crtc
, src_w
, src_h
, pixel_size
,
413 src_w
!= crtc_w
|| src_h
!= crtc_h
);
415 /* Sizes are 0 based */
421 if (crtc_w
!= src_w
|| crtc_h
!= src_h
)
422 sprscale
= SPRITE_SCALE_ENABLE
| (src_w
<< 16) | src_h
;
424 linear_offset
= y
* fb
->pitches
[0] + x
* pixel_size
;
426 intel_gen4_compute_page_offset(&x
, &y
, obj
->tiling_mode
,
427 pixel_size
, fb
->pitches
[0]);
428 linear_offset
-= sprsurf_offset
;
430 atomic_update
= intel_pipe_update_start(intel_crtc
, &start_vbl_count
);
432 intel_update_primary_plane(intel_crtc
);
434 I915_WRITE(SPRSTRIDE(pipe
), fb
->pitches
[0]);
435 I915_WRITE(SPRPOS(pipe
), (crtc_y
<< 16) | crtc_x
);
437 /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
439 if (IS_HASWELL(dev
) || IS_BROADWELL(dev
))
440 I915_WRITE(SPROFFSET(pipe
), (y
<< 16) | x
);
441 else if (obj
->tiling_mode
!= I915_TILING_NONE
)
442 I915_WRITE(SPRTILEOFF(pipe
), (y
<< 16) | x
);
444 I915_WRITE(SPRLINOFF(pipe
), linear_offset
);
446 I915_WRITE(SPRSIZE(pipe
), (crtc_h
<< 16) | crtc_w
);
447 if (intel_plane
->can_scale
)
448 I915_WRITE(SPRSCALE(pipe
), sprscale
);
449 I915_WRITE(SPRCTL(pipe
), sprctl
);
450 I915_WRITE(SPRSURF(pipe
),
451 i915_gem_obj_ggtt_offset(obj
) + sprsurf_offset
);
453 intel_flush_primary_plane(dev_priv
, intel_crtc
->plane
);
456 intel_pipe_update_end(intel_crtc
, start_vbl_count
);
460 ivb_disable_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
)
462 struct drm_device
*dev
= plane
->dev
;
463 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
464 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
465 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
466 int pipe
= intel_plane
->pipe
;
470 atomic_update
= intel_pipe_update_start(intel_crtc
, &start_vbl_count
);
472 intel_update_primary_plane(intel_crtc
);
474 I915_WRITE(SPRCTL(pipe
), I915_READ(SPRCTL(pipe
)) & ~SPRITE_ENABLE
);
475 /* Can't leave the scaler enabled... */
476 if (intel_plane
->can_scale
)
477 I915_WRITE(SPRSCALE(pipe
), 0);
478 /* Activate double buffered register update */
479 I915_WRITE(SPRSURF(pipe
), 0);
481 intel_flush_primary_plane(dev_priv
, intel_crtc
->plane
);
484 intel_pipe_update_end(intel_crtc
, start_vbl_count
);
487 * Avoid underruns when disabling the sprite.
488 * FIXME remove once watermark updates are done properly.
490 intel_wait_for_vblank(dev
, pipe
);
492 intel_update_sprite_watermarks(plane
, crtc
, 0, 0, 0, false, false);
496 ivb_update_colorkey(struct drm_plane
*plane
,
497 struct drm_intel_sprite_colorkey
*key
)
499 struct drm_device
*dev
= plane
->dev
;
500 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
501 struct intel_plane
*intel_plane
;
505 intel_plane
= to_intel_plane(plane
);
507 I915_WRITE(SPRKEYVAL(intel_plane
->pipe
), key
->min_value
);
508 I915_WRITE(SPRKEYMAX(intel_plane
->pipe
), key
->max_value
);
509 I915_WRITE(SPRKEYMSK(intel_plane
->pipe
), key
->channel_mask
);
511 sprctl
= I915_READ(SPRCTL(intel_plane
->pipe
));
512 sprctl
&= ~(SPRITE_SOURCE_KEY
| SPRITE_DEST_KEY
);
513 if (key
->flags
& I915_SET_COLORKEY_DESTINATION
)
514 sprctl
|= SPRITE_DEST_KEY
;
515 else if (key
->flags
& I915_SET_COLORKEY_SOURCE
)
516 sprctl
|= SPRITE_SOURCE_KEY
;
517 I915_WRITE(SPRCTL(intel_plane
->pipe
), sprctl
);
519 POSTING_READ(SPRKEYMSK(intel_plane
->pipe
));
525 ivb_get_colorkey(struct drm_plane
*plane
, struct drm_intel_sprite_colorkey
*key
)
527 struct drm_device
*dev
= plane
->dev
;
528 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
529 struct intel_plane
*intel_plane
;
532 intel_plane
= to_intel_plane(plane
);
534 key
->min_value
= I915_READ(SPRKEYVAL(intel_plane
->pipe
));
535 key
->max_value
= I915_READ(SPRKEYMAX(intel_plane
->pipe
));
536 key
->channel_mask
= I915_READ(SPRKEYMSK(intel_plane
->pipe
));
539 sprctl
= I915_READ(SPRCTL(intel_plane
->pipe
));
541 if (sprctl
& SPRITE_DEST_KEY
)
542 key
->flags
= I915_SET_COLORKEY_DESTINATION
;
543 else if (sprctl
& SPRITE_SOURCE_KEY
)
544 key
->flags
= I915_SET_COLORKEY_SOURCE
;
546 key
->flags
= I915_SET_COLORKEY_NONE
;
550 ilk_update_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
,
551 struct drm_framebuffer
*fb
,
552 struct drm_i915_gem_object
*obj
, int crtc_x
, int crtc_y
,
553 unsigned int crtc_w
, unsigned int crtc_h
,
554 uint32_t x
, uint32_t y
,
555 uint32_t src_w
, uint32_t src_h
)
557 struct drm_device
*dev
= plane
->dev
;
558 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
559 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
560 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
561 int pipe
= intel_plane
->pipe
;
562 unsigned long dvssurf_offset
, linear_offset
;
563 u32 dvscntr
, dvsscale
;
564 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
568 dvscntr
= I915_READ(DVSCNTR(pipe
));
570 /* Mask out pixel format bits in case we change it */
571 dvscntr
&= ~DVS_PIXFORMAT_MASK
;
572 dvscntr
&= ~DVS_RGB_ORDER_XBGR
;
573 dvscntr
&= ~DVS_YUV_BYTE_ORDER_MASK
;
574 dvscntr
&= ~DVS_TILED
;
576 switch (fb
->pixel_format
) {
577 case DRM_FORMAT_XBGR8888
:
578 dvscntr
|= DVS_FORMAT_RGBX888
| DVS_RGB_ORDER_XBGR
;
580 case DRM_FORMAT_XRGB8888
:
581 dvscntr
|= DVS_FORMAT_RGBX888
;
583 case DRM_FORMAT_YUYV
:
584 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_YUYV
;
586 case DRM_FORMAT_YVYU
:
587 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_YVYU
;
589 case DRM_FORMAT_UYVY
:
590 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_UYVY
;
592 case DRM_FORMAT_VYUY
:
593 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_VYUY
;
600 * Enable gamma to match primary/cursor plane behaviour.
601 * FIXME should be user controllable via propertiesa.
603 dvscntr
|= DVS_GAMMA_ENABLE
;
605 if (obj
->tiling_mode
!= I915_TILING_NONE
)
606 dvscntr
|= DVS_TILED
;
609 dvscntr
|= DVS_TRICKLE_FEED_DISABLE
; /* must disable */
610 dvscntr
|= DVS_ENABLE
;
612 intel_update_sprite_watermarks(plane
, crtc
, src_w
, src_h
,
614 src_w
!= crtc_w
|| src_h
!= crtc_h
);
616 /* Sizes are 0 based */
623 if (crtc_w
!= src_w
|| crtc_h
!= src_h
)
624 dvsscale
= DVS_SCALE_ENABLE
| (src_w
<< 16) | src_h
;
626 linear_offset
= y
* fb
->pitches
[0] + x
* pixel_size
;
628 intel_gen4_compute_page_offset(&x
, &y
, obj
->tiling_mode
,
629 pixel_size
, fb
->pitches
[0]);
630 linear_offset
-= dvssurf_offset
;
632 atomic_update
= intel_pipe_update_start(intel_crtc
, &start_vbl_count
);
634 intel_update_primary_plane(intel_crtc
);
636 I915_WRITE(DVSSTRIDE(pipe
), fb
->pitches
[0]);
637 I915_WRITE(DVSPOS(pipe
), (crtc_y
<< 16) | crtc_x
);
639 if (obj
->tiling_mode
!= I915_TILING_NONE
)
640 I915_WRITE(DVSTILEOFF(pipe
), (y
<< 16) | x
);
642 I915_WRITE(DVSLINOFF(pipe
), linear_offset
);
644 I915_WRITE(DVSSIZE(pipe
), (crtc_h
<< 16) | crtc_w
);
645 I915_WRITE(DVSSCALE(pipe
), dvsscale
);
646 I915_WRITE(DVSCNTR(pipe
), dvscntr
);
647 I915_WRITE(DVSSURF(pipe
),
648 i915_gem_obj_ggtt_offset(obj
) + dvssurf_offset
);
650 intel_flush_primary_plane(dev_priv
, intel_crtc
->plane
);
653 intel_pipe_update_end(intel_crtc
, start_vbl_count
);
657 ilk_disable_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
)
659 struct drm_device
*dev
= plane
->dev
;
660 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
661 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
662 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
663 int pipe
= intel_plane
->pipe
;
667 atomic_update
= intel_pipe_update_start(intel_crtc
, &start_vbl_count
);
669 intel_update_primary_plane(intel_crtc
);
671 I915_WRITE(DVSCNTR(pipe
), I915_READ(DVSCNTR(pipe
)) & ~DVS_ENABLE
);
672 /* Disable the scaler */
673 I915_WRITE(DVSSCALE(pipe
), 0);
674 /* Flush double buffered register updates */
675 I915_WRITE(DVSSURF(pipe
), 0);
677 intel_flush_primary_plane(dev_priv
, intel_crtc
->plane
);
680 intel_pipe_update_end(intel_crtc
, start_vbl_count
);
683 * Avoid underruns when disabling the sprite.
684 * FIXME remove once watermark updates are done properly.
686 intel_wait_for_vblank(dev
, pipe
);
688 intel_update_sprite_watermarks(plane
, crtc
, 0, 0, 0, false, false);
692 intel_post_enable_primary(struct drm_crtc
*crtc
)
694 struct drm_device
*dev
= crtc
->dev
;
695 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
698 * BDW signals flip done immediately if the plane
699 * is disabled, even if the plane enable is already
700 * armed to occur at the next vblank :(
702 if (IS_BROADWELL(dev
))
703 intel_wait_for_vblank(dev
, intel_crtc
->pipe
);
706 * FIXME IPS should be fine as long as one plane is
707 * enabled, but in practice it seems to have problems
708 * when going from primary only to sprite only and vice
711 hsw_enable_ips(intel_crtc
);
713 mutex_lock(&dev
->struct_mutex
);
714 intel_update_fbc(dev
);
715 mutex_unlock(&dev
->struct_mutex
);
719 intel_pre_disable_primary(struct drm_crtc
*crtc
)
721 struct drm_device
*dev
= crtc
->dev
;
722 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
723 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
725 mutex_lock(&dev
->struct_mutex
);
726 if (dev_priv
->fbc
.plane
== intel_crtc
->plane
)
727 intel_disable_fbc(dev
);
728 mutex_unlock(&dev
->struct_mutex
);
731 * FIXME IPS should be fine as long as one plane is
732 * enabled, but in practice it seems to have problems
733 * when going from primary only to sprite only and vice
736 hsw_disable_ips(intel_crtc
);
740 ilk_update_colorkey(struct drm_plane
*plane
,
741 struct drm_intel_sprite_colorkey
*key
)
743 struct drm_device
*dev
= plane
->dev
;
744 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
745 struct intel_plane
*intel_plane
;
749 intel_plane
= to_intel_plane(plane
);
751 I915_WRITE(DVSKEYVAL(intel_plane
->pipe
), key
->min_value
);
752 I915_WRITE(DVSKEYMAX(intel_plane
->pipe
), key
->max_value
);
753 I915_WRITE(DVSKEYMSK(intel_plane
->pipe
), key
->channel_mask
);
755 dvscntr
= I915_READ(DVSCNTR(intel_plane
->pipe
));
756 dvscntr
&= ~(DVS_SOURCE_KEY
| DVS_DEST_KEY
);
757 if (key
->flags
& I915_SET_COLORKEY_DESTINATION
)
758 dvscntr
|= DVS_DEST_KEY
;
759 else if (key
->flags
& I915_SET_COLORKEY_SOURCE
)
760 dvscntr
|= DVS_SOURCE_KEY
;
761 I915_WRITE(DVSCNTR(intel_plane
->pipe
), dvscntr
);
763 POSTING_READ(DVSKEYMSK(intel_plane
->pipe
));
769 ilk_get_colorkey(struct drm_plane
*plane
, struct drm_intel_sprite_colorkey
*key
)
771 struct drm_device
*dev
= plane
->dev
;
772 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
773 struct intel_plane
*intel_plane
;
776 intel_plane
= to_intel_plane(plane
);
778 key
->min_value
= I915_READ(DVSKEYVAL(intel_plane
->pipe
));
779 key
->max_value
= I915_READ(DVSKEYMAX(intel_plane
->pipe
));
780 key
->channel_mask
= I915_READ(DVSKEYMSK(intel_plane
->pipe
));
783 dvscntr
= I915_READ(DVSCNTR(intel_plane
->pipe
));
785 if (dvscntr
& DVS_DEST_KEY
)
786 key
->flags
= I915_SET_COLORKEY_DESTINATION
;
787 else if (dvscntr
& DVS_SOURCE_KEY
)
788 key
->flags
= I915_SET_COLORKEY_SOURCE
;
790 key
->flags
= I915_SET_COLORKEY_NONE
;
794 format_is_yuv(uint32_t format
)
797 case DRM_FORMAT_YUYV
:
798 case DRM_FORMAT_UYVY
:
799 case DRM_FORMAT_VYUY
:
800 case DRM_FORMAT_YVYU
:
807 static bool colorkey_enabled(struct intel_plane
*intel_plane
)
809 struct drm_intel_sprite_colorkey key
;
811 intel_plane
->get_colorkey(&intel_plane
->base
, &key
);
813 return key
.flags
!= I915_SET_COLORKEY_NONE
;
817 intel_update_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
,
818 struct drm_framebuffer
*fb
, int crtc_x
, int crtc_y
,
819 unsigned int crtc_w
, unsigned int crtc_h
,
820 uint32_t src_x
, uint32_t src_y
,
821 uint32_t src_w
, uint32_t src_h
)
823 struct drm_device
*dev
= plane
->dev
;
824 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
825 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
826 enum pipe pipe
= intel_crtc
->pipe
;
827 struct intel_framebuffer
*intel_fb
= to_intel_framebuffer(fb
);
828 struct drm_i915_gem_object
*obj
= intel_fb
->obj
;
829 struct drm_i915_gem_object
*old_obj
= intel_plane
->obj
;
831 bool primary_enabled
;
834 int max_scale
, min_scale
;
835 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
836 struct drm_rect src
= {
837 /* sample coordinates in 16.16 fixed point */
843 struct drm_rect dst
= {
846 .x2
= crtc_x
+ crtc_w
,
848 .y2
= crtc_y
+ crtc_h
,
850 const struct drm_rect clip
= {
851 .x2
= intel_crtc
->active
? intel_crtc
->config
.pipe_src_w
: 0,
852 .y2
= intel_crtc
->active
? intel_crtc
->config
.pipe_src_h
: 0,
856 unsigned int crtc_w
, crtc_h
;
857 uint32_t src_x
, src_y
, src_w
, src_h
;
869 /* Don't modify another pipe's plane */
870 if (intel_plane
->pipe
!= intel_crtc
->pipe
) {
871 DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n");
875 /* FIXME check all gen limits */
876 if (fb
->width
< 3 || fb
->height
< 3 || fb
->pitches
[0] > 16384) {
877 DRM_DEBUG_KMS("Unsuitable framebuffer for plane\n");
881 /* Sprite planes can be linear or x-tiled surfaces */
882 switch (obj
->tiling_mode
) {
883 case I915_TILING_NONE
:
887 DRM_DEBUG_KMS("Unsupported tiling mode\n");
892 * FIXME the following code does a bunch of fuzzy adjustments to the
893 * coordinates and sizes. We probably need some way to decide whether
894 * more strict checking should be done instead.
896 max_scale
= intel_plane
->max_downscale
<< 16;
897 min_scale
= intel_plane
->can_scale
? 1 : (1 << 16);
899 hscale
= drm_rect_calc_hscale_relaxed(&src
, &dst
, min_scale
, max_scale
);
902 vscale
= drm_rect_calc_vscale_relaxed(&src
, &dst
, min_scale
, max_scale
);
905 visible
= drm_rect_clip_scaled(&src
, &dst
, &clip
, hscale
, vscale
);
909 crtc_w
= drm_rect_width(&dst
);
910 crtc_h
= drm_rect_height(&dst
);
913 /* check again in case clipping clamped the results */
914 hscale
= drm_rect_calc_hscale(&src
, &dst
, min_scale
, max_scale
);
916 DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n");
917 drm_rect_debug_print(&src
, true);
918 drm_rect_debug_print(&dst
, false);
923 vscale
= drm_rect_calc_vscale(&src
, &dst
, min_scale
, max_scale
);
925 DRM_DEBUG_KMS("Vertical scaling factor out of limits\n");
926 drm_rect_debug_print(&src
, true);
927 drm_rect_debug_print(&dst
, false);
932 /* Make the source viewport size an exact multiple of the scaling factors. */
933 drm_rect_adjust_size(&src
,
934 drm_rect_width(&dst
) * hscale
- drm_rect_width(&src
),
935 drm_rect_height(&dst
) * vscale
- drm_rect_height(&src
));
937 /* sanity check to make sure the src viewport wasn't enlarged */
938 WARN_ON(src
.x1
< (int) src_x
||
939 src
.y1
< (int) src_y
||
940 src
.x2
> (int) (src_x
+ src_w
) ||
941 src
.y2
> (int) (src_y
+ src_h
));
944 * Hardware doesn't handle subpixel coordinates.
945 * Adjust to (macro)pixel boundary, but be careful not to
946 * increase the source viewport size, because that could
947 * push the downscaling factor out of bounds.
949 src_x
= src
.x1
>> 16;
950 src_w
= drm_rect_width(&src
) >> 16;
951 src_y
= src
.y1
>> 16;
952 src_h
= drm_rect_height(&src
) >> 16;
954 if (format_is_yuv(fb
->pixel_format
)) {
959 * Must keep src and dst the
960 * same if we can't scale.
962 if (!intel_plane
->can_scale
)
970 /* Check size restrictions when scaling */
971 if (visible
&& (src_w
!= crtc_w
|| src_h
!= crtc_h
)) {
972 unsigned int width_bytes
;
974 WARN_ON(!intel_plane
->can_scale
);
976 /* FIXME interlacing min height is 6 */
978 if (crtc_w
< 3 || crtc_h
< 3)
981 if (src_w
< 3 || src_h
< 3)
984 width_bytes
= ((src_x
* pixel_size
) & 63) + src_w
* pixel_size
;
986 if (src_w
> 2048 || src_h
> 2048 ||
987 width_bytes
> 4096 || fb
->pitches
[0] > 4096) {
988 DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
994 dst
.x2
= crtc_x
+ crtc_w
;
996 dst
.y2
= crtc_y
+ crtc_h
;
999 * If the sprite is completely covering the primary plane,
1000 * we can disable the primary and save power.
1002 primary_enabled
= !drm_rect_equals(&dst
, &clip
) || colorkey_enabled(intel_plane
);
1003 WARN_ON(!primary_enabled
&& !visible
&& intel_crtc
->active
);
1005 mutex_lock(&dev
->struct_mutex
);
1007 /* Note that this will apply the VT-d workaround for scanouts,
1008 * which is more restrictive than required for sprites. (The
1009 * primary plane requires 256KiB alignment with 64 PTE padding,
1010 * the sprite planes only require 128KiB alignment and 32 PTE padding.
1012 ret
= intel_pin_and_fence_fb_obj(dev
, obj
, NULL
);
1014 i915_gem_track_fb(old_obj
, obj
,
1015 INTEL_FRONTBUFFER_SPRITE(pipe
));
1016 mutex_unlock(&dev
->struct_mutex
);
1021 intel_plane
->crtc_x
= orig
.crtc_x
;
1022 intel_plane
->crtc_y
= orig
.crtc_y
;
1023 intel_plane
->crtc_w
= orig
.crtc_w
;
1024 intel_plane
->crtc_h
= orig
.crtc_h
;
1025 intel_plane
->src_x
= orig
.src_x
;
1026 intel_plane
->src_y
= orig
.src_y
;
1027 intel_plane
->src_w
= orig
.src_w
;
1028 intel_plane
->src_h
= orig
.src_h
;
1029 intel_plane
->obj
= obj
;
1031 if (intel_crtc
->active
) {
1032 bool primary_was_enabled
= intel_crtc
->primary_enabled
;
1034 intel_crtc
->primary_enabled
= primary_enabled
;
1036 if (primary_was_enabled
!= primary_enabled
)
1037 intel_crtc_wait_for_pending_flips(crtc
);
1039 if (primary_was_enabled
&& !primary_enabled
)
1040 intel_pre_disable_primary(crtc
);
1043 intel_plane
->update_plane(plane
, crtc
, fb
, obj
,
1044 crtc_x
, crtc_y
, crtc_w
, crtc_h
,
1045 src_x
, src_y
, src_w
, src_h
);
1047 intel_plane
->disable_plane(plane
, crtc
);
1049 intel_frontbuffer_flip(dev
, INTEL_FRONTBUFFER_SPRITE(pipe
));
1051 if (!primary_was_enabled
&& primary_enabled
)
1052 intel_post_enable_primary(crtc
);
1055 /* Unpin old obj after new one is active to avoid ugliness */
1058 * It's fairly common to simply update the position of
1059 * an existing object. In that case, we don't need to
1060 * wait for vblank to avoid ugliness, we only need to
1061 * do the pin & ref bookkeeping.
1063 if (old_obj
!= obj
&& intel_crtc
->active
)
1064 intel_wait_for_vblank(dev
, intel_crtc
->pipe
);
1066 mutex_lock(&dev
->struct_mutex
);
1067 intel_unpin_fb_obj(old_obj
);
1068 mutex_unlock(&dev
->struct_mutex
);
1075 intel_disable_plane(struct drm_plane
*plane
)
1077 struct drm_device
*dev
= plane
->dev
;
1078 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
1079 struct intel_crtc
*intel_crtc
;
1085 if (WARN_ON(!plane
->crtc
))
1088 intel_crtc
= to_intel_crtc(plane
->crtc
);
1089 pipe
= intel_crtc
->pipe
;
1091 if (intel_crtc
->active
) {
1092 bool primary_was_enabled
= intel_crtc
->primary_enabled
;
1094 intel_crtc
->primary_enabled
= true;
1096 intel_plane
->disable_plane(plane
, plane
->crtc
);
1098 if (!primary_was_enabled
&& intel_crtc
->primary_enabled
)
1099 intel_post_enable_primary(plane
->crtc
);
1102 if (intel_plane
->obj
) {
1103 if (intel_crtc
->active
)
1104 intel_wait_for_vblank(dev
, intel_plane
->pipe
);
1106 mutex_lock(&dev
->struct_mutex
);
1107 intel_unpin_fb_obj(intel_plane
->obj
);
1108 i915_gem_track_fb(intel_plane
->obj
, NULL
,
1109 INTEL_FRONTBUFFER_SPRITE(pipe
));
1110 mutex_unlock(&dev
->struct_mutex
);
1112 intel_plane
->obj
= NULL
;
1118 static void intel_destroy_plane(struct drm_plane
*plane
)
1120 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
1121 intel_disable_plane(plane
);
1122 drm_plane_cleanup(plane
);
1126 int intel_sprite_set_colorkey(struct drm_device
*dev
, void *data
,
1127 struct drm_file
*file_priv
)
1129 struct drm_intel_sprite_colorkey
*set
= data
;
1130 struct drm_plane
*plane
;
1131 struct intel_plane
*intel_plane
;
1134 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
1137 /* Make sure we don't try to enable both src & dest simultaneously */
1138 if ((set
->flags
& (I915_SET_COLORKEY_DESTINATION
| I915_SET_COLORKEY_SOURCE
)) == (I915_SET_COLORKEY_DESTINATION
| I915_SET_COLORKEY_SOURCE
))
1141 drm_modeset_lock_all(dev
);
1143 plane
= drm_plane_find(dev
, set
->plane_id
);
1149 intel_plane
= to_intel_plane(plane
);
1150 ret
= intel_plane
->update_colorkey(plane
, set
);
1153 drm_modeset_unlock_all(dev
);
1157 int intel_sprite_get_colorkey(struct drm_device
*dev
, void *data
,
1158 struct drm_file
*file_priv
)
1160 struct drm_intel_sprite_colorkey
*get
= data
;
1161 struct drm_plane
*plane
;
1162 struct intel_plane
*intel_plane
;
1165 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
1168 drm_modeset_lock_all(dev
);
1170 plane
= drm_plane_find(dev
, get
->plane_id
);
1176 intel_plane
= to_intel_plane(plane
);
1177 intel_plane
->get_colorkey(plane
, get
);
1180 drm_modeset_unlock_all(dev
);
1184 void intel_plane_restore(struct drm_plane
*plane
)
1186 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
1188 if (!plane
->crtc
|| !plane
->fb
)
1191 intel_update_plane(plane
, plane
->crtc
, plane
->fb
,
1192 intel_plane
->crtc_x
, intel_plane
->crtc_y
,
1193 intel_plane
->crtc_w
, intel_plane
->crtc_h
,
1194 intel_plane
->src_x
, intel_plane
->src_y
,
1195 intel_plane
->src_w
, intel_plane
->src_h
);
1198 void intel_plane_disable(struct drm_plane
*plane
)
1200 if (!plane
->crtc
|| !plane
->fb
)
1203 intel_disable_plane(plane
);
1206 static const struct drm_plane_funcs intel_plane_funcs
= {
1207 .update_plane
= intel_update_plane
,
1208 .disable_plane
= intel_disable_plane
,
1209 .destroy
= intel_destroy_plane
,
1212 static uint32_t ilk_plane_formats
[] = {
1213 DRM_FORMAT_XRGB8888
,
1220 static uint32_t snb_plane_formats
[] = {
1221 DRM_FORMAT_XBGR8888
,
1222 DRM_FORMAT_XRGB8888
,
1229 static uint32_t vlv_plane_formats
[] = {
1231 DRM_FORMAT_ABGR8888
,
1232 DRM_FORMAT_ARGB8888
,
1233 DRM_FORMAT_XBGR8888
,
1234 DRM_FORMAT_XRGB8888
,
1235 DRM_FORMAT_XBGR2101010
,
1236 DRM_FORMAT_ABGR2101010
,
1244 intel_plane_init(struct drm_device
*dev
, enum pipe pipe
, int plane
)
1246 struct intel_plane
*intel_plane
;
1247 unsigned long possible_crtcs
;
1248 const uint32_t *plane_formats
;
1249 int num_plane_formats
;
1252 if (INTEL_INFO(dev
)->gen
< 5)
1255 intel_plane
= kzalloc(sizeof(*intel_plane
), GFP_KERNEL
);
1259 switch (INTEL_INFO(dev
)->gen
) {
1262 intel_plane
->can_scale
= true;
1263 intel_plane
->max_downscale
= 16;
1264 intel_plane
->update_plane
= ilk_update_plane
;
1265 intel_plane
->disable_plane
= ilk_disable_plane
;
1266 intel_plane
->update_colorkey
= ilk_update_colorkey
;
1267 intel_plane
->get_colorkey
= ilk_get_colorkey
;
1270 plane_formats
= snb_plane_formats
;
1271 num_plane_formats
= ARRAY_SIZE(snb_plane_formats
);
1273 plane_formats
= ilk_plane_formats
;
1274 num_plane_formats
= ARRAY_SIZE(ilk_plane_formats
);
1280 if (IS_IVYBRIDGE(dev
)) {
1281 intel_plane
->can_scale
= true;
1282 intel_plane
->max_downscale
= 2;
1284 intel_plane
->can_scale
= false;
1285 intel_plane
->max_downscale
= 1;
1288 if (IS_VALLEYVIEW(dev
)) {
1289 intel_plane
->update_plane
= vlv_update_plane
;
1290 intel_plane
->disable_plane
= vlv_disable_plane
;
1291 intel_plane
->update_colorkey
= vlv_update_colorkey
;
1292 intel_plane
->get_colorkey
= vlv_get_colorkey
;
1294 plane_formats
= vlv_plane_formats
;
1295 num_plane_formats
= ARRAY_SIZE(vlv_plane_formats
);
1297 intel_plane
->update_plane
= ivb_update_plane
;
1298 intel_plane
->disable_plane
= ivb_disable_plane
;
1299 intel_plane
->update_colorkey
= ivb_update_colorkey
;
1300 intel_plane
->get_colorkey
= ivb_get_colorkey
;
1302 plane_formats
= snb_plane_formats
;
1303 num_plane_formats
= ARRAY_SIZE(snb_plane_formats
);
1312 intel_plane
->pipe
= pipe
;
1313 intel_plane
->plane
= plane
;
1314 possible_crtcs
= (1 << pipe
);
1315 ret
= drm_plane_init(dev
, &intel_plane
->base
, possible_crtcs
,
1317 plane_formats
, num_plane_formats
,