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
;
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 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
, pixel_size
, true,
222 src_w
!= crtc_w
|| src_h
!= crtc_h
);
224 /* Sizes are 0 based */
230 linear_offset
= y
* fb
->pitches
[0] + x
* pixel_size
;
231 sprsurf_offset
= intel_gen4_compute_page_offset(&x
, &y
,
235 linear_offset
-= sprsurf_offset
;
237 atomic_update
= intel_pipe_update_start(intel_crtc
, &start_vbl_count
);
239 intel_update_primary_plane(intel_crtc
);
241 I915_WRITE(SPSTRIDE(pipe
, plane
), fb
->pitches
[0]);
242 I915_WRITE(SPPOS(pipe
, plane
), (crtc_y
<< 16) | crtc_x
);
244 if (obj
->tiling_mode
!= I915_TILING_NONE
)
245 I915_WRITE(SPTILEOFF(pipe
, plane
), (y
<< 16) | x
);
247 I915_WRITE(SPLINOFF(pipe
, plane
), linear_offset
);
249 I915_WRITE(SPSIZE(pipe
, plane
), (crtc_h
<< 16) | crtc_w
);
250 I915_WRITE(SPCNTR(pipe
, plane
), sprctl
);
251 I915_WRITE(SPSURF(pipe
, plane
), i915_gem_obj_ggtt_offset(obj
) +
254 intel_flush_primary_plane(dev_priv
, intel_crtc
->plane
);
257 intel_pipe_update_end(intel_crtc
, start_vbl_count
);
261 vlv_disable_plane(struct drm_plane
*dplane
, struct drm_crtc
*crtc
)
263 struct drm_device
*dev
= dplane
->dev
;
264 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
265 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
266 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
267 int pipe
= intel_plane
->pipe
;
268 int plane
= intel_plane
->plane
;
272 atomic_update
= intel_pipe_update_start(intel_crtc
, &start_vbl_count
);
274 intel_update_primary_plane(intel_crtc
);
276 I915_WRITE(SPCNTR(pipe
, plane
), I915_READ(SPCNTR(pipe
, plane
)) &
278 /* Activate double buffered register update */
279 I915_WRITE(SPSURF(pipe
, plane
), 0);
281 intel_flush_primary_plane(dev_priv
, intel_crtc
->plane
);
284 intel_pipe_update_end(intel_crtc
, start_vbl_count
);
286 intel_update_sprite_watermarks(dplane
, crtc
, 0, 0, false, false);
290 vlv_update_colorkey(struct drm_plane
*dplane
,
291 struct drm_intel_sprite_colorkey
*key
)
293 struct drm_device
*dev
= dplane
->dev
;
294 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
295 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
296 int pipe
= intel_plane
->pipe
;
297 int plane
= intel_plane
->plane
;
300 if (key
->flags
& I915_SET_COLORKEY_DESTINATION
)
303 I915_WRITE(SPKEYMINVAL(pipe
, plane
), key
->min_value
);
304 I915_WRITE(SPKEYMAXVAL(pipe
, plane
), key
->max_value
);
305 I915_WRITE(SPKEYMSK(pipe
, plane
), key
->channel_mask
);
307 sprctl
= I915_READ(SPCNTR(pipe
, plane
));
308 sprctl
&= ~SP_SOURCE_KEY
;
309 if (key
->flags
& I915_SET_COLORKEY_SOURCE
)
310 sprctl
|= SP_SOURCE_KEY
;
311 I915_WRITE(SPCNTR(pipe
, plane
), sprctl
);
313 POSTING_READ(SPKEYMSK(pipe
, plane
));
319 vlv_get_colorkey(struct drm_plane
*dplane
,
320 struct drm_intel_sprite_colorkey
*key
)
322 struct drm_device
*dev
= dplane
->dev
;
323 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
324 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
325 int pipe
= intel_plane
->pipe
;
326 int plane
= intel_plane
->plane
;
329 key
->min_value
= I915_READ(SPKEYMINVAL(pipe
, plane
));
330 key
->max_value
= I915_READ(SPKEYMAXVAL(pipe
, plane
));
331 key
->channel_mask
= I915_READ(SPKEYMSK(pipe
, plane
));
333 sprctl
= I915_READ(SPCNTR(pipe
, plane
));
334 if (sprctl
& SP_SOURCE_KEY
)
335 key
->flags
= I915_SET_COLORKEY_SOURCE
;
337 key
->flags
= I915_SET_COLORKEY_NONE
;
341 ivb_update_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
,
342 struct drm_framebuffer
*fb
,
343 struct drm_i915_gem_object
*obj
, int crtc_x
, int crtc_y
,
344 unsigned int crtc_w
, unsigned int crtc_h
,
345 uint32_t x
, uint32_t y
,
346 uint32_t src_w
, uint32_t src_h
)
348 struct drm_device
*dev
= plane
->dev
;
349 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
350 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
351 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
352 int pipe
= intel_plane
->pipe
;
353 u32 sprctl
, sprscale
= 0;
354 unsigned long sprsurf_offset
, linear_offset
;
355 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
359 sprctl
= I915_READ(SPRCTL(pipe
));
361 /* Mask out pixel format bits in case we change it */
362 sprctl
&= ~SPRITE_PIXFORMAT_MASK
;
363 sprctl
&= ~SPRITE_RGB_ORDER_RGBX
;
364 sprctl
&= ~SPRITE_YUV_BYTE_ORDER_MASK
;
365 sprctl
&= ~SPRITE_TILED
;
367 switch (fb
->pixel_format
) {
368 case DRM_FORMAT_XBGR8888
:
369 sprctl
|= SPRITE_FORMAT_RGBX888
| SPRITE_RGB_ORDER_RGBX
;
371 case DRM_FORMAT_XRGB8888
:
372 sprctl
|= SPRITE_FORMAT_RGBX888
;
374 case DRM_FORMAT_YUYV
:
375 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_YUYV
;
377 case DRM_FORMAT_YVYU
:
378 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_YVYU
;
380 case DRM_FORMAT_UYVY
:
381 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_UYVY
;
383 case DRM_FORMAT_VYUY
:
384 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_VYUY
;
391 * Enable gamma to match primary/cursor plane behaviour.
392 * FIXME should be user controllable via propertiesa.
394 sprctl
|= SPRITE_GAMMA_ENABLE
;
396 if (obj
->tiling_mode
!= I915_TILING_NONE
)
397 sprctl
|= SPRITE_TILED
;
399 if (IS_HASWELL(dev
) || IS_BROADWELL(dev
))
400 sprctl
&= ~SPRITE_TRICKLE_FEED_DISABLE
;
402 sprctl
|= SPRITE_TRICKLE_FEED_DISABLE
;
404 sprctl
|= SPRITE_ENABLE
;
406 if (IS_HASWELL(dev
) || IS_BROADWELL(dev
))
407 sprctl
|= SPRITE_PIPE_CSC_ENABLE
;
409 intel_update_sprite_watermarks(plane
, crtc
, src_w
, pixel_size
, true,
410 src_w
!= crtc_w
|| src_h
!= crtc_h
);
412 /* Sizes are 0 based */
418 if (crtc_w
!= src_w
|| crtc_h
!= src_h
)
419 sprscale
= SPRITE_SCALE_ENABLE
| (src_w
<< 16) | src_h
;
421 linear_offset
= y
* fb
->pitches
[0] + x
* pixel_size
;
423 intel_gen4_compute_page_offset(&x
, &y
, obj
->tiling_mode
,
424 pixel_size
, fb
->pitches
[0]);
425 linear_offset
-= sprsurf_offset
;
427 atomic_update
= intel_pipe_update_start(intel_crtc
, &start_vbl_count
);
429 intel_update_primary_plane(intel_crtc
);
431 I915_WRITE(SPRSTRIDE(pipe
), fb
->pitches
[0]);
432 I915_WRITE(SPRPOS(pipe
), (crtc_y
<< 16) | crtc_x
);
434 /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
436 if (IS_HASWELL(dev
) || IS_BROADWELL(dev
))
437 I915_WRITE(SPROFFSET(pipe
), (y
<< 16) | x
);
438 else if (obj
->tiling_mode
!= I915_TILING_NONE
)
439 I915_WRITE(SPRTILEOFF(pipe
), (y
<< 16) | x
);
441 I915_WRITE(SPRLINOFF(pipe
), linear_offset
);
443 I915_WRITE(SPRSIZE(pipe
), (crtc_h
<< 16) | crtc_w
);
444 if (intel_plane
->can_scale
)
445 I915_WRITE(SPRSCALE(pipe
), sprscale
);
446 I915_WRITE(SPRCTL(pipe
), sprctl
);
447 I915_WRITE(SPRSURF(pipe
),
448 i915_gem_obj_ggtt_offset(obj
) + sprsurf_offset
);
450 intel_flush_primary_plane(dev_priv
, intel_crtc
->plane
);
453 intel_pipe_update_end(intel_crtc
, start_vbl_count
);
457 ivb_disable_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
)
459 struct drm_device
*dev
= plane
->dev
;
460 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
461 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
462 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
463 int pipe
= intel_plane
->pipe
;
467 atomic_update
= intel_pipe_update_start(intel_crtc
, &start_vbl_count
);
469 intel_update_primary_plane(intel_crtc
);
471 I915_WRITE(SPRCTL(pipe
), I915_READ(SPRCTL(pipe
)) & ~SPRITE_ENABLE
);
472 /* Can't leave the scaler enabled... */
473 if (intel_plane
->can_scale
)
474 I915_WRITE(SPRSCALE(pipe
), 0);
475 /* Activate double buffered register update */
476 I915_WRITE(SPRSURF(pipe
), 0);
478 intel_flush_primary_plane(dev_priv
, intel_crtc
->plane
);
481 intel_pipe_update_end(intel_crtc
, start_vbl_count
);
484 * Avoid underruns when disabling the sprite.
485 * FIXME remove once watermark updates are done properly.
487 intel_wait_for_vblank(dev
, pipe
);
489 intel_update_sprite_watermarks(plane
, crtc
, 0, 0, false, false);
493 ivb_update_colorkey(struct drm_plane
*plane
,
494 struct drm_intel_sprite_colorkey
*key
)
496 struct drm_device
*dev
= plane
->dev
;
497 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
498 struct intel_plane
*intel_plane
;
502 intel_plane
= to_intel_plane(plane
);
504 I915_WRITE(SPRKEYVAL(intel_plane
->pipe
), key
->min_value
);
505 I915_WRITE(SPRKEYMAX(intel_plane
->pipe
), key
->max_value
);
506 I915_WRITE(SPRKEYMSK(intel_plane
->pipe
), key
->channel_mask
);
508 sprctl
= I915_READ(SPRCTL(intel_plane
->pipe
));
509 sprctl
&= ~(SPRITE_SOURCE_KEY
| SPRITE_DEST_KEY
);
510 if (key
->flags
& I915_SET_COLORKEY_DESTINATION
)
511 sprctl
|= SPRITE_DEST_KEY
;
512 else if (key
->flags
& I915_SET_COLORKEY_SOURCE
)
513 sprctl
|= SPRITE_SOURCE_KEY
;
514 I915_WRITE(SPRCTL(intel_plane
->pipe
), sprctl
);
516 POSTING_READ(SPRKEYMSK(intel_plane
->pipe
));
522 ivb_get_colorkey(struct drm_plane
*plane
, struct drm_intel_sprite_colorkey
*key
)
524 struct drm_device
*dev
= plane
->dev
;
525 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
526 struct intel_plane
*intel_plane
;
529 intel_plane
= to_intel_plane(plane
);
531 key
->min_value
= I915_READ(SPRKEYVAL(intel_plane
->pipe
));
532 key
->max_value
= I915_READ(SPRKEYMAX(intel_plane
->pipe
));
533 key
->channel_mask
= I915_READ(SPRKEYMSK(intel_plane
->pipe
));
536 sprctl
= I915_READ(SPRCTL(intel_plane
->pipe
));
538 if (sprctl
& SPRITE_DEST_KEY
)
539 key
->flags
= I915_SET_COLORKEY_DESTINATION
;
540 else if (sprctl
& SPRITE_SOURCE_KEY
)
541 key
->flags
= I915_SET_COLORKEY_SOURCE
;
543 key
->flags
= I915_SET_COLORKEY_NONE
;
547 ilk_update_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
,
548 struct drm_framebuffer
*fb
,
549 struct drm_i915_gem_object
*obj
, int crtc_x
, int crtc_y
,
550 unsigned int crtc_w
, unsigned int crtc_h
,
551 uint32_t x
, uint32_t y
,
552 uint32_t src_w
, uint32_t src_h
)
554 struct drm_device
*dev
= plane
->dev
;
555 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
556 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
557 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
558 int pipe
= intel_plane
->pipe
;
559 unsigned long dvssurf_offset
, linear_offset
;
560 u32 dvscntr
, dvsscale
;
561 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
565 dvscntr
= I915_READ(DVSCNTR(pipe
));
567 /* Mask out pixel format bits in case we change it */
568 dvscntr
&= ~DVS_PIXFORMAT_MASK
;
569 dvscntr
&= ~DVS_RGB_ORDER_XBGR
;
570 dvscntr
&= ~DVS_YUV_BYTE_ORDER_MASK
;
571 dvscntr
&= ~DVS_TILED
;
573 switch (fb
->pixel_format
) {
574 case DRM_FORMAT_XBGR8888
:
575 dvscntr
|= DVS_FORMAT_RGBX888
| DVS_RGB_ORDER_XBGR
;
577 case DRM_FORMAT_XRGB8888
:
578 dvscntr
|= DVS_FORMAT_RGBX888
;
580 case DRM_FORMAT_YUYV
:
581 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_YUYV
;
583 case DRM_FORMAT_YVYU
:
584 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_YVYU
;
586 case DRM_FORMAT_UYVY
:
587 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_UYVY
;
589 case DRM_FORMAT_VYUY
:
590 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_VYUY
;
597 * Enable gamma to match primary/cursor plane behaviour.
598 * FIXME should be user controllable via propertiesa.
600 dvscntr
|= DVS_GAMMA_ENABLE
;
602 if (obj
->tiling_mode
!= I915_TILING_NONE
)
603 dvscntr
|= DVS_TILED
;
606 dvscntr
|= DVS_TRICKLE_FEED_DISABLE
; /* must disable */
607 dvscntr
|= DVS_ENABLE
;
609 intel_update_sprite_watermarks(plane
, crtc
, src_w
, pixel_size
, true,
610 src_w
!= crtc_w
|| src_h
!= crtc_h
);
612 /* Sizes are 0 based */
619 if (crtc_w
!= src_w
|| crtc_h
!= src_h
)
620 dvsscale
= DVS_SCALE_ENABLE
| (src_w
<< 16) | src_h
;
622 linear_offset
= y
* fb
->pitches
[0] + x
* pixel_size
;
624 intel_gen4_compute_page_offset(&x
, &y
, obj
->tiling_mode
,
625 pixel_size
, fb
->pitches
[0]);
626 linear_offset
-= dvssurf_offset
;
628 atomic_update
= intel_pipe_update_start(intel_crtc
, &start_vbl_count
);
630 intel_update_primary_plane(intel_crtc
);
632 I915_WRITE(DVSSTRIDE(pipe
), fb
->pitches
[0]);
633 I915_WRITE(DVSPOS(pipe
), (crtc_y
<< 16) | crtc_x
);
635 if (obj
->tiling_mode
!= I915_TILING_NONE
)
636 I915_WRITE(DVSTILEOFF(pipe
), (y
<< 16) | x
);
638 I915_WRITE(DVSLINOFF(pipe
), linear_offset
);
640 I915_WRITE(DVSSIZE(pipe
), (crtc_h
<< 16) | crtc_w
);
641 I915_WRITE(DVSSCALE(pipe
), dvsscale
);
642 I915_WRITE(DVSCNTR(pipe
), dvscntr
);
643 I915_WRITE(DVSSURF(pipe
),
644 i915_gem_obj_ggtt_offset(obj
) + dvssurf_offset
);
646 intel_flush_primary_plane(dev_priv
, intel_crtc
->plane
);
649 intel_pipe_update_end(intel_crtc
, start_vbl_count
);
653 ilk_disable_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
)
655 struct drm_device
*dev
= plane
->dev
;
656 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
657 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
658 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
659 int pipe
= intel_plane
->pipe
;
663 atomic_update
= intel_pipe_update_start(intel_crtc
, &start_vbl_count
);
665 intel_update_primary_plane(intel_crtc
);
667 I915_WRITE(DVSCNTR(pipe
), I915_READ(DVSCNTR(pipe
)) & ~DVS_ENABLE
);
668 /* Disable the scaler */
669 I915_WRITE(DVSSCALE(pipe
), 0);
670 /* Flush double buffered register updates */
671 I915_WRITE(DVSSURF(pipe
), 0);
673 intel_flush_primary_plane(dev_priv
, intel_crtc
->plane
);
676 intel_pipe_update_end(intel_crtc
, start_vbl_count
);
679 * Avoid underruns when disabling the sprite.
680 * FIXME remove once watermark updates are done properly.
682 intel_wait_for_vblank(dev
, pipe
);
684 intel_update_sprite_watermarks(plane
, crtc
, 0, 0, false, false);
688 intel_post_enable_primary(struct drm_crtc
*crtc
)
690 struct drm_device
*dev
= crtc
->dev
;
691 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
694 * BDW signals flip done immediately if the plane
695 * is disabled, even if the plane enable is already
696 * armed to occur at the next vblank :(
698 if (IS_BROADWELL(dev
))
699 intel_wait_for_vblank(dev
, intel_crtc
->pipe
);
702 * FIXME IPS should be fine as long as one plane is
703 * enabled, but in practice it seems to have problems
704 * when going from primary only to sprite only and vice
707 hsw_enable_ips(intel_crtc
);
709 mutex_lock(&dev
->struct_mutex
);
710 intel_update_fbc(dev
);
711 mutex_unlock(&dev
->struct_mutex
);
715 intel_pre_disable_primary(struct drm_crtc
*crtc
)
717 struct drm_device
*dev
= crtc
->dev
;
718 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
719 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
721 mutex_lock(&dev
->struct_mutex
);
722 if (dev_priv
->fbc
.plane
== intel_crtc
->plane
)
723 intel_disable_fbc(dev
);
724 mutex_unlock(&dev
->struct_mutex
);
727 * FIXME IPS should be fine as long as one plane is
728 * enabled, but in practice it seems to have problems
729 * when going from primary only to sprite only and vice
732 hsw_disable_ips(intel_crtc
);
736 ilk_update_colorkey(struct drm_plane
*plane
,
737 struct drm_intel_sprite_colorkey
*key
)
739 struct drm_device
*dev
= plane
->dev
;
740 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
741 struct intel_plane
*intel_plane
;
745 intel_plane
= to_intel_plane(plane
);
747 I915_WRITE(DVSKEYVAL(intel_plane
->pipe
), key
->min_value
);
748 I915_WRITE(DVSKEYMAX(intel_plane
->pipe
), key
->max_value
);
749 I915_WRITE(DVSKEYMSK(intel_plane
->pipe
), key
->channel_mask
);
751 dvscntr
= I915_READ(DVSCNTR(intel_plane
->pipe
));
752 dvscntr
&= ~(DVS_SOURCE_KEY
| DVS_DEST_KEY
);
753 if (key
->flags
& I915_SET_COLORKEY_DESTINATION
)
754 dvscntr
|= DVS_DEST_KEY
;
755 else if (key
->flags
& I915_SET_COLORKEY_SOURCE
)
756 dvscntr
|= DVS_SOURCE_KEY
;
757 I915_WRITE(DVSCNTR(intel_plane
->pipe
), dvscntr
);
759 POSTING_READ(DVSKEYMSK(intel_plane
->pipe
));
765 ilk_get_colorkey(struct drm_plane
*plane
, struct drm_intel_sprite_colorkey
*key
)
767 struct drm_device
*dev
= plane
->dev
;
768 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
769 struct intel_plane
*intel_plane
;
772 intel_plane
= to_intel_plane(plane
);
774 key
->min_value
= I915_READ(DVSKEYVAL(intel_plane
->pipe
));
775 key
->max_value
= I915_READ(DVSKEYMAX(intel_plane
->pipe
));
776 key
->channel_mask
= I915_READ(DVSKEYMSK(intel_plane
->pipe
));
779 dvscntr
= I915_READ(DVSCNTR(intel_plane
->pipe
));
781 if (dvscntr
& DVS_DEST_KEY
)
782 key
->flags
= I915_SET_COLORKEY_DESTINATION
;
783 else if (dvscntr
& DVS_SOURCE_KEY
)
784 key
->flags
= I915_SET_COLORKEY_SOURCE
;
786 key
->flags
= I915_SET_COLORKEY_NONE
;
790 format_is_yuv(uint32_t format
)
793 case DRM_FORMAT_YUYV
:
794 case DRM_FORMAT_UYVY
:
795 case DRM_FORMAT_VYUY
:
796 case DRM_FORMAT_YVYU
:
803 static bool colorkey_enabled(struct intel_plane
*intel_plane
)
805 struct drm_intel_sprite_colorkey key
;
807 intel_plane
->get_colorkey(&intel_plane
->base
, &key
);
809 return key
.flags
!= I915_SET_COLORKEY_NONE
;
813 intel_update_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
,
814 struct drm_framebuffer
*fb
, int crtc_x
, int crtc_y
,
815 unsigned int crtc_w
, unsigned int crtc_h
,
816 uint32_t src_x
, uint32_t src_y
,
817 uint32_t src_w
, uint32_t src_h
)
819 struct drm_device
*dev
= plane
->dev
;
820 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
821 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
822 enum pipe pipe
= intel_crtc
->pipe
;
823 struct intel_framebuffer
*intel_fb
= to_intel_framebuffer(fb
);
824 struct drm_i915_gem_object
*obj
= intel_fb
->obj
;
825 struct drm_i915_gem_object
*old_obj
= intel_plane
->obj
;
827 bool primary_enabled
;
830 int max_scale
, min_scale
;
831 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
832 struct drm_rect src
= {
833 /* sample coordinates in 16.16 fixed point */
839 struct drm_rect dst
= {
842 .x2
= crtc_x
+ crtc_w
,
844 .y2
= crtc_y
+ crtc_h
,
846 const struct drm_rect clip
= {
847 .x2
= intel_crtc
->active
? intel_crtc
->config
.pipe_src_w
: 0,
848 .y2
= intel_crtc
->active
? intel_crtc
->config
.pipe_src_h
: 0,
852 unsigned int crtc_w
, crtc_h
;
853 uint32_t src_x
, src_y
, src_w
, src_h
;
865 /* Don't modify another pipe's plane */
866 if (intel_plane
->pipe
!= intel_crtc
->pipe
) {
867 DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n");
871 /* FIXME check all gen limits */
872 if (fb
->width
< 3 || fb
->height
< 3 || fb
->pitches
[0] > 16384) {
873 DRM_DEBUG_KMS("Unsuitable framebuffer for plane\n");
877 /* Sprite planes can be linear or x-tiled surfaces */
878 switch (obj
->tiling_mode
) {
879 case I915_TILING_NONE
:
883 DRM_DEBUG_KMS("Unsupported tiling mode\n");
888 * FIXME the following code does a bunch of fuzzy adjustments to the
889 * coordinates and sizes. We probably need some way to decide whether
890 * more strict checking should be done instead.
892 max_scale
= intel_plane
->max_downscale
<< 16;
893 min_scale
= intel_plane
->can_scale
? 1 : (1 << 16);
895 hscale
= drm_rect_calc_hscale_relaxed(&src
, &dst
, min_scale
, max_scale
);
898 vscale
= drm_rect_calc_vscale_relaxed(&src
, &dst
, min_scale
, max_scale
);
901 visible
= drm_rect_clip_scaled(&src
, &dst
, &clip
, hscale
, vscale
);
905 crtc_w
= drm_rect_width(&dst
);
906 crtc_h
= drm_rect_height(&dst
);
909 /* check again in case clipping clamped the results */
910 hscale
= drm_rect_calc_hscale(&src
, &dst
, min_scale
, max_scale
);
912 DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n");
913 drm_rect_debug_print(&src
, true);
914 drm_rect_debug_print(&dst
, false);
919 vscale
= drm_rect_calc_vscale(&src
, &dst
, min_scale
, max_scale
);
921 DRM_DEBUG_KMS("Vertical scaling factor out of limits\n");
922 drm_rect_debug_print(&src
, true);
923 drm_rect_debug_print(&dst
, false);
928 /* Make the source viewport size an exact multiple of the scaling factors. */
929 drm_rect_adjust_size(&src
,
930 drm_rect_width(&dst
) * hscale
- drm_rect_width(&src
),
931 drm_rect_height(&dst
) * vscale
- drm_rect_height(&src
));
933 /* sanity check to make sure the src viewport wasn't enlarged */
934 WARN_ON(src
.x1
< (int) src_x
||
935 src
.y1
< (int) src_y
||
936 src
.x2
> (int) (src_x
+ src_w
) ||
937 src
.y2
> (int) (src_y
+ src_h
));
940 * Hardware doesn't handle subpixel coordinates.
941 * Adjust to (macro)pixel boundary, but be careful not to
942 * increase the source viewport size, because that could
943 * push the downscaling factor out of bounds.
945 src_x
= src
.x1
>> 16;
946 src_w
= drm_rect_width(&src
) >> 16;
947 src_y
= src
.y1
>> 16;
948 src_h
= drm_rect_height(&src
) >> 16;
950 if (format_is_yuv(fb
->pixel_format
)) {
955 * Must keep src and dst the
956 * same if we can't scale.
958 if (!intel_plane
->can_scale
)
966 /* Check size restrictions when scaling */
967 if (visible
&& (src_w
!= crtc_w
|| src_h
!= crtc_h
)) {
968 unsigned int width_bytes
;
970 WARN_ON(!intel_plane
->can_scale
);
972 /* FIXME interlacing min height is 6 */
974 if (crtc_w
< 3 || crtc_h
< 3)
977 if (src_w
< 3 || src_h
< 3)
980 width_bytes
= ((src_x
* pixel_size
) & 63) + src_w
* pixel_size
;
982 if (src_w
> 2048 || src_h
> 2048 ||
983 width_bytes
> 4096 || fb
->pitches
[0] > 4096) {
984 DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
990 dst
.x2
= crtc_x
+ crtc_w
;
992 dst
.y2
= crtc_y
+ crtc_h
;
995 * If the sprite is completely covering the primary plane,
996 * we can disable the primary and save power.
998 primary_enabled
= !drm_rect_equals(&dst
, &clip
) || colorkey_enabled(intel_plane
);
999 WARN_ON(!primary_enabled
&& !visible
&& intel_crtc
->active
);
1001 mutex_lock(&dev
->struct_mutex
);
1003 /* Note that this will apply the VT-d workaround for scanouts,
1004 * which is more restrictive than required for sprites. (The
1005 * primary plane requires 256KiB alignment with 64 PTE padding,
1006 * the sprite planes only require 128KiB alignment and 32 PTE padding.
1008 ret
= intel_pin_and_fence_fb_obj(dev
, obj
, NULL
);
1010 i915_gem_track_fb(old_obj
, obj
,
1011 INTEL_FRONTBUFFER_SPRITE(pipe
));
1012 mutex_unlock(&dev
->struct_mutex
);
1017 intel_plane
->crtc_x
= orig
.crtc_x
;
1018 intel_plane
->crtc_y
= orig
.crtc_y
;
1019 intel_plane
->crtc_w
= orig
.crtc_w
;
1020 intel_plane
->crtc_h
= orig
.crtc_h
;
1021 intel_plane
->src_x
= orig
.src_x
;
1022 intel_plane
->src_y
= orig
.src_y
;
1023 intel_plane
->src_w
= orig
.src_w
;
1024 intel_plane
->src_h
= orig
.src_h
;
1025 intel_plane
->obj
= obj
;
1027 if (intel_crtc
->active
) {
1028 bool primary_was_enabled
= intel_crtc
->primary_enabled
;
1030 intel_crtc
->primary_enabled
= primary_enabled
;
1032 if (primary_was_enabled
!= primary_enabled
)
1033 intel_crtc_wait_for_pending_flips(crtc
);
1035 if (primary_was_enabled
&& !primary_enabled
)
1036 intel_pre_disable_primary(crtc
);
1039 intel_plane
->update_plane(plane
, crtc
, fb
, obj
,
1040 crtc_x
, crtc_y
, crtc_w
, crtc_h
,
1041 src_x
, src_y
, src_w
, src_h
);
1043 intel_plane
->disable_plane(plane
, crtc
);
1045 intel_frontbuffer_flip(dev
, INTEL_FRONTBUFFER_SPRITE(pipe
));
1047 if (!primary_was_enabled
&& primary_enabled
)
1048 intel_post_enable_primary(crtc
);
1051 /* Unpin old obj after new one is active to avoid ugliness */
1054 * It's fairly common to simply update the position of
1055 * an existing object. In that case, we don't need to
1056 * wait for vblank to avoid ugliness, we only need to
1057 * do the pin & ref bookkeeping.
1059 if (old_obj
!= obj
&& intel_crtc
->active
)
1060 intel_wait_for_vblank(dev
, intel_crtc
->pipe
);
1062 mutex_lock(&dev
->struct_mutex
);
1063 intel_unpin_fb_obj(old_obj
);
1064 mutex_unlock(&dev
->struct_mutex
);
1071 intel_disable_plane(struct drm_plane
*plane
)
1073 struct drm_device
*dev
= plane
->dev
;
1074 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
1075 struct intel_crtc
*intel_crtc
;
1081 if (WARN_ON(!plane
->crtc
))
1084 intel_crtc
= to_intel_crtc(plane
->crtc
);
1085 pipe
= intel_crtc
->pipe
;
1087 if (intel_crtc
->active
) {
1088 bool primary_was_enabled
= intel_crtc
->primary_enabled
;
1090 intel_crtc
->primary_enabled
= true;
1092 intel_plane
->disable_plane(plane
, plane
->crtc
);
1094 if (!primary_was_enabled
&& intel_crtc
->primary_enabled
)
1095 intel_post_enable_primary(plane
->crtc
);
1098 if (intel_plane
->obj
) {
1099 if (intel_crtc
->active
)
1100 intel_wait_for_vblank(dev
, intel_plane
->pipe
);
1102 mutex_lock(&dev
->struct_mutex
);
1103 intel_unpin_fb_obj(intel_plane
->obj
);
1104 i915_gem_track_fb(intel_plane
->obj
, NULL
,
1105 INTEL_FRONTBUFFER_SPRITE(pipe
));
1106 mutex_unlock(&dev
->struct_mutex
);
1108 intel_plane
->obj
= NULL
;
1114 static void intel_destroy_plane(struct drm_plane
*plane
)
1116 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
1117 intel_disable_plane(plane
);
1118 drm_plane_cleanup(plane
);
1122 int intel_sprite_set_colorkey(struct drm_device
*dev
, void *data
,
1123 struct drm_file
*file_priv
)
1125 struct drm_intel_sprite_colorkey
*set
= data
;
1126 struct drm_plane
*plane
;
1127 struct intel_plane
*intel_plane
;
1130 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
1133 /* Make sure we don't try to enable both src & dest simultaneously */
1134 if ((set
->flags
& (I915_SET_COLORKEY_DESTINATION
| I915_SET_COLORKEY_SOURCE
)) == (I915_SET_COLORKEY_DESTINATION
| I915_SET_COLORKEY_SOURCE
))
1137 drm_modeset_lock_all(dev
);
1139 plane
= drm_plane_find(dev
, set
->plane_id
);
1145 intel_plane
= to_intel_plane(plane
);
1146 ret
= intel_plane
->update_colorkey(plane
, set
);
1149 drm_modeset_unlock_all(dev
);
1153 int intel_sprite_get_colorkey(struct drm_device
*dev
, void *data
,
1154 struct drm_file
*file_priv
)
1156 struct drm_intel_sprite_colorkey
*get
= data
;
1157 struct drm_plane
*plane
;
1158 struct intel_plane
*intel_plane
;
1161 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
1164 drm_modeset_lock_all(dev
);
1166 plane
= drm_plane_find(dev
, get
->plane_id
);
1172 intel_plane
= to_intel_plane(plane
);
1173 intel_plane
->get_colorkey(plane
, get
);
1176 drm_modeset_unlock_all(dev
);
1180 void intel_plane_restore(struct drm_plane
*plane
)
1182 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
1184 if (!plane
->crtc
|| !plane
->fb
)
1187 intel_update_plane(plane
, plane
->crtc
, plane
->fb
,
1188 intel_plane
->crtc_x
, intel_plane
->crtc_y
,
1189 intel_plane
->crtc_w
, intel_plane
->crtc_h
,
1190 intel_plane
->src_x
, intel_plane
->src_y
,
1191 intel_plane
->src_w
, intel_plane
->src_h
);
1194 void intel_plane_disable(struct drm_plane
*plane
)
1196 if (!plane
->crtc
|| !plane
->fb
)
1199 intel_disable_plane(plane
);
1202 static const struct drm_plane_funcs intel_plane_funcs
= {
1203 .update_plane
= intel_update_plane
,
1204 .disable_plane
= intel_disable_plane
,
1205 .destroy
= intel_destroy_plane
,
1208 static uint32_t ilk_plane_formats
[] = {
1209 DRM_FORMAT_XRGB8888
,
1216 static uint32_t snb_plane_formats
[] = {
1217 DRM_FORMAT_XBGR8888
,
1218 DRM_FORMAT_XRGB8888
,
1225 static uint32_t vlv_plane_formats
[] = {
1227 DRM_FORMAT_ABGR8888
,
1228 DRM_FORMAT_ARGB8888
,
1229 DRM_FORMAT_XBGR8888
,
1230 DRM_FORMAT_XRGB8888
,
1231 DRM_FORMAT_XBGR2101010
,
1232 DRM_FORMAT_ABGR2101010
,
1240 intel_plane_init(struct drm_device
*dev
, enum pipe pipe
, int plane
)
1242 struct intel_plane
*intel_plane
;
1243 unsigned long possible_crtcs
;
1244 const uint32_t *plane_formats
;
1245 int num_plane_formats
;
1248 if (INTEL_INFO(dev
)->gen
< 5)
1251 intel_plane
= kzalloc(sizeof(*intel_plane
), GFP_KERNEL
);
1255 switch (INTEL_INFO(dev
)->gen
) {
1258 intel_plane
->can_scale
= true;
1259 intel_plane
->max_downscale
= 16;
1260 intel_plane
->update_plane
= ilk_update_plane
;
1261 intel_plane
->disable_plane
= ilk_disable_plane
;
1262 intel_plane
->update_colorkey
= ilk_update_colorkey
;
1263 intel_plane
->get_colorkey
= ilk_get_colorkey
;
1266 plane_formats
= snb_plane_formats
;
1267 num_plane_formats
= ARRAY_SIZE(snb_plane_formats
);
1269 plane_formats
= ilk_plane_formats
;
1270 num_plane_formats
= ARRAY_SIZE(ilk_plane_formats
);
1276 if (IS_IVYBRIDGE(dev
)) {
1277 intel_plane
->can_scale
= true;
1278 intel_plane
->max_downscale
= 2;
1280 intel_plane
->can_scale
= false;
1281 intel_plane
->max_downscale
= 1;
1284 if (IS_VALLEYVIEW(dev
)) {
1285 intel_plane
->update_plane
= vlv_update_plane
;
1286 intel_plane
->disable_plane
= vlv_disable_plane
;
1287 intel_plane
->update_colorkey
= vlv_update_colorkey
;
1288 intel_plane
->get_colorkey
= vlv_get_colorkey
;
1290 plane_formats
= vlv_plane_formats
;
1291 num_plane_formats
= ARRAY_SIZE(vlv_plane_formats
);
1293 intel_plane
->update_plane
= ivb_update_plane
;
1294 intel_plane
->disable_plane
= ivb_disable_plane
;
1295 intel_plane
->update_colorkey
= ivb_update_colorkey
;
1296 intel_plane
->get_colorkey
= ivb_get_colorkey
;
1298 plane_formats
= snb_plane_formats
;
1299 num_plane_formats
= ARRAY_SIZE(snb_plane_formats
);
1308 intel_plane
->pipe
= pipe
;
1309 intel_plane
->plane
= plane
;
1310 possible_crtcs
= (1 << pipe
);
1311 ret
= drm_plane_init(dev
, &intel_plane
->base
, possible_crtcs
,
1313 plane_formats
, num_plane_formats
,