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 <uapi_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 i915_pipe pipe
= crtc
->pipe
;
54 long timeout
= msecs_to_jiffies_timeout(1);
55 int scanline
, min
, max
, vblank_start
;
58 WARN_ON(!drm_modeset_is_locked(&crtc
->base
.mutex
));
60 vblank_start
= mode
->crtc_vblank_start
;
61 if (mode
->flags
& DRM_MODE_FLAG_INTERLACE
)
62 vblank_start
= DIV_ROUND_UP(vblank_start
, 2);
64 /* FIXME needs to be calibrated sensibly */
65 min
= vblank_start
- usecs_to_scanlines(mode
, 100);
66 max
= vblank_start
- 1;
68 if (min
<= 0 || max
<= 0)
71 if (WARN_ON(drm_vblank_get(dev
, pipe
)))
76 trace_i915_pipe_update_start(crtc
, min
, max
);
80 * prepare_to_wait() has a memory barrier, which guarantees
81 * other CPUs can see the task state update by the time we
84 prepare_to_wait(&crtc
->vbl_wait
, &wait
, TASK_UNINTERRUPTIBLE
);
86 scanline
= intel_get_crtc_scanline(crtc
);
87 if (scanline
< min
|| scanline
> max
)
91 DRM_ERROR("Potential atomic update failure on pipe %c\n",
92 pipe_name(crtc
->pipe
));
98 timeout
= schedule_timeout(timeout
);
103 finish_wait(&crtc
->vbl_wait
, &wait
);
105 drm_vblank_put(dev
, pipe
);
107 *start_vbl_count
= dev
->driver
->get_vblank_counter(dev
, pipe
);
109 trace_i915_pipe_update_vblank_evaded(crtc
, min
, max
, *start_vbl_count
);
114 static void intel_pipe_update_end(struct intel_crtc
*crtc
, u32 start_vbl_count
)
116 struct drm_device
*dev
= crtc
->base
.dev
;
117 enum i915_pipe pipe
= crtc
->pipe
;
118 u32 end_vbl_count
= dev
->driver
->get_vblank_counter(dev
, pipe
);
120 trace_i915_pipe_update_end(crtc
, end_vbl_count
);
124 if (start_vbl_count
!= end_vbl_count
)
125 DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u)\n",
126 pipe_name(pipe
), start_vbl_count
, end_vbl_count
);
129 static void intel_update_primary_plane(struct intel_crtc
*crtc
)
131 struct drm_i915_private
*dev_priv
= crtc
->base
.dev
->dev_private
;
132 int reg
= DSPCNTR(crtc
->plane
);
134 if (crtc
->primary_enabled
)
135 I915_WRITE(reg
, I915_READ(reg
) | DISPLAY_PLANE_ENABLE
);
137 I915_WRITE(reg
, I915_READ(reg
) & ~DISPLAY_PLANE_ENABLE
);
141 vlv_update_plane(struct drm_plane
*dplane
, struct drm_crtc
*crtc
,
142 struct drm_framebuffer
*fb
,
143 struct drm_i915_gem_object
*obj
, int crtc_x
, int crtc_y
,
144 unsigned int crtc_w
, unsigned int crtc_h
,
145 uint32_t x
, uint32_t y
,
146 uint32_t src_w
, uint32_t src_h
)
148 struct drm_device
*dev
= dplane
->dev
;
149 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
150 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
151 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
152 int pipe
= intel_plane
->pipe
;
153 int plane
= intel_plane
->plane
;
155 unsigned long sprsurf_offset
, linear_offset
;
156 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
160 sprctl
= I915_READ(SPCNTR(pipe
, plane
));
162 /* Mask out pixel format bits in case we change it */
163 sprctl
&= ~SP_PIXFORMAT_MASK
;
164 sprctl
&= ~SP_YUV_BYTE_ORDER_MASK
;
167 switch (fb
->pixel_format
) {
168 case DRM_FORMAT_YUYV
:
169 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_YUYV
;
171 case DRM_FORMAT_YVYU
:
172 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_YVYU
;
174 case DRM_FORMAT_UYVY
:
175 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_UYVY
;
177 case DRM_FORMAT_VYUY
:
178 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_VYUY
;
180 case DRM_FORMAT_RGB565
:
181 sprctl
|= SP_FORMAT_BGR565
;
183 case DRM_FORMAT_XRGB8888
:
184 sprctl
|= SP_FORMAT_BGRX8888
;
186 case DRM_FORMAT_ARGB8888
:
187 sprctl
|= SP_FORMAT_BGRA8888
;
189 case DRM_FORMAT_XBGR2101010
:
190 sprctl
|= SP_FORMAT_RGBX1010102
;
192 case DRM_FORMAT_ABGR2101010
:
193 sprctl
|= SP_FORMAT_RGBA1010102
;
195 case DRM_FORMAT_XBGR8888
:
196 sprctl
|= SP_FORMAT_RGBX8888
;
198 case DRM_FORMAT_ABGR8888
:
199 sprctl
|= SP_FORMAT_RGBA8888
;
203 * If we get here one of the upper layers failed to filter
204 * out the unsupported plane formats
211 * Enable gamma to match primary/cursor plane behaviour.
212 * FIXME should be user controllable via propertiesa.
214 sprctl
|= SP_GAMMA_ENABLE
;
216 if (obj
->tiling_mode
!= I915_TILING_NONE
)
221 intel_update_sprite_watermarks(dplane
, crtc
, src_w
, src_h
,
223 src_w
!= crtc_w
|| src_h
!= crtc_h
);
225 /* Sizes are 0 based */
231 linear_offset
= y
* fb
->pitches
[0] + x
* pixel_size
;
232 sprsurf_offset
= intel_gen4_compute_page_offset(&x
, &y
,
236 linear_offset
-= sprsurf_offset
;
238 atomic_update
= intel_pipe_update_start(intel_crtc
, &start_vbl_count
);
240 intel_update_primary_plane(intel_crtc
);
242 I915_WRITE(SPSTRIDE(pipe
, plane
), fb
->pitches
[0]);
243 I915_WRITE(SPPOS(pipe
, plane
), (crtc_y
<< 16) | crtc_x
);
245 if (obj
->tiling_mode
!= I915_TILING_NONE
)
246 I915_WRITE(SPTILEOFF(pipe
, plane
), (y
<< 16) | x
);
248 I915_WRITE(SPLINOFF(pipe
, plane
), linear_offset
);
250 I915_WRITE(SPSIZE(pipe
, plane
), (crtc_h
<< 16) | crtc_w
);
251 I915_WRITE(SPCNTR(pipe
, plane
), sprctl
);
252 I915_WRITE(SPSURF(pipe
, plane
), i915_gem_obj_ggtt_offset(obj
) +
255 intel_flush_primary_plane(dev_priv
, intel_crtc
->plane
);
258 intel_pipe_update_end(intel_crtc
, start_vbl_count
);
262 vlv_disable_plane(struct drm_plane
*dplane
, struct drm_crtc
*crtc
)
264 struct drm_device
*dev
= dplane
->dev
;
265 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
266 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
267 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
268 int pipe
= intel_plane
->pipe
;
269 int plane
= intel_plane
->plane
;
273 atomic_update
= intel_pipe_update_start(intel_crtc
, &start_vbl_count
);
275 intel_update_primary_plane(intel_crtc
);
277 I915_WRITE(SPCNTR(pipe
, plane
), I915_READ(SPCNTR(pipe
, plane
)) &
279 /* Activate double buffered register update */
280 I915_WRITE(SPSURF(pipe
, plane
), 0);
282 intel_flush_primary_plane(dev_priv
, intel_crtc
->plane
);
285 intel_pipe_update_end(intel_crtc
, start_vbl_count
);
287 intel_update_sprite_watermarks(dplane
, crtc
, 0, 0, 0, false, false);
291 vlv_update_colorkey(struct drm_plane
*dplane
,
292 struct drm_intel_sprite_colorkey
*key
)
294 struct drm_device
*dev
= dplane
->dev
;
295 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
296 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
297 int pipe
= intel_plane
->pipe
;
298 int plane
= intel_plane
->plane
;
301 if (key
->flags
& I915_SET_COLORKEY_DESTINATION
)
304 I915_WRITE(SPKEYMINVAL(pipe
, plane
), key
->min_value
);
305 I915_WRITE(SPKEYMAXVAL(pipe
, plane
), key
->max_value
);
306 I915_WRITE(SPKEYMSK(pipe
, plane
), key
->channel_mask
);
308 sprctl
= I915_READ(SPCNTR(pipe
, plane
));
309 sprctl
&= ~SP_SOURCE_KEY
;
310 if (key
->flags
& I915_SET_COLORKEY_SOURCE
)
311 sprctl
|= SP_SOURCE_KEY
;
312 I915_WRITE(SPCNTR(pipe
, plane
), sprctl
);
314 POSTING_READ(SPKEYMSK(pipe
, plane
));
320 vlv_get_colorkey(struct drm_plane
*dplane
,
321 struct drm_intel_sprite_colorkey
*key
)
323 struct drm_device
*dev
= dplane
->dev
;
324 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
325 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
326 int pipe
= intel_plane
->pipe
;
327 int plane
= intel_plane
->plane
;
330 key
->min_value
= I915_READ(SPKEYMINVAL(pipe
, plane
));
331 key
->max_value
= I915_READ(SPKEYMAXVAL(pipe
, plane
));
332 key
->channel_mask
= I915_READ(SPKEYMSK(pipe
, plane
));
334 sprctl
= I915_READ(SPCNTR(pipe
, plane
));
335 if (sprctl
& SP_SOURCE_KEY
)
336 key
->flags
= I915_SET_COLORKEY_SOURCE
;
338 key
->flags
= I915_SET_COLORKEY_NONE
;
342 ivb_update_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
,
343 struct drm_framebuffer
*fb
,
344 struct drm_i915_gem_object
*obj
, int crtc_x
, int crtc_y
,
345 unsigned int crtc_w
, unsigned int crtc_h
,
346 uint32_t x
, uint32_t y
,
347 uint32_t src_w
, uint32_t src_h
)
349 struct drm_device
*dev
= plane
->dev
;
350 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
351 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
352 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
353 int pipe
= intel_plane
->pipe
;
354 u32 sprctl
, sprscale
= 0;
355 unsigned long sprsurf_offset
, linear_offset
;
356 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
360 sprctl
= I915_READ(SPRCTL(pipe
));
362 /* Mask out pixel format bits in case we change it */
363 sprctl
&= ~SPRITE_PIXFORMAT_MASK
;
364 sprctl
&= ~SPRITE_RGB_ORDER_RGBX
;
365 sprctl
&= ~SPRITE_YUV_BYTE_ORDER_MASK
;
366 sprctl
&= ~SPRITE_TILED
;
368 switch (fb
->pixel_format
) {
369 case DRM_FORMAT_XBGR8888
:
370 sprctl
|= SPRITE_FORMAT_RGBX888
| SPRITE_RGB_ORDER_RGBX
;
372 case DRM_FORMAT_XRGB8888
:
373 sprctl
|= SPRITE_FORMAT_RGBX888
;
375 case DRM_FORMAT_YUYV
:
376 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_YUYV
;
378 case DRM_FORMAT_YVYU
:
379 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_YVYU
;
381 case DRM_FORMAT_UYVY
:
382 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_UYVY
;
384 case DRM_FORMAT_VYUY
:
385 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_VYUY
;
392 * Enable gamma to match primary/cursor plane behaviour.
393 * FIXME should be user controllable via propertiesa.
395 sprctl
|= SPRITE_GAMMA_ENABLE
;
397 if (obj
->tiling_mode
!= I915_TILING_NONE
)
398 sprctl
|= SPRITE_TILED
;
400 if (IS_HASWELL(dev
) || IS_BROADWELL(dev
))
401 sprctl
&= ~SPRITE_TRICKLE_FEED_DISABLE
;
403 sprctl
|= SPRITE_TRICKLE_FEED_DISABLE
;
405 sprctl
|= SPRITE_ENABLE
;
407 if (IS_HASWELL(dev
) || IS_BROADWELL(dev
))
408 sprctl
|= SPRITE_PIPE_CSC_ENABLE
;
410 intel_update_sprite_watermarks(plane
, crtc
, src_w
, src_h
, pixel_size
,
412 src_w
!= crtc_w
|| src_h
!= crtc_h
);
414 /* Sizes are 0 based */
420 if (crtc_w
!= src_w
|| crtc_h
!= src_h
)
421 sprscale
= SPRITE_SCALE_ENABLE
| (src_w
<< 16) | src_h
;
423 linear_offset
= y
* fb
->pitches
[0] + x
* pixel_size
;
425 intel_gen4_compute_page_offset(&x
, &y
, obj
->tiling_mode
,
426 pixel_size
, fb
->pitches
[0]);
427 linear_offset
-= sprsurf_offset
;
429 atomic_update
= intel_pipe_update_start(intel_crtc
, &start_vbl_count
);
431 intel_update_primary_plane(intel_crtc
);
433 I915_WRITE(SPRSTRIDE(pipe
), fb
->pitches
[0]);
434 I915_WRITE(SPRPOS(pipe
), (crtc_y
<< 16) | crtc_x
);
436 /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
438 if (IS_HASWELL(dev
) || IS_BROADWELL(dev
))
439 I915_WRITE(SPROFFSET(pipe
), (y
<< 16) | x
);
440 else if (obj
->tiling_mode
!= I915_TILING_NONE
)
441 I915_WRITE(SPRTILEOFF(pipe
), (y
<< 16) | x
);
443 I915_WRITE(SPRLINOFF(pipe
), linear_offset
);
445 I915_WRITE(SPRSIZE(pipe
), (crtc_h
<< 16) | crtc_w
);
446 if (intel_plane
->can_scale
)
447 I915_WRITE(SPRSCALE(pipe
), sprscale
);
448 I915_WRITE(SPRCTL(pipe
), sprctl
);
449 I915_WRITE(SPRSURF(pipe
),
450 i915_gem_obj_ggtt_offset(obj
) + sprsurf_offset
);
452 intel_flush_primary_plane(dev_priv
, intel_crtc
->plane
);
455 intel_pipe_update_end(intel_crtc
, start_vbl_count
);
459 ivb_disable_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
)
461 struct drm_device
*dev
= plane
->dev
;
462 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
463 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
464 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
465 int pipe
= intel_plane
->pipe
;
469 atomic_update
= intel_pipe_update_start(intel_crtc
, &start_vbl_count
);
471 intel_update_primary_plane(intel_crtc
);
473 I915_WRITE(SPRCTL(pipe
), I915_READ(SPRCTL(pipe
)) & ~SPRITE_ENABLE
);
474 /* Can't leave the scaler enabled... */
475 if (intel_plane
->can_scale
)
476 I915_WRITE(SPRSCALE(pipe
), 0);
477 /* Activate double buffered register update */
478 I915_WRITE(SPRSURF(pipe
), 0);
480 intel_flush_primary_plane(dev_priv
, intel_crtc
->plane
);
483 intel_pipe_update_end(intel_crtc
, start_vbl_count
);
486 * Avoid underruns when disabling the sprite.
487 * FIXME remove once watermark updates are done properly.
489 intel_wait_for_vblank(dev
, pipe
);
491 intel_update_sprite_watermarks(plane
, crtc
, 0, 0, 0, false, false);
495 ivb_update_colorkey(struct drm_plane
*plane
,
496 struct drm_intel_sprite_colorkey
*key
)
498 struct drm_device
*dev
= plane
->dev
;
499 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
500 struct intel_plane
*intel_plane
;
504 intel_plane
= to_intel_plane(plane
);
506 I915_WRITE(SPRKEYVAL(intel_plane
->pipe
), key
->min_value
);
507 I915_WRITE(SPRKEYMAX(intel_plane
->pipe
), key
->max_value
);
508 I915_WRITE(SPRKEYMSK(intel_plane
->pipe
), key
->channel_mask
);
510 sprctl
= I915_READ(SPRCTL(intel_plane
->pipe
));
511 sprctl
&= ~(SPRITE_SOURCE_KEY
| SPRITE_DEST_KEY
);
512 if (key
->flags
& I915_SET_COLORKEY_DESTINATION
)
513 sprctl
|= SPRITE_DEST_KEY
;
514 else if (key
->flags
& I915_SET_COLORKEY_SOURCE
)
515 sprctl
|= SPRITE_SOURCE_KEY
;
516 I915_WRITE(SPRCTL(intel_plane
->pipe
), sprctl
);
518 POSTING_READ(SPRKEYMSK(intel_plane
->pipe
));
524 ivb_get_colorkey(struct drm_plane
*plane
, struct drm_intel_sprite_colorkey
*key
)
526 struct drm_device
*dev
= plane
->dev
;
527 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
528 struct intel_plane
*intel_plane
;
531 intel_plane
= to_intel_plane(plane
);
533 key
->min_value
= I915_READ(SPRKEYVAL(intel_plane
->pipe
));
534 key
->max_value
= I915_READ(SPRKEYMAX(intel_plane
->pipe
));
535 key
->channel_mask
= I915_READ(SPRKEYMSK(intel_plane
->pipe
));
538 sprctl
= I915_READ(SPRCTL(intel_plane
->pipe
));
540 if (sprctl
& SPRITE_DEST_KEY
)
541 key
->flags
= I915_SET_COLORKEY_DESTINATION
;
542 else if (sprctl
& SPRITE_SOURCE_KEY
)
543 key
->flags
= I915_SET_COLORKEY_SOURCE
;
545 key
->flags
= I915_SET_COLORKEY_NONE
;
549 ilk_update_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
,
550 struct drm_framebuffer
*fb
,
551 struct drm_i915_gem_object
*obj
, int crtc_x
, int crtc_y
,
552 unsigned int crtc_w
, unsigned int crtc_h
,
553 uint32_t x
, uint32_t y
,
554 uint32_t src_w
, uint32_t src_h
)
556 struct drm_device
*dev
= plane
->dev
;
557 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
558 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
559 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
560 int pipe
= intel_plane
->pipe
;
561 unsigned long dvssurf_offset
, linear_offset
;
562 u32 dvscntr
, dvsscale
;
563 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
567 dvscntr
= I915_READ(DVSCNTR(pipe
));
569 /* Mask out pixel format bits in case we change it */
570 dvscntr
&= ~DVS_PIXFORMAT_MASK
;
571 dvscntr
&= ~DVS_RGB_ORDER_XBGR
;
572 dvscntr
&= ~DVS_YUV_BYTE_ORDER_MASK
;
573 dvscntr
&= ~DVS_TILED
;
575 switch (fb
->pixel_format
) {
576 case DRM_FORMAT_XBGR8888
:
577 dvscntr
|= DVS_FORMAT_RGBX888
| DVS_RGB_ORDER_XBGR
;
579 case DRM_FORMAT_XRGB8888
:
580 dvscntr
|= DVS_FORMAT_RGBX888
;
582 case DRM_FORMAT_YUYV
:
583 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_YUYV
;
585 case DRM_FORMAT_YVYU
:
586 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_YVYU
;
588 case DRM_FORMAT_UYVY
:
589 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_UYVY
;
591 case DRM_FORMAT_VYUY
:
592 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_VYUY
;
599 * Enable gamma to match primary/cursor plane behaviour.
600 * FIXME should be user controllable via propertiesa.
602 dvscntr
|= DVS_GAMMA_ENABLE
;
604 if (obj
->tiling_mode
!= I915_TILING_NONE
)
605 dvscntr
|= DVS_TILED
;
608 dvscntr
|= DVS_TRICKLE_FEED_DISABLE
; /* must disable */
609 dvscntr
|= DVS_ENABLE
;
611 intel_update_sprite_watermarks(plane
, crtc
, src_w
, src_h
,
613 src_w
!= crtc_w
|| src_h
!= crtc_h
);
615 /* Sizes are 0 based */
622 if (crtc_w
!= src_w
|| crtc_h
!= src_h
)
623 dvsscale
= DVS_SCALE_ENABLE
| (src_w
<< 16) | src_h
;
625 linear_offset
= y
* fb
->pitches
[0] + x
* pixel_size
;
627 intel_gen4_compute_page_offset(&x
, &y
, obj
->tiling_mode
,
628 pixel_size
, fb
->pitches
[0]);
629 linear_offset
-= dvssurf_offset
;
631 atomic_update
= intel_pipe_update_start(intel_crtc
, &start_vbl_count
);
633 intel_update_primary_plane(intel_crtc
);
635 I915_WRITE(DVSSTRIDE(pipe
), fb
->pitches
[0]);
636 I915_WRITE(DVSPOS(pipe
), (crtc_y
<< 16) | crtc_x
);
638 if (obj
->tiling_mode
!= I915_TILING_NONE
)
639 I915_WRITE(DVSTILEOFF(pipe
), (y
<< 16) | x
);
641 I915_WRITE(DVSLINOFF(pipe
), linear_offset
);
643 I915_WRITE(DVSSIZE(pipe
), (crtc_h
<< 16) | crtc_w
);
644 I915_WRITE(DVSSCALE(pipe
), dvsscale
);
645 I915_WRITE(DVSCNTR(pipe
), dvscntr
);
646 I915_WRITE(DVSSURF(pipe
),
647 i915_gem_obj_ggtt_offset(obj
) + dvssurf_offset
);
649 intel_flush_primary_plane(dev_priv
, intel_crtc
->plane
);
652 intel_pipe_update_end(intel_crtc
, start_vbl_count
);
656 ilk_disable_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
)
658 struct drm_device
*dev
= plane
->dev
;
659 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
660 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
661 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
662 int pipe
= intel_plane
->pipe
;
666 atomic_update
= intel_pipe_update_start(intel_crtc
, &start_vbl_count
);
668 intel_update_primary_plane(intel_crtc
);
670 I915_WRITE(DVSCNTR(pipe
), I915_READ(DVSCNTR(pipe
)) & ~DVS_ENABLE
);
671 /* Disable the scaler */
672 I915_WRITE(DVSSCALE(pipe
), 0);
673 /* Flush double buffered register updates */
674 I915_WRITE(DVSSURF(pipe
), 0);
676 intel_flush_primary_plane(dev_priv
, intel_crtc
->plane
);
679 intel_pipe_update_end(intel_crtc
, start_vbl_count
);
682 * Avoid underruns when disabling the sprite.
683 * FIXME remove once watermark updates are done properly.
685 intel_wait_for_vblank(dev
, pipe
);
687 intel_update_sprite_watermarks(plane
, crtc
, 0, 0, 0, false, false);
691 intel_post_enable_primary(struct drm_crtc
*crtc
)
693 struct drm_device
*dev
= crtc
->dev
;
694 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
697 * BDW signals flip done immediately if the plane
698 * is disabled, even if the plane enable is already
699 * armed to occur at the next vblank :(
701 if (IS_BROADWELL(dev
))
702 intel_wait_for_vblank(dev
, intel_crtc
->pipe
);
705 * FIXME IPS should be fine as long as one plane is
706 * enabled, but in practice it seems to have problems
707 * when going from primary only to sprite only and vice
710 hsw_enable_ips(intel_crtc
);
712 mutex_lock(&dev
->struct_mutex
);
713 intel_update_fbc(dev
);
714 mutex_unlock(&dev
->struct_mutex
);
718 intel_pre_disable_primary(struct drm_crtc
*crtc
)
720 struct drm_device
*dev
= crtc
->dev
;
721 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
722 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
724 mutex_lock(&dev
->struct_mutex
);
725 if (dev_priv
->fbc
.plane
== intel_crtc
->plane
)
726 intel_disable_fbc(dev
);
727 mutex_unlock(&dev
->struct_mutex
);
730 * FIXME IPS should be fine as long as one plane is
731 * enabled, but in practice it seems to have problems
732 * when going from primary only to sprite only and vice
735 hsw_disable_ips(intel_crtc
);
739 ilk_update_colorkey(struct drm_plane
*plane
,
740 struct drm_intel_sprite_colorkey
*key
)
742 struct drm_device
*dev
= plane
->dev
;
743 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
744 struct intel_plane
*intel_plane
;
748 intel_plane
= to_intel_plane(plane
);
750 I915_WRITE(DVSKEYVAL(intel_plane
->pipe
), key
->min_value
);
751 I915_WRITE(DVSKEYMAX(intel_plane
->pipe
), key
->max_value
);
752 I915_WRITE(DVSKEYMSK(intel_plane
->pipe
), key
->channel_mask
);
754 dvscntr
= I915_READ(DVSCNTR(intel_plane
->pipe
));
755 dvscntr
&= ~(DVS_SOURCE_KEY
| DVS_DEST_KEY
);
756 if (key
->flags
& I915_SET_COLORKEY_DESTINATION
)
757 dvscntr
|= DVS_DEST_KEY
;
758 else if (key
->flags
& I915_SET_COLORKEY_SOURCE
)
759 dvscntr
|= DVS_SOURCE_KEY
;
760 I915_WRITE(DVSCNTR(intel_plane
->pipe
), dvscntr
);
762 POSTING_READ(DVSKEYMSK(intel_plane
->pipe
));
768 ilk_get_colorkey(struct drm_plane
*plane
, struct drm_intel_sprite_colorkey
*key
)
770 struct drm_device
*dev
= plane
->dev
;
771 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
772 struct intel_plane
*intel_plane
;
775 intel_plane
= to_intel_plane(plane
);
777 key
->min_value
= I915_READ(DVSKEYVAL(intel_plane
->pipe
));
778 key
->max_value
= I915_READ(DVSKEYMAX(intel_plane
->pipe
));
779 key
->channel_mask
= I915_READ(DVSKEYMSK(intel_plane
->pipe
));
782 dvscntr
= I915_READ(DVSCNTR(intel_plane
->pipe
));
784 if (dvscntr
& DVS_DEST_KEY
)
785 key
->flags
= I915_SET_COLORKEY_DESTINATION
;
786 else if (dvscntr
& DVS_SOURCE_KEY
)
787 key
->flags
= I915_SET_COLORKEY_SOURCE
;
789 key
->flags
= I915_SET_COLORKEY_NONE
;
793 format_is_yuv(uint32_t format
)
796 case DRM_FORMAT_YUYV
:
797 case DRM_FORMAT_UYVY
:
798 case DRM_FORMAT_VYUY
:
799 case DRM_FORMAT_YVYU
:
806 static bool colorkey_enabled(struct intel_plane
*intel_plane
)
808 struct drm_intel_sprite_colorkey key
;
810 intel_plane
->get_colorkey(&intel_plane
->base
, &key
);
812 return key
.flags
!= I915_SET_COLORKEY_NONE
;
816 intel_update_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
,
817 struct drm_framebuffer
*fb
, int crtc_x
, int crtc_y
,
818 unsigned int crtc_w
, unsigned int crtc_h
,
819 uint32_t src_x
, uint32_t src_y
,
820 uint32_t src_w
, uint32_t src_h
)
822 struct drm_device
*dev
= plane
->dev
;
823 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
824 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
825 enum i915_pipe pipe
= intel_crtc
->pipe
;
826 struct intel_framebuffer
*intel_fb
= to_intel_framebuffer(fb
);
827 struct drm_i915_gem_object
*obj
= intel_fb
->obj
;
828 struct drm_i915_gem_object
*old_obj
= intel_plane
->obj
;
830 bool primary_enabled
;
833 int max_scale
, min_scale
;
834 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
835 struct drm_rect src
= {
836 /* sample coordinates in 16.16 fixed point */
842 struct drm_rect dst
= {
845 .x2
= crtc_x
+ crtc_w
,
847 .y2
= crtc_y
+ crtc_h
,
849 const struct drm_rect clip
= {
850 .x2
= intel_crtc
->active
? intel_crtc
->config
.pipe_src_w
: 0,
851 .y2
= intel_crtc
->active
? intel_crtc
->config
.pipe_src_h
: 0,
855 unsigned int crtc_w
, crtc_h
;
856 uint32_t src_x
, src_y
, src_w
, src_h
;
868 /* Don't modify another pipe's plane */
869 if (intel_plane
->pipe
!= intel_crtc
->pipe
) {
870 DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n");
874 /* FIXME check all gen limits */
875 if (fb
->width
< 3 || fb
->height
< 3 || fb
->pitches
[0] > 16384) {
876 DRM_DEBUG_KMS("Unsuitable framebuffer for plane\n");
880 /* Sprite planes can be linear or x-tiled surfaces */
881 switch (obj
->tiling_mode
) {
882 case I915_TILING_NONE
:
886 DRM_DEBUG_KMS("Unsupported tiling mode\n");
891 * FIXME the following code does a bunch of fuzzy adjustments to the
892 * coordinates and sizes. We probably need some way to decide whether
893 * more strict checking should be done instead.
895 max_scale
= intel_plane
->max_downscale
<< 16;
896 min_scale
= intel_plane
->can_scale
? 1 : (1 << 16);
898 hscale
= drm_rect_calc_hscale_relaxed(&src
, &dst
, min_scale
, max_scale
);
901 vscale
= drm_rect_calc_vscale_relaxed(&src
, &dst
, min_scale
, max_scale
);
904 visible
= drm_rect_clip_scaled(&src
, &dst
, &clip
, hscale
, vscale
);
908 crtc_w
= drm_rect_width(&dst
);
909 crtc_h
= drm_rect_height(&dst
);
912 /* check again in case clipping clamped the results */
913 hscale
= drm_rect_calc_hscale(&src
, &dst
, min_scale
, max_scale
);
915 DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n");
916 drm_rect_debug_print(&src
, true);
917 drm_rect_debug_print(&dst
, false);
922 vscale
= drm_rect_calc_vscale(&src
, &dst
, min_scale
, max_scale
);
924 DRM_DEBUG_KMS("Vertical scaling factor out of limits\n");
925 drm_rect_debug_print(&src
, true);
926 drm_rect_debug_print(&dst
, false);
931 /* Make the source viewport size an exact multiple of the scaling factors. */
932 drm_rect_adjust_size(&src
,
933 drm_rect_width(&dst
) * hscale
- drm_rect_width(&src
),
934 drm_rect_height(&dst
) * vscale
- drm_rect_height(&src
));
936 /* sanity check to make sure the src viewport wasn't enlarged */
937 WARN_ON(src
.x1
< (int) src_x
||
938 src
.y1
< (int) src_y
||
939 src
.x2
> (int) (src_x
+ src_w
) ||
940 src
.y2
> (int) (src_y
+ src_h
));
943 * Hardware doesn't handle subpixel coordinates.
944 * Adjust to (macro)pixel boundary, but be careful not to
945 * increase the source viewport size, because that could
946 * push the downscaling factor out of bounds.
948 src_x
= src
.x1
>> 16;
949 src_w
= drm_rect_width(&src
) >> 16;
950 src_y
= src
.y1
>> 16;
951 src_h
= drm_rect_height(&src
) >> 16;
953 if (format_is_yuv(fb
->pixel_format
)) {
958 * Must keep src and dst the
959 * same if we can't scale.
961 if (!intel_plane
->can_scale
)
969 /* Check size restrictions when scaling */
970 if (visible
&& (src_w
!= crtc_w
|| src_h
!= crtc_h
)) {
971 unsigned int width_bytes
;
973 WARN_ON(!intel_plane
->can_scale
);
975 /* FIXME interlacing min height is 6 */
977 if (crtc_w
< 3 || crtc_h
< 3)
980 if (src_w
< 3 || src_h
< 3)
983 width_bytes
= ((src_x
* pixel_size
) & 63) + src_w
* pixel_size
;
985 if (src_w
> 2048 || src_h
> 2048 ||
986 width_bytes
> 4096 || fb
->pitches
[0] > 4096) {
987 DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
993 dst
.x2
= crtc_x
+ crtc_w
;
995 dst
.y2
= crtc_y
+ crtc_h
;
998 * If the sprite is completely covering the primary plane,
999 * we can disable the primary and save power.
1001 primary_enabled
= !drm_rect_equals(&dst
, &clip
) || colorkey_enabled(intel_plane
);
1002 WARN_ON(!primary_enabled
&& !visible
&& intel_crtc
->active
);
1004 mutex_lock(&dev
->struct_mutex
);
1006 /* Note that this will apply the VT-d workaround for scanouts,
1007 * which is more restrictive than required for sprites. (The
1008 * primary plane requires 256KiB alignment with 64 PTE padding,
1009 * the sprite planes only require 128KiB alignment and 32 PTE padding.
1011 ret
= intel_pin_and_fence_fb_obj(dev
, obj
, NULL
);
1013 i915_gem_track_fb(old_obj
, obj
,
1014 INTEL_FRONTBUFFER_SPRITE(pipe
));
1015 mutex_unlock(&dev
->struct_mutex
);
1020 intel_plane
->crtc_x
= orig
.crtc_x
;
1021 intel_plane
->crtc_y
= orig
.crtc_y
;
1022 intel_plane
->crtc_w
= orig
.crtc_w
;
1023 intel_plane
->crtc_h
= orig
.crtc_h
;
1024 intel_plane
->src_x
= orig
.src_x
;
1025 intel_plane
->src_y
= orig
.src_y
;
1026 intel_plane
->src_w
= orig
.src_w
;
1027 intel_plane
->src_h
= orig
.src_h
;
1028 intel_plane
->obj
= obj
;
1030 if (intel_crtc
->active
) {
1031 bool primary_was_enabled
= intel_crtc
->primary_enabled
;
1033 intel_crtc
->primary_enabled
= primary_enabled
;
1035 if (primary_was_enabled
!= primary_enabled
)
1036 intel_crtc_wait_for_pending_flips(crtc
);
1038 if (primary_was_enabled
&& !primary_enabled
)
1039 intel_pre_disable_primary(crtc
);
1042 intel_plane
->update_plane(plane
, crtc
, fb
, obj
,
1043 crtc_x
, crtc_y
, crtc_w
, crtc_h
,
1044 src_x
, src_y
, src_w
, src_h
);
1046 intel_plane
->disable_plane(plane
, crtc
);
1048 intel_frontbuffer_flip(dev
, INTEL_FRONTBUFFER_SPRITE(pipe
));
1050 if (!primary_was_enabled
&& primary_enabled
)
1051 intel_post_enable_primary(crtc
);
1054 /* Unpin old obj after new one is active to avoid ugliness */
1057 * It's fairly common to simply update the position of
1058 * an existing object. In that case, we don't need to
1059 * wait for vblank to avoid ugliness, we only need to
1060 * do the pin & ref bookkeeping.
1062 if (old_obj
!= obj
&& intel_crtc
->active
)
1063 intel_wait_for_vblank(dev
, intel_crtc
->pipe
);
1065 mutex_lock(&dev
->struct_mutex
);
1066 intel_unpin_fb_obj(old_obj
);
1067 mutex_unlock(&dev
->struct_mutex
);
1074 intel_disable_plane(struct drm_plane
*plane
)
1076 struct drm_device
*dev
= plane
->dev
;
1077 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
1078 struct intel_crtc
*intel_crtc
;
1079 enum i915_pipe pipe
;
1084 if (WARN_ON(!plane
->crtc
))
1087 intel_crtc
= to_intel_crtc(plane
->crtc
);
1088 pipe
= intel_crtc
->pipe
;
1090 if (intel_crtc
->active
) {
1091 bool primary_was_enabled
= intel_crtc
->primary_enabled
;
1093 intel_crtc
->primary_enabled
= true;
1095 intel_plane
->disable_plane(plane
, plane
->crtc
);
1097 if (!primary_was_enabled
&& intel_crtc
->primary_enabled
)
1098 intel_post_enable_primary(plane
->crtc
);
1101 if (intel_plane
->obj
) {
1102 if (intel_crtc
->active
)
1103 intel_wait_for_vblank(dev
, intel_plane
->pipe
);
1105 mutex_lock(&dev
->struct_mutex
);
1106 intel_unpin_fb_obj(intel_plane
->obj
);
1107 i915_gem_track_fb(intel_plane
->obj
, NULL
,
1108 INTEL_FRONTBUFFER_SPRITE(pipe
));
1109 mutex_unlock(&dev
->struct_mutex
);
1111 intel_plane
->obj
= NULL
;
1117 static void intel_destroy_plane(struct drm_plane
*plane
)
1119 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
1120 intel_disable_plane(plane
);
1121 drm_plane_cleanup(plane
);
1125 int intel_sprite_set_colorkey(struct drm_device
*dev
, void *data
,
1126 struct drm_file
*file_priv
)
1128 struct drm_intel_sprite_colorkey
*set
= data
;
1129 struct drm_plane
*plane
;
1130 struct intel_plane
*intel_plane
;
1133 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
1136 /* Make sure we don't try to enable both src & dest simultaneously */
1137 if ((set
->flags
& (I915_SET_COLORKEY_DESTINATION
| I915_SET_COLORKEY_SOURCE
)) == (I915_SET_COLORKEY_DESTINATION
| I915_SET_COLORKEY_SOURCE
))
1140 drm_modeset_lock_all(dev
);
1142 plane
= drm_plane_find(dev
, set
->plane_id
);
1148 intel_plane
= to_intel_plane(plane
);
1149 ret
= intel_plane
->update_colorkey(plane
, set
);
1152 drm_modeset_unlock_all(dev
);
1156 int intel_sprite_get_colorkey(struct drm_device
*dev
, void *data
,
1157 struct drm_file
*file_priv
)
1159 struct drm_intel_sprite_colorkey
*get
= data
;
1160 struct drm_plane
*plane
;
1161 struct intel_plane
*intel_plane
;
1164 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
1167 drm_modeset_lock_all(dev
);
1169 plane
= drm_plane_find(dev
, get
->plane_id
);
1175 intel_plane
= to_intel_plane(plane
);
1176 intel_plane
->get_colorkey(plane
, get
);
1179 drm_modeset_unlock_all(dev
);
1183 void intel_plane_restore(struct drm_plane
*plane
)
1185 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
1187 if (!plane
->crtc
|| !plane
->fb
)
1190 intel_update_plane(plane
, plane
->crtc
, plane
->fb
,
1191 intel_plane
->crtc_x
, intel_plane
->crtc_y
,
1192 intel_plane
->crtc_w
, intel_plane
->crtc_h
,
1193 intel_plane
->src_x
, intel_plane
->src_y
,
1194 intel_plane
->src_w
, intel_plane
->src_h
);
1197 void intel_plane_disable(struct drm_plane
*plane
)
1199 if (!plane
->crtc
|| !plane
->fb
)
1202 intel_disable_plane(plane
);
1205 static const struct drm_plane_funcs intel_plane_funcs
= {
1206 .update_plane
= intel_update_plane
,
1207 .disable_plane
= intel_disable_plane
,
1208 .destroy
= intel_destroy_plane
,
1211 static uint32_t ilk_plane_formats
[] = {
1212 DRM_FORMAT_XRGB8888
,
1219 static uint32_t snb_plane_formats
[] = {
1220 DRM_FORMAT_XBGR8888
,
1221 DRM_FORMAT_XRGB8888
,
1228 static uint32_t vlv_plane_formats
[] = {
1230 DRM_FORMAT_ABGR8888
,
1231 DRM_FORMAT_ARGB8888
,
1232 DRM_FORMAT_XBGR8888
,
1233 DRM_FORMAT_XRGB8888
,
1234 DRM_FORMAT_XBGR2101010
,
1235 DRM_FORMAT_ABGR2101010
,
1243 intel_plane_init(struct drm_device
*dev
, enum i915_pipe pipe
, int plane
)
1245 struct intel_plane
*intel_plane
;
1246 unsigned long possible_crtcs
;
1247 const uint32_t *plane_formats
;
1248 int num_plane_formats
;
1251 if (INTEL_INFO(dev
)->gen
< 5)
1254 intel_plane
= kzalloc(sizeof(*intel_plane
), GFP_KERNEL
);
1258 switch (INTEL_INFO(dev
)->gen
) {
1261 intel_plane
->can_scale
= true;
1262 intel_plane
->max_downscale
= 16;
1263 intel_plane
->update_plane
= ilk_update_plane
;
1264 intel_plane
->disable_plane
= ilk_disable_plane
;
1265 intel_plane
->update_colorkey
= ilk_update_colorkey
;
1266 intel_plane
->get_colorkey
= ilk_get_colorkey
;
1269 plane_formats
= snb_plane_formats
;
1270 num_plane_formats
= ARRAY_SIZE(snb_plane_formats
);
1272 plane_formats
= ilk_plane_formats
;
1273 num_plane_formats
= ARRAY_SIZE(ilk_plane_formats
);
1279 if (IS_IVYBRIDGE(dev
)) {
1280 intel_plane
->can_scale
= true;
1281 intel_plane
->max_downscale
= 2;
1283 intel_plane
->can_scale
= false;
1284 intel_plane
->max_downscale
= 1;
1287 if (IS_VALLEYVIEW(dev
)) {
1288 intel_plane
->update_plane
= vlv_update_plane
;
1289 intel_plane
->disable_plane
= vlv_disable_plane
;
1290 intel_plane
->update_colorkey
= vlv_update_colorkey
;
1291 intel_plane
->get_colorkey
= vlv_get_colorkey
;
1293 plane_formats
= vlv_plane_formats
;
1294 num_plane_formats
= ARRAY_SIZE(vlv_plane_formats
);
1296 intel_plane
->update_plane
= ivb_update_plane
;
1297 intel_plane
->disable_plane
= ivb_disable_plane
;
1298 intel_plane
->update_colorkey
= ivb_update_colorkey
;
1299 intel_plane
->get_colorkey
= ivb_get_colorkey
;
1301 plane_formats
= snb_plane_formats
;
1302 num_plane_formats
= ARRAY_SIZE(snb_plane_formats
);
1311 intel_plane
->pipe
= pipe
;
1312 intel_plane
->plane
= plane
;
1313 possible_crtcs
= (1 << pipe
);
1314 ret
= drm_plane_init(dev
, &intel_plane
->base
, possible_crtcs
,
1316 plane_formats
, num_plane_formats
,