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
;
56 wait_queue_head_t
*wq
= drm_crtc_vblank_waitqueue(&crtc
->base
);
59 WARN_ON(!drm_modeset_is_locked(&crtc
->base
.mutex
));
61 vblank_start
= mode
->crtc_vblank_start
;
62 if (mode
->flags
& DRM_MODE_FLAG_INTERLACE
)
63 vblank_start
= DIV_ROUND_UP(vblank_start
, 2);
65 /* FIXME needs to be calibrated sensibly */
66 min
= vblank_start
- usecs_to_scanlines(mode
, 100);
67 max
= vblank_start
- 1;
69 if (min
<= 0 || max
<= 0)
72 if (WARN_ON(drm_vblank_get(dev
, pipe
)))
77 trace_i915_pipe_update_start(crtc
, min
, max
);
81 * prepare_to_wait() has a memory barrier, which guarantees
82 * other CPUs can see the task state update by the time we
85 prepare_to_wait(wq
, &wait
, TASK_UNINTERRUPTIBLE
);
87 scanline
= intel_get_crtc_scanline(crtc
);
88 if (scanline
< min
|| scanline
> max
)
92 DRM_ERROR("Potential atomic update failure on pipe %c\n",
93 pipe_name(crtc
->pipe
));
99 timeout
= schedule_timeout(timeout
);
104 finish_wait(wq
, &wait
);
106 drm_vblank_put(dev
, pipe
);
108 *start_vbl_count
= dev
->driver
->get_vblank_counter(dev
, pipe
);
110 trace_i915_pipe_update_vblank_evaded(crtc
, min
, max
, *start_vbl_count
);
115 static void intel_pipe_update_end(struct intel_crtc
*crtc
, u32 start_vbl_count
)
117 struct drm_device
*dev
= crtc
->base
.dev
;
118 enum pipe pipe
= crtc
->pipe
;
119 u32 end_vbl_count
= dev
->driver
->get_vblank_counter(dev
, pipe
);
121 trace_i915_pipe_update_end(crtc
, end_vbl_count
);
125 if (start_vbl_count
!= end_vbl_count
)
126 DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u)\n",
127 pipe_name(pipe
), start_vbl_count
, end_vbl_count
);
130 static void intel_update_primary_plane(struct intel_crtc
*crtc
)
132 struct drm_i915_private
*dev_priv
= crtc
->base
.dev
->dev_private
;
133 int reg
= DSPCNTR(crtc
->plane
);
135 if (crtc
->primary_enabled
)
136 I915_WRITE(reg
, I915_READ(reg
) | DISPLAY_PLANE_ENABLE
);
138 I915_WRITE(reg
, I915_READ(reg
) & ~DISPLAY_PLANE_ENABLE
);
142 vlv_update_plane(struct drm_plane
*dplane
, struct drm_crtc
*crtc
,
143 struct drm_framebuffer
*fb
,
144 struct drm_i915_gem_object
*obj
, int crtc_x
, int crtc_y
,
145 unsigned int crtc_w
, unsigned int crtc_h
,
146 uint32_t x
, uint32_t y
,
147 uint32_t src_w
, uint32_t src_h
)
149 struct drm_device
*dev
= dplane
->dev
;
150 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
151 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
152 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
153 int pipe
= intel_plane
->pipe
;
154 int plane
= intel_plane
->plane
;
156 unsigned long sprsurf_offset
, linear_offset
;
157 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
161 sprctl
= I915_READ(SPCNTR(pipe
, plane
));
163 /* Mask out pixel format bits in case we change it */
164 sprctl
&= ~SP_PIXFORMAT_MASK
;
165 sprctl
&= ~SP_YUV_BYTE_ORDER_MASK
;
167 sprctl
&= ~SP_ROTATE_180
;
169 switch (fb
->pixel_format
) {
170 case DRM_FORMAT_YUYV
:
171 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_YUYV
;
173 case DRM_FORMAT_YVYU
:
174 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_YVYU
;
176 case DRM_FORMAT_UYVY
:
177 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_UYVY
;
179 case DRM_FORMAT_VYUY
:
180 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_VYUY
;
182 case DRM_FORMAT_RGB565
:
183 sprctl
|= SP_FORMAT_BGR565
;
185 case DRM_FORMAT_XRGB8888
:
186 sprctl
|= SP_FORMAT_BGRX8888
;
188 case DRM_FORMAT_ARGB8888
:
189 sprctl
|= SP_FORMAT_BGRA8888
;
191 case DRM_FORMAT_XBGR2101010
:
192 sprctl
|= SP_FORMAT_RGBX1010102
;
194 case DRM_FORMAT_ABGR2101010
:
195 sprctl
|= SP_FORMAT_RGBA1010102
;
197 case DRM_FORMAT_XBGR8888
:
198 sprctl
|= SP_FORMAT_RGBX8888
;
200 case DRM_FORMAT_ABGR8888
:
201 sprctl
|= SP_FORMAT_RGBA8888
;
205 * If we get here one of the upper layers failed to filter
206 * out the unsupported plane formats
213 * Enable gamma to match primary/cursor plane behaviour.
214 * FIXME should be user controllable via propertiesa.
216 sprctl
|= SP_GAMMA_ENABLE
;
218 if (obj
->tiling_mode
!= I915_TILING_NONE
)
223 intel_update_sprite_watermarks(dplane
, crtc
, src_w
, src_h
,
225 src_w
!= crtc_w
|| src_h
!= crtc_h
);
227 /* Sizes are 0 based */
233 linear_offset
= y
* fb
->pitches
[0] + x
* pixel_size
;
234 sprsurf_offset
= intel_gen4_compute_page_offset(&x
, &y
,
238 linear_offset
-= sprsurf_offset
;
240 if (intel_plane
->rotation
== BIT(DRM_ROTATE_180
)) {
241 sprctl
|= SP_ROTATE_180
;
245 linear_offset
+= src_h
* fb
->pitches
[0] + src_w
* pixel_size
;
248 atomic_update
= intel_pipe_update_start(intel_crtc
, &start_vbl_count
);
250 intel_update_primary_plane(intel_crtc
);
252 I915_WRITE(SPSTRIDE(pipe
, plane
), fb
->pitches
[0]);
253 I915_WRITE(SPPOS(pipe
, plane
), (crtc_y
<< 16) | crtc_x
);
255 if (obj
->tiling_mode
!= I915_TILING_NONE
)
256 I915_WRITE(SPTILEOFF(pipe
, plane
), (y
<< 16) | x
);
258 I915_WRITE(SPLINOFF(pipe
, plane
), linear_offset
);
260 I915_WRITE(SPSIZE(pipe
, plane
), (crtc_h
<< 16) | crtc_w
);
261 I915_WRITE(SPCNTR(pipe
, plane
), sprctl
);
262 I915_WRITE(SPSURF(pipe
, plane
), i915_gem_obj_ggtt_offset(obj
) +
265 intel_flush_primary_plane(dev_priv
, intel_crtc
->plane
);
268 intel_pipe_update_end(intel_crtc
, start_vbl_count
);
272 vlv_disable_plane(struct drm_plane
*dplane
, struct drm_crtc
*crtc
)
274 struct drm_device
*dev
= dplane
->dev
;
275 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
276 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
277 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
278 int pipe
= intel_plane
->pipe
;
279 int plane
= intel_plane
->plane
;
283 atomic_update
= intel_pipe_update_start(intel_crtc
, &start_vbl_count
);
285 intel_update_primary_plane(intel_crtc
);
287 I915_WRITE(SPCNTR(pipe
, plane
), I915_READ(SPCNTR(pipe
, plane
)) &
289 /* Activate double buffered register update */
290 I915_WRITE(SPSURF(pipe
, plane
), 0);
292 intel_flush_primary_plane(dev_priv
, intel_crtc
->plane
);
295 intel_pipe_update_end(intel_crtc
, start_vbl_count
);
297 intel_update_sprite_watermarks(dplane
, crtc
, 0, 0, 0, false, false);
301 vlv_update_colorkey(struct drm_plane
*dplane
,
302 struct drm_intel_sprite_colorkey
*key
)
304 struct drm_device
*dev
= dplane
->dev
;
305 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
306 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
307 int pipe
= intel_plane
->pipe
;
308 int plane
= intel_plane
->plane
;
311 if (key
->flags
& I915_SET_COLORKEY_DESTINATION
)
314 I915_WRITE(SPKEYMINVAL(pipe
, plane
), key
->min_value
);
315 I915_WRITE(SPKEYMAXVAL(pipe
, plane
), key
->max_value
);
316 I915_WRITE(SPKEYMSK(pipe
, plane
), key
->channel_mask
);
318 sprctl
= I915_READ(SPCNTR(pipe
, plane
));
319 sprctl
&= ~SP_SOURCE_KEY
;
320 if (key
->flags
& I915_SET_COLORKEY_SOURCE
)
321 sprctl
|= SP_SOURCE_KEY
;
322 I915_WRITE(SPCNTR(pipe
, plane
), sprctl
);
324 POSTING_READ(SPKEYMSK(pipe
, plane
));
330 vlv_get_colorkey(struct drm_plane
*dplane
,
331 struct drm_intel_sprite_colorkey
*key
)
333 struct drm_device
*dev
= dplane
->dev
;
334 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
335 struct intel_plane
*intel_plane
= to_intel_plane(dplane
);
336 int pipe
= intel_plane
->pipe
;
337 int plane
= intel_plane
->plane
;
340 key
->min_value
= I915_READ(SPKEYMINVAL(pipe
, plane
));
341 key
->max_value
= I915_READ(SPKEYMAXVAL(pipe
, plane
));
342 key
->channel_mask
= I915_READ(SPKEYMSK(pipe
, plane
));
344 sprctl
= I915_READ(SPCNTR(pipe
, plane
));
345 if (sprctl
& SP_SOURCE_KEY
)
346 key
->flags
= I915_SET_COLORKEY_SOURCE
;
348 key
->flags
= I915_SET_COLORKEY_NONE
;
352 ivb_update_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
,
353 struct drm_framebuffer
*fb
,
354 struct drm_i915_gem_object
*obj
, int crtc_x
, int crtc_y
,
355 unsigned int crtc_w
, unsigned int crtc_h
,
356 uint32_t x
, uint32_t y
,
357 uint32_t src_w
, uint32_t src_h
)
359 struct drm_device
*dev
= plane
->dev
;
360 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
361 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
362 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
363 int pipe
= intel_plane
->pipe
;
364 u32 sprctl
, sprscale
= 0;
365 unsigned long sprsurf_offset
, linear_offset
;
366 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
370 sprctl
= I915_READ(SPRCTL(pipe
));
372 /* Mask out pixel format bits in case we change it */
373 sprctl
&= ~SPRITE_PIXFORMAT_MASK
;
374 sprctl
&= ~SPRITE_RGB_ORDER_RGBX
;
375 sprctl
&= ~SPRITE_YUV_BYTE_ORDER_MASK
;
376 sprctl
&= ~SPRITE_TILED
;
377 sprctl
&= ~SPRITE_ROTATE_180
;
379 switch (fb
->pixel_format
) {
380 case DRM_FORMAT_XBGR8888
:
381 sprctl
|= SPRITE_FORMAT_RGBX888
| SPRITE_RGB_ORDER_RGBX
;
383 case DRM_FORMAT_XRGB8888
:
384 sprctl
|= SPRITE_FORMAT_RGBX888
;
386 case DRM_FORMAT_YUYV
:
387 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_YUYV
;
389 case DRM_FORMAT_YVYU
:
390 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_YVYU
;
392 case DRM_FORMAT_UYVY
:
393 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_UYVY
;
395 case DRM_FORMAT_VYUY
:
396 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_VYUY
;
403 * Enable gamma to match primary/cursor plane behaviour.
404 * FIXME should be user controllable via propertiesa.
406 sprctl
|= SPRITE_GAMMA_ENABLE
;
408 if (obj
->tiling_mode
!= I915_TILING_NONE
)
409 sprctl
|= SPRITE_TILED
;
411 if (IS_HASWELL(dev
) || IS_BROADWELL(dev
))
412 sprctl
&= ~SPRITE_TRICKLE_FEED_DISABLE
;
414 sprctl
|= SPRITE_TRICKLE_FEED_DISABLE
;
416 sprctl
|= SPRITE_ENABLE
;
418 if (IS_HASWELL(dev
) || IS_BROADWELL(dev
))
419 sprctl
|= SPRITE_PIPE_CSC_ENABLE
;
421 intel_update_sprite_watermarks(plane
, crtc
, src_w
, src_h
, pixel_size
,
423 src_w
!= crtc_w
|| src_h
!= crtc_h
);
425 /* Sizes are 0 based */
431 if (crtc_w
!= src_w
|| crtc_h
!= src_h
)
432 sprscale
= SPRITE_SCALE_ENABLE
| (src_w
<< 16) | src_h
;
434 linear_offset
= y
* fb
->pitches
[0] + x
* pixel_size
;
436 intel_gen4_compute_page_offset(&x
, &y
, obj
->tiling_mode
,
437 pixel_size
, fb
->pitches
[0]);
438 linear_offset
-= sprsurf_offset
;
440 if (intel_plane
->rotation
== BIT(DRM_ROTATE_180
)) {
441 sprctl
|= SPRITE_ROTATE_180
;
443 /* HSW and BDW does this automagically in hardware */
444 if (!IS_HASWELL(dev
) && !IS_BROADWELL(dev
)) {
447 linear_offset
+= src_h
* fb
->pitches
[0] +
452 atomic_update
= intel_pipe_update_start(intel_crtc
, &start_vbl_count
);
454 intel_update_primary_plane(intel_crtc
);
456 I915_WRITE(SPRSTRIDE(pipe
), fb
->pitches
[0]);
457 I915_WRITE(SPRPOS(pipe
), (crtc_y
<< 16) | crtc_x
);
459 /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
461 if (IS_HASWELL(dev
) || IS_BROADWELL(dev
))
462 I915_WRITE(SPROFFSET(pipe
), (y
<< 16) | x
);
463 else if (obj
->tiling_mode
!= I915_TILING_NONE
)
464 I915_WRITE(SPRTILEOFF(pipe
), (y
<< 16) | x
);
466 I915_WRITE(SPRLINOFF(pipe
), linear_offset
);
468 I915_WRITE(SPRSIZE(pipe
), (crtc_h
<< 16) | crtc_w
);
469 if (intel_plane
->can_scale
)
470 I915_WRITE(SPRSCALE(pipe
), sprscale
);
471 I915_WRITE(SPRCTL(pipe
), sprctl
);
472 I915_WRITE(SPRSURF(pipe
),
473 i915_gem_obj_ggtt_offset(obj
) + sprsurf_offset
);
475 intel_flush_primary_plane(dev_priv
, intel_crtc
->plane
);
478 intel_pipe_update_end(intel_crtc
, start_vbl_count
);
482 ivb_disable_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
)
484 struct drm_device
*dev
= plane
->dev
;
485 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
486 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
487 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
488 int pipe
= intel_plane
->pipe
;
492 atomic_update
= intel_pipe_update_start(intel_crtc
, &start_vbl_count
);
494 intel_update_primary_plane(intel_crtc
);
496 I915_WRITE(SPRCTL(pipe
), I915_READ(SPRCTL(pipe
)) & ~SPRITE_ENABLE
);
497 /* Can't leave the scaler enabled... */
498 if (intel_plane
->can_scale
)
499 I915_WRITE(SPRSCALE(pipe
), 0);
500 /* Activate double buffered register update */
501 I915_WRITE(SPRSURF(pipe
), 0);
503 intel_flush_primary_plane(dev_priv
, intel_crtc
->plane
);
506 intel_pipe_update_end(intel_crtc
, start_vbl_count
);
509 * Avoid underruns when disabling the sprite.
510 * FIXME remove once watermark updates are done properly.
512 intel_wait_for_vblank(dev
, pipe
);
514 intel_update_sprite_watermarks(plane
, crtc
, 0, 0, 0, false, false);
518 ivb_update_colorkey(struct drm_plane
*plane
,
519 struct drm_intel_sprite_colorkey
*key
)
521 struct drm_device
*dev
= plane
->dev
;
522 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
523 struct intel_plane
*intel_plane
;
527 intel_plane
= to_intel_plane(plane
);
529 I915_WRITE(SPRKEYVAL(intel_plane
->pipe
), key
->min_value
);
530 I915_WRITE(SPRKEYMAX(intel_plane
->pipe
), key
->max_value
);
531 I915_WRITE(SPRKEYMSK(intel_plane
->pipe
), key
->channel_mask
);
533 sprctl
= I915_READ(SPRCTL(intel_plane
->pipe
));
534 sprctl
&= ~(SPRITE_SOURCE_KEY
| SPRITE_DEST_KEY
);
535 if (key
->flags
& I915_SET_COLORKEY_DESTINATION
)
536 sprctl
|= SPRITE_DEST_KEY
;
537 else if (key
->flags
& I915_SET_COLORKEY_SOURCE
)
538 sprctl
|= SPRITE_SOURCE_KEY
;
539 I915_WRITE(SPRCTL(intel_plane
->pipe
), sprctl
);
541 POSTING_READ(SPRKEYMSK(intel_plane
->pipe
));
547 ivb_get_colorkey(struct drm_plane
*plane
, struct drm_intel_sprite_colorkey
*key
)
549 struct drm_device
*dev
= plane
->dev
;
550 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
551 struct intel_plane
*intel_plane
;
554 intel_plane
= to_intel_plane(plane
);
556 key
->min_value
= I915_READ(SPRKEYVAL(intel_plane
->pipe
));
557 key
->max_value
= I915_READ(SPRKEYMAX(intel_plane
->pipe
));
558 key
->channel_mask
= I915_READ(SPRKEYMSK(intel_plane
->pipe
));
561 sprctl
= I915_READ(SPRCTL(intel_plane
->pipe
));
563 if (sprctl
& SPRITE_DEST_KEY
)
564 key
->flags
= I915_SET_COLORKEY_DESTINATION
;
565 else if (sprctl
& SPRITE_SOURCE_KEY
)
566 key
->flags
= I915_SET_COLORKEY_SOURCE
;
568 key
->flags
= I915_SET_COLORKEY_NONE
;
572 ilk_update_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
,
573 struct drm_framebuffer
*fb
,
574 struct drm_i915_gem_object
*obj
, int crtc_x
, int crtc_y
,
575 unsigned int crtc_w
, unsigned int crtc_h
,
576 uint32_t x
, uint32_t y
,
577 uint32_t src_w
, uint32_t src_h
)
579 struct drm_device
*dev
= plane
->dev
;
580 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
581 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
582 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
583 int pipe
= intel_plane
->pipe
;
584 unsigned long dvssurf_offset
, linear_offset
;
585 u32 dvscntr
, dvsscale
;
586 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
590 dvscntr
= I915_READ(DVSCNTR(pipe
));
592 /* Mask out pixel format bits in case we change it */
593 dvscntr
&= ~DVS_PIXFORMAT_MASK
;
594 dvscntr
&= ~DVS_RGB_ORDER_XBGR
;
595 dvscntr
&= ~DVS_YUV_BYTE_ORDER_MASK
;
596 dvscntr
&= ~DVS_TILED
;
597 dvscntr
&= ~DVS_ROTATE_180
;
599 switch (fb
->pixel_format
) {
600 case DRM_FORMAT_XBGR8888
:
601 dvscntr
|= DVS_FORMAT_RGBX888
| DVS_RGB_ORDER_XBGR
;
603 case DRM_FORMAT_XRGB8888
:
604 dvscntr
|= DVS_FORMAT_RGBX888
;
606 case DRM_FORMAT_YUYV
:
607 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_YUYV
;
609 case DRM_FORMAT_YVYU
:
610 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_YVYU
;
612 case DRM_FORMAT_UYVY
:
613 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_UYVY
;
615 case DRM_FORMAT_VYUY
:
616 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_VYUY
;
623 * Enable gamma to match primary/cursor plane behaviour.
624 * FIXME should be user controllable via propertiesa.
626 dvscntr
|= DVS_GAMMA_ENABLE
;
628 if (obj
->tiling_mode
!= I915_TILING_NONE
)
629 dvscntr
|= DVS_TILED
;
632 dvscntr
|= DVS_TRICKLE_FEED_DISABLE
; /* must disable */
633 dvscntr
|= DVS_ENABLE
;
635 intel_update_sprite_watermarks(plane
, crtc
, src_w
, src_h
,
637 src_w
!= crtc_w
|| src_h
!= crtc_h
);
639 /* Sizes are 0 based */
646 if (crtc_w
!= src_w
|| crtc_h
!= src_h
)
647 dvsscale
= DVS_SCALE_ENABLE
| (src_w
<< 16) | src_h
;
649 linear_offset
= y
* fb
->pitches
[0] + x
* pixel_size
;
651 intel_gen4_compute_page_offset(&x
, &y
, obj
->tiling_mode
,
652 pixel_size
, fb
->pitches
[0]);
653 linear_offset
-= dvssurf_offset
;
655 if (intel_plane
->rotation
== BIT(DRM_ROTATE_180
)) {
656 dvscntr
|= DVS_ROTATE_180
;
660 linear_offset
+= src_h
* fb
->pitches
[0] + src_w
* pixel_size
;
663 atomic_update
= intel_pipe_update_start(intel_crtc
, &start_vbl_count
);
665 intel_update_primary_plane(intel_crtc
);
667 I915_WRITE(DVSSTRIDE(pipe
), fb
->pitches
[0]);
668 I915_WRITE(DVSPOS(pipe
), (crtc_y
<< 16) | crtc_x
);
670 if (obj
->tiling_mode
!= I915_TILING_NONE
)
671 I915_WRITE(DVSTILEOFF(pipe
), (y
<< 16) | x
);
673 I915_WRITE(DVSLINOFF(pipe
), linear_offset
);
675 I915_WRITE(DVSSIZE(pipe
), (crtc_h
<< 16) | crtc_w
);
676 I915_WRITE(DVSSCALE(pipe
), dvsscale
);
677 I915_WRITE(DVSCNTR(pipe
), dvscntr
);
678 I915_WRITE(DVSSURF(pipe
),
679 i915_gem_obj_ggtt_offset(obj
) + dvssurf_offset
);
681 intel_flush_primary_plane(dev_priv
, intel_crtc
->plane
);
684 intel_pipe_update_end(intel_crtc
, start_vbl_count
);
688 ilk_disable_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
)
690 struct drm_device
*dev
= plane
->dev
;
691 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
692 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
693 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
694 int pipe
= intel_plane
->pipe
;
698 atomic_update
= intel_pipe_update_start(intel_crtc
, &start_vbl_count
);
700 intel_update_primary_plane(intel_crtc
);
702 I915_WRITE(DVSCNTR(pipe
), I915_READ(DVSCNTR(pipe
)) & ~DVS_ENABLE
);
703 /* Disable the scaler */
704 I915_WRITE(DVSSCALE(pipe
), 0);
705 /* Flush double buffered register updates */
706 I915_WRITE(DVSSURF(pipe
), 0);
708 intel_flush_primary_plane(dev_priv
, intel_crtc
->plane
);
711 intel_pipe_update_end(intel_crtc
, start_vbl_count
);
714 * Avoid underruns when disabling the sprite.
715 * FIXME remove once watermark updates are done properly.
717 intel_wait_for_vblank(dev
, pipe
);
719 intel_update_sprite_watermarks(plane
, crtc
, 0, 0, 0, false, false);
723 intel_post_enable_primary(struct drm_crtc
*crtc
)
725 struct drm_device
*dev
= crtc
->dev
;
726 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
729 * BDW signals flip done immediately if the plane
730 * is disabled, even if the plane enable is already
731 * armed to occur at the next vblank :(
733 if (IS_BROADWELL(dev
))
734 intel_wait_for_vblank(dev
, intel_crtc
->pipe
);
737 * FIXME IPS should be fine as long as one plane is
738 * enabled, but in practice it seems to have problems
739 * when going from primary only to sprite only and vice
742 hsw_enable_ips(intel_crtc
);
744 mutex_lock(&dev
->struct_mutex
);
745 intel_update_fbc(dev
);
746 mutex_unlock(&dev
->struct_mutex
);
750 intel_pre_disable_primary(struct drm_crtc
*crtc
)
752 struct drm_device
*dev
= crtc
->dev
;
753 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
754 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
756 mutex_lock(&dev
->struct_mutex
);
757 if (dev_priv
->fbc
.plane
== intel_crtc
->plane
)
758 intel_disable_fbc(dev
);
759 mutex_unlock(&dev
->struct_mutex
);
762 * FIXME IPS should be fine as long as one plane is
763 * enabled, but in practice it seems to have problems
764 * when going from primary only to sprite only and vice
767 hsw_disable_ips(intel_crtc
);
771 ilk_update_colorkey(struct drm_plane
*plane
,
772 struct drm_intel_sprite_colorkey
*key
)
774 struct drm_device
*dev
= plane
->dev
;
775 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
776 struct intel_plane
*intel_plane
;
780 intel_plane
= to_intel_plane(plane
);
782 I915_WRITE(DVSKEYVAL(intel_plane
->pipe
), key
->min_value
);
783 I915_WRITE(DVSKEYMAX(intel_plane
->pipe
), key
->max_value
);
784 I915_WRITE(DVSKEYMSK(intel_plane
->pipe
), key
->channel_mask
);
786 dvscntr
= I915_READ(DVSCNTR(intel_plane
->pipe
));
787 dvscntr
&= ~(DVS_SOURCE_KEY
| DVS_DEST_KEY
);
788 if (key
->flags
& I915_SET_COLORKEY_DESTINATION
)
789 dvscntr
|= DVS_DEST_KEY
;
790 else if (key
->flags
& I915_SET_COLORKEY_SOURCE
)
791 dvscntr
|= DVS_SOURCE_KEY
;
792 I915_WRITE(DVSCNTR(intel_plane
->pipe
), dvscntr
);
794 POSTING_READ(DVSKEYMSK(intel_plane
->pipe
));
800 ilk_get_colorkey(struct drm_plane
*plane
, struct drm_intel_sprite_colorkey
*key
)
802 struct drm_device
*dev
= plane
->dev
;
803 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
804 struct intel_plane
*intel_plane
;
807 intel_plane
= to_intel_plane(plane
);
809 key
->min_value
= I915_READ(DVSKEYVAL(intel_plane
->pipe
));
810 key
->max_value
= I915_READ(DVSKEYMAX(intel_plane
->pipe
));
811 key
->channel_mask
= I915_READ(DVSKEYMSK(intel_plane
->pipe
));
814 dvscntr
= I915_READ(DVSCNTR(intel_plane
->pipe
));
816 if (dvscntr
& DVS_DEST_KEY
)
817 key
->flags
= I915_SET_COLORKEY_DESTINATION
;
818 else if (dvscntr
& DVS_SOURCE_KEY
)
819 key
->flags
= I915_SET_COLORKEY_SOURCE
;
821 key
->flags
= I915_SET_COLORKEY_NONE
;
825 format_is_yuv(uint32_t format
)
828 case DRM_FORMAT_YUYV
:
829 case DRM_FORMAT_UYVY
:
830 case DRM_FORMAT_VYUY
:
831 case DRM_FORMAT_YVYU
:
838 static bool colorkey_enabled(struct intel_plane
*intel_plane
)
840 struct drm_intel_sprite_colorkey key
;
842 intel_plane
->get_colorkey(&intel_plane
->base
, &key
);
844 return key
.flags
!= I915_SET_COLORKEY_NONE
;
848 intel_update_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
,
849 struct drm_framebuffer
*fb
, int crtc_x
, int crtc_y
,
850 unsigned int crtc_w
, unsigned int crtc_h
,
851 uint32_t src_x
, uint32_t src_y
,
852 uint32_t src_w
, uint32_t src_h
)
854 struct drm_device
*dev
= plane
->dev
;
855 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
856 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
857 enum pipe pipe
= intel_crtc
->pipe
;
858 struct intel_framebuffer
*intel_fb
= to_intel_framebuffer(fb
);
859 struct drm_i915_gem_object
*obj
= intel_fb
->obj
;
860 struct drm_i915_gem_object
*old_obj
= intel_plane
->obj
;
862 bool primary_enabled
;
865 int max_scale
, min_scale
;
866 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
867 struct drm_rect src
= {
868 /* sample coordinates in 16.16 fixed point */
874 struct drm_rect dst
= {
877 .x2
= crtc_x
+ crtc_w
,
879 .y2
= crtc_y
+ crtc_h
,
881 const struct drm_rect clip
= {
882 .x2
= intel_crtc
->active
? intel_crtc
->config
.pipe_src_w
: 0,
883 .y2
= intel_crtc
->active
? intel_crtc
->config
.pipe_src_h
: 0,
887 unsigned int crtc_w
, crtc_h
;
888 uint32_t src_x
, src_y
, src_w
, src_h
;
900 /* Don't modify another pipe's plane */
901 if (intel_plane
->pipe
!= intel_crtc
->pipe
) {
902 DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n");
906 /* FIXME check all gen limits */
907 if (fb
->width
< 3 || fb
->height
< 3 || fb
->pitches
[0] > 16384) {
908 DRM_DEBUG_KMS("Unsuitable framebuffer for plane\n");
912 /* Sprite planes can be linear or x-tiled surfaces */
913 switch (obj
->tiling_mode
) {
914 case I915_TILING_NONE
:
918 DRM_DEBUG_KMS("Unsupported tiling mode\n");
923 * FIXME the following code does a bunch of fuzzy adjustments to the
924 * coordinates and sizes. We probably need some way to decide whether
925 * more strict checking should be done instead.
927 max_scale
= intel_plane
->max_downscale
<< 16;
928 min_scale
= intel_plane
->can_scale
? 1 : (1 << 16);
930 drm_rect_rotate(&src
, fb
->width
<< 16, fb
->height
<< 16,
931 intel_plane
->rotation
);
933 hscale
= drm_rect_calc_hscale_relaxed(&src
, &dst
, min_scale
, max_scale
);
936 vscale
= drm_rect_calc_vscale_relaxed(&src
, &dst
, min_scale
, max_scale
);
939 visible
= drm_rect_clip_scaled(&src
, &dst
, &clip
, hscale
, vscale
);
943 crtc_w
= drm_rect_width(&dst
);
944 crtc_h
= drm_rect_height(&dst
);
947 /* check again in case clipping clamped the results */
948 hscale
= drm_rect_calc_hscale(&src
, &dst
, min_scale
, max_scale
);
950 DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n");
951 drm_rect_debug_print(&src
, true);
952 drm_rect_debug_print(&dst
, false);
957 vscale
= drm_rect_calc_vscale(&src
, &dst
, min_scale
, max_scale
);
959 DRM_DEBUG_KMS("Vertical scaling factor out of limits\n");
960 drm_rect_debug_print(&src
, true);
961 drm_rect_debug_print(&dst
, false);
966 /* Make the source viewport size an exact multiple of the scaling factors. */
967 drm_rect_adjust_size(&src
,
968 drm_rect_width(&dst
) * hscale
- drm_rect_width(&src
),
969 drm_rect_height(&dst
) * vscale
- drm_rect_height(&src
));
971 drm_rect_rotate_inv(&src
, fb
->width
<< 16, fb
->height
<< 16,
972 intel_plane
->rotation
);
974 /* sanity check to make sure the src viewport wasn't enlarged */
975 WARN_ON(src
.x1
< (int) src_x
||
976 src
.y1
< (int) src_y
||
977 src
.x2
> (int) (src_x
+ src_w
) ||
978 src
.y2
> (int) (src_y
+ src_h
));
981 * Hardware doesn't handle subpixel coordinates.
982 * Adjust to (macro)pixel boundary, but be careful not to
983 * increase the source viewport size, because that could
984 * push the downscaling factor out of bounds.
986 src_x
= src
.x1
>> 16;
987 src_w
= drm_rect_width(&src
) >> 16;
988 src_y
= src
.y1
>> 16;
989 src_h
= drm_rect_height(&src
) >> 16;
991 if (format_is_yuv(fb
->pixel_format
)) {
996 * Must keep src and dst the
997 * same if we can't scale.
999 if (!intel_plane
->can_scale
)
1007 /* Check size restrictions when scaling */
1008 if (visible
&& (src_w
!= crtc_w
|| src_h
!= crtc_h
)) {
1009 unsigned int width_bytes
;
1011 WARN_ON(!intel_plane
->can_scale
);
1013 /* FIXME interlacing min height is 6 */
1015 if (crtc_w
< 3 || crtc_h
< 3)
1018 if (src_w
< 3 || src_h
< 3)
1021 width_bytes
= ((src_x
* pixel_size
) & 63) + src_w
* pixel_size
;
1023 if (src_w
> 2048 || src_h
> 2048 ||
1024 width_bytes
> 4096 || fb
->pitches
[0] > 4096) {
1025 DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
1031 dst
.x2
= crtc_x
+ crtc_w
;
1033 dst
.y2
= crtc_y
+ crtc_h
;
1036 * If the sprite is completely covering the primary plane,
1037 * we can disable the primary and save power.
1039 primary_enabled
= !drm_rect_equals(&dst
, &clip
) || colorkey_enabled(intel_plane
);
1040 WARN_ON(!primary_enabled
&& !visible
&& intel_crtc
->active
);
1042 mutex_lock(&dev
->struct_mutex
);
1044 /* Note that this will apply the VT-d workaround for scanouts,
1045 * which is more restrictive than required for sprites. (The
1046 * primary plane requires 256KiB alignment with 64 PTE padding,
1047 * the sprite planes only require 128KiB alignment and 32 PTE padding.
1049 ret
= intel_pin_and_fence_fb_obj(dev
, obj
, NULL
);
1051 i915_gem_track_fb(old_obj
, obj
,
1052 INTEL_FRONTBUFFER_SPRITE(pipe
));
1053 mutex_unlock(&dev
->struct_mutex
);
1058 intel_plane
->crtc_x
= orig
.crtc_x
;
1059 intel_plane
->crtc_y
= orig
.crtc_y
;
1060 intel_plane
->crtc_w
= orig
.crtc_w
;
1061 intel_plane
->crtc_h
= orig
.crtc_h
;
1062 intel_plane
->src_x
= orig
.src_x
;
1063 intel_plane
->src_y
= orig
.src_y
;
1064 intel_plane
->src_w
= orig
.src_w
;
1065 intel_plane
->src_h
= orig
.src_h
;
1066 intel_plane
->obj
= obj
;
1068 if (intel_crtc
->active
) {
1069 bool primary_was_enabled
= intel_crtc
->primary_enabled
;
1071 intel_crtc
->primary_enabled
= primary_enabled
;
1073 if (primary_was_enabled
!= primary_enabled
)
1074 intel_crtc_wait_for_pending_flips(crtc
);
1076 if (primary_was_enabled
&& !primary_enabled
)
1077 intel_pre_disable_primary(crtc
);
1080 intel_plane
->update_plane(plane
, crtc
, fb
, obj
,
1081 crtc_x
, crtc_y
, crtc_w
, crtc_h
,
1082 src_x
, src_y
, src_w
, src_h
);
1084 intel_plane
->disable_plane(plane
, crtc
);
1086 intel_frontbuffer_flip(dev
, INTEL_FRONTBUFFER_SPRITE(pipe
));
1088 if (!primary_was_enabled
&& primary_enabled
)
1089 intel_post_enable_primary(crtc
);
1092 /* Unpin old obj after new one is active to avoid ugliness */
1095 * It's fairly common to simply update the position of
1096 * an existing object. In that case, we don't need to
1097 * wait for vblank to avoid ugliness, we only need to
1098 * do the pin & ref bookkeeping.
1100 if (old_obj
!= obj
&& intel_crtc
->active
)
1101 intel_wait_for_vblank(dev
, intel_crtc
->pipe
);
1103 mutex_lock(&dev
->struct_mutex
);
1104 intel_unpin_fb_obj(old_obj
);
1105 mutex_unlock(&dev
->struct_mutex
);
1112 intel_disable_plane(struct drm_plane
*plane
)
1114 struct drm_device
*dev
= plane
->dev
;
1115 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
1116 struct intel_crtc
*intel_crtc
;
1122 if (WARN_ON(!plane
->crtc
))
1125 intel_crtc
= to_intel_crtc(plane
->crtc
);
1126 pipe
= intel_crtc
->pipe
;
1128 if (intel_crtc
->active
) {
1129 bool primary_was_enabled
= intel_crtc
->primary_enabled
;
1131 intel_crtc
->primary_enabled
= true;
1133 intel_plane
->disable_plane(plane
, plane
->crtc
);
1135 if (!primary_was_enabled
&& intel_crtc
->primary_enabled
)
1136 intel_post_enable_primary(plane
->crtc
);
1139 if (intel_plane
->obj
) {
1140 if (intel_crtc
->active
)
1141 intel_wait_for_vblank(dev
, intel_plane
->pipe
);
1143 mutex_lock(&dev
->struct_mutex
);
1144 intel_unpin_fb_obj(intel_plane
->obj
);
1145 i915_gem_track_fb(intel_plane
->obj
, NULL
,
1146 INTEL_FRONTBUFFER_SPRITE(pipe
));
1147 mutex_unlock(&dev
->struct_mutex
);
1149 intel_plane
->obj
= NULL
;
1155 static void intel_destroy_plane(struct drm_plane
*plane
)
1157 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
1158 intel_disable_plane(plane
);
1159 drm_plane_cleanup(plane
);
1163 int intel_sprite_set_colorkey(struct drm_device
*dev
, void *data
,
1164 struct drm_file
*file_priv
)
1166 struct drm_intel_sprite_colorkey
*set
= data
;
1167 struct drm_plane
*plane
;
1168 struct intel_plane
*intel_plane
;
1171 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
1174 /* Make sure we don't try to enable both src & dest simultaneously */
1175 if ((set
->flags
& (I915_SET_COLORKEY_DESTINATION
| I915_SET_COLORKEY_SOURCE
)) == (I915_SET_COLORKEY_DESTINATION
| I915_SET_COLORKEY_SOURCE
))
1178 drm_modeset_lock_all(dev
);
1180 plane
= drm_plane_find(dev
, set
->plane_id
);
1186 intel_plane
= to_intel_plane(plane
);
1187 ret
= intel_plane
->update_colorkey(plane
, set
);
1190 drm_modeset_unlock_all(dev
);
1194 int intel_sprite_get_colorkey(struct drm_device
*dev
, void *data
,
1195 struct drm_file
*file_priv
)
1197 struct drm_intel_sprite_colorkey
*get
= data
;
1198 struct drm_plane
*plane
;
1199 struct intel_plane
*intel_plane
;
1202 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
1205 drm_modeset_lock_all(dev
);
1207 plane
= drm_plane_find(dev
, get
->plane_id
);
1213 intel_plane
= to_intel_plane(plane
);
1214 intel_plane
->get_colorkey(plane
, get
);
1217 drm_modeset_unlock_all(dev
);
1221 int intel_plane_set_property(struct drm_plane
*plane
,
1222 struct drm_property
*prop
,
1225 struct drm_device
*dev
= plane
->dev
;
1226 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
1230 if (prop
== dev
->mode_config
.rotation_property
) {
1231 /* exactly one rotation angle please */
1232 if (hweight32(val
& 0xf) != 1)
1235 if (intel_plane
->rotation
== val
)
1238 old_val
= intel_plane
->rotation
;
1239 intel_plane
->rotation
= val
;
1240 ret
= intel_plane_restore(plane
);
1242 intel_plane
->rotation
= old_val
;
1248 int intel_plane_restore(struct drm_plane
*plane
)
1250 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
1252 if (!plane
->crtc
|| !plane
->fb
)
1255 return plane
->funcs
->update_plane(plane
, plane
->crtc
, plane
->fb
,
1256 intel_plane
->crtc_x
, intel_plane
->crtc_y
,
1257 intel_plane
->crtc_w
, intel_plane
->crtc_h
,
1258 intel_plane
->src_x
, intel_plane
->src_y
,
1259 intel_plane
->src_w
, intel_plane
->src_h
);
1262 void intel_plane_disable(struct drm_plane
*plane
)
1264 if (!plane
->crtc
|| !plane
->fb
)
1267 intel_disable_plane(plane
);
1270 static const struct drm_plane_funcs intel_plane_funcs
= {
1271 .update_plane
= intel_update_plane
,
1272 .disable_plane
= intel_disable_plane
,
1273 .destroy
= intel_destroy_plane
,
1274 .set_property
= intel_plane_set_property
,
1277 static uint32_t ilk_plane_formats
[] = {
1278 DRM_FORMAT_XRGB8888
,
1285 static uint32_t snb_plane_formats
[] = {
1286 DRM_FORMAT_XBGR8888
,
1287 DRM_FORMAT_XRGB8888
,
1294 static uint32_t vlv_plane_formats
[] = {
1296 DRM_FORMAT_ABGR8888
,
1297 DRM_FORMAT_ARGB8888
,
1298 DRM_FORMAT_XBGR8888
,
1299 DRM_FORMAT_XRGB8888
,
1300 DRM_FORMAT_XBGR2101010
,
1301 DRM_FORMAT_ABGR2101010
,
1309 intel_plane_init(struct drm_device
*dev
, enum pipe pipe
, int plane
)
1311 struct intel_plane
*intel_plane
;
1312 unsigned long possible_crtcs
;
1313 const uint32_t *plane_formats
;
1314 int num_plane_formats
;
1317 if (INTEL_INFO(dev
)->gen
< 5)
1320 intel_plane
= kzalloc(sizeof(*intel_plane
), GFP_KERNEL
);
1324 switch (INTEL_INFO(dev
)->gen
) {
1327 intel_plane
->can_scale
= true;
1328 intel_plane
->max_downscale
= 16;
1329 intel_plane
->update_plane
= ilk_update_plane
;
1330 intel_plane
->disable_plane
= ilk_disable_plane
;
1331 intel_plane
->update_colorkey
= ilk_update_colorkey
;
1332 intel_plane
->get_colorkey
= ilk_get_colorkey
;
1335 plane_formats
= snb_plane_formats
;
1336 num_plane_formats
= ARRAY_SIZE(snb_plane_formats
);
1338 plane_formats
= ilk_plane_formats
;
1339 num_plane_formats
= ARRAY_SIZE(ilk_plane_formats
);
1345 if (IS_IVYBRIDGE(dev
)) {
1346 intel_plane
->can_scale
= true;
1347 intel_plane
->max_downscale
= 2;
1349 intel_plane
->can_scale
= false;
1350 intel_plane
->max_downscale
= 1;
1353 if (IS_VALLEYVIEW(dev
)) {
1354 intel_plane
->update_plane
= vlv_update_plane
;
1355 intel_plane
->disable_plane
= vlv_disable_plane
;
1356 intel_plane
->update_colorkey
= vlv_update_colorkey
;
1357 intel_plane
->get_colorkey
= vlv_get_colorkey
;
1359 plane_formats
= vlv_plane_formats
;
1360 num_plane_formats
= ARRAY_SIZE(vlv_plane_formats
);
1362 intel_plane
->update_plane
= ivb_update_plane
;
1363 intel_plane
->disable_plane
= ivb_disable_plane
;
1364 intel_plane
->update_colorkey
= ivb_update_colorkey
;
1365 intel_plane
->get_colorkey
= ivb_get_colorkey
;
1367 plane_formats
= snb_plane_formats
;
1368 num_plane_formats
= ARRAY_SIZE(snb_plane_formats
);
1377 intel_plane
->pipe
= pipe
;
1378 intel_plane
->plane
= plane
;
1379 intel_plane
->rotation
= BIT(DRM_ROTATE_0
);
1380 possible_crtcs
= (1 << pipe
);
1381 ret
= drm_universal_plane_init(dev
, &intel_plane
->base
, possible_crtcs
,
1383 plane_formats
, num_plane_formats
,
1384 DRM_PLANE_TYPE_OVERLAY
);
1390 if (!dev
->mode_config
.rotation_property
)
1391 dev
->mode_config
.rotation_property
=
1392 drm_mode_create_rotation_property(dev
,
1394 BIT(DRM_ROTATE_180
));
1396 if (dev
->mode_config
.rotation_property
)
1397 drm_object_attach_property(&intel_plane
->base
.base
,
1398 dev
->mode_config
.rotation_property
,
1399 intel_plane
->rotation
);