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 struct intel_framebuffer
*intel_fb
= to_intel_framebuffer(fb
);
823 struct drm_i915_gem_object
*obj
= intel_fb
->obj
;
824 struct drm_i915_gem_object
*old_obj
= intel_plane
->obj
;
826 bool primary_enabled
;
829 int max_scale
, min_scale
;
830 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
831 struct drm_rect src
= {
832 /* sample coordinates in 16.16 fixed point */
838 struct drm_rect dst
= {
841 .x2
= crtc_x
+ crtc_w
,
843 .y2
= crtc_y
+ crtc_h
,
845 const struct drm_rect clip
= {
846 .x2
= intel_crtc
->active
? intel_crtc
->config
.pipe_src_w
: 0,
847 .y2
= intel_crtc
->active
? intel_crtc
->config
.pipe_src_h
: 0,
851 unsigned int crtc_w
, crtc_h
;
852 uint32_t src_x
, src_y
, src_w
, src_h
;
864 /* Don't modify another pipe's plane */
865 if (intel_plane
->pipe
!= intel_crtc
->pipe
) {
866 DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n");
870 /* FIXME check all gen limits */
871 if (fb
->width
< 3 || fb
->height
< 3 || fb
->pitches
[0] > 16384) {
872 DRM_DEBUG_KMS("Unsuitable framebuffer for plane\n");
876 /* Sprite planes can be linear or x-tiled surfaces */
877 switch (obj
->tiling_mode
) {
878 case I915_TILING_NONE
:
882 DRM_DEBUG_KMS("Unsupported tiling mode\n");
887 * FIXME the following code does a bunch of fuzzy adjustments to the
888 * coordinates and sizes. We probably need some way to decide whether
889 * more strict checking should be done instead.
891 max_scale
= intel_plane
->max_downscale
<< 16;
892 min_scale
= intel_plane
->can_scale
? 1 : (1 << 16);
894 hscale
= drm_rect_calc_hscale_relaxed(&src
, &dst
, min_scale
, max_scale
);
897 vscale
= drm_rect_calc_vscale_relaxed(&src
, &dst
, min_scale
, max_scale
);
900 visible
= drm_rect_clip_scaled(&src
, &dst
, &clip
, hscale
, vscale
);
904 crtc_w
= drm_rect_width(&dst
);
905 crtc_h
= drm_rect_height(&dst
);
908 /* check again in case clipping clamped the results */
909 hscale
= drm_rect_calc_hscale(&src
, &dst
, min_scale
, max_scale
);
911 DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n");
912 drm_rect_debug_print(&src
, true);
913 drm_rect_debug_print(&dst
, false);
918 vscale
= drm_rect_calc_vscale(&src
, &dst
, min_scale
, max_scale
);
920 DRM_DEBUG_KMS("Vertical scaling factor out of limits\n");
921 drm_rect_debug_print(&src
, true);
922 drm_rect_debug_print(&dst
, false);
927 /* Make the source viewport size an exact multiple of the scaling factors. */
928 drm_rect_adjust_size(&src
,
929 drm_rect_width(&dst
) * hscale
- drm_rect_width(&src
),
930 drm_rect_height(&dst
) * vscale
- drm_rect_height(&src
));
932 /* sanity check to make sure the src viewport wasn't enlarged */
933 WARN_ON(src
.x1
< (int) src_x
||
934 src
.y1
< (int) src_y
||
935 src
.x2
> (int) (src_x
+ src_w
) ||
936 src
.y2
> (int) (src_y
+ src_h
));
939 * Hardware doesn't handle subpixel coordinates.
940 * Adjust to (macro)pixel boundary, but be careful not to
941 * increase the source viewport size, because that could
942 * push the downscaling factor out of bounds.
944 src_x
= src
.x1
>> 16;
945 src_w
= drm_rect_width(&src
) >> 16;
946 src_y
= src
.y1
>> 16;
947 src_h
= drm_rect_height(&src
) >> 16;
949 if (format_is_yuv(fb
->pixel_format
)) {
954 * Must keep src and dst the
955 * same if we can't scale.
957 if (!intel_plane
->can_scale
)
965 /* Check size restrictions when scaling */
966 if (visible
&& (src_w
!= crtc_w
|| src_h
!= crtc_h
)) {
967 unsigned int width_bytes
;
969 WARN_ON(!intel_plane
->can_scale
);
971 /* FIXME interlacing min height is 6 */
973 if (crtc_w
< 3 || crtc_h
< 3)
976 if (src_w
< 3 || src_h
< 3)
979 width_bytes
= ((src_x
* pixel_size
) & 63) + src_w
* pixel_size
;
981 if (src_w
> 2048 || src_h
> 2048 ||
982 width_bytes
> 4096 || fb
->pitches
[0] > 4096) {
983 DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
989 dst
.x2
= crtc_x
+ crtc_w
;
991 dst
.y2
= crtc_y
+ crtc_h
;
994 * If the sprite is completely covering the primary plane,
995 * we can disable the primary and save power.
997 primary_enabled
= !drm_rect_equals(&dst
, &clip
) || colorkey_enabled(intel_plane
);
998 WARN_ON(!primary_enabled
&& !visible
&& intel_crtc
->active
);
1000 mutex_lock(&dev
->struct_mutex
);
1002 /* Note that this will apply the VT-d workaround for scanouts,
1003 * which is more restrictive than required for sprites. (The
1004 * primary plane requires 256KiB alignment with 64 PTE padding,
1005 * the sprite planes only require 128KiB alignment and 32 PTE padding.
1007 ret
= intel_pin_and_fence_fb_obj(dev
, obj
, NULL
);
1009 mutex_unlock(&dev
->struct_mutex
);
1014 intel_plane
->crtc_x
= orig
.crtc_x
;
1015 intel_plane
->crtc_y
= orig
.crtc_y
;
1016 intel_plane
->crtc_w
= orig
.crtc_w
;
1017 intel_plane
->crtc_h
= orig
.crtc_h
;
1018 intel_plane
->src_x
= orig
.src_x
;
1019 intel_plane
->src_y
= orig
.src_y
;
1020 intel_plane
->src_w
= orig
.src_w
;
1021 intel_plane
->src_h
= orig
.src_h
;
1022 intel_plane
->obj
= obj
;
1024 if (intel_crtc
->active
) {
1025 bool primary_was_enabled
= intel_crtc
->primary_enabled
;
1027 intel_crtc
->primary_enabled
= primary_enabled
;
1029 if (primary_was_enabled
!= primary_enabled
)
1030 intel_crtc_wait_for_pending_flips(crtc
);
1032 if (primary_was_enabled
&& !primary_enabled
)
1033 intel_pre_disable_primary(crtc
);
1036 intel_plane
->update_plane(plane
, crtc
, fb
, obj
,
1037 crtc_x
, crtc_y
, crtc_w
, crtc_h
,
1038 src_x
, src_y
, src_w
, src_h
);
1040 intel_plane
->disable_plane(plane
, crtc
);
1042 if (!primary_was_enabled
&& primary_enabled
)
1043 intel_post_enable_primary(crtc
);
1046 /* Unpin old obj after new one is active to avoid ugliness */
1049 * It's fairly common to simply update the position of
1050 * an existing object. In that case, we don't need to
1051 * wait for vblank to avoid ugliness, we only need to
1052 * do the pin & ref bookkeeping.
1054 if (old_obj
!= obj
&& intel_crtc
->active
)
1055 intel_wait_for_vblank(dev
, intel_crtc
->pipe
);
1057 mutex_lock(&dev
->struct_mutex
);
1058 intel_unpin_fb_obj(old_obj
);
1059 mutex_unlock(&dev
->struct_mutex
);
1066 intel_disable_plane(struct drm_plane
*plane
)
1068 struct drm_device
*dev
= plane
->dev
;
1069 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
1070 struct intel_crtc
*intel_crtc
;
1075 if (WARN_ON(!plane
->crtc
))
1078 intel_crtc
= to_intel_crtc(plane
->crtc
);
1080 if (intel_crtc
->active
) {
1081 bool primary_was_enabled
= intel_crtc
->primary_enabled
;
1083 intel_crtc
->primary_enabled
= true;
1085 intel_plane
->disable_plane(plane
, plane
->crtc
);
1087 if (!primary_was_enabled
&& intel_crtc
->primary_enabled
)
1088 intel_post_enable_primary(plane
->crtc
);
1091 if (intel_plane
->obj
) {
1092 if (intel_crtc
->active
)
1093 intel_wait_for_vblank(dev
, intel_plane
->pipe
);
1095 mutex_lock(&dev
->struct_mutex
);
1096 intel_unpin_fb_obj(intel_plane
->obj
);
1097 mutex_unlock(&dev
->struct_mutex
);
1099 intel_plane
->obj
= NULL
;
1105 static void intel_destroy_plane(struct drm_plane
*plane
)
1107 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
1108 intel_disable_plane(plane
);
1109 drm_plane_cleanup(plane
);
1113 int intel_sprite_set_colorkey(struct drm_device
*dev
, void *data
,
1114 struct drm_file
*file_priv
)
1116 struct drm_intel_sprite_colorkey
*set
= data
;
1117 struct drm_mode_object
*obj
;
1118 struct drm_plane
*plane
;
1119 struct intel_plane
*intel_plane
;
1122 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
1125 /* Make sure we don't try to enable both src & dest simultaneously */
1126 if ((set
->flags
& (I915_SET_COLORKEY_DESTINATION
| I915_SET_COLORKEY_SOURCE
)) == (I915_SET_COLORKEY_DESTINATION
| I915_SET_COLORKEY_SOURCE
))
1129 drm_modeset_lock_all(dev
);
1131 obj
= drm_mode_object_find(dev
, set
->plane_id
, DRM_MODE_OBJECT_PLANE
);
1137 plane
= obj_to_plane(obj
);
1138 intel_plane
= to_intel_plane(plane
);
1139 ret
= intel_plane
->update_colorkey(plane
, set
);
1142 drm_modeset_unlock_all(dev
);
1146 int intel_sprite_get_colorkey(struct drm_device
*dev
, void *data
,
1147 struct drm_file
*file_priv
)
1149 struct drm_intel_sprite_colorkey
*get
= data
;
1150 struct drm_mode_object
*obj
;
1151 struct drm_plane
*plane
;
1152 struct intel_plane
*intel_plane
;
1155 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
1158 drm_modeset_lock_all(dev
);
1160 obj
= drm_mode_object_find(dev
, get
->plane_id
, DRM_MODE_OBJECT_PLANE
);
1166 plane
= obj_to_plane(obj
);
1167 intel_plane
= to_intel_plane(plane
);
1168 intel_plane
->get_colorkey(plane
, get
);
1171 drm_modeset_unlock_all(dev
);
1175 void intel_plane_restore(struct drm_plane
*plane
)
1177 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
1179 if (!plane
->crtc
|| !plane
->fb
)
1182 intel_update_plane(plane
, plane
->crtc
, plane
->fb
,
1183 intel_plane
->crtc_x
, intel_plane
->crtc_y
,
1184 intel_plane
->crtc_w
, intel_plane
->crtc_h
,
1185 intel_plane
->src_x
, intel_plane
->src_y
,
1186 intel_plane
->src_w
, intel_plane
->src_h
);
1189 void intel_plane_disable(struct drm_plane
*plane
)
1191 if (!plane
->crtc
|| !plane
->fb
)
1194 intel_disable_plane(plane
);
1197 static const struct drm_plane_funcs intel_plane_funcs
= {
1198 .update_plane
= intel_update_plane
,
1199 .disable_plane
= intel_disable_plane
,
1200 .destroy
= intel_destroy_plane
,
1203 static uint32_t ilk_plane_formats
[] = {
1204 DRM_FORMAT_XRGB8888
,
1211 static uint32_t snb_plane_formats
[] = {
1212 DRM_FORMAT_XBGR8888
,
1213 DRM_FORMAT_XRGB8888
,
1220 static uint32_t vlv_plane_formats
[] = {
1222 DRM_FORMAT_ABGR8888
,
1223 DRM_FORMAT_ARGB8888
,
1224 DRM_FORMAT_XBGR8888
,
1225 DRM_FORMAT_XRGB8888
,
1226 DRM_FORMAT_XBGR2101010
,
1227 DRM_FORMAT_ABGR2101010
,
1235 intel_plane_init(struct drm_device
*dev
, enum pipe pipe
, int plane
)
1237 struct intel_plane
*intel_plane
;
1238 unsigned long possible_crtcs
;
1239 const uint32_t *plane_formats
;
1240 int num_plane_formats
;
1243 if (INTEL_INFO(dev
)->gen
< 5)
1246 intel_plane
= kzalloc(sizeof(*intel_plane
), GFP_KERNEL
);
1250 switch (INTEL_INFO(dev
)->gen
) {
1253 intel_plane
->can_scale
= true;
1254 intel_plane
->max_downscale
= 16;
1255 intel_plane
->update_plane
= ilk_update_plane
;
1256 intel_plane
->disable_plane
= ilk_disable_plane
;
1257 intel_plane
->update_colorkey
= ilk_update_colorkey
;
1258 intel_plane
->get_colorkey
= ilk_get_colorkey
;
1261 plane_formats
= snb_plane_formats
;
1262 num_plane_formats
= ARRAY_SIZE(snb_plane_formats
);
1264 plane_formats
= ilk_plane_formats
;
1265 num_plane_formats
= ARRAY_SIZE(ilk_plane_formats
);
1271 if (IS_IVYBRIDGE(dev
)) {
1272 intel_plane
->can_scale
= true;
1273 intel_plane
->max_downscale
= 2;
1275 intel_plane
->can_scale
= false;
1276 intel_plane
->max_downscale
= 1;
1279 if (IS_VALLEYVIEW(dev
)) {
1280 intel_plane
->update_plane
= vlv_update_plane
;
1281 intel_plane
->disable_plane
= vlv_disable_plane
;
1282 intel_plane
->update_colorkey
= vlv_update_colorkey
;
1283 intel_plane
->get_colorkey
= vlv_get_colorkey
;
1285 plane_formats
= vlv_plane_formats
;
1286 num_plane_formats
= ARRAY_SIZE(vlv_plane_formats
);
1288 intel_plane
->update_plane
= ivb_update_plane
;
1289 intel_plane
->disable_plane
= ivb_disable_plane
;
1290 intel_plane
->update_colorkey
= ivb_update_colorkey
;
1291 intel_plane
->get_colorkey
= ivb_get_colorkey
;
1293 plane_formats
= snb_plane_formats
;
1294 num_plane_formats
= ARRAY_SIZE(snb_plane_formats
);
1303 intel_plane
->pipe
= pipe
;
1304 intel_plane
->plane
= plane
;
1305 possible_crtcs
= (1 << pipe
);
1306 ret
= drm_plane_init(dev
, &intel_plane
->base
, possible_crtcs
,
1308 plane_formats
, num_plane_formats
,