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_crtc
*crtc
,
42 struct drm_framebuffer
*fb
,
43 struct drm_i915_gem_object
*obj
, int crtc_x
, int crtc_y
,
44 unsigned int crtc_w
, unsigned int crtc_h
,
45 uint32_t x
, uint32_t y
,
46 uint32_t src_w
, uint32_t src_h
)
48 struct drm_device
*dev
= dplane
->dev
;
49 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
50 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
51 int pipe
= intel_plane
->pipe
;
52 int plane
= intel_plane
->plane
;
54 unsigned long sprsurf_offset
, linear_offset
;
55 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
57 sprctl
= I915_READ(SPCNTR(pipe
, plane
));
59 /* Mask out pixel format bits in case we change it */
60 sprctl
&= ~SP_PIXFORMAT_MASK
;
61 sprctl
&= ~SP_YUV_BYTE_ORDER_MASK
;
64 switch (fb
->pixel_format
) {
66 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_YUYV
;
69 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_YVYU
;
72 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_UYVY
;
75 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_VYUY
;
77 case DRM_FORMAT_RGB565
:
78 sprctl
|= SP_FORMAT_BGR565
;
80 case DRM_FORMAT_XRGB8888
:
81 sprctl
|= SP_FORMAT_BGRX8888
;
83 case DRM_FORMAT_ARGB8888
:
84 sprctl
|= SP_FORMAT_BGRA8888
;
86 case DRM_FORMAT_XBGR2101010
:
87 sprctl
|= SP_FORMAT_RGBX1010102
;
89 case DRM_FORMAT_ABGR2101010
:
90 sprctl
|= SP_FORMAT_RGBA1010102
;
92 case DRM_FORMAT_XBGR8888
:
93 sprctl
|= SP_FORMAT_RGBX8888
;
95 case DRM_FORMAT_ABGR8888
:
96 sprctl
|= SP_FORMAT_RGBA8888
;
100 * If we get here one of the upper layers failed to filter
101 * out the unsupported plane formats
107 if (obj
->tiling_mode
!= I915_TILING_NONE
)
112 intel_update_sprite_watermarks(dplane
, crtc
, src_w
, pixel_size
, true,
113 src_w
!= crtc_w
|| src_h
!= crtc_h
);
115 /* Sizes are 0 based */
121 I915_WRITE(SPSTRIDE(pipe
, plane
), fb
->pitches
[0]);
122 I915_WRITE(SPPOS(pipe
, plane
), (crtc_y
<< 16) | crtc_x
);
124 linear_offset
= y
* fb
->pitches
[0] + x
* pixel_size
;
125 sprsurf_offset
= intel_gen4_compute_page_offset(&x
, &y
,
129 linear_offset
-= sprsurf_offset
;
131 if (obj
->tiling_mode
!= I915_TILING_NONE
)
132 I915_WRITE(SPTILEOFF(pipe
, plane
), (y
<< 16) | x
);
134 I915_WRITE(SPLINOFF(pipe
, plane
), linear_offset
);
136 I915_WRITE(SPSIZE(pipe
, plane
), (crtc_h
<< 16) | crtc_w
);
137 I915_WRITE(SPCNTR(pipe
, plane
), sprctl
);
138 I915_MODIFY_DISPBASE(SPSURF(pipe
, plane
), i915_gem_obj_ggtt_offset(obj
) +
140 POSTING_READ(SPSURF(pipe
, plane
));
144 vlv_disable_plane(struct drm_plane
*dplane
, struct drm_crtc
*crtc
)
146 struct drm_device
*dev
= dplane
->dev
;
147 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
148 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
149 int pipe
= intel_plane
->pipe
;
150 int plane
= intel_plane
->plane
;
152 I915_WRITE(SPCNTR(pipe
, plane
), I915_READ(SPCNTR(pipe
, plane
)) &
154 /* Activate double buffered register update */
155 I915_MODIFY_DISPBASE(SPSURF(pipe
, plane
), 0);
156 POSTING_READ(SPSURF(pipe
, plane
));
158 intel_update_sprite_watermarks(dplane
, crtc
, 0, 0, false, false);
162 vlv_update_colorkey(struct drm_plane
*dplane
,
163 struct drm_intel_sprite_colorkey
*key
)
165 struct drm_device
*dev
= dplane
->dev
;
166 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
167 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
168 int pipe
= intel_plane
->pipe
;
169 int plane
= intel_plane
->plane
;
172 if (key
->flags
& I915_SET_COLORKEY_DESTINATION
)
175 I915_WRITE(SPKEYMINVAL(pipe
, plane
), key
->min_value
);
176 I915_WRITE(SPKEYMAXVAL(pipe
, plane
), key
->max_value
);
177 I915_WRITE(SPKEYMSK(pipe
, plane
), key
->channel_mask
);
179 sprctl
= I915_READ(SPCNTR(pipe
, plane
));
180 sprctl
&= ~SP_SOURCE_KEY
;
181 if (key
->flags
& I915_SET_COLORKEY_SOURCE
)
182 sprctl
|= SP_SOURCE_KEY
;
183 I915_WRITE(SPCNTR(pipe
, plane
), sprctl
);
185 POSTING_READ(SPKEYMSK(pipe
, plane
));
191 vlv_get_colorkey(struct drm_plane
*dplane
,
192 struct drm_intel_sprite_colorkey
*key
)
194 struct drm_device
*dev
= dplane
->dev
;
195 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
196 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
197 int pipe
= intel_plane
->pipe
;
198 int plane
= intel_plane
->plane
;
201 key
->min_value
= I915_READ(SPKEYMINVAL(pipe
, plane
));
202 key
->max_value
= I915_READ(SPKEYMAXVAL(pipe
, plane
));
203 key
->channel_mask
= I915_READ(SPKEYMSK(pipe
, plane
));
205 sprctl
= I915_READ(SPCNTR(pipe
, plane
));
206 if (sprctl
& SP_SOURCE_KEY
)
207 key
->flags
= I915_SET_COLORKEY_SOURCE
;
209 key
->flags
= I915_SET_COLORKEY_NONE
;
213 ivb_update_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
,
214 struct drm_framebuffer
*fb
,
215 struct drm_i915_gem_object
*obj
, int crtc_x
, int crtc_y
,
216 unsigned int crtc_w
, unsigned int crtc_h
,
217 uint32_t x
, uint32_t y
,
218 uint32_t src_w
, uint32_t src_h
)
220 struct drm_device
*dev
= plane
->dev
;
221 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
222 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
223 int pipe
= intel_plane
->pipe
;
224 u32 sprctl
, sprscale
= 0;
225 unsigned long sprsurf_offset
, linear_offset
;
226 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
227 bool scaling_was_enabled
= dev_priv
->sprite_scaling_enabled
;
229 sprctl
= I915_READ(SPRCTL(pipe
));
231 /* Mask out pixel format bits in case we change it */
232 sprctl
&= ~SPRITE_PIXFORMAT_MASK
;
233 sprctl
&= ~SPRITE_RGB_ORDER_RGBX
;
234 sprctl
&= ~SPRITE_YUV_BYTE_ORDER_MASK
;
235 sprctl
&= ~SPRITE_TILED
;
237 switch (fb
->pixel_format
) {
238 case DRM_FORMAT_XBGR8888
:
239 sprctl
|= SPRITE_FORMAT_RGBX888
| SPRITE_RGB_ORDER_RGBX
;
241 case DRM_FORMAT_XRGB8888
:
242 sprctl
|= SPRITE_FORMAT_RGBX888
;
244 case DRM_FORMAT_YUYV
:
245 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_YUYV
;
247 case DRM_FORMAT_YVYU
:
248 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_YVYU
;
250 case DRM_FORMAT_UYVY
:
251 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_UYVY
;
253 case DRM_FORMAT_VYUY
:
254 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_VYUY
;
260 if (obj
->tiling_mode
!= I915_TILING_NONE
)
261 sprctl
|= SPRITE_TILED
;
264 sprctl
&= ~SPRITE_TRICKLE_FEED_DISABLE
;
266 sprctl
|= SPRITE_TRICKLE_FEED_DISABLE
;
268 sprctl
|= SPRITE_ENABLE
;
271 sprctl
|= SPRITE_PIPE_CSC_ENABLE
;
273 intel_update_sprite_watermarks(plane
, crtc
, src_w
, pixel_size
, true,
274 src_w
!= crtc_w
|| src_h
!= crtc_h
);
276 /* Sizes are 0 based */
283 * IVB workaround: must disable low power watermarks for at least
284 * one frame before enabling scaling. LP watermarks can be re-enabled
285 * when scaling is disabled.
287 if (crtc_w
!= src_w
|| crtc_h
!= src_h
) {
288 dev_priv
->sprite_scaling_enabled
|= 1 << pipe
;
290 if (!scaling_was_enabled
) {
291 intel_update_watermarks(dev
);
292 intel_wait_for_vblank(dev
, pipe
);
294 sprscale
= SPRITE_SCALE_ENABLE
| (src_w
<< 16) | src_h
;
296 dev_priv
->sprite_scaling_enabled
&= ~(1 << pipe
);
298 I915_WRITE(SPRSTRIDE(pipe
), fb
->pitches
[0]);
299 I915_WRITE(SPRPOS(pipe
), (crtc_y
<< 16) | crtc_x
);
301 linear_offset
= y
* fb
->pitches
[0] + x
* pixel_size
;
303 intel_gen4_compute_page_offset(&x
, &y
, obj
->tiling_mode
,
304 pixel_size
, fb
->pitches
[0]);
305 linear_offset
-= sprsurf_offset
;
307 /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
310 I915_WRITE(SPROFFSET(pipe
), (y
<< 16) | x
);
311 else if (obj
->tiling_mode
!= I915_TILING_NONE
)
312 I915_WRITE(SPRTILEOFF(pipe
), (y
<< 16) | x
);
314 I915_WRITE(SPRLINOFF(pipe
), linear_offset
);
316 I915_WRITE(SPRSIZE(pipe
), (crtc_h
<< 16) | crtc_w
);
317 if (intel_plane
->can_scale
)
318 I915_WRITE(SPRSCALE(pipe
), sprscale
);
319 I915_WRITE(SPRCTL(pipe
), sprctl
);
320 I915_MODIFY_DISPBASE(SPRSURF(pipe
),
321 i915_gem_obj_ggtt_offset(obj
) + sprsurf_offset
);
322 POSTING_READ(SPRSURF(pipe
));
324 /* potentially re-enable LP watermarks */
325 if (scaling_was_enabled
&& !dev_priv
->sprite_scaling_enabled
)
326 intel_update_watermarks(dev
);
330 ivb_disable_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
)
332 struct drm_device
*dev
= plane
->dev
;
333 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
334 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
335 int pipe
= intel_plane
->pipe
;
336 bool scaling_was_enabled
= dev_priv
->sprite_scaling_enabled
;
338 I915_WRITE(SPRCTL(pipe
), I915_READ(SPRCTL(pipe
)) & ~SPRITE_ENABLE
);
339 /* Can't leave the scaler enabled... */
340 if (intel_plane
->can_scale
)
341 I915_WRITE(SPRSCALE(pipe
), 0);
342 /* Activate double buffered register update */
343 I915_MODIFY_DISPBASE(SPRSURF(pipe
), 0);
344 POSTING_READ(SPRSURF(pipe
));
346 dev_priv
->sprite_scaling_enabled
&= ~(1 << pipe
);
348 intel_update_sprite_watermarks(plane
, crtc
, 0, 0, false, false);
350 /* potentially re-enable LP watermarks */
351 if (scaling_was_enabled
&& !dev_priv
->sprite_scaling_enabled
)
352 intel_update_watermarks(dev
);
356 ivb_update_colorkey(struct drm_plane
*plane
,
357 struct drm_intel_sprite_colorkey
*key
)
359 struct drm_device
*dev
= plane
->dev
;
360 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
361 struct intel_plane
*intel_plane
;
365 intel_plane
= to_intel_plane(plane
);
367 I915_WRITE(SPRKEYVAL(intel_plane
->pipe
), key
->min_value
);
368 I915_WRITE(SPRKEYMAX(intel_plane
->pipe
), key
->max_value
);
369 I915_WRITE(SPRKEYMSK(intel_plane
->pipe
), key
->channel_mask
);
371 sprctl
= I915_READ(SPRCTL(intel_plane
->pipe
));
372 sprctl
&= ~(SPRITE_SOURCE_KEY
| SPRITE_DEST_KEY
);
373 if (key
->flags
& I915_SET_COLORKEY_DESTINATION
)
374 sprctl
|= SPRITE_DEST_KEY
;
375 else if (key
->flags
& I915_SET_COLORKEY_SOURCE
)
376 sprctl
|= SPRITE_SOURCE_KEY
;
377 I915_WRITE(SPRCTL(intel_plane
->pipe
), sprctl
);
379 POSTING_READ(SPRKEYMSK(intel_plane
->pipe
));
385 ivb_get_colorkey(struct drm_plane
*plane
, struct drm_intel_sprite_colorkey
*key
)
387 struct drm_device
*dev
= plane
->dev
;
388 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
389 struct intel_plane
*intel_plane
;
392 intel_plane
= to_intel_plane(plane
);
394 key
->min_value
= I915_READ(SPRKEYVAL(intel_plane
->pipe
));
395 key
->max_value
= I915_READ(SPRKEYMAX(intel_plane
->pipe
));
396 key
->channel_mask
= I915_READ(SPRKEYMSK(intel_plane
->pipe
));
399 sprctl
= I915_READ(SPRCTL(intel_plane
->pipe
));
401 if (sprctl
& SPRITE_DEST_KEY
)
402 key
->flags
= I915_SET_COLORKEY_DESTINATION
;
403 else if (sprctl
& SPRITE_SOURCE_KEY
)
404 key
->flags
= I915_SET_COLORKEY_SOURCE
;
406 key
->flags
= I915_SET_COLORKEY_NONE
;
410 ilk_update_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
,
411 struct drm_framebuffer
*fb
,
412 struct drm_i915_gem_object
*obj
, int crtc_x
, int crtc_y
,
413 unsigned int crtc_w
, unsigned int crtc_h
,
414 uint32_t x
, uint32_t y
,
415 uint32_t src_w
, uint32_t src_h
)
417 struct drm_device
*dev
= plane
->dev
;
418 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
419 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
420 int pipe
= intel_plane
->pipe
;
421 unsigned long dvssurf_offset
, linear_offset
;
422 u32 dvscntr
, dvsscale
;
423 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
425 dvscntr
= I915_READ(DVSCNTR(pipe
));
427 /* Mask out pixel format bits in case we change it */
428 dvscntr
&= ~DVS_PIXFORMAT_MASK
;
429 dvscntr
&= ~DVS_RGB_ORDER_XBGR
;
430 dvscntr
&= ~DVS_YUV_BYTE_ORDER_MASK
;
431 dvscntr
&= ~DVS_TILED
;
433 switch (fb
->pixel_format
) {
434 case DRM_FORMAT_XBGR8888
:
435 dvscntr
|= DVS_FORMAT_RGBX888
| DVS_RGB_ORDER_XBGR
;
437 case DRM_FORMAT_XRGB8888
:
438 dvscntr
|= DVS_FORMAT_RGBX888
;
440 case DRM_FORMAT_YUYV
:
441 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_YUYV
;
443 case DRM_FORMAT_YVYU
:
444 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_YVYU
;
446 case DRM_FORMAT_UYVY
:
447 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_UYVY
;
449 case DRM_FORMAT_VYUY
:
450 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_VYUY
;
456 if (obj
->tiling_mode
!= I915_TILING_NONE
)
457 dvscntr
|= DVS_TILED
;
460 dvscntr
|= DVS_TRICKLE_FEED_DISABLE
; /* must disable */
461 dvscntr
|= DVS_ENABLE
;
463 intel_update_sprite_watermarks(plane
, crtc
, src_w
, pixel_size
, true,
464 src_w
!= crtc_w
|| src_h
!= crtc_h
);
466 /* Sizes are 0 based */
473 if (IS_GEN5(dev
) || crtc_w
!= src_w
|| crtc_h
!= src_h
)
474 dvsscale
= DVS_SCALE_ENABLE
| (src_w
<< 16) | src_h
;
476 I915_WRITE(DVSSTRIDE(pipe
), fb
->pitches
[0]);
477 I915_WRITE(DVSPOS(pipe
), (crtc_y
<< 16) | crtc_x
);
479 linear_offset
= y
* fb
->pitches
[0] + x
* pixel_size
;
481 intel_gen4_compute_page_offset(&x
, &y
, obj
->tiling_mode
,
482 pixel_size
, fb
->pitches
[0]);
483 linear_offset
-= dvssurf_offset
;
485 if (obj
->tiling_mode
!= I915_TILING_NONE
)
486 I915_WRITE(DVSTILEOFF(pipe
), (y
<< 16) | x
);
488 I915_WRITE(DVSLINOFF(pipe
), linear_offset
);
490 I915_WRITE(DVSSIZE(pipe
), (crtc_h
<< 16) | crtc_w
);
491 I915_WRITE(DVSSCALE(pipe
), dvsscale
);
492 I915_WRITE(DVSCNTR(pipe
), dvscntr
);
493 I915_MODIFY_DISPBASE(DVSSURF(pipe
),
494 i915_gem_obj_ggtt_offset(obj
) + dvssurf_offset
);
495 POSTING_READ(DVSSURF(pipe
));
499 ilk_disable_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
)
501 struct drm_device
*dev
= plane
->dev
;
502 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
503 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
504 int pipe
= intel_plane
->pipe
;
506 I915_WRITE(DVSCNTR(pipe
), I915_READ(DVSCNTR(pipe
)) & ~DVS_ENABLE
);
507 /* Disable the scaler */
508 I915_WRITE(DVSSCALE(pipe
), 0);
509 /* Flush double buffered register updates */
510 I915_MODIFY_DISPBASE(DVSSURF(pipe
), 0);
511 POSTING_READ(DVSSURF(pipe
));
513 intel_update_sprite_watermarks(plane
, crtc
, 0, 0, false, false);
517 intel_enable_primary(struct drm_crtc
*crtc
)
519 struct drm_device
*dev
= crtc
->dev
;
520 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
521 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
522 int reg
= DSPCNTR(intel_crtc
->plane
);
524 if (!intel_crtc
->primary_disabled
)
527 intel_crtc
->primary_disabled
= false;
528 intel_update_fbc(dev
);
530 I915_WRITE(reg
, I915_READ(reg
) | DISPLAY_PLANE_ENABLE
);
534 intel_disable_primary(struct drm_crtc
*crtc
)
536 struct drm_device
*dev
= crtc
->dev
;
537 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
538 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
539 int reg
= DSPCNTR(intel_crtc
->plane
);
541 if (intel_crtc
->primary_disabled
)
544 I915_WRITE(reg
, I915_READ(reg
) & ~DISPLAY_PLANE_ENABLE
);
546 intel_crtc
->primary_disabled
= true;
547 intel_update_fbc(dev
);
551 ilk_update_colorkey(struct drm_plane
*plane
,
552 struct drm_intel_sprite_colorkey
*key
)
554 struct drm_device
*dev
= plane
->dev
;
555 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
556 struct intel_plane
*intel_plane
;
560 intel_plane
= to_intel_plane(plane
);
562 I915_WRITE(DVSKEYVAL(intel_plane
->pipe
), key
->min_value
);
563 I915_WRITE(DVSKEYMAX(intel_plane
->pipe
), key
->max_value
);
564 I915_WRITE(DVSKEYMSK(intel_plane
->pipe
), key
->channel_mask
);
566 dvscntr
= I915_READ(DVSCNTR(intel_plane
->pipe
));
567 dvscntr
&= ~(DVS_SOURCE_KEY
| DVS_DEST_KEY
);
568 if (key
->flags
& I915_SET_COLORKEY_DESTINATION
)
569 dvscntr
|= DVS_DEST_KEY
;
570 else if (key
->flags
& I915_SET_COLORKEY_SOURCE
)
571 dvscntr
|= DVS_SOURCE_KEY
;
572 I915_WRITE(DVSCNTR(intel_plane
->pipe
), dvscntr
);
574 POSTING_READ(DVSKEYMSK(intel_plane
->pipe
));
580 ilk_get_colorkey(struct drm_plane
*plane
, struct drm_intel_sprite_colorkey
*key
)
582 struct drm_device
*dev
= plane
->dev
;
583 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
584 struct intel_plane
*intel_plane
;
587 intel_plane
= to_intel_plane(plane
);
589 key
->min_value
= I915_READ(DVSKEYVAL(intel_plane
->pipe
));
590 key
->max_value
= I915_READ(DVSKEYMAX(intel_plane
->pipe
));
591 key
->channel_mask
= I915_READ(DVSKEYMSK(intel_plane
->pipe
));
594 dvscntr
= I915_READ(DVSCNTR(intel_plane
->pipe
));
596 if (dvscntr
& DVS_DEST_KEY
)
597 key
->flags
= I915_SET_COLORKEY_DESTINATION
;
598 else if (dvscntr
& DVS_SOURCE_KEY
)
599 key
->flags
= I915_SET_COLORKEY_SOURCE
;
601 key
->flags
= I915_SET_COLORKEY_NONE
;
605 format_is_yuv(uint32_t format
)
608 case DRM_FORMAT_YUYV
:
609 case DRM_FORMAT_UYVY
:
610 case DRM_FORMAT_VYUY
:
611 case DRM_FORMAT_YVYU
:
619 intel_update_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
,
620 struct drm_framebuffer
*fb
, int crtc_x
, int crtc_y
,
621 unsigned int crtc_w
, unsigned int crtc_h
,
622 uint32_t src_x
, uint32_t src_y
,
623 uint32_t src_w
, uint32_t src_h
)
625 struct drm_device
*dev
= plane
->dev
;
626 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
627 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
628 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
629 struct intel_framebuffer
*intel_fb
;
630 struct drm_i915_gem_object
*obj
, *old_obj
;
631 int pipe
= intel_plane
->pipe
;
632 enum transcoder cpu_transcoder
= intel_pipe_to_cpu_transcoder(dev_priv
,
635 bool disable_primary
= false;
638 int max_scale
, min_scale
;
639 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
640 struct drm_rect src
= {
641 /* sample coordinates in 16.16 fixed point */
647 struct drm_rect dst
= {
650 .x2
= crtc_x
+ crtc_w
,
652 .y2
= crtc_y
+ crtc_h
,
654 const struct drm_rect clip
= {
655 .x2
= crtc
->mode
.hdisplay
,
656 .y2
= crtc
->mode
.vdisplay
,
659 intel_fb
= to_intel_framebuffer(fb
);
662 old_obj
= intel_plane
->obj
;
664 intel_plane
->crtc_x
= crtc_x
;
665 intel_plane
->crtc_y
= crtc_y
;
666 intel_plane
->crtc_w
= crtc_w
;
667 intel_plane
->crtc_h
= crtc_h
;
668 intel_plane
->src_x
= src_x
;
669 intel_plane
->src_y
= src_y
;
670 intel_plane
->src_w
= src_w
;
671 intel_plane
->src_h
= src_h
;
673 /* Pipe must be running... */
674 if (!(I915_READ(PIPECONF(cpu_transcoder
)) & PIPECONF_ENABLE
)) {
675 DRM_DEBUG_KMS("Pipe disabled\n");
679 /* Don't modify another pipe's plane */
680 if (intel_plane
->pipe
!= intel_crtc
->pipe
) {
681 DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n");
685 /* FIXME check all gen limits */
686 if (fb
->width
< 3 || fb
->height
< 3 || fb
->pitches
[0] > 16384) {
687 DRM_DEBUG_KMS("Unsuitable framebuffer for plane\n");
691 /* Sprite planes can be linear or x-tiled surfaces */
692 switch (obj
->tiling_mode
) {
693 case I915_TILING_NONE
:
697 DRM_DEBUG_KMS("Unsupported tiling mode\n");
702 * FIXME the following code does a bunch of fuzzy adjustments to the
703 * coordinates and sizes. We probably need some way to decide whether
704 * more strict checking should be done instead.
706 max_scale
= intel_plane
->max_downscale
<< 16;
707 min_scale
= intel_plane
->can_scale
? 1 : (1 << 16);
709 hscale
= drm_rect_calc_hscale_relaxed(&src
, &dst
, min_scale
, max_scale
);
712 vscale
= drm_rect_calc_vscale_relaxed(&src
, &dst
, min_scale
, max_scale
);
715 visible
= drm_rect_clip_scaled(&src
, &dst
, &clip
, hscale
, vscale
);
719 crtc_w
= drm_rect_width(&dst
);
720 crtc_h
= drm_rect_height(&dst
);
723 /* check again in case clipping clamped the results */
724 hscale
= drm_rect_calc_hscale(&src
, &dst
, min_scale
, max_scale
);
726 DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n");
727 drm_rect_debug_print(&src
, true);
728 drm_rect_debug_print(&dst
, false);
733 vscale
= drm_rect_calc_vscale(&src
, &dst
, min_scale
, max_scale
);
735 DRM_DEBUG_KMS("Vertical scaling factor out of limits\n");
736 drm_rect_debug_print(&src
, true);
737 drm_rect_debug_print(&dst
, false);
742 /* Make the source viewport size an exact multiple of the scaling factors. */
743 drm_rect_adjust_size(&src
,
744 drm_rect_width(&dst
) * hscale
- drm_rect_width(&src
),
745 drm_rect_height(&dst
) * vscale
- drm_rect_height(&src
));
747 /* sanity check to make sure the src viewport wasn't enlarged */
748 WARN_ON(src
.x1
< (int) src_x
||
749 src
.y1
< (int) src_y
||
750 src
.x2
> (int) (src_x
+ src_w
) ||
751 src
.y2
> (int) (src_y
+ src_h
));
754 * Hardware doesn't handle subpixel coordinates.
755 * Adjust to (macro)pixel boundary, but be careful not to
756 * increase the source viewport size, because that could
757 * push the downscaling factor out of bounds.
759 src_x
= src
.x1
>> 16;
760 src_w
= drm_rect_width(&src
) >> 16;
761 src_y
= src
.y1
>> 16;
762 src_h
= drm_rect_height(&src
) >> 16;
764 if (format_is_yuv(fb
->pixel_format
)) {
769 * Must keep src and dst the
770 * same if we can't scale.
772 if (!intel_plane
->can_scale
)
780 /* Check size restrictions when scaling */
781 if (visible
&& (src_w
!= crtc_w
|| src_h
!= crtc_h
)) {
782 unsigned int width_bytes
;
784 WARN_ON(!intel_plane
->can_scale
);
786 /* FIXME interlacing min height is 6 */
788 if (crtc_w
< 3 || crtc_h
< 3)
791 if (src_w
< 3 || src_h
< 3)
794 width_bytes
= ((src_x
* pixel_size
) & 63) + src_w
* pixel_size
;
796 if (src_w
> 2048 || src_h
> 2048 ||
797 width_bytes
> 4096 || fb
->pitches
[0] > 4096) {
798 DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
804 dst
.x2
= crtc_x
+ crtc_w
;
806 dst
.y2
= crtc_y
+ crtc_h
;
809 * If the sprite is completely covering the primary plane,
810 * we can disable the primary and save power.
812 disable_primary
= drm_rect_equals(&dst
, &clip
);
813 WARN_ON(disable_primary
&& !visible
);
815 mutex_lock(&dev
->struct_mutex
);
817 /* Note that this will apply the VT-d workaround for scanouts,
818 * which is more restrictive than required for sprites. (The
819 * primary plane requires 256KiB alignment with 64 PTE padding,
820 * the sprite planes only require 128KiB alignment and 32 PTE padding.
822 ret
= intel_pin_and_fence_fb_obj(dev
, obj
, NULL
);
826 intel_plane
->obj
= obj
;
829 * Be sure to re-enable the primary before the sprite is no longer
832 if (!disable_primary
)
833 intel_enable_primary(crtc
);
836 intel_plane
->update_plane(plane
, crtc
, fb
, obj
,
837 crtc_x
, crtc_y
, crtc_w
, crtc_h
,
838 src_x
, src_y
, src_w
, src_h
);
840 intel_plane
->disable_plane(plane
, crtc
);
843 intel_disable_primary(crtc
);
845 /* Unpin old obj after new one is active to avoid ugliness */
848 * It's fairly common to simply update the position of
849 * an existing object. In that case, we don't need to
850 * wait for vblank to avoid ugliness, we only need to
851 * do the pin & ref bookkeeping.
853 if (old_obj
!= obj
) {
854 mutex_unlock(&dev
->struct_mutex
);
855 intel_wait_for_vblank(dev
, to_intel_crtc(crtc
)->pipe
);
856 mutex_lock(&dev
->struct_mutex
);
858 intel_unpin_fb_obj(old_obj
);
862 mutex_unlock(&dev
->struct_mutex
);
867 intel_disable_plane(struct drm_plane
*plane
)
869 struct drm_device
*dev
= plane
->dev
;
870 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
876 if (WARN_ON(!plane
->crtc
))
879 intel_enable_primary(plane
->crtc
);
880 intel_plane
->disable_plane(plane
, plane
->crtc
);
882 if (!intel_plane
->obj
)
885 intel_wait_for_vblank(dev
, intel_plane
->pipe
);
887 mutex_lock(&dev
->struct_mutex
);
888 intel_unpin_fb_obj(intel_plane
->obj
);
889 intel_plane
->obj
= NULL
;
890 mutex_unlock(&dev
->struct_mutex
);
896 static void intel_destroy_plane(struct drm_plane
*plane
)
898 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
899 intel_disable_plane(plane
);
900 drm_plane_cleanup(plane
);
904 int intel_sprite_set_colorkey(struct drm_device
*dev
, void *data
,
905 struct drm_file
*file_priv
)
907 struct drm_intel_sprite_colorkey
*set
= data
;
908 struct drm_mode_object
*obj
;
909 struct drm_plane
*plane
;
910 struct intel_plane
*intel_plane
;
913 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
916 /* Make sure we don't try to enable both src & dest simultaneously */
917 if ((set
->flags
& (I915_SET_COLORKEY_DESTINATION
| I915_SET_COLORKEY_SOURCE
)) == (I915_SET_COLORKEY_DESTINATION
| I915_SET_COLORKEY_SOURCE
))
920 drm_modeset_lock_all(dev
);
922 obj
= drm_mode_object_find(dev
, set
->plane_id
, DRM_MODE_OBJECT_PLANE
);
928 plane
= obj_to_plane(obj
);
929 intel_plane
= to_intel_plane(plane
);
930 ret
= intel_plane
->update_colorkey(plane
, set
);
933 drm_modeset_unlock_all(dev
);
937 int intel_sprite_get_colorkey(struct drm_device
*dev
, void *data
,
938 struct drm_file
*file_priv
)
940 struct drm_intel_sprite_colorkey
*get
= data
;
941 struct drm_mode_object
*obj
;
942 struct drm_plane
*plane
;
943 struct intel_plane
*intel_plane
;
946 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
949 drm_modeset_lock_all(dev
);
951 obj
= drm_mode_object_find(dev
, get
->plane_id
, DRM_MODE_OBJECT_PLANE
);
957 plane
= obj_to_plane(obj
);
958 intel_plane
= to_intel_plane(plane
);
959 intel_plane
->get_colorkey(plane
, get
);
962 drm_modeset_unlock_all(dev
);
966 void intel_plane_restore(struct drm_plane
*plane
)
968 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
970 if (!plane
->crtc
|| !plane
->fb
)
973 intel_update_plane(plane
, plane
->crtc
, plane
->fb
,
974 intel_plane
->crtc_x
, intel_plane
->crtc_y
,
975 intel_plane
->crtc_w
, intel_plane
->crtc_h
,
976 intel_plane
->src_x
, intel_plane
->src_y
,
977 intel_plane
->src_w
, intel_plane
->src_h
);
980 void intel_plane_disable(struct drm_plane
*plane
)
982 if (!plane
->crtc
|| !plane
->fb
)
985 intel_disable_plane(plane
);
988 static const struct drm_plane_funcs intel_plane_funcs
= {
989 .update_plane
= intel_update_plane
,
990 .disable_plane
= intel_disable_plane
,
991 .destroy
= intel_destroy_plane
,
994 static uint32_t ilk_plane_formats
[] = {
1002 static uint32_t snb_plane_formats
[] = {
1003 DRM_FORMAT_XBGR8888
,
1004 DRM_FORMAT_XRGB8888
,
1011 static uint32_t vlv_plane_formats
[] = {
1013 DRM_FORMAT_ABGR8888
,
1014 DRM_FORMAT_ARGB8888
,
1015 DRM_FORMAT_XBGR8888
,
1016 DRM_FORMAT_XRGB8888
,
1017 DRM_FORMAT_XBGR2101010
,
1018 DRM_FORMAT_ABGR2101010
,
1026 intel_plane_init(struct drm_device
*dev
, enum pipe pipe
, int plane
)
1028 struct intel_plane
*intel_plane
;
1029 unsigned long possible_crtcs
;
1030 const uint32_t *plane_formats
;
1031 int num_plane_formats
;
1034 if (INTEL_INFO(dev
)->gen
< 5)
1037 intel_plane
= kzalloc(sizeof(struct intel_plane
), GFP_KERNEL
);
1041 switch (INTEL_INFO(dev
)->gen
) {
1044 intel_plane
->can_scale
= true;
1045 intel_plane
->max_downscale
= 16;
1046 intel_plane
->update_plane
= ilk_update_plane
;
1047 intel_plane
->disable_plane
= ilk_disable_plane
;
1048 intel_plane
->update_colorkey
= ilk_update_colorkey
;
1049 intel_plane
->get_colorkey
= ilk_get_colorkey
;
1052 plane_formats
= snb_plane_formats
;
1053 num_plane_formats
= ARRAY_SIZE(snb_plane_formats
);
1055 plane_formats
= ilk_plane_formats
;
1056 num_plane_formats
= ARRAY_SIZE(ilk_plane_formats
);
1061 if (IS_IVYBRIDGE(dev
)) {
1062 intel_plane
->can_scale
= true;
1063 intel_plane
->max_downscale
= 2;
1065 intel_plane
->can_scale
= false;
1066 intel_plane
->max_downscale
= 1;
1069 if (IS_VALLEYVIEW(dev
)) {
1070 intel_plane
->update_plane
= vlv_update_plane
;
1071 intel_plane
->disable_plane
= vlv_disable_plane
;
1072 intel_plane
->update_colorkey
= vlv_update_colorkey
;
1073 intel_plane
->get_colorkey
= vlv_get_colorkey
;
1075 plane_formats
= vlv_plane_formats
;
1076 num_plane_formats
= ARRAY_SIZE(vlv_plane_formats
);
1078 intel_plane
->update_plane
= ivb_update_plane
;
1079 intel_plane
->disable_plane
= ivb_disable_plane
;
1080 intel_plane
->update_colorkey
= ivb_update_colorkey
;
1081 intel_plane
->get_colorkey
= ivb_get_colorkey
;
1083 plane_formats
= snb_plane_formats
;
1084 num_plane_formats
= ARRAY_SIZE(snb_plane_formats
);
1093 intel_plane
->pipe
= pipe
;
1094 intel_plane
->plane
= plane
;
1095 possible_crtcs
= (1 << pipe
);
1096 ret
= drm_plane_init(dev
, &intel_plane
->base
, possible_crtcs
,
1098 plane_formats
, num_plane_formats
,