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>
41 vlv_update_plane(struct drm_plane
*dplane
, struct drm_framebuffer
*fb
,
42 struct drm_i915_gem_object
*obj
, int crtc_x
, int crtc_y
,
43 unsigned int crtc_w
, unsigned int crtc_h
,
44 uint32_t x
, uint32_t y
,
45 uint32_t src_w
, uint32_t src_h
)
47 struct drm_device
*dev
= dplane
->dev
;
48 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
49 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
50 int pipe
= intel_plane
->pipe
;
51 int plane
= intel_plane
->plane
;
53 unsigned long sprsurf_offset
, linear_offset
;
54 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
56 sprctl
= I915_READ(SPCNTR(pipe
, plane
));
58 /* Mask out pixel format bits in case we change it */
59 sprctl
&= ~SP_PIXFORMAT_MASK
;
60 sprctl
&= ~SP_YUV_BYTE_ORDER_MASK
;
63 switch (fb
->pixel_format
) {
65 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_YUYV
;
68 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_YVYU
;
71 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_UYVY
;
74 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_VYUY
;
76 case DRM_FORMAT_RGB565
:
77 sprctl
|= SP_FORMAT_BGR565
;
79 case DRM_FORMAT_XRGB8888
:
80 sprctl
|= SP_FORMAT_BGRX8888
;
82 case DRM_FORMAT_ARGB8888
:
83 sprctl
|= SP_FORMAT_BGRA8888
;
85 case DRM_FORMAT_XBGR2101010
:
86 sprctl
|= SP_FORMAT_RGBX1010102
;
88 case DRM_FORMAT_ABGR2101010
:
89 sprctl
|= SP_FORMAT_RGBA1010102
;
91 case DRM_FORMAT_XBGR8888
:
92 sprctl
|= SP_FORMAT_RGBX8888
;
94 case DRM_FORMAT_ABGR8888
:
95 sprctl
|= SP_FORMAT_RGBA8888
;
99 * If we get here one of the upper layers failed to filter
100 * out the unsupported plane formats
106 if (obj
->tiling_mode
!= I915_TILING_NONE
)
111 /* Sizes are 0 based */
117 intel_update_sprite_watermarks(dev
, pipe
, crtc_w
, pixel_size
, true);
119 I915_WRITE(SPSTRIDE(pipe
, plane
), fb
->pitches
[0]);
120 I915_WRITE(SPPOS(pipe
, plane
), (crtc_y
<< 16) | crtc_x
);
122 linear_offset
= y
* fb
->pitches
[0] + x
* pixel_size
;
123 sprsurf_offset
= intel_gen4_compute_page_offset(&x
, &y
,
127 linear_offset
-= sprsurf_offset
;
129 if (obj
->tiling_mode
!= I915_TILING_NONE
)
130 I915_WRITE(SPTILEOFF(pipe
, plane
), (y
<< 16) | x
);
132 I915_WRITE(SPLINOFF(pipe
, plane
), linear_offset
);
134 I915_WRITE(SPSIZE(pipe
, plane
), (crtc_h
<< 16) | crtc_w
);
135 I915_WRITE(SPCNTR(pipe
, plane
), sprctl
);
136 I915_MODIFY_DISPBASE(SPSURF(pipe
, plane
), obj
->gtt_offset
+
138 POSTING_READ(SPSURF(pipe
, plane
));
142 vlv_disable_plane(struct drm_plane
*dplane
)
144 struct drm_device
*dev
= dplane
->dev
;
145 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
146 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
147 int pipe
= intel_plane
->pipe
;
148 int plane
= intel_plane
->plane
;
150 I915_WRITE(SPCNTR(pipe
, plane
), I915_READ(SPCNTR(pipe
, plane
)) &
152 /* Activate double buffered register update */
153 I915_MODIFY_DISPBASE(SPSURF(pipe
, plane
), 0);
154 POSTING_READ(SPSURF(pipe
, plane
));
158 vlv_update_colorkey(struct drm_plane
*dplane
,
159 struct drm_intel_sprite_colorkey
*key
)
161 struct drm_device
*dev
= dplane
->dev
;
162 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
163 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
164 int pipe
= intel_plane
->pipe
;
165 int plane
= intel_plane
->plane
;
168 if (key
->flags
& I915_SET_COLORKEY_DESTINATION
)
171 I915_WRITE(SPKEYMINVAL(pipe
, plane
), key
->min_value
);
172 I915_WRITE(SPKEYMAXVAL(pipe
, plane
), key
->max_value
);
173 I915_WRITE(SPKEYMSK(pipe
, plane
), key
->channel_mask
);
175 sprctl
= I915_READ(SPCNTR(pipe
, plane
));
176 sprctl
&= ~SP_SOURCE_KEY
;
177 if (key
->flags
& I915_SET_COLORKEY_SOURCE
)
178 sprctl
|= SP_SOURCE_KEY
;
179 I915_WRITE(SPCNTR(pipe
, plane
), sprctl
);
181 POSTING_READ(SPKEYMSK(pipe
, plane
));
187 vlv_get_colorkey(struct drm_plane
*dplane
,
188 struct drm_intel_sprite_colorkey
*key
)
190 struct drm_device
*dev
= dplane
->dev
;
191 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
192 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
193 int pipe
= intel_plane
->pipe
;
194 int plane
= intel_plane
->plane
;
197 key
->min_value
= I915_READ(SPKEYMINVAL(pipe
, plane
));
198 key
->max_value
= I915_READ(SPKEYMAXVAL(pipe
, plane
));
199 key
->channel_mask
= I915_READ(SPKEYMSK(pipe
, plane
));
201 sprctl
= I915_READ(SPCNTR(pipe
, plane
));
202 if (sprctl
& SP_SOURCE_KEY
)
203 key
->flags
= I915_SET_COLORKEY_SOURCE
;
205 key
->flags
= I915_SET_COLORKEY_NONE
;
209 ivb_update_plane(struct drm_plane
*plane
, struct drm_framebuffer
*fb
,
210 struct drm_i915_gem_object
*obj
, int crtc_x
, int crtc_y
,
211 unsigned int crtc_w
, unsigned int crtc_h
,
212 uint32_t x
, uint32_t y
,
213 uint32_t src_w
, uint32_t src_h
)
215 struct drm_device
*dev
= plane
->dev
;
216 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
217 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
218 int pipe
= intel_plane
->pipe
;
219 u32 sprctl
, sprscale
= 0;
220 unsigned long sprsurf_offset
, linear_offset
;
221 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
222 bool scaling_was_enabled
= dev_priv
->sprite_scaling_enabled
;
224 sprctl
= I915_READ(SPRCTL(pipe
));
226 /* Mask out pixel format bits in case we change it */
227 sprctl
&= ~SPRITE_PIXFORMAT_MASK
;
228 sprctl
&= ~SPRITE_RGB_ORDER_RGBX
;
229 sprctl
&= ~SPRITE_YUV_BYTE_ORDER_MASK
;
230 sprctl
&= ~SPRITE_TILED
;
232 switch (fb
->pixel_format
) {
233 case DRM_FORMAT_XBGR8888
:
234 sprctl
|= SPRITE_FORMAT_RGBX888
| SPRITE_RGB_ORDER_RGBX
;
236 case DRM_FORMAT_XRGB8888
:
237 sprctl
|= SPRITE_FORMAT_RGBX888
;
239 case DRM_FORMAT_YUYV
:
240 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_YUYV
;
242 case DRM_FORMAT_YVYU
:
243 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_YVYU
;
245 case DRM_FORMAT_UYVY
:
246 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_UYVY
;
248 case DRM_FORMAT_VYUY
:
249 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_VYUY
;
255 if (obj
->tiling_mode
!= I915_TILING_NONE
)
256 sprctl
|= SPRITE_TILED
;
259 sprctl
|= SPRITE_TRICKLE_FEED_DISABLE
;
260 sprctl
|= SPRITE_ENABLE
;
263 sprctl
|= SPRITE_PIPE_CSC_ENABLE
;
265 /* Sizes are 0 based */
271 intel_update_sprite_watermarks(dev
, pipe
, crtc_w
, pixel_size
, true);
274 * IVB workaround: must disable low power watermarks for at least
275 * one frame before enabling scaling. LP watermarks can be re-enabled
276 * when scaling is disabled.
278 if (crtc_w
!= src_w
|| crtc_h
!= src_h
) {
279 dev_priv
->sprite_scaling_enabled
|= 1 << pipe
;
281 if (!scaling_was_enabled
) {
282 intel_update_watermarks(dev
);
283 intel_wait_for_vblank(dev
, pipe
);
285 sprscale
= SPRITE_SCALE_ENABLE
| (src_w
<< 16) | src_h
;
287 dev_priv
->sprite_scaling_enabled
&= ~(1 << pipe
);
289 I915_WRITE(SPRSTRIDE(pipe
), fb
->pitches
[0]);
290 I915_WRITE(SPRPOS(pipe
), (crtc_y
<< 16) | crtc_x
);
292 linear_offset
= y
* fb
->pitches
[0] + x
* pixel_size
;
294 intel_gen4_compute_page_offset(&x
, &y
, obj
->tiling_mode
,
295 pixel_size
, fb
->pitches
[0]);
296 linear_offset
-= sprsurf_offset
;
298 /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
301 I915_WRITE(SPROFFSET(pipe
), (y
<< 16) | x
);
302 else if (obj
->tiling_mode
!= I915_TILING_NONE
)
303 I915_WRITE(SPRTILEOFF(pipe
), (y
<< 16) | x
);
305 I915_WRITE(SPRLINOFF(pipe
), linear_offset
);
307 I915_WRITE(SPRSIZE(pipe
), (crtc_h
<< 16) | crtc_w
);
308 if (intel_plane
->can_scale
)
309 I915_WRITE(SPRSCALE(pipe
), sprscale
);
310 I915_WRITE(SPRCTL(pipe
), sprctl
);
311 I915_MODIFY_DISPBASE(SPRSURF(pipe
), obj
->gtt_offset
+ sprsurf_offset
);
312 POSTING_READ(SPRSURF(pipe
));
314 /* potentially re-enable LP watermarks */
315 if (scaling_was_enabled
&& !dev_priv
->sprite_scaling_enabled
)
316 intel_update_watermarks(dev
);
320 ivb_disable_plane(struct drm_plane
*plane
)
322 struct drm_device
*dev
= plane
->dev
;
323 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
324 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
325 int pipe
= intel_plane
->pipe
;
326 bool scaling_was_enabled
= dev_priv
->sprite_scaling_enabled
;
328 I915_WRITE(SPRCTL(pipe
), I915_READ(SPRCTL(pipe
)) & ~SPRITE_ENABLE
);
329 /* Can't leave the scaler enabled... */
330 if (intel_plane
->can_scale
)
331 I915_WRITE(SPRSCALE(pipe
), 0);
332 /* Activate double buffered register update */
333 I915_MODIFY_DISPBASE(SPRSURF(pipe
), 0);
334 POSTING_READ(SPRSURF(pipe
));
336 dev_priv
->sprite_scaling_enabled
&= ~(1 << pipe
);
338 intel_update_sprite_watermarks(dev
, pipe
, 0, 0, false);
340 /* potentially re-enable LP watermarks */
341 if (scaling_was_enabled
&& !dev_priv
->sprite_scaling_enabled
)
342 intel_update_watermarks(dev
);
346 ivb_update_colorkey(struct drm_plane
*plane
,
347 struct drm_intel_sprite_colorkey
*key
)
349 struct drm_device
*dev
= plane
->dev
;
350 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
351 struct intel_plane
*intel_plane
;
355 intel_plane
= to_intel_plane(plane
);
357 I915_WRITE(SPRKEYVAL(intel_plane
->pipe
), key
->min_value
);
358 I915_WRITE(SPRKEYMAX(intel_plane
->pipe
), key
->max_value
);
359 I915_WRITE(SPRKEYMSK(intel_plane
->pipe
), key
->channel_mask
);
361 sprctl
= I915_READ(SPRCTL(intel_plane
->pipe
));
362 sprctl
&= ~(SPRITE_SOURCE_KEY
| SPRITE_DEST_KEY
);
363 if (key
->flags
& I915_SET_COLORKEY_DESTINATION
)
364 sprctl
|= SPRITE_DEST_KEY
;
365 else if (key
->flags
& I915_SET_COLORKEY_SOURCE
)
366 sprctl
|= SPRITE_SOURCE_KEY
;
367 I915_WRITE(SPRCTL(intel_plane
->pipe
), sprctl
);
369 POSTING_READ(SPRKEYMSK(intel_plane
->pipe
));
375 ivb_get_colorkey(struct drm_plane
*plane
, struct drm_intel_sprite_colorkey
*key
)
377 struct drm_device
*dev
= plane
->dev
;
378 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
379 struct intel_plane
*intel_plane
;
382 intel_plane
= to_intel_plane(plane
);
384 key
->min_value
= I915_READ(SPRKEYVAL(intel_plane
->pipe
));
385 key
->max_value
= I915_READ(SPRKEYMAX(intel_plane
->pipe
));
386 key
->channel_mask
= I915_READ(SPRKEYMSK(intel_plane
->pipe
));
389 sprctl
= I915_READ(SPRCTL(intel_plane
->pipe
));
391 if (sprctl
& SPRITE_DEST_KEY
)
392 key
->flags
= I915_SET_COLORKEY_DESTINATION
;
393 else if (sprctl
& SPRITE_SOURCE_KEY
)
394 key
->flags
= I915_SET_COLORKEY_SOURCE
;
396 key
->flags
= I915_SET_COLORKEY_NONE
;
400 ilk_update_plane(struct drm_plane
*plane
, struct drm_framebuffer
*fb
,
401 struct drm_i915_gem_object
*obj
, int crtc_x
, int crtc_y
,
402 unsigned int crtc_w
, unsigned int crtc_h
,
403 uint32_t x
, uint32_t y
,
404 uint32_t src_w
, uint32_t src_h
)
406 struct drm_device
*dev
= plane
->dev
;
407 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
408 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
409 int pipe
= intel_plane
->pipe
;
410 unsigned long dvssurf_offset
, linear_offset
;
411 u32 dvscntr
, dvsscale
;
412 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
414 dvscntr
= I915_READ(DVSCNTR(pipe
));
416 /* Mask out pixel format bits in case we change it */
417 dvscntr
&= ~DVS_PIXFORMAT_MASK
;
418 dvscntr
&= ~DVS_RGB_ORDER_XBGR
;
419 dvscntr
&= ~DVS_YUV_BYTE_ORDER_MASK
;
420 dvscntr
&= ~DVS_TILED
;
422 switch (fb
->pixel_format
) {
423 case DRM_FORMAT_XBGR8888
:
424 dvscntr
|= DVS_FORMAT_RGBX888
| DVS_RGB_ORDER_XBGR
;
426 case DRM_FORMAT_XRGB8888
:
427 dvscntr
|= DVS_FORMAT_RGBX888
;
429 case DRM_FORMAT_YUYV
:
430 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_YUYV
;
432 case DRM_FORMAT_YVYU
:
433 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_YVYU
;
435 case DRM_FORMAT_UYVY
:
436 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_UYVY
;
438 case DRM_FORMAT_VYUY
:
439 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_VYUY
;
445 if (obj
->tiling_mode
!= I915_TILING_NONE
)
446 dvscntr
|= DVS_TILED
;
449 dvscntr
|= DVS_TRICKLE_FEED_DISABLE
; /* must disable */
450 dvscntr
|= DVS_ENABLE
;
452 /* Sizes are 0 based */
458 intel_update_sprite_watermarks(dev
, pipe
, crtc_w
, pixel_size
, true);
461 if (IS_GEN5(dev
) || crtc_w
!= src_w
|| crtc_h
!= src_h
)
462 dvsscale
= DVS_SCALE_ENABLE
| (src_w
<< 16) | src_h
;
464 I915_WRITE(DVSSTRIDE(pipe
), fb
->pitches
[0]);
465 I915_WRITE(DVSPOS(pipe
), (crtc_y
<< 16) | crtc_x
);
467 linear_offset
= y
* fb
->pitches
[0] + x
* pixel_size
;
469 intel_gen4_compute_page_offset(&x
, &y
, obj
->tiling_mode
,
470 pixel_size
, fb
->pitches
[0]);
471 linear_offset
-= dvssurf_offset
;
473 if (obj
->tiling_mode
!= I915_TILING_NONE
)
474 I915_WRITE(DVSTILEOFF(pipe
), (y
<< 16) | x
);
476 I915_WRITE(DVSLINOFF(pipe
), linear_offset
);
478 I915_WRITE(DVSSIZE(pipe
), (crtc_h
<< 16) | crtc_w
);
479 I915_WRITE(DVSSCALE(pipe
), dvsscale
);
480 I915_WRITE(DVSCNTR(pipe
), dvscntr
);
481 I915_MODIFY_DISPBASE(DVSSURF(pipe
), obj
->gtt_offset
+ dvssurf_offset
);
482 POSTING_READ(DVSSURF(pipe
));
486 ilk_disable_plane(struct drm_plane
*plane
)
488 struct drm_device
*dev
= plane
->dev
;
489 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
490 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
491 int pipe
= intel_plane
->pipe
;
493 I915_WRITE(DVSCNTR(pipe
), I915_READ(DVSCNTR(pipe
)) & ~DVS_ENABLE
);
494 /* Disable the scaler */
495 I915_WRITE(DVSSCALE(pipe
), 0);
496 /* Flush double buffered register updates */
497 I915_MODIFY_DISPBASE(DVSSURF(pipe
), 0);
498 POSTING_READ(DVSSURF(pipe
));
502 intel_enable_primary(struct drm_crtc
*crtc
)
504 struct drm_device
*dev
= crtc
->dev
;
505 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
506 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
507 int reg
= DSPCNTR(intel_crtc
->plane
);
509 if (!intel_crtc
->primary_disabled
)
512 intel_crtc
->primary_disabled
= false;
513 intel_update_fbc(dev
);
515 I915_WRITE(reg
, I915_READ(reg
) | DISPLAY_PLANE_ENABLE
);
519 intel_disable_primary(struct drm_crtc
*crtc
)
521 struct drm_device
*dev
= crtc
->dev
;
522 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
523 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
524 int reg
= DSPCNTR(intel_crtc
->plane
);
526 if (intel_crtc
->primary_disabled
)
529 I915_WRITE(reg
, I915_READ(reg
) & ~DISPLAY_PLANE_ENABLE
);
531 intel_crtc
->primary_disabled
= true;
532 intel_update_fbc(dev
);
536 ilk_update_colorkey(struct drm_plane
*plane
,
537 struct drm_intel_sprite_colorkey
*key
)
539 struct drm_device
*dev
= plane
->dev
;
540 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
541 struct intel_plane
*intel_plane
;
545 intel_plane
= to_intel_plane(plane
);
547 I915_WRITE(DVSKEYVAL(intel_plane
->pipe
), key
->min_value
);
548 I915_WRITE(DVSKEYMAX(intel_plane
->pipe
), key
->max_value
);
549 I915_WRITE(DVSKEYMSK(intel_plane
->pipe
), key
->channel_mask
);
551 dvscntr
= I915_READ(DVSCNTR(intel_plane
->pipe
));
552 dvscntr
&= ~(DVS_SOURCE_KEY
| DVS_DEST_KEY
);
553 if (key
->flags
& I915_SET_COLORKEY_DESTINATION
)
554 dvscntr
|= DVS_DEST_KEY
;
555 else if (key
->flags
& I915_SET_COLORKEY_SOURCE
)
556 dvscntr
|= DVS_SOURCE_KEY
;
557 I915_WRITE(DVSCNTR(intel_plane
->pipe
), dvscntr
);
559 POSTING_READ(DVSKEYMSK(intel_plane
->pipe
));
565 ilk_get_colorkey(struct drm_plane
*plane
, struct drm_intel_sprite_colorkey
*key
)
567 struct drm_device
*dev
= plane
->dev
;
568 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
569 struct intel_plane
*intel_plane
;
572 intel_plane
= to_intel_plane(plane
);
574 key
->min_value
= I915_READ(DVSKEYVAL(intel_plane
->pipe
));
575 key
->max_value
= I915_READ(DVSKEYMAX(intel_plane
->pipe
));
576 key
->channel_mask
= I915_READ(DVSKEYMSK(intel_plane
->pipe
));
579 dvscntr
= I915_READ(DVSCNTR(intel_plane
->pipe
));
581 if (dvscntr
& DVS_DEST_KEY
)
582 key
->flags
= I915_SET_COLORKEY_DESTINATION
;
583 else if (dvscntr
& DVS_SOURCE_KEY
)
584 key
->flags
= I915_SET_COLORKEY_SOURCE
;
586 key
->flags
= I915_SET_COLORKEY_NONE
;
590 format_is_yuv(uint32_t format
)
593 case DRM_FORMAT_YUYV
:
594 case DRM_FORMAT_UYVY
:
595 case DRM_FORMAT_VYUY
:
596 case DRM_FORMAT_YVYU
:
604 intel_update_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
,
605 struct drm_framebuffer
*fb
, int crtc_x
, int crtc_y
,
606 unsigned int crtc_w
, unsigned int crtc_h
,
607 uint32_t src_x
, uint32_t src_y
,
608 uint32_t src_w
, uint32_t src_h
)
610 struct drm_device
*dev
= plane
->dev
;
611 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
612 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
613 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
614 struct intel_framebuffer
*intel_fb
;
615 struct drm_i915_gem_object
*obj
, *old_obj
;
616 int pipe
= intel_plane
->pipe
;
617 enum transcoder cpu_transcoder
= intel_pipe_to_cpu_transcoder(dev_priv
,
620 bool disable_primary
= false;
623 int max_scale
, min_scale
;
624 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
625 struct drm_rect src
= {
626 /* sample coordinates in 16.16 fixed point */
632 struct drm_rect dst
= {
635 .x2
= crtc_x
+ crtc_w
,
637 .y2
= crtc_y
+ crtc_h
,
639 const struct drm_rect clip
= {
640 .x2
= crtc
->mode
.hdisplay
,
641 .y2
= crtc
->mode
.vdisplay
,
644 intel_fb
= to_intel_framebuffer(fb
);
647 old_obj
= intel_plane
->obj
;
649 intel_plane
->crtc_x
= crtc_x
;
650 intel_plane
->crtc_y
= crtc_y
;
651 intel_plane
->crtc_w
= crtc_w
;
652 intel_plane
->crtc_h
= crtc_h
;
653 intel_plane
->src_x
= src_x
;
654 intel_plane
->src_y
= src_y
;
655 intel_plane
->src_w
= src_w
;
656 intel_plane
->src_h
= src_h
;
658 /* Pipe must be running... */
659 if (!(I915_READ(PIPECONF(cpu_transcoder
)) & PIPECONF_ENABLE
)) {
660 DRM_DEBUG_KMS("Pipe disabled\n");
664 /* Don't modify another pipe's plane */
665 if (intel_plane
->pipe
!= intel_crtc
->pipe
) {
666 DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n");
670 /* FIXME check all gen limits */
671 if (fb
->width
< 3 || fb
->height
< 3 || fb
->pitches
[0] > 16384) {
672 DRM_DEBUG_KMS("Unsuitable framebuffer for plane\n");
676 /* Sprite planes can be linear or x-tiled surfaces */
677 switch (obj
->tiling_mode
) {
678 case I915_TILING_NONE
:
682 DRM_DEBUG_KMS("Unsupported tiling mode\n");
687 * FIXME the following code does a bunch of fuzzy adjustments to the
688 * coordinates and sizes. We probably need some way to decide whether
689 * more strict checking should be done instead.
691 max_scale
= intel_plane
->max_downscale
<< 16;
692 min_scale
= intel_plane
->can_scale
? 1 : (1 << 16);
694 hscale
= drm_rect_calc_hscale_relaxed(&src
, &dst
, min_scale
, max_scale
);
697 vscale
= drm_rect_calc_vscale_relaxed(&src
, &dst
, min_scale
, max_scale
);
700 visible
= drm_rect_clip_scaled(&src
, &dst
, &clip
, hscale
, vscale
);
704 crtc_w
= drm_rect_width(&dst
);
705 crtc_h
= drm_rect_height(&dst
);
708 /* check again in case clipping clamped the results */
709 hscale
= drm_rect_calc_hscale(&src
, &dst
, min_scale
, max_scale
);
711 DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n");
712 drm_rect_debug_print(&src
, true);
713 drm_rect_debug_print(&dst
, false);
718 vscale
= drm_rect_calc_vscale(&src
, &dst
, min_scale
, max_scale
);
720 DRM_DEBUG_KMS("Vertical scaling factor out of limits\n");
721 drm_rect_debug_print(&src
, true);
722 drm_rect_debug_print(&dst
, false);
727 /* Make the source viewport size an exact multiple of the scaling factors. */
728 drm_rect_adjust_size(&src
,
729 drm_rect_width(&dst
) * hscale
- drm_rect_width(&src
),
730 drm_rect_height(&dst
) * vscale
- drm_rect_height(&src
));
732 /* sanity check to make sure the src viewport wasn't enlarged */
733 WARN_ON(src
.x1
< (int) src_x
||
734 src
.y1
< (int) src_y
||
735 src
.x2
> (int) (src_x
+ src_w
) ||
736 src
.y2
> (int) (src_y
+ src_h
));
739 * Hardware doesn't handle subpixel coordinates.
740 * Adjust to (macro)pixel boundary, but be careful not to
741 * increase the source viewport size, because that could
742 * push the downscaling factor out of bounds.
744 src_x
= src
.x1
>> 16;
745 src_w
= drm_rect_width(&src
) >> 16;
746 src_y
= src
.y1
>> 16;
747 src_h
= drm_rect_height(&src
) >> 16;
749 if (format_is_yuv(fb
->pixel_format
)) {
754 * Must keep src and dst the
755 * same if we can't scale.
757 if (!intel_plane
->can_scale
)
765 /* Check size restrictions when scaling */
766 if (visible
&& (src_w
!= crtc_w
|| src_h
!= crtc_h
)) {
767 unsigned int width_bytes
;
769 WARN_ON(!intel_plane
->can_scale
);
771 /* FIXME interlacing min height is 6 */
773 if (crtc_w
< 3 || crtc_h
< 3)
776 if (src_w
< 3 || src_h
< 3)
779 width_bytes
= ((src_x
* pixel_size
) & 63) + src_w
* pixel_size
;
781 if (src_w
> 2048 || src_h
> 2048 ||
782 width_bytes
> 4096 || fb
->pitches
[0] > 4096) {
783 DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
789 dst
.x2
= crtc_x
+ crtc_w
;
791 dst
.y2
= crtc_y
+ crtc_h
;
794 * If the sprite is completely covering the primary plane,
795 * we can disable the primary and save power.
797 disable_primary
= drm_rect_equals(&dst
, &clip
);
798 WARN_ON(disable_primary
&& !visible
);
800 mutex_lock(&dev
->struct_mutex
);
802 /* Note that this will apply the VT-d workaround for scanouts,
803 * which is more restrictive than required for sprites. (The
804 * primary plane requires 256KiB alignment with 64 PTE padding,
805 * the sprite planes only require 128KiB alignment and 32 PTE padding.
807 ret
= intel_pin_and_fence_fb_obj(dev
, obj
, NULL
);
811 intel_plane
->obj
= obj
;
814 * Be sure to re-enable the primary before the sprite is no longer
817 if (!disable_primary
)
818 intel_enable_primary(crtc
);
821 intel_plane
->update_plane(plane
, fb
, obj
,
822 crtc_x
, crtc_y
, crtc_w
, crtc_h
,
823 src_x
, src_y
, src_w
, src_h
);
825 intel_plane
->disable_plane(plane
);
828 intel_disable_primary(crtc
);
830 /* Unpin old obj after new one is active to avoid ugliness */
833 * It's fairly common to simply update the position of
834 * an existing object. In that case, we don't need to
835 * wait for vblank to avoid ugliness, we only need to
836 * do the pin & ref bookkeeping.
838 if (old_obj
!= obj
) {
839 mutex_unlock(&dev
->struct_mutex
);
840 intel_wait_for_vblank(dev
, to_intel_crtc(crtc
)->pipe
);
841 mutex_lock(&dev
->struct_mutex
);
843 intel_unpin_fb_obj(old_obj
);
847 mutex_unlock(&dev
->struct_mutex
);
852 intel_disable_plane(struct drm_plane
*plane
)
854 struct drm_device
*dev
= plane
->dev
;
855 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
859 intel_enable_primary(plane
->crtc
);
860 intel_plane
->disable_plane(plane
);
862 if (!intel_plane
->obj
)
865 intel_wait_for_vblank(dev
, intel_plane
->pipe
);
867 mutex_lock(&dev
->struct_mutex
);
868 intel_unpin_fb_obj(intel_plane
->obj
);
869 intel_plane
->obj
= NULL
;
870 mutex_unlock(&dev
->struct_mutex
);
876 static void intel_destroy_plane(struct drm_plane
*plane
)
878 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
879 intel_disable_plane(plane
);
880 drm_plane_cleanup(plane
);
884 int intel_sprite_set_colorkey(struct drm_device
*dev
, void *data
,
885 struct drm_file
*file_priv
)
887 struct drm_intel_sprite_colorkey
*set
= data
;
888 struct drm_mode_object
*obj
;
889 struct drm_plane
*plane
;
890 struct intel_plane
*intel_plane
;
893 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
896 /* Make sure we don't try to enable both src & dest simultaneously */
897 if ((set
->flags
& (I915_SET_COLORKEY_DESTINATION
| I915_SET_COLORKEY_SOURCE
)) == (I915_SET_COLORKEY_DESTINATION
| I915_SET_COLORKEY_SOURCE
))
900 drm_modeset_lock_all(dev
);
902 obj
= drm_mode_object_find(dev
, set
->plane_id
, DRM_MODE_OBJECT_PLANE
);
908 plane
= obj_to_plane(obj
);
909 intel_plane
= to_intel_plane(plane
);
910 ret
= intel_plane
->update_colorkey(plane
, set
);
913 drm_modeset_unlock_all(dev
);
917 int intel_sprite_get_colorkey(struct drm_device
*dev
, void *data
,
918 struct drm_file
*file_priv
)
920 struct drm_intel_sprite_colorkey
*get
= data
;
921 struct drm_mode_object
*obj
;
922 struct drm_plane
*plane
;
923 struct intel_plane
*intel_plane
;
926 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
929 drm_modeset_lock_all(dev
);
931 obj
= drm_mode_object_find(dev
, get
->plane_id
, DRM_MODE_OBJECT_PLANE
);
937 plane
= obj_to_plane(obj
);
938 intel_plane
= to_intel_plane(plane
);
939 intel_plane
->get_colorkey(plane
, get
);
942 drm_modeset_unlock_all(dev
);
946 void intel_plane_restore(struct drm_plane
*plane
)
948 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
950 if (!plane
->crtc
|| !plane
->fb
)
953 intel_update_plane(plane
, plane
->crtc
, plane
->fb
,
954 intel_plane
->crtc_x
, intel_plane
->crtc_y
,
955 intel_plane
->crtc_w
, intel_plane
->crtc_h
,
956 intel_plane
->src_x
, intel_plane
->src_y
,
957 intel_plane
->src_w
, intel_plane
->src_h
);
960 void intel_plane_disable(struct drm_plane
*plane
)
962 if (!plane
->crtc
|| !plane
->fb
)
965 intel_disable_plane(plane
);
968 static const struct drm_plane_funcs intel_plane_funcs
= {
969 .update_plane
= intel_update_plane
,
970 .disable_plane
= intel_disable_plane
,
971 .destroy
= intel_destroy_plane
,
974 static uint32_t ilk_plane_formats
[] = {
982 static uint32_t snb_plane_formats
[] = {
991 static uint32_t vlv_plane_formats
[] = {
997 DRM_FORMAT_XBGR2101010
,
998 DRM_FORMAT_ABGR2101010
,
1006 intel_plane_init(struct drm_device
*dev
, enum pipe pipe
, int plane
)
1008 struct intel_plane
*intel_plane
;
1009 unsigned long possible_crtcs
;
1010 const uint32_t *plane_formats
;
1011 int num_plane_formats
;
1014 if (INTEL_INFO(dev
)->gen
< 5)
1017 intel_plane
= kzalloc(sizeof(struct intel_plane
), GFP_KERNEL
);
1021 switch (INTEL_INFO(dev
)->gen
) {
1024 intel_plane
->can_scale
= true;
1025 intel_plane
->max_downscale
= 16;
1026 intel_plane
->update_plane
= ilk_update_plane
;
1027 intel_plane
->disable_plane
= ilk_disable_plane
;
1028 intel_plane
->update_colorkey
= ilk_update_colorkey
;
1029 intel_plane
->get_colorkey
= ilk_get_colorkey
;
1032 plane_formats
= snb_plane_formats
;
1033 num_plane_formats
= ARRAY_SIZE(snb_plane_formats
);
1035 plane_formats
= ilk_plane_formats
;
1036 num_plane_formats
= ARRAY_SIZE(ilk_plane_formats
);
1041 if (IS_IVYBRIDGE(dev
)) {
1042 intel_plane
->can_scale
= true;
1043 intel_plane
->max_downscale
= 2;
1045 intel_plane
->can_scale
= false;
1046 intel_plane
->max_downscale
= 1;
1049 if (IS_VALLEYVIEW(dev
)) {
1050 intel_plane
->update_plane
= vlv_update_plane
;
1051 intel_plane
->disable_plane
= vlv_disable_plane
;
1052 intel_plane
->update_colorkey
= vlv_update_colorkey
;
1053 intel_plane
->get_colorkey
= vlv_get_colorkey
;
1055 plane_formats
= vlv_plane_formats
;
1056 num_plane_formats
= ARRAY_SIZE(vlv_plane_formats
);
1058 intel_plane
->update_plane
= ivb_update_plane
;
1059 intel_plane
->disable_plane
= ivb_disable_plane
;
1060 intel_plane
->update_colorkey
= ivb_update_colorkey
;
1061 intel_plane
->get_colorkey
= ivb_get_colorkey
;
1063 plane_formats
= snb_plane_formats
;
1064 num_plane_formats
= ARRAY_SIZE(snb_plane_formats
);
1073 intel_plane
->pipe
= pipe
;
1074 intel_plane
->plane
= plane
;
1075 possible_crtcs
= (1 << pipe
);
1076 ret
= drm_plane_init(dev
, &intel_plane
->base
, possible_crtcs
,
1078 plane_formats
, num_plane_formats
,