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 "intel_drv.h"
36 #include <drm/i915_drm.h>
40 vlv_update_plane(struct drm_plane
*dplane
, struct drm_framebuffer
*fb
,
41 struct drm_i915_gem_object
*obj
, int crtc_x
, int crtc_y
,
42 unsigned int crtc_w
, unsigned int crtc_h
,
43 uint32_t x
, uint32_t y
,
44 uint32_t src_w
, uint32_t src_h
)
46 struct drm_device
*dev
= dplane
->dev
;
47 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
48 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
49 int pipe
= intel_plane
->pipe
;
50 int plane
= intel_plane
->plane
;
52 unsigned long sprsurf_offset
, linear_offset
;
53 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
55 sprctl
= I915_READ(SPCNTR(pipe
, plane
));
57 /* Mask out pixel format bits in case we change it */
58 sprctl
&= ~SP_PIXFORMAT_MASK
;
59 sprctl
&= ~SP_YUV_BYTE_ORDER_MASK
;
62 switch (fb
->pixel_format
) {
64 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_YUYV
;
67 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_YVYU
;
70 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_UYVY
;
73 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_VYUY
;
75 case DRM_FORMAT_RGB565
:
76 sprctl
|= SP_FORMAT_BGR565
;
78 case DRM_FORMAT_XRGB8888
:
79 sprctl
|= SP_FORMAT_BGRX8888
;
81 case DRM_FORMAT_ARGB8888
:
82 sprctl
|= SP_FORMAT_BGRA8888
;
84 case DRM_FORMAT_XBGR2101010
:
85 sprctl
|= SP_FORMAT_RGBX1010102
;
87 case DRM_FORMAT_ABGR2101010
:
88 sprctl
|= SP_FORMAT_RGBA1010102
;
90 case DRM_FORMAT_XBGR8888
:
91 sprctl
|= SP_FORMAT_RGBX8888
;
93 case DRM_FORMAT_ABGR8888
:
94 sprctl
|= SP_FORMAT_RGBA8888
;
98 * If we get here one of the upper layers failed to filter
99 * out the unsupported plane formats
105 if (obj
->tiling_mode
!= I915_TILING_NONE
)
110 /* Sizes are 0 based */
116 intel_update_sprite_watermarks(dev
, pipe
, crtc_w
, pixel_size
);
118 I915_WRITE(SPSTRIDE(pipe
, plane
), fb
->pitches
[0]);
119 I915_WRITE(SPPOS(pipe
, plane
), (crtc_y
<< 16) | crtc_x
);
121 linear_offset
= y
* fb
->pitches
[0] + x
* pixel_size
;
122 sprsurf_offset
= intel_gen4_compute_page_offset(&x
, &y
,
126 linear_offset
-= sprsurf_offset
;
128 if (obj
->tiling_mode
!= I915_TILING_NONE
)
129 I915_WRITE(SPTILEOFF(pipe
, plane
), (y
<< 16) | x
);
131 I915_WRITE(SPLINOFF(pipe
, plane
), linear_offset
);
133 I915_WRITE(SPSIZE(pipe
, plane
), (crtc_h
<< 16) | crtc_w
);
134 I915_WRITE(SPCNTR(pipe
, plane
), sprctl
);
135 I915_MODIFY_DISPBASE(SPSURF(pipe
, plane
), obj
->gtt_offset
+
137 POSTING_READ(SPSURF(pipe
, plane
));
141 vlv_disable_plane(struct drm_plane
*dplane
)
143 struct drm_device
*dev
= dplane
->dev
;
144 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
145 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
146 int pipe
= intel_plane
->pipe
;
147 int plane
= intel_plane
->plane
;
149 I915_WRITE(SPCNTR(pipe
, plane
), I915_READ(SPCNTR(pipe
, plane
)) &
151 /* Activate double buffered register update */
152 I915_MODIFY_DISPBASE(SPSURF(pipe
, plane
), 0);
153 POSTING_READ(SPSURF(pipe
, plane
));
157 vlv_update_colorkey(struct drm_plane
*dplane
,
158 struct drm_intel_sprite_colorkey
*key
)
160 struct drm_device
*dev
= dplane
->dev
;
161 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
162 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
163 int pipe
= intel_plane
->pipe
;
164 int plane
= intel_plane
->plane
;
167 if (key
->flags
& I915_SET_COLORKEY_DESTINATION
)
170 I915_WRITE(SPKEYMINVAL(pipe
, plane
), key
->min_value
);
171 I915_WRITE(SPKEYMAXVAL(pipe
, plane
), key
->max_value
);
172 I915_WRITE(SPKEYMSK(pipe
, plane
), key
->channel_mask
);
174 sprctl
= I915_READ(SPCNTR(pipe
, plane
));
175 sprctl
&= ~SP_SOURCE_KEY
;
176 if (key
->flags
& I915_SET_COLORKEY_SOURCE
)
177 sprctl
|= SP_SOURCE_KEY
;
178 I915_WRITE(SPCNTR(pipe
, plane
), sprctl
);
180 POSTING_READ(SPKEYMSK(pipe
, plane
));
186 vlv_get_colorkey(struct drm_plane
*dplane
,
187 struct drm_intel_sprite_colorkey
*key
)
189 struct drm_device
*dev
= dplane
->dev
;
190 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
191 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
192 int pipe
= intel_plane
->pipe
;
193 int plane
= intel_plane
->plane
;
196 key
->min_value
= I915_READ(SPKEYMINVAL(pipe
, plane
));
197 key
->max_value
= I915_READ(SPKEYMAXVAL(pipe
, plane
));
198 key
->channel_mask
= I915_READ(SPKEYMSK(pipe
, plane
));
200 sprctl
= I915_READ(SPCNTR(pipe
, plane
));
201 if (sprctl
& SP_SOURCE_KEY
)
202 key
->flags
= I915_SET_COLORKEY_SOURCE
;
204 key
->flags
= I915_SET_COLORKEY_NONE
;
208 ivb_update_plane(struct drm_plane
*plane
, struct drm_framebuffer
*fb
,
209 struct drm_i915_gem_object
*obj
, int crtc_x
, int crtc_y
,
210 unsigned int crtc_w
, unsigned int crtc_h
,
211 uint32_t x
, uint32_t y
,
212 uint32_t src_w
, uint32_t src_h
)
214 struct drm_device
*dev
= plane
->dev
;
215 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
216 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
217 int pipe
= intel_plane
->pipe
;
218 u32 sprctl
, sprscale
= 0;
219 unsigned long sprsurf_offset
, linear_offset
;
220 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
221 bool scaling_was_enabled
= dev_priv
->sprite_scaling_enabled
;
223 sprctl
= I915_READ(SPRCTL(pipe
));
225 /* Mask out pixel format bits in case we change it */
226 sprctl
&= ~SPRITE_PIXFORMAT_MASK
;
227 sprctl
&= ~SPRITE_RGB_ORDER_RGBX
;
228 sprctl
&= ~SPRITE_YUV_BYTE_ORDER_MASK
;
229 sprctl
&= ~SPRITE_TILED
;
231 switch (fb
->pixel_format
) {
232 case DRM_FORMAT_XBGR8888
:
233 sprctl
|= SPRITE_FORMAT_RGBX888
| SPRITE_RGB_ORDER_RGBX
;
235 case DRM_FORMAT_XRGB8888
:
236 sprctl
|= SPRITE_FORMAT_RGBX888
;
238 case DRM_FORMAT_YUYV
:
239 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_YUYV
;
241 case DRM_FORMAT_YVYU
:
242 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_YVYU
;
244 case DRM_FORMAT_UYVY
:
245 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_UYVY
;
247 case DRM_FORMAT_VYUY
:
248 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_VYUY
;
254 if (obj
->tiling_mode
!= I915_TILING_NONE
)
255 sprctl
|= SPRITE_TILED
;
258 sprctl
|= SPRITE_TRICKLE_FEED_DISABLE
;
259 sprctl
|= SPRITE_ENABLE
;
262 sprctl
|= SPRITE_PIPE_CSC_ENABLE
;
264 /* Sizes are 0 based */
270 intel_update_sprite_watermarks(dev
, pipe
, crtc_w
, pixel_size
);
273 * IVB workaround: must disable low power watermarks for at least
274 * one frame before enabling scaling. LP watermarks can be re-enabled
275 * when scaling is disabled.
277 if (crtc_w
!= src_w
|| crtc_h
!= src_h
) {
278 dev_priv
->sprite_scaling_enabled
|= 1 << pipe
;
280 if (!scaling_was_enabled
) {
281 intel_update_watermarks(dev
);
282 intel_wait_for_vblank(dev
, pipe
);
284 sprscale
= SPRITE_SCALE_ENABLE
| (src_w
<< 16) | src_h
;
286 dev_priv
->sprite_scaling_enabled
&= ~(1 << pipe
);
288 I915_WRITE(SPRSTRIDE(pipe
), fb
->pitches
[0]);
289 I915_WRITE(SPRPOS(pipe
), (crtc_y
<< 16) | crtc_x
);
291 linear_offset
= y
* fb
->pitches
[0] + x
* pixel_size
;
293 intel_gen4_compute_page_offset(&x
, &y
, obj
->tiling_mode
,
294 pixel_size
, fb
->pitches
[0]);
295 linear_offset
-= sprsurf_offset
;
297 /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
300 I915_WRITE(SPROFFSET(pipe
), (y
<< 16) | x
);
301 else if (obj
->tiling_mode
!= I915_TILING_NONE
)
302 I915_WRITE(SPRTILEOFF(pipe
), (y
<< 16) | x
);
304 I915_WRITE(SPRLINOFF(pipe
), linear_offset
);
306 I915_WRITE(SPRSIZE(pipe
), (crtc_h
<< 16) | crtc_w
);
307 if (intel_plane
->can_scale
)
308 I915_WRITE(SPRSCALE(pipe
), sprscale
);
309 I915_WRITE(SPRCTL(pipe
), sprctl
);
310 I915_MODIFY_DISPBASE(SPRSURF(pipe
), obj
->gtt_offset
+ sprsurf_offset
);
311 POSTING_READ(SPRSURF(pipe
));
313 /* potentially re-enable LP watermarks */
314 if (scaling_was_enabled
&& !dev_priv
->sprite_scaling_enabled
)
315 intel_update_watermarks(dev
);
319 ivb_disable_plane(struct drm_plane
*plane
)
321 struct drm_device
*dev
= plane
->dev
;
322 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
323 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
324 int pipe
= intel_plane
->pipe
;
325 bool scaling_was_enabled
= dev_priv
->sprite_scaling_enabled
;
327 I915_WRITE(SPRCTL(pipe
), I915_READ(SPRCTL(pipe
)) & ~SPRITE_ENABLE
);
328 /* Can't leave the scaler enabled... */
329 if (intel_plane
->can_scale
)
330 I915_WRITE(SPRSCALE(pipe
), 0);
331 /* Activate double buffered register update */
332 I915_MODIFY_DISPBASE(SPRSURF(pipe
), 0);
333 POSTING_READ(SPRSURF(pipe
));
335 dev_priv
->sprite_scaling_enabled
&= ~(1 << pipe
);
337 /* potentially re-enable LP watermarks */
338 if (scaling_was_enabled
&& !dev_priv
->sprite_scaling_enabled
)
339 intel_update_watermarks(dev
);
343 ivb_update_colorkey(struct drm_plane
*plane
,
344 struct drm_intel_sprite_colorkey
*key
)
346 struct drm_device
*dev
= plane
->dev
;
347 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
348 struct intel_plane
*intel_plane
;
352 intel_plane
= to_intel_plane(plane
);
354 I915_WRITE(SPRKEYVAL(intel_plane
->pipe
), key
->min_value
);
355 I915_WRITE(SPRKEYMAX(intel_plane
->pipe
), key
->max_value
);
356 I915_WRITE(SPRKEYMSK(intel_plane
->pipe
), key
->channel_mask
);
358 sprctl
= I915_READ(SPRCTL(intel_plane
->pipe
));
359 sprctl
&= ~(SPRITE_SOURCE_KEY
| SPRITE_DEST_KEY
);
360 if (key
->flags
& I915_SET_COLORKEY_DESTINATION
)
361 sprctl
|= SPRITE_DEST_KEY
;
362 else if (key
->flags
& I915_SET_COLORKEY_SOURCE
)
363 sprctl
|= SPRITE_SOURCE_KEY
;
364 I915_WRITE(SPRCTL(intel_plane
->pipe
), sprctl
);
366 POSTING_READ(SPRKEYMSK(intel_plane
->pipe
));
372 ivb_get_colorkey(struct drm_plane
*plane
, struct drm_intel_sprite_colorkey
*key
)
374 struct drm_device
*dev
= plane
->dev
;
375 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
376 struct intel_plane
*intel_plane
;
379 intel_plane
= to_intel_plane(plane
);
381 key
->min_value
= I915_READ(SPRKEYVAL(intel_plane
->pipe
));
382 key
->max_value
= I915_READ(SPRKEYMAX(intel_plane
->pipe
));
383 key
->channel_mask
= I915_READ(SPRKEYMSK(intel_plane
->pipe
));
386 sprctl
= I915_READ(SPRCTL(intel_plane
->pipe
));
388 if (sprctl
& SPRITE_DEST_KEY
)
389 key
->flags
= I915_SET_COLORKEY_DESTINATION
;
390 else if (sprctl
& SPRITE_SOURCE_KEY
)
391 key
->flags
= I915_SET_COLORKEY_SOURCE
;
393 key
->flags
= I915_SET_COLORKEY_NONE
;
397 ilk_update_plane(struct drm_plane
*plane
, struct drm_framebuffer
*fb
,
398 struct drm_i915_gem_object
*obj
, int crtc_x
, int crtc_y
,
399 unsigned int crtc_w
, unsigned int crtc_h
,
400 uint32_t x
, uint32_t y
,
401 uint32_t src_w
, uint32_t src_h
)
403 struct drm_device
*dev
= plane
->dev
;
404 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
405 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
406 int pipe
= intel_plane
->pipe
;
407 unsigned long dvssurf_offset
, linear_offset
;
408 u32 dvscntr
, dvsscale
;
409 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
411 dvscntr
= I915_READ(DVSCNTR(pipe
));
413 /* Mask out pixel format bits in case we change it */
414 dvscntr
&= ~DVS_PIXFORMAT_MASK
;
415 dvscntr
&= ~DVS_RGB_ORDER_XBGR
;
416 dvscntr
&= ~DVS_YUV_BYTE_ORDER_MASK
;
417 dvscntr
&= ~DVS_TILED
;
419 switch (fb
->pixel_format
) {
420 case DRM_FORMAT_XBGR8888
:
421 dvscntr
|= DVS_FORMAT_RGBX888
| DVS_RGB_ORDER_XBGR
;
423 case DRM_FORMAT_XRGB8888
:
424 dvscntr
|= DVS_FORMAT_RGBX888
;
426 case DRM_FORMAT_YUYV
:
427 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_YUYV
;
429 case DRM_FORMAT_YVYU
:
430 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_YVYU
;
432 case DRM_FORMAT_UYVY
:
433 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_UYVY
;
435 case DRM_FORMAT_VYUY
:
436 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_VYUY
;
442 if (obj
->tiling_mode
!= I915_TILING_NONE
)
443 dvscntr
|= DVS_TILED
;
446 dvscntr
|= DVS_TRICKLE_FEED_DISABLE
; /* must disable */
447 dvscntr
|= DVS_ENABLE
;
449 /* Sizes are 0 based */
455 intel_update_sprite_watermarks(dev
, pipe
, crtc_w
, pixel_size
);
458 if (IS_GEN5(dev
) || crtc_w
!= src_w
|| crtc_h
!= src_h
)
459 dvsscale
= DVS_SCALE_ENABLE
| (src_w
<< 16) | src_h
;
461 I915_WRITE(DVSSTRIDE(pipe
), fb
->pitches
[0]);
462 I915_WRITE(DVSPOS(pipe
), (crtc_y
<< 16) | crtc_x
);
464 linear_offset
= y
* fb
->pitches
[0] + x
* pixel_size
;
466 intel_gen4_compute_page_offset(&x
, &y
, obj
->tiling_mode
,
467 pixel_size
, fb
->pitches
[0]);
468 linear_offset
-= dvssurf_offset
;
470 if (obj
->tiling_mode
!= I915_TILING_NONE
)
471 I915_WRITE(DVSTILEOFF(pipe
), (y
<< 16) | x
);
473 I915_WRITE(DVSLINOFF(pipe
), linear_offset
);
475 I915_WRITE(DVSSIZE(pipe
), (crtc_h
<< 16) | crtc_w
);
476 I915_WRITE(DVSSCALE(pipe
), dvsscale
);
477 I915_WRITE(DVSCNTR(pipe
), dvscntr
);
478 I915_MODIFY_DISPBASE(DVSSURF(pipe
), obj
->gtt_offset
+ dvssurf_offset
);
479 POSTING_READ(DVSSURF(pipe
));
483 ilk_disable_plane(struct drm_plane
*plane
)
485 struct drm_device
*dev
= plane
->dev
;
486 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
487 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
488 int pipe
= intel_plane
->pipe
;
490 I915_WRITE(DVSCNTR(pipe
), I915_READ(DVSCNTR(pipe
)) & ~DVS_ENABLE
);
491 /* Disable the scaler */
492 I915_WRITE(DVSSCALE(pipe
), 0);
493 /* Flush double buffered register updates */
494 I915_MODIFY_DISPBASE(DVSSURF(pipe
), 0);
495 POSTING_READ(DVSSURF(pipe
));
499 intel_enable_primary(struct drm_crtc
*crtc
)
501 struct drm_device
*dev
= crtc
->dev
;
502 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
503 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
504 int reg
= DSPCNTR(intel_crtc
->plane
);
506 if (!intel_crtc
->primary_disabled
)
509 intel_crtc
->primary_disabled
= false;
510 intel_update_fbc(dev
);
512 I915_WRITE(reg
, I915_READ(reg
) | DISPLAY_PLANE_ENABLE
);
516 intel_disable_primary(struct drm_crtc
*crtc
)
518 struct drm_device
*dev
= crtc
->dev
;
519 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
520 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
521 int reg
= DSPCNTR(intel_crtc
->plane
);
523 if (intel_crtc
->primary_disabled
)
526 I915_WRITE(reg
, I915_READ(reg
) & ~DISPLAY_PLANE_ENABLE
);
528 intel_crtc
->primary_disabled
= true;
529 intel_update_fbc(dev
);
533 ilk_update_colorkey(struct drm_plane
*plane
,
534 struct drm_intel_sprite_colorkey
*key
)
536 struct drm_device
*dev
= plane
->dev
;
537 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
538 struct intel_plane
*intel_plane
;
542 intel_plane
= to_intel_plane(plane
);
544 I915_WRITE(DVSKEYVAL(intel_plane
->pipe
), key
->min_value
);
545 I915_WRITE(DVSKEYMAX(intel_plane
->pipe
), key
->max_value
);
546 I915_WRITE(DVSKEYMSK(intel_plane
->pipe
), key
->channel_mask
);
548 dvscntr
= I915_READ(DVSCNTR(intel_plane
->pipe
));
549 dvscntr
&= ~(DVS_SOURCE_KEY
| DVS_DEST_KEY
);
550 if (key
->flags
& I915_SET_COLORKEY_DESTINATION
)
551 dvscntr
|= DVS_DEST_KEY
;
552 else if (key
->flags
& I915_SET_COLORKEY_SOURCE
)
553 dvscntr
|= DVS_SOURCE_KEY
;
554 I915_WRITE(DVSCNTR(intel_plane
->pipe
), dvscntr
);
556 POSTING_READ(DVSKEYMSK(intel_plane
->pipe
));
562 ilk_get_colorkey(struct drm_plane
*plane
, struct drm_intel_sprite_colorkey
*key
)
564 struct drm_device
*dev
= plane
->dev
;
565 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
566 struct intel_plane
*intel_plane
;
569 intel_plane
= to_intel_plane(plane
);
571 key
->min_value
= I915_READ(DVSKEYVAL(intel_plane
->pipe
));
572 key
->max_value
= I915_READ(DVSKEYMAX(intel_plane
->pipe
));
573 key
->channel_mask
= I915_READ(DVSKEYMSK(intel_plane
->pipe
));
576 dvscntr
= I915_READ(DVSCNTR(intel_plane
->pipe
));
578 if (dvscntr
& DVS_DEST_KEY
)
579 key
->flags
= I915_SET_COLORKEY_DESTINATION
;
580 else if (dvscntr
& DVS_SOURCE_KEY
)
581 key
->flags
= I915_SET_COLORKEY_SOURCE
;
583 key
->flags
= I915_SET_COLORKEY_NONE
;
587 intel_update_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
,
588 struct drm_framebuffer
*fb
, int crtc_x
, int crtc_y
,
589 unsigned int crtc_w
, unsigned int crtc_h
,
590 uint32_t src_x
, uint32_t src_y
,
591 uint32_t src_w
, uint32_t src_h
)
593 struct drm_device
*dev
= plane
->dev
;
594 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
595 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
596 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
597 struct intel_framebuffer
*intel_fb
;
598 struct drm_i915_gem_object
*obj
, *old_obj
;
599 int pipe
= intel_plane
->pipe
;
600 enum transcoder cpu_transcoder
= intel_pipe_to_cpu_transcoder(dev_priv
,
603 int x
= src_x
>> 16, y
= src_y
>> 16;
604 int primary_w
= crtc
->mode
.hdisplay
, primary_h
= crtc
->mode
.vdisplay
;
605 bool disable_primary
= false;
607 intel_fb
= to_intel_framebuffer(fb
);
610 old_obj
= intel_plane
->obj
;
612 intel_plane
->crtc_x
= crtc_x
;
613 intel_plane
->crtc_y
= crtc_y
;
614 intel_plane
->crtc_w
= crtc_w
;
615 intel_plane
->crtc_h
= crtc_h
;
616 intel_plane
->src_x
= src_x
;
617 intel_plane
->src_y
= src_y
;
618 intel_plane
->src_w
= src_w
;
619 intel_plane
->src_h
= src_h
;
624 /* Pipe must be running... */
625 if (!(I915_READ(PIPECONF(cpu_transcoder
)) & PIPECONF_ENABLE
))
628 if (crtc_x
>= primary_w
|| crtc_y
>= primary_h
)
631 /* Don't modify another pipe's plane */
632 if (intel_plane
->pipe
!= intel_crtc
->pipe
)
635 /* Sprite planes can be linear or x-tiled surfaces */
636 switch (obj
->tiling_mode
) {
637 case I915_TILING_NONE
:
645 * Clamp the width & height into the visible area. Note we don't
646 * try to scale the source if part of the visible region is offscreen.
647 * The caller must handle that by adjusting source offset and size.
649 if ((crtc_x
< 0) && ((crtc_x
+ crtc_w
) > 0)) {
653 if ((crtc_x
+ crtc_w
) <= 0) /* Nothing to display */
655 if ((crtc_x
+ crtc_w
) > primary_w
)
656 crtc_w
= primary_w
- crtc_x
;
658 if ((crtc_y
< 0) && ((crtc_y
+ crtc_h
) > 0)) {
662 if ((crtc_y
+ crtc_h
) <= 0) /* Nothing to display */
664 if (crtc_y
+ crtc_h
> primary_h
)
665 crtc_h
= primary_h
- crtc_y
;
667 if (!crtc_w
|| !crtc_h
) /* Again, nothing to display */
671 * We may not have a scaler, eg. HSW does not have it any more
673 if (!intel_plane
->can_scale
&& (crtc_w
!= src_w
|| crtc_h
!= src_h
))
677 * We can take a larger source and scale it down, but
678 * only so much... 16x is the max on SNB.
680 if (((src_w
* src_h
) / (crtc_w
* crtc_h
)) > intel_plane
->max_downscale
)
684 * If the sprite is completely covering the primary plane,
685 * we can disable the primary and save power.
687 if ((crtc_x
== 0) && (crtc_y
== 0) &&
688 (crtc_w
== primary_w
) && (crtc_h
== primary_h
))
689 disable_primary
= true;
691 mutex_lock(&dev
->struct_mutex
);
693 /* Note that this will apply the VT-d workaround for scanouts,
694 * which is more restrictive than required for sprites. (The
695 * primary plane requires 256KiB alignment with 64 PTE padding,
696 * the sprite planes only require 128KiB alignment and 32 PTE padding.
698 ret
= intel_pin_and_fence_fb_obj(dev
, obj
, NULL
);
702 intel_plane
->obj
= obj
;
705 * Be sure to re-enable the primary before the sprite is no longer
708 if (!disable_primary
)
709 intel_enable_primary(crtc
);
711 intel_plane
->update_plane(plane
, fb
, obj
, crtc_x
, crtc_y
,
712 crtc_w
, crtc_h
, x
, y
, src_w
, src_h
);
715 intel_disable_primary(crtc
);
717 /* Unpin old obj after new one is active to avoid ugliness */
720 * It's fairly common to simply update the position of
721 * an existing object. In that case, we don't need to
722 * wait for vblank to avoid ugliness, we only need to
723 * do the pin & ref bookkeeping.
725 if (old_obj
!= obj
) {
726 mutex_unlock(&dev
->struct_mutex
);
727 intel_wait_for_vblank(dev
, to_intel_crtc(crtc
)->pipe
);
728 mutex_lock(&dev
->struct_mutex
);
730 intel_unpin_fb_obj(old_obj
);
734 mutex_unlock(&dev
->struct_mutex
);
740 intel_disable_plane(struct drm_plane
*plane
)
742 struct drm_device
*dev
= plane
->dev
;
743 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
747 intel_enable_primary(plane
->crtc
);
748 intel_plane
->disable_plane(plane
);
750 if (!intel_plane
->obj
)
753 intel_wait_for_vblank(dev
, intel_plane
->pipe
);
755 mutex_lock(&dev
->struct_mutex
);
756 intel_unpin_fb_obj(intel_plane
->obj
);
757 intel_plane
->obj
= NULL
;
758 mutex_unlock(&dev
->struct_mutex
);
764 static void intel_destroy_plane(struct drm_plane
*plane
)
766 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
767 intel_disable_plane(plane
);
768 drm_plane_cleanup(plane
);
772 int intel_sprite_set_colorkey(struct drm_device
*dev
, void *data
,
773 struct drm_file
*file_priv
)
775 struct drm_intel_sprite_colorkey
*set
= data
;
776 struct drm_mode_object
*obj
;
777 struct drm_plane
*plane
;
778 struct intel_plane
*intel_plane
;
781 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
784 /* Make sure we don't try to enable both src & dest simultaneously */
785 if ((set
->flags
& (I915_SET_COLORKEY_DESTINATION
| I915_SET_COLORKEY_SOURCE
)) == (I915_SET_COLORKEY_DESTINATION
| I915_SET_COLORKEY_SOURCE
))
788 drm_modeset_lock_all(dev
);
790 obj
= drm_mode_object_find(dev
, set
->plane_id
, DRM_MODE_OBJECT_PLANE
);
796 plane
= obj_to_plane(obj
);
797 intel_plane
= to_intel_plane(plane
);
798 ret
= intel_plane
->update_colorkey(plane
, set
);
801 drm_modeset_unlock_all(dev
);
805 int intel_sprite_get_colorkey(struct drm_device
*dev
, void *data
,
806 struct drm_file
*file_priv
)
808 struct drm_intel_sprite_colorkey
*get
= data
;
809 struct drm_mode_object
*obj
;
810 struct drm_plane
*plane
;
811 struct intel_plane
*intel_plane
;
814 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
817 drm_modeset_lock_all(dev
);
819 obj
= drm_mode_object_find(dev
, get
->plane_id
, DRM_MODE_OBJECT_PLANE
);
825 plane
= obj_to_plane(obj
);
826 intel_plane
= to_intel_plane(plane
);
827 intel_plane
->get_colorkey(plane
, get
);
830 drm_modeset_unlock_all(dev
);
834 void intel_plane_restore(struct drm_plane
*plane
)
836 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
838 if (!plane
->crtc
|| !plane
->fb
)
841 intel_update_plane(plane
, plane
->crtc
, plane
->fb
,
842 intel_plane
->crtc_x
, intel_plane
->crtc_y
,
843 intel_plane
->crtc_w
, intel_plane
->crtc_h
,
844 intel_plane
->src_x
, intel_plane
->src_y
,
845 intel_plane
->src_w
, intel_plane
->src_h
);
848 static const struct drm_plane_funcs intel_plane_funcs
= {
849 .update_plane
= intel_update_plane
,
850 .disable_plane
= intel_disable_plane
,
851 .destroy
= intel_destroy_plane
,
854 static uint32_t ilk_plane_formats
[] = {
862 static uint32_t snb_plane_formats
[] = {
871 static uint32_t vlv_plane_formats
[] = {
877 DRM_FORMAT_XBGR2101010
,
878 DRM_FORMAT_ABGR2101010
,
886 intel_plane_init(struct drm_device
*dev
, enum pipe pipe
, int plane
)
888 struct intel_plane
*intel_plane
;
889 unsigned long possible_crtcs
;
890 const uint32_t *plane_formats
;
891 int num_plane_formats
;
894 if (INTEL_INFO(dev
)->gen
< 5)
897 intel_plane
= kzalloc(sizeof(struct intel_plane
), GFP_KERNEL
);
901 switch (INTEL_INFO(dev
)->gen
) {
904 intel_plane
->can_scale
= true;
905 intel_plane
->max_downscale
= 16;
906 intel_plane
->update_plane
= ilk_update_plane
;
907 intel_plane
->disable_plane
= ilk_disable_plane
;
908 intel_plane
->update_colorkey
= ilk_update_colorkey
;
909 intel_plane
->get_colorkey
= ilk_get_colorkey
;
912 plane_formats
= snb_plane_formats
;
913 num_plane_formats
= ARRAY_SIZE(snb_plane_formats
);
915 plane_formats
= ilk_plane_formats
;
916 num_plane_formats
= ARRAY_SIZE(ilk_plane_formats
);
921 if (IS_HASWELL(dev
) || IS_VALLEYVIEW(dev
))
922 intel_plane
->can_scale
= false;
924 intel_plane
->can_scale
= true;
926 if (IS_VALLEYVIEW(dev
)) {
927 intel_plane
->max_downscale
= 1;
928 intel_plane
->update_plane
= vlv_update_plane
;
929 intel_plane
->disable_plane
= vlv_disable_plane
;
930 intel_plane
->update_colorkey
= vlv_update_colorkey
;
931 intel_plane
->get_colorkey
= vlv_get_colorkey
;
933 plane_formats
= vlv_plane_formats
;
934 num_plane_formats
= ARRAY_SIZE(vlv_plane_formats
);
936 intel_plane
->max_downscale
= 2;
937 intel_plane
->update_plane
= ivb_update_plane
;
938 intel_plane
->disable_plane
= ivb_disable_plane
;
939 intel_plane
->update_colorkey
= ivb_update_colorkey
;
940 intel_plane
->get_colorkey
= ivb_get_colorkey
;
942 plane_formats
= snb_plane_formats
;
943 num_plane_formats
= ARRAY_SIZE(snb_plane_formats
);
952 intel_plane
->pipe
= pipe
;
953 intel_plane
->plane
= plane
;
954 possible_crtcs
= (1 << pipe
);
955 ret
= drm_plane_init(dev
, &intel_plane
->base
, possible_crtcs
,
957 plane_formats
, num_plane_formats
,