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 ivb_update_plane(struct drm_plane
*plane
, 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
= plane
->dev
;
47 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
48 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
49 int pipe
= intel_plane
->pipe
;
50 u32 sprctl
, sprscale
= 0;
51 unsigned long sprsurf_offset
, linear_offset
;
52 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
53 bool scaling_was_enabled
= dev_priv
->sprite_scaling_enabled
;
55 sprctl
= I915_READ(SPRCTL(pipe
));
57 /* Mask out pixel format bits in case we change it */
58 sprctl
&= ~SPRITE_PIXFORMAT_MASK
;
59 sprctl
&= ~SPRITE_RGB_ORDER_RGBX
;
60 sprctl
&= ~SPRITE_YUV_BYTE_ORDER_MASK
;
61 sprctl
&= ~SPRITE_TILED
;
63 switch (fb
->pixel_format
) {
64 case DRM_FORMAT_XBGR8888
:
65 sprctl
|= SPRITE_FORMAT_RGBX888
| SPRITE_RGB_ORDER_RGBX
;
67 case DRM_FORMAT_XRGB8888
:
68 sprctl
|= SPRITE_FORMAT_RGBX888
;
71 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_YUYV
;
74 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_YVYU
;
77 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_UYVY
;
80 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_VYUY
;
86 if (obj
->tiling_mode
!= I915_TILING_NONE
)
87 sprctl
|= SPRITE_TILED
;
90 sprctl
|= SPRITE_TRICKLE_FEED_DISABLE
;
91 sprctl
|= SPRITE_ENABLE
;
94 sprctl
|= SPRITE_PIPE_CSC_ENABLE
;
96 /* Sizes are 0 based */
102 intel_update_sprite_watermarks(dev
, pipe
, crtc_w
, pixel_size
);
105 * IVB workaround: must disable low power watermarks for at least
106 * one frame before enabling scaling. LP watermarks can be re-enabled
107 * when scaling is disabled.
109 if (crtc_w
!= src_w
|| crtc_h
!= src_h
) {
110 dev_priv
->sprite_scaling_enabled
|= 1 << pipe
;
112 if (!scaling_was_enabled
) {
113 intel_update_watermarks(dev
);
114 intel_wait_for_vblank(dev
, pipe
);
116 sprscale
= SPRITE_SCALE_ENABLE
| (src_w
<< 16) | src_h
;
118 dev_priv
->sprite_scaling_enabled
&= ~(1 << pipe
);
120 I915_WRITE(SPRSTRIDE(pipe
), fb
->pitches
[0]);
121 I915_WRITE(SPRPOS(pipe
), (crtc_y
<< 16) | crtc_x
);
123 linear_offset
= y
* fb
->pitches
[0] + x
* pixel_size
;
125 intel_gen4_compute_page_offset(&x
, &y
, obj
->tiling_mode
,
126 pixel_size
, fb
->pitches
[0]);
127 linear_offset
-= sprsurf_offset
;
129 /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
132 I915_WRITE(SPROFFSET(pipe
), (y
<< 16) | x
);
133 else if (obj
->tiling_mode
!= I915_TILING_NONE
)
134 I915_WRITE(SPRTILEOFF(pipe
), (y
<< 16) | x
);
136 I915_WRITE(SPRLINOFF(pipe
), linear_offset
);
138 I915_WRITE(SPRSIZE(pipe
), (crtc_h
<< 16) | crtc_w
);
139 if (intel_plane
->can_scale
)
140 I915_WRITE(SPRSCALE(pipe
), sprscale
);
141 I915_WRITE(SPRCTL(pipe
), sprctl
);
142 I915_MODIFY_DISPBASE(SPRSURF(pipe
), obj
->gtt_offset
+ sprsurf_offset
);
143 POSTING_READ(SPRSURF(pipe
));
145 /* potentially re-enable LP watermarks */
146 if (scaling_was_enabled
&& !dev_priv
->sprite_scaling_enabled
)
147 intel_update_watermarks(dev
);
151 ivb_disable_plane(struct drm_plane
*plane
)
153 struct drm_device
*dev
= plane
->dev
;
154 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
155 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
156 int pipe
= intel_plane
->pipe
;
157 bool scaling_was_enabled
= dev_priv
->sprite_scaling_enabled
;
159 I915_WRITE(SPRCTL(pipe
), I915_READ(SPRCTL(pipe
)) & ~SPRITE_ENABLE
);
160 /* Can't leave the scaler enabled... */
161 if (intel_plane
->can_scale
)
162 I915_WRITE(SPRSCALE(pipe
), 0);
163 /* Activate double buffered register update */
164 I915_MODIFY_DISPBASE(SPRSURF(pipe
), 0);
165 POSTING_READ(SPRSURF(pipe
));
167 dev_priv
->sprite_scaling_enabled
&= ~(1 << pipe
);
169 /* potentially re-enable LP watermarks */
170 if (scaling_was_enabled
&& !dev_priv
->sprite_scaling_enabled
)
171 intel_update_watermarks(dev
);
175 ivb_update_colorkey(struct drm_plane
*plane
,
176 struct drm_intel_sprite_colorkey
*key
)
178 struct drm_device
*dev
= plane
->dev
;
179 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
180 struct intel_plane
*intel_plane
;
184 intel_plane
= to_intel_plane(plane
);
186 I915_WRITE(SPRKEYVAL(intel_plane
->pipe
), key
->min_value
);
187 I915_WRITE(SPRKEYMAX(intel_plane
->pipe
), key
->max_value
);
188 I915_WRITE(SPRKEYMSK(intel_plane
->pipe
), key
->channel_mask
);
190 sprctl
= I915_READ(SPRCTL(intel_plane
->pipe
));
191 sprctl
&= ~(SPRITE_SOURCE_KEY
| SPRITE_DEST_KEY
);
192 if (key
->flags
& I915_SET_COLORKEY_DESTINATION
)
193 sprctl
|= SPRITE_DEST_KEY
;
194 else if (key
->flags
& I915_SET_COLORKEY_SOURCE
)
195 sprctl
|= SPRITE_SOURCE_KEY
;
196 I915_WRITE(SPRCTL(intel_plane
->pipe
), sprctl
);
198 POSTING_READ(SPRKEYMSK(intel_plane
->pipe
));
204 ivb_get_colorkey(struct drm_plane
*plane
, struct drm_intel_sprite_colorkey
*key
)
206 struct drm_device
*dev
= plane
->dev
;
207 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
208 struct intel_plane
*intel_plane
;
211 intel_plane
= to_intel_plane(plane
);
213 key
->min_value
= I915_READ(SPRKEYVAL(intel_plane
->pipe
));
214 key
->max_value
= I915_READ(SPRKEYMAX(intel_plane
->pipe
));
215 key
->channel_mask
= I915_READ(SPRKEYMSK(intel_plane
->pipe
));
218 sprctl
= I915_READ(SPRCTL(intel_plane
->pipe
));
220 if (sprctl
& SPRITE_DEST_KEY
)
221 key
->flags
= I915_SET_COLORKEY_DESTINATION
;
222 else if (sprctl
& SPRITE_SOURCE_KEY
)
223 key
->flags
= I915_SET_COLORKEY_SOURCE
;
225 key
->flags
= I915_SET_COLORKEY_NONE
;
229 ilk_update_plane(struct drm_plane
*plane
, struct drm_framebuffer
*fb
,
230 struct drm_i915_gem_object
*obj
, int crtc_x
, int crtc_y
,
231 unsigned int crtc_w
, unsigned int crtc_h
,
232 uint32_t x
, uint32_t y
,
233 uint32_t src_w
, uint32_t src_h
)
235 struct drm_device
*dev
= plane
->dev
;
236 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
237 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
238 int pipe
= intel_plane
->pipe
;
239 unsigned long dvssurf_offset
, linear_offset
;
240 u32 dvscntr
, dvsscale
;
241 int pixel_size
= drm_format_plane_cpp(fb
->pixel_format
, 0);
243 dvscntr
= I915_READ(DVSCNTR(pipe
));
245 /* Mask out pixel format bits in case we change it */
246 dvscntr
&= ~DVS_PIXFORMAT_MASK
;
247 dvscntr
&= ~DVS_RGB_ORDER_XBGR
;
248 dvscntr
&= ~DVS_YUV_BYTE_ORDER_MASK
;
249 dvscntr
&= ~DVS_TILED
;
251 switch (fb
->pixel_format
) {
252 case DRM_FORMAT_XBGR8888
:
253 dvscntr
|= DVS_FORMAT_RGBX888
| DVS_RGB_ORDER_XBGR
;
255 case DRM_FORMAT_XRGB8888
:
256 dvscntr
|= DVS_FORMAT_RGBX888
;
258 case DRM_FORMAT_YUYV
:
259 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_YUYV
;
261 case DRM_FORMAT_YVYU
:
262 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_YVYU
;
264 case DRM_FORMAT_UYVY
:
265 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_UYVY
;
267 case DRM_FORMAT_VYUY
:
268 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_VYUY
;
274 if (obj
->tiling_mode
!= I915_TILING_NONE
)
275 dvscntr
|= DVS_TILED
;
278 dvscntr
|= DVS_TRICKLE_FEED_DISABLE
; /* must disable */
279 dvscntr
|= DVS_ENABLE
;
281 /* Sizes are 0 based */
287 intel_update_sprite_watermarks(dev
, pipe
, crtc_w
, pixel_size
);
290 if (IS_GEN5(dev
) || crtc_w
!= src_w
|| crtc_h
!= src_h
)
291 dvsscale
= DVS_SCALE_ENABLE
| (src_w
<< 16) | src_h
;
293 I915_WRITE(DVSSTRIDE(pipe
), fb
->pitches
[0]);
294 I915_WRITE(DVSPOS(pipe
), (crtc_y
<< 16) | crtc_x
);
296 linear_offset
= y
* fb
->pitches
[0] + x
* pixel_size
;
298 intel_gen4_compute_page_offset(&x
, &y
, obj
->tiling_mode
,
299 pixel_size
, fb
->pitches
[0]);
300 linear_offset
-= dvssurf_offset
;
302 if (obj
->tiling_mode
!= I915_TILING_NONE
)
303 I915_WRITE(DVSTILEOFF(pipe
), (y
<< 16) | x
);
305 I915_WRITE(DVSLINOFF(pipe
), linear_offset
);
307 I915_WRITE(DVSSIZE(pipe
), (crtc_h
<< 16) | crtc_w
);
308 I915_WRITE(DVSSCALE(pipe
), dvsscale
);
309 I915_WRITE(DVSCNTR(pipe
), dvscntr
);
310 I915_MODIFY_DISPBASE(DVSSURF(pipe
), obj
->gtt_offset
+ dvssurf_offset
);
311 POSTING_READ(DVSSURF(pipe
));
315 ilk_disable_plane(struct drm_plane
*plane
)
317 struct drm_device
*dev
= plane
->dev
;
318 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
319 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
320 int pipe
= intel_plane
->pipe
;
322 I915_WRITE(DVSCNTR(pipe
), I915_READ(DVSCNTR(pipe
)) & ~DVS_ENABLE
);
323 /* Disable the scaler */
324 I915_WRITE(DVSSCALE(pipe
), 0);
325 /* Flush double buffered register updates */
326 I915_MODIFY_DISPBASE(DVSSURF(pipe
), 0);
327 POSTING_READ(DVSSURF(pipe
));
331 intel_enable_primary(struct drm_crtc
*crtc
)
333 struct drm_device
*dev
= crtc
->dev
;
334 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
335 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
336 int reg
= DSPCNTR(intel_crtc
->plane
);
338 if (!intel_crtc
->primary_disabled
)
341 intel_crtc
->primary_disabled
= false;
342 intel_update_fbc(dev
);
344 I915_WRITE(reg
, I915_READ(reg
) | DISPLAY_PLANE_ENABLE
);
348 intel_disable_primary(struct drm_crtc
*crtc
)
350 struct drm_device
*dev
= crtc
->dev
;
351 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
352 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
353 int reg
= DSPCNTR(intel_crtc
->plane
);
355 if (intel_crtc
->primary_disabled
)
358 I915_WRITE(reg
, I915_READ(reg
) & ~DISPLAY_PLANE_ENABLE
);
360 intel_crtc
->primary_disabled
= true;
361 intel_update_fbc(dev
);
365 ilk_update_colorkey(struct drm_plane
*plane
,
366 struct drm_intel_sprite_colorkey
*key
)
368 struct drm_device
*dev
= plane
->dev
;
369 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
370 struct intel_plane
*intel_plane
;
374 intel_plane
= to_intel_plane(plane
);
376 I915_WRITE(DVSKEYVAL(intel_plane
->pipe
), key
->min_value
);
377 I915_WRITE(DVSKEYMAX(intel_plane
->pipe
), key
->max_value
);
378 I915_WRITE(DVSKEYMSK(intel_plane
->pipe
), key
->channel_mask
);
380 dvscntr
= I915_READ(DVSCNTR(intel_plane
->pipe
));
381 dvscntr
&= ~(DVS_SOURCE_KEY
| DVS_DEST_KEY
);
382 if (key
->flags
& I915_SET_COLORKEY_DESTINATION
)
383 dvscntr
|= DVS_DEST_KEY
;
384 else if (key
->flags
& I915_SET_COLORKEY_SOURCE
)
385 dvscntr
|= DVS_SOURCE_KEY
;
386 I915_WRITE(DVSCNTR(intel_plane
->pipe
), dvscntr
);
388 POSTING_READ(DVSKEYMSK(intel_plane
->pipe
));
394 ilk_get_colorkey(struct drm_plane
*plane
, struct drm_intel_sprite_colorkey
*key
)
396 struct drm_device
*dev
= plane
->dev
;
397 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
398 struct intel_plane
*intel_plane
;
401 intel_plane
= to_intel_plane(plane
);
403 key
->min_value
= I915_READ(DVSKEYVAL(intel_plane
->pipe
));
404 key
->max_value
= I915_READ(DVSKEYMAX(intel_plane
->pipe
));
405 key
->channel_mask
= I915_READ(DVSKEYMSK(intel_plane
->pipe
));
408 dvscntr
= I915_READ(DVSCNTR(intel_plane
->pipe
));
410 if (dvscntr
& DVS_DEST_KEY
)
411 key
->flags
= I915_SET_COLORKEY_DESTINATION
;
412 else if (dvscntr
& DVS_SOURCE_KEY
)
413 key
->flags
= I915_SET_COLORKEY_SOURCE
;
415 key
->flags
= I915_SET_COLORKEY_NONE
;
419 intel_update_plane(struct drm_plane
*plane
, struct drm_crtc
*crtc
,
420 struct drm_framebuffer
*fb
, int crtc_x
, int crtc_y
,
421 unsigned int crtc_w
, unsigned int crtc_h
,
422 uint32_t src_x
, uint32_t src_y
,
423 uint32_t src_w
, uint32_t src_h
)
425 struct drm_device
*dev
= plane
->dev
;
426 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
427 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
428 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
429 struct intel_framebuffer
*intel_fb
;
430 struct drm_i915_gem_object
*obj
, *old_obj
;
431 int pipe
= intel_plane
->pipe
;
432 enum transcoder cpu_transcoder
= intel_pipe_to_cpu_transcoder(dev_priv
,
435 int x
= src_x
>> 16, y
= src_y
>> 16;
436 int primary_w
= crtc
->mode
.hdisplay
, primary_h
= crtc
->mode
.vdisplay
;
437 bool disable_primary
= false;
439 intel_fb
= to_intel_framebuffer(fb
);
442 old_obj
= intel_plane
->obj
;
444 intel_plane
->crtc_x
= crtc_x
;
445 intel_plane
->crtc_y
= crtc_y
;
446 intel_plane
->crtc_w
= crtc_w
;
447 intel_plane
->crtc_h
= crtc_h
;
448 intel_plane
->src_x
= src_x
;
449 intel_plane
->src_y
= src_y
;
450 intel_plane
->src_w
= src_w
;
451 intel_plane
->src_h
= src_h
;
456 /* Pipe must be running... */
457 if (!(I915_READ(PIPECONF(cpu_transcoder
)) & PIPECONF_ENABLE
))
460 if (crtc_x
>= primary_w
|| crtc_y
>= primary_h
)
463 /* Don't modify another pipe's plane */
464 if (intel_plane
->pipe
!= intel_crtc
->pipe
)
467 /* Sprite planes can be linear or x-tiled surfaces */
468 switch (obj
->tiling_mode
) {
469 case I915_TILING_NONE
:
477 * Clamp the width & height into the visible area. Note we don't
478 * try to scale the source if part of the visible region is offscreen.
479 * The caller must handle that by adjusting source offset and size.
481 if ((crtc_x
< 0) && ((crtc_x
+ crtc_w
) > 0)) {
485 if ((crtc_x
+ crtc_w
) <= 0) /* Nothing to display */
487 if ((crtc_x
+ crtc_w
) > primary_w
)
488 crtc_w
= primary_w
- crtc_x
;
490 if ((crtc_y
< 0) && ((crtc_y
+ crtc_h
) > 0)) {
494 if ((crtc_y
+ crtc_h
) <= 0) /* Nothing to display */
496 if (crtc_y
+ crtc_h
> primary_h
)
497 crtc_h
= primary_h
- crtc_y
;
499 if (!crtc_w
|| !crtc_h
) /* Again, nothing to display */
503 * We may not have a scaler, eg. HSW does not have it any more
505 if (!intel_plane
->can_scale
&& (crtc_w
!= src_w
|| crtc_h
!= src_h
))
509 * We can take a larger source and scale it down, but
510 * only so much... 16x is the max on SNB.
512 if (((src_w
* src_h
) / (crtc_w
* crtc_h
)) > intel_plane
->max_downscale
)
516 * If the sprite is completely covering the primary plane,
517 * we can disable the primary and save power.
519 if ((crtc_x
== 0) && (crtc_y
== 0) &&
520 (crtc_w
== primary_w
) && (crtc_h
== primary_h
))
521 disable_primary
= true;
523 mutex_lock(&dev
->struct_mutex
);
525 /* Note that this will apply the VT-d workaround for scanouts,
526 * which is more restrictive than required for sprites. (The
527 * primary plane requires 256KiB alignment with 64 PTE padding,
528 * the sprite planes only require 128KiB alignment and 32 PTE padding.
530 ret
= intel_pin_and_fence_fb_obj(dev
, obj
, NULL
);
534 intel_plane
->obj
= obj
;
537 * Be sure to re-enable the primary before the sprite is no longer
540 if (!disable_primary
)
541 intel_enable_primary(crtc
);
543 intel_plane
->update_plane(plane
, fb
, obj
, crtc_x
, crtc_y
,
544 crtc_w
, crtc_h
, x
, y
, src_w
, src_h
);
547 intel_disable_primary(crtc
);
549 /* Unpin old obj after new one is active to avoid ugliness */
552 * It's fairly common to simply update the position of
553 * an existing object. In that case, we don't need to
554 * wait for vblank to avoid ugliness, we only need to
555 * do the pin & ref bookkeeping.
557 if (old_obj
!= obj
) {
558 mutex_unlock(&dev
->struct_mutex
);
559 intel_wait_for_vblank(dev
, to_intel_crtc(crtc
)->pipe
);
560 mutex_lock(&dev
->struct_mutex
);
562 intel_unpin_fb_obj(old_obj
);
566 mutex_unlock(&dev
->struct_mutex
);
572 intel_disable_plane(struct drm_plane
*plane
)
574 struct drm_device
*dev
= plane
->dev
;
575 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
579 intel_enable_primary(plane
->crtc
);
580 intel_plane
->disable_plane(plane
);
582 if (!intel_plane
->obj
)
585 intel_wait_for_vblank(dev
, intel_plane
->pipe
);
587 mutex_lock(&dev
->struct_mutex
);
588 intel_unpin_fb_obj(intel_plane
->obj
);
589 intel_plane
->obj
= NULL
;
590 mutex_unlock(&dev
->struct_mutex
);
596 static void intel_destroy_plane(struct drm_plane
*plane
)
598 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
599 intel_disable_plane(plane
);
600 drm_plane_cleanup(plane
);
604 int intel_sprite_set_colorkey(struct drm_device
*dev
, void *data
,
605 struct drm_file
*file_priv
)
607 struct drm_intel_sprite_colorkey
*set
= data
;
608 struct drm_mode_object
*obj
;
609 struct drm_plane
*plane
;
610 struct intel_plane
*intel_plane
;
613 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
616 /* Make sure we don't try to enable both src & dest simultaneously */
617 if ((set
->flags
& (I915_SET_COLORKEY_DESTINATION
| I915_SET_COLORKEY_SOURCE
)) == (I915_SET_COLORKEY_DESTINATION
| I915_SET_COLORKEY_SOURCE
))
620 drm_modeset_lock_all(dev
);
622 obj
= drm_mode_object_find(dev
, set
->plane_id
, DRM_MODE_OBJECT_PLANE
);
628 plane
= obj_to_plane(obj
);
629 intel_plane
= to_intel_plane(plane
);
630 ret
= intel_plane
->update_colorkey(plane
, set
);
633 drm_modeset_unlock_all(dev
);
637 int intel_sprite_get_colorkey(struct drm_device
*dev
, void *data
,
638 struct drm_file
*file_priv
)
640 struct drm_intel_sprite_colorkey
*get
= data
;
641 struct drm_mode_object
*obj
;
642 struct drm_plane
*plane
;
643 struct intel_plane
*intel_plane
;
646 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
649 drm_modeset_lock_all(dev
);
651 obj
= drm_mode_object_find(dev
, get
->plane_id
, DRM_MODE_OBJECT_PLANE
);
657 plane
= obj_to_plane(obj
);
658 intel_plane
= to_intel_plane(plane
);
659 intel_plane
->get_colorkey(plane
, get
);
662 drm_modeset_unlock_all(dev
);
666 void intel_plane_restore(struct drm_plane
*plane
)
668 struct intel_plane
*intel_plane
= to_intel_plane(plane
);
670 if (!plane
->crtc
|| !plane
->fb
)
673 intel_update_plane(plane
, plane
->crtc
, plane
->fb
,
674 intel_plane
->crtc_x
, intel_plane
->crtc_y
,
675 intel_plane
->crtc_w
, intel_plane
->crtc_h
,
676 intel_plane
->src_x
, intel_plane
->src_y
,
677 intel_plane
->src_w
, intel_plane
->src_h
);
680 static const struct drm_plane_funcs intel_plane_funcs
= {
681 .update_plane
= intel_update_plane
,
682 .disable_plane
= intel_disable_plane
,
683 .destroy
= intel_destroy_plane
,
686 static uint32_t ilk_plane_formats
[] = {
694 static uint32_t snb_plane_formats
[] = {
704 intel_plane_init(struct drm_device
*dev
, enum pipe pipe
)
706 struct intel_plane
*intel_plane
;
707 unsigned long possible_crtcs
;
708 const uint32_t *plane_formats
;
709 int num_plane_formats
;
712 if (INTEL_INFO(dev
)->gen
< 5)
715 intel_plane
= kzalloc(sizeof(struct intel_plane
), GFP_KERNEL
);
719 switch (INTEL_INFO(dev
)->gen
) {
722 intel_plane
->can_scale
= true;
723 intel_plane
->max_downscale
= 16;
724 intel_plane
->update_plane
= ilk_update_plane
;
725 intel_plane
->disable_plane
= ilk_disable_plane
;
726 intel_plane
->update_colorkey
= ilk_update_colorkey
;
727 intel_plane
->get_colorkey
= ilk_get_colorkey
;
730 plane_formats
= snb_plane_formats
;
731 num_plane_formats
= ARRAY_SIZE(snb_plane_formats
);
733 plane_formats
= ilk_plane_formats
;
734 num_plane_formats
= ARRAY_SIZE(ilk_plane_formats
);
739 if (IS_HASWELL(dev
) || IS_VALLEYVIEW(dev
))
740 intel_plane
->can_scale
= false;
742 intel_plane
->can_scale
= true;
743 intel_plane
->max_downscale
= 2;
744 intel_plane
->update_plane
= ivb_update_plane
;
745 intel_plane
->disable_plane
= ivb_disable_plane
;
746 intel_plane
->update_colorkey
= ivb_update_colorkey
;
747 intel_plane
->get_colorkey
= ivb_get_colorkey
;
749 plane_formats
= snb_plane_formats
;
750 num_plane_formats
= ARRAY_SIZE(snb_plane_formats
);
758 intel_plane
->pipe
= pipe
;
759 possible_crtcs
= (1 << pipe
);
760 ret
= drm_plane_init(dev
, &intel_plane
->base
, possible_crtcs
,
762 plane_formats
, num_plane_formats
,