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_atomic.h>
34 #include <drm/drm_atomic_helper.h>
35 #include <drm/drm_color_mgmt.h>
36 #include <drm/drm_crtc.h>
37 #include <drm/drm_damage_helper.h>
38 #include <drm/drm_fourcc.h>
39 #include <drm/drm_plane_helper.h>
40 #include <drm/drm_rect.h>
43 #include "i915_trace.h"
44 #include "i915_vgpu.h"
45 #include "intel_atomic_plane.h"
46 #include "intel_display_types.h"
47 #include "intel_frontbuffer.h"
49 #include "intel_psr.h"
50 #include "intel_dsi.h"
51 #include "intel_sprite.h"
53 int intel_usecs_to_scanlines(const struct drm_display_mode
*adjusted_mode
,
57 if (!adjusted_mode
->crtc_htotal
)
60 return DIV_ROUND_UP(usecs
* adjusted_mode
->crtc_clock
,
61 1000 * adjusted_mode
->crtc_htotal
);
64 /* FIXME: We should instead only take spinlocks once for the entire update
65 * instead of once per mmio. */
66 #if IS_ENABLED(CONFIG_PROVE_LOCKING)
67 #define VBLANK_EVASION_TIME_US 250
69 #define VBLANK_EVASION_TIME_US 100
73 * intel_pipe_update_start() - start update of a set of display registers
74 * @new_crtc_state: the new crtc state
76 * Mark the start of an update to pipe registers that should be updated
77 * atomically regarding vblank. If the next vblank will happens within
78 * the next 100 us, this function waits until the vblank passes.
80 * After a successful call to this function, interrupts will be disabled
81 * until a subsequent call to intel_pipe_update_end(). That is done to
82 * avoid random delays.
84 void intel_pipe_update_start(const struct intel_crtc_state
*new_crtc_state
)
86 struct intel_crtc
*crtc
= to_intel_crtc(new_crtc_state
->uapi
.crtc
);
87 struct drm_i915_private
*dev_priv
= to_i915(crtc
->base
.dev
);
88 const struct drm_display_mode
*adjusted_mode
= &new_crtc_state
->hw
.adjusted_mode
;
89 long timeout
= msecs_to_jiffies_timeout(1);
90 int scanline
, min
, max
, vblank_start
;
91 wait_queue_head_t
*wq
= drm_crtc_vblank_waitqueue(&crtc
->base
);
92 bool need_vlv_dsi_wa
= (IS_VALLEYVIEW(dev_priv
) || IS_CHERRYVIEW(dev_priv
)) &&
93 intel_crtc_has_type(new_crtc_state
, INTEL_OUTPUT_DSI
);
97 if (new_crtc_state
->uapi
.async_flip
)
100 vblank_start
= adjusted_mode
->crtc_vblank_start
;
101 if (adjusted_mode
->flags
& DRM_MODE_FLAG_INTERLACE
)
102 vblank_start
= DIV_ROUND_UP(vblank_start
, 2);
104 /* FIXME needs to be calibrated sensibly */
105 min
= vblank_start
- intel_usecs_to_scanlines(adjusted_mode
,
106 VBLANK_EVASION_TIME_US
);
107 max
= vblank_start
- 1;
109 if (min
<= 0 || max
<= 0)
112 if (drm_WARN_ON(&dev_priv
->drm
, drm_crtc_vblank_get(&crtc
->base
)))
116 * Wait for psr to idle out after enabling the VBL interrupts
117 * VBL interrupts will start the PSR exit and prevent a PSR
120 if (intel_psr_wait_for_idle(new_crtc_state
, &psr_status
))
121 drm_err(&dev_priv
->drm
,
122 "PSR idle timed out 0x%x, atomic update may fail\n",
127 crtc
->debug
.min_vbl
= min
;
128 crtc
->debug
.max_vbl
= max
;
129 trace_intel_pipe_update_start(crtc
);
133 * prepare_to_wait() has a memory barrier, which guarantees
134 * other CPUs can see the task state update by the time we
137 prepare_to_wait(wq
, &wait
, TASK_UNINTERRUPTIBLE
);
139 scanline
= intel_get_crtc_scanline(crtc
);
140 if (scanline
< min
|| scanline
> max
)
144 drm_err(&dev_priv
->drm
,
145 "Potential atomic update failure on pipe %c\n",
146 pipe_name(crtc
->pipe
));
152 timeout
= schedule_timeout(timeout
);
157 finish_wait(wq
, &wait
);
159 drm_crtc_vblank_put(&crtc
->base
);
162 * On VLV/CHV DSI the scanline counter would appear to
163 * increment approx. 1/3 of a scanline before start of vblank.
164 * The registers still get latched at start of vblank however.
165 * This means we must not write any registers on the first
166 * line of vblank (since not the whole line is actually in
167 * vblank). And unfortunately we can't use the interrupt to
168 * wait here since it will fire too soon. We could use the
169 * frame start interrupt instead since it will fire after the
170 * critical scanline, but that would require more changes
171 * in the interrupt code. So for now we'll just do the nasty
172 * thing and poll for the bad scanline to pass us by.
174 * FIXME figure out if BXT+ DSI suffers from this as well
176 while (need_vlv_dsi_wa
&& scanline
== vblank_start
)
177 scanline
= intel_get_crtc_scanline(crtc
);
179 crtc
->debug
.scanline_start
= scanline
;
180 crtc
->debug
.start_vbl_time
= ktime_get();
181 crtc
->debug
.start_vbl_count
= intel_crtc_get_vblank_counter(crtc
);
183 trace_intel_pipe_update_vblank_evaded(crtc
);
191 * intel_pipe_update_end() - end update of a set of display registers
192 * @new_crtc_state: the new crtc state
194 * Mark the end of an update started with intel_pipe_update_start(). This
195 * re-enables interrupts and verifies the update was actually completed
198 void intel_pipe_update_end(struct intel_crtc_state
*new_crtc_state
)
200 struct intel_crtc
*crtc
= to_intel_crtc(new_crtc_state
->uapi
.crtc
);
201 enum pipe pipe
= crtc
->pipe
;
202 int scanline_end
= intel_get_crtc_scanline(crtc
);
203 u32 end_vbl_count
= intel_crtc_get_vblank_counter(crtc
);
204 ktime_t end_vbl_time
= ktime_get();
205 struct drm_i915_private
*dev_priv
= to_i915(crtc
->base
.dev
);
207 if (new_crtc_state
->uapi
.async_flip
)
210 trace_intel_pipe_update_end(crtc
, end_vbl_count
, scanline_end
);
213 * Incase of mipi dsi command mode, we need to set frame update
214 * request for every commit.
216 if (INTEL_GEN(dev_priv
) >= 11 &&
217 intel_crtc_has_type(new_crtc_state
, INTEL_OUTPUT_DSI
))
218 icl_dsi_frame_update(new_crtc_state
);
220 /* We're still in the vblank-evade critical section, this can't race.
221 * Would be slightly nice to just grab the vblank count and arm the
222 * event outside of the critical section - the spinlock might spin for a
224 if (new_crtc_state
->uapi
.event
) {
225 drm_WARN_ON(&dev_priv
->drm
,
226 drm_crtc_vblank_get(&crtc
->base
) != 0);
228 spin_lock(&crtc
->base
.dev
->event_lock
);
229 drm_crtc_arm_vblank_event(&crtc
->base
,
230 new_crtc_state
->uapi
.event
);
231 spin_unlock(&crtc
->base
.dev
->event_lock
);
233 new_crtc_state
->uapi
.event
= NULL
;
238 if (intel_vgpu_active(dev_priv
))
241 if (crtc
->debug
.start_vbl_count
&&
242 crtc
->debug
.start_vbl_count
!= end_vbl_count
) {
243 drm_err(&dev_priv
->drm
,
244 "Atomic update failure on pipe %c (start=%u end=%u) time %lld us, min %d, max %d, scanline start %d, end %d\n",
245 pipe_name(pipe
), crtc
->debug
.start_vbl_count
,
247 ktime_us_delta(end_vbl_time
,
248 crtc
->debug
.start_vbl_time
),
249 crtc
->debug
.min_vbl
, crtc
->debug
.max_vbl
,
250 crtc
->debug
.scanline_start
, scanline_end
);
252 #ifdef CONFIG_DRM_I915_DEBUG_VBLANK_EVADE
253 else if (ktime_us_delta(end_vbl_time
, crtc
->debug
.start_vbl_time
) >
254 VBLANK_EVASION_TIME_US
)
255 drm_warn(&dev_priv
->drm
,
256 "Atomic update on pipe (%c) took %lld us, max time under evasion is %u us\n",
258 ktime_us_delta(end_vbl_time
, crtc
->debug
.start_vbl_time
),
259 VBLANK_EVASION_TIME_US
);
263 int intel_plane_check_stride(const struct intel_plane_state
*plane_state
)
265 struct intel_plane
*plane
= to_intel_plane(plane_state
->uapi
.plane
);
266 const struct drm_framebuffer
*fb
= plane_state
->hw
.fb
;
267 unsigned int rotation
= plane_state
->hw
.rotation
;
268 u32 stride
, max_stride
;
271 * We ignore stride for all invisible planes that
272 * can be remapped. Otherwise we could end up
273 * with a false positive when the remapping didn't
274 * kick in due the plane being invisible.
276 if (intel_plane_can_remap(plane_state
) &&
277 !plane_state
->uapi
.visible
)
280 /* FIXME other color planes? */
281 stride
= plane_state
->color_plane
[0].stride
;
282 max_stride
= plane
->max_stride(plane
, fb
->format
->format
,
283 fb
->modifier
, rotation
);
285 if (stride
> max_stride
) {
286 DRM_DEBUG_KMS("[FB:%d] stride (%d) exceeds [PLANE:%d:%s] max stride (%d)\n",
288 plane
->base
.base
.id
, plane
->base
.name
, max_stride
);
295 int intel_plane_check_src_coordinates(struct intel_plane_state
*plane_state
)
297 const struct drm_framebuffer
*fb
= plane_state
->hw
.fb
;
298 struct drm_rect
*src
= &plane_state
->uapi
.src
;
299 u32 src_x
, src_y
, src_w
, src_h
, hsub
, vsub
;
300 bool rotated
= drm_rotation_90_or_270(plane_state
->hw
.rotation
);
303 * FIXME hsub/vsub vs. block size is a mess. Pre-tgl CCS
304 * abuses hsub/vsub so we can't use them here. But as they
305 * are limited to 32bpp RGB formats we don't actually need
308 if (fb
->modifier
== I915_FORMAT_MOD_Y_TILED_CCS
||
309 fb
->modifier
== I915_FORMAT_MOD_Yf_TILED_CCS
)
313 * Hardware doesn't handle subpixel coordinates.
314 * Adjust to (macro)pixel boundary, but be careful not to
315 * increase the source viewport size, because that could
316 * push the downscaling factor out of bounds.
318 src_x
= src
->x1
>> 16;
319 src_w
= drm_rect_width(src
) >> 16;
320 src_y
= src
->y1
>> 16;
321 src_h
= drm_rect_height(src
) >> 16;
323 drm_rect_init(src
, src_x
<< 16, src_y
<< 16,
324 src_w
<< 16, src_h
<< 16);
326 if (fb
->format
->format
== DRM_FORMAT_RGB565
&& rotated
) {
330 hsub
= fb
->format
->hsub
;
331 vsub
= fb
->format
->vsub
;
335 hsub
= vsub
= max(hsub
, vsub
);
337 if (src_x
% hsub
|| src_w
% hsub
) {
338 DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of %u (rotated: %s)\n",
339 src_x
, src_w
, hsub
, yesno(rotated
));
343 if (src_y
% vsub
|| src_h
% vsub
) {
344 DRM_DEBUG_KMS("src y/h (%u, %u) must be a multiple of %u (rotated: %s)\n",
345 src_y
, src_h
, vsub
, yesno(rotated
));
352 static u8
icl_nv12_y_plane_mask(struct drm_i915_private
*i915
)
354 if (IS_ROCKETLAKE(i915
))
355 return BIT(PLANE_SPRITE2
) | BIT(PLANE_SPRITE3
);
357 return BIT(PLANE_SPRITE4
) | BIT(PLANE_SPRITE5
);
360 bool icl_is_nv12_y_plane(struct drm_i915_private
*dev_priv
,
361 enum plane_id plane_id
)
363 return INTEL_GEN(dev_priv
) >= 11 &&
364 icl_nv12_y_plane_mask(dev_priv
) & BIT(plane_id
);
367 bool icl_is_hdr_plane(struct drm_i915_private
*dev_priv
, enum plane_id plane_id
)
369 return INTEL_GEN(dev_priv
) >= 11 &&
370 icl_hdr_plane_mask() & BIT(plane_id
);
374 skl_plane_ratio(const struct intel_crtc_state
*crtc_state
,
375 const struct intel_plane_state
*plane_state
,
376 unsigned int *num
, unsigned int *den
)
378 struct drm_i915_private
*dev_priv
= to_i915(plane_state
->uapi
.plane
->dev
);
379 const struct drm_framebuffer
*fb
= plane_state
->hw
.fb
;
381 if (fb
->format
->cpp
[0] == 8) {
382 if (INTEL_GEN(dev_priv
) >= 10 || IS_GEMINILAKE(dev_priv
)) {
395 static int skl_plane_min_cdclk(const struct intel_crtc_state
*crtc_state
,
396 const struct intel_plane_state
*plane_state
)
398 struct drm_i915_private
*dev_priv
= to_i915(plane_state
->uapi
.plane
->dev
);
399 unsigned int num
, den
;
400 unsigned int pixel_rate
= intel_plane_pixel_rate(crtc_state
, plane_state
);
402 skl_plane_ratio(crtc_state
, plane_state
, &num
, &den
);
404 /* two pixels per clock on glk+ */
405 if (INTEL_GEN(dev_priv
) >= 10 || IS_GEMINILAKE(dev_priv
))
408 return DIV_ROUND_UP(pixel_rate
* num
, den
);
411 static int skl_plane_max_width(const struct drm_framebuffer
*fb
,
413 unsigned int rotation
)
415 int cpp
= fb
->format
->cpp
[color_plane
];
417 switch (fb
->modifier
) {
418 case DRM_FORMAT_MOD_LINEAR
:
419 case I915_FORMAT_MOD_X_TILED
:
421 * Validated limit is 4k, but has 5k should
422 * work apart from the following features:
423 * - Ytile (already limited to 4k)
424 * - FP16 (already limited to 4k)
425 * - render compression (already limited to 4k)
426 * - KVMR sprite and cursor (don't care)
427 * - horizontal panning (TODO verify this)
428 * - pipe and plane scaling (TODO verify this)
434 case I915_FORMAT_MOD_Y_TILED_CCS
:
435 case I915_FORMAT_MOD_Yf_TILED_CCS
:
436 case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS
:
437 /* FIXME AUX plane? */
438 case I915_FORMAT_MOD_Y_TILED
:
439 case I915_FORMAT_MOD_Yf_TILED
:
445 MISSING_CASE(fb
->modifier
);
450 static int glk_plane_max_width(const struct drm_framebuffer
*fb
,
452 unsigned int rotation
)
454 int cpp
= fb
->format
->cpp
[color_plane
];
456 switch (fb
->modifier
) {
457 case DRM_FORMAT_MOD_LINEAR
:
458 case I915_FORMAT_MOD_X_TILED
:
463 case I915_FORMAT_MOD_Y_TILED_CCS
:
464 case I915_FORMAT_MOD_Yf_TILED_CCS
:
465 /* FIXME AUX plane? */
466 case I915_FORMAT_MOD_Y_TILED
:
467 case I915_FORMAT_MOD_Yf_TILED
:
473 MISSING_CASE(fb
->modifier
);
478 static int icl_plane_min_width(const struct drm_framebuffer
*fb
,
480 unsigned int rotation
)
482 /* Wa_14011264657, Wa_14011050563: gen11+ */
483 switch (fb
->format
->format
) {
486 case DRM_FORMAT_RGB565
:
488 case DRM_FORMAT_XRGB8888
:
489 case DRM_FORMAT_XBGR8888
:
490 case DRM_FORMAT_ARGB8888
:
491 case DRM_FORMAT_ABGR8888
:
492 case DRM_FORMAT_XRGB2101010
:
493 case DRM_FORMAT_XBGR2101010
:
494 case DRM_FORMAT_ARGB2101010
:
495 case DRM_FORMAT_ABGR2101010
:
496 case DRM_FORMAT_XVYU2101010
:
497 case DRM_FORMAT_Y212
:
498 case DRM_FORMAT_Y216
:
500 case DRM_FORMAT_NV12
:
502 case DRM_FORMAT_P010
:
503 case DRM_FORMAT_P012
:
504 case DRM_FORMAT_P016
:
506 case DRM_FORMAT_XRGB16161616F
:
507 case DRM_FORMAT_XBGR16161616F
:
508 case DRM_FORMAT_ARGB16161616F
:
509 case DRM_FORMAT_ABGR16161616F
:
510 case DRM_FORMAT_XVYU12_16161616
:
511 case DRM_FORMAT_XVYU16161616
:
518 static int icl_plane_max_width(const struct drm_framebuffer
*fb
,
520 unsigned int rotation
)
525 static int skl_plane_max_height(const struct drm_framebuffer
*fb
,
527 unsigned int rotation
)
532 static int icl_plane_max_height(const struct drm_framebuffer
*fb
,
534 unsigned int rotation
)
540 skl_plane_max_stride(struct intel_plane
*plane
,
541 u32 pixel_format
, u64 modifier
,
542 unsigned int rotation
)
544 const struct drm_format_info
*info
= drm_format_info(pixel_format
);
545 int cpp
= info
->cpp
[0];
548 * "The stride in bytes must not exceed the
549 * of the size of 8K pixels and 32K bytes."
551 if (drm_rotation_90_or_270(rotation
))
552 return min(8192, 32768 / cpp
);
554 return min(8192 * cpp
, 32768);
558 skl_program_scaler(struct intel_plane
*plane
,
559 const struct intel_crtc_state
*crtc_state
,
560 const struct intel_plane_state
*plane_state
)
562 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
563 const struct drm_framebuffer
*fb
= plane_state
->hw
.fb
;
564 enum pipe pipe
= plane
->pipe
;
565 int scaler_id
= plane_state
->scaler_id
;
566 const struct intel_scaler
*scaler
=
567 &crtc_state
->scaler_state
.scalers
[scaler_id
];
568 int crtc_x
= plane_state
->uapi
.dst
.x1
;
569 int crtc_y
= plane_state
->uapi
.dst
.y1
;
570 u32 crtc_w
= drm_rect_width(&plane_state
->uapi
.dst
);
571 u32 crtc_h
= drm_rect_height(&plane_state
->uapi
.dst
);
572 u16 y_hphase
, uv_rgb_hphase
;
573 u16 y_vphase
, uv_rgb_vphase
;
577 hscale
= drm_rect_calc_hscale(&plane_state
->uapi
.src
,
578 &plane_state
->uapi
.dst
,
580 vscale
= drm_rect_calc_vscale(&plane_state
->uapi
.src
,
581 &plane_state
->uapi
.dst
,
584 /* TODO: handle sub-pixel coordinates */
585 if (intel_format_info_is_yuv_semiplanar(fb
->format
, fb
->modifier
) &&
586 !icl_is_hdr_plane(dev_priv
, plane
->id
)) {
587 y_hphase
= skl_scaler_calc_phase(1, hscale
, false);
588 y_vphase
= skl_scaler_calc_phase(1, vscale
, false);
590 /* MPEG2 chroma siting convention */
591 uv_rgb_hphase
= skl_scaler_calc_phase(2, hscale
, true);
592 uv_rgb_vphase
= skl_scaler_calc_phase(2, vscale
, false);
598 uv_rgb_hphase
= skl_scaler_calc_phase(1, hscale
, false);
599 uv_rgb_vphase
= skl_scaler_calc_phase(1, vscale
, false);
602 ps_ctrl
= skl_scaler_get_filter_select(plane_state
->hw
.scaling_filter
, 0);
603 ps_ctrl
|= PS_SCALER_EN
| PS_PLANE_SEL(plane
->id
) | scaler
->mode
;
605 skl_scaler_setup_filter(dev_priv
, pipe
, scaler_id
, 0,
606 plane_state
->hw
.scaling_filter
);
608 intel_de_write_fw(dev_priv
, SKL_PS_CTRL(pipe
, scaler_id
), ps_ctrl
);
609 intel_de_write_fw(dev_priv
, SKL_PS_VPHASE(pipe
, scaler_id
),
610 PS_Y_PHASE(y_vphase
) | PS_UV_RGB_PHASE(uv_rgb_vphase
));
611 intel_de_write_fw(dev_priv
, SKL_PS_HPHASE(pipe
, scaler_id
),
612 PS_Y_PHASE(y_hphase
) | PS_UV_RGB_PHASE(uv_rgb_hphase
));
613 intel_de_write_fw(dev_priv
, SKL_PS_WIN_POS(pipe
, scaler_id
),
614 (crtc_x
<< 16) | crtc_y
);
615 intel_de_write_fw(dev_priv
, SKL_PS_WIN_SZ(pipe
, scaler_id
),
616 (crtc_w
<< 16) | crtc_h
);
619 /* Preoffset values for YUV to RGB Conversion */
620 #define PREOFF_YUV_TO_RGB_HI 0x1800
621 #define PREOFF_YUV_TO_RGB_ME 0x1F00
622 #define PREOFF_YUV_TO_RGB_LO 0x1800
624 #define ROFF(x) (((x) & 0xffff) << 16)
625 #define GOFF(x) (((x) & 0xffff) << 0)
626 #define BOFF(x) (((x) & 0xffff) << 16)
629 icl_program_input_csc(struct intel_plane
*plane
,
630 const struct intel_crtc_state
*crtc_state
,
631 const struct intel_plane_state
*plane_state
)
633 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
634 enum pipe pipe
= plane
->pipe
;
635 enum plane_id plane_id
= plane
->id
;
637 static const u16 input_csc_matrix
[][9] = {
639 * BT.601 full range YCbCr -> full range RGB
640 * The matrix required is :
641 * [1.000, 0.000, 1.371,
642 * 1.000, -0.336, -0.698,
643 * 1.000, 1.732, 0.0000]
645 [DRM_COLOR_YCBCR_BT601
] = {
647 0x8B28, 0x7800, 0x9AC0,
651 * BT.709 full range YCbCr -> full range RGB
652 * The matrix required is :
653 * [1.000, 0.000, 1.574,
654 * 1.000, -0.187, -0.468,
655 * 1.000, 1.855, 0.0000]
657 [DRM_COLOR_YCBCR_BT709
] = {
659 0x9EF8, 0x7800, 0xAC00,
663 * BT.2020 full range YCbCr -> full range RGB
664 * The matrix required is :
665 * [1.000, 0.000, 1.474,
666 * 1.000, -0.1645, -0.5713,
667 * 1.000, 1.8814, 0.0000]
669 [DRM_COLOR_YCBCR_BT2020
] = {
671 0x8928, 0x7800, 0xAA88,
676 /* Matrix for Limited Range to Full Range Conversion */
677 static const u16 input_csc_matrix_lr
[][9] = {
679 * BT.601 Limted range YCbCr -> full range RGB
680 * The matrix required is :
681 * [1.164384, 0.000, 1.596027,
682 * 1.164384, -0.39175, -0.812813,
683 * 1.164384, 2.017232, 0.0000]
685 [DRM_COLOR_YCBCR_BT601
] = {
687 0x8D00, 0x7950, 0x9C88,
691 * BT.709 Limited range YCbCr -> full range RGB
692 * The matrix required is :
693 * [1.164384, 0.000, 1.792741,
694 * 1.164384, -0.213249, -0.532909,
695 * 1.164384, 2.112402, 0.0000]
697 [DRM_COLOR_YCBCR_BT709
] = {
699 0x8888, 0x7950, 0xADA8,
703 * BT.2020 Limited range YCbCr -> full range RGB
704 * The matrix required is :
705 * [1.164, 0.000, 1.678,
706 * 1.164, -0.1873, -0.6504,
707 * 1.164, 2.1417, 0.0000]
709 [DRM_COLOR_YCBCR_BT2020
] = {
711 0x8A68, 0x7950, 0xAC00,
717 if (plane_state
->hw
.color_range
== DRM_COLOR_YCBCR_FULL_RANGE
)
718 csc
= input_csc_matrix
[plane_state
->hw
.color_encoding
];
720 csc
= input_csc_matrix_lr
[plane_state
->hw
.color_encoding
];
722 intel_de_write_fw(dev_priv
, PLANE_INPUT_CSC_COEFF(pipe
, plane_id
, 0),
723 ROFF(csc
[0]) | GOFF(csc
[1]));
724 intel_de_write_fw(dev_priv
, PLANE_INPUT_CSC_COEFF(pipe
, plane_id
, 1),
726 intel_de_write_fw(dev_priv
, PLANE_INPUT_CSC_COEFF(pipe
, plane_id
, 2),
727 ROFF(csc
[3]) | GOFF(csc
[4]));
728 intel_de_write_fw(dev_priv
, PLANE_INPUT_CSC_COEFF(pipe
, plane_id
, 3),
730 intel_de_write_fw(dev_priv
, PLANE_INPUT_CSC_COEFF(pipe
, plane_id
, 4),
731 ROFF(csc
[6]) | GOFF(csc
[7]));
732 intel_de_write_fw(dev_priv
, PLANE_INPUT_CSC_COEFF(pipe
, plane_id
, 5),
735 intel_de_write_fw(dev_priv
, PLANE_INPUT_CSC_PREOFF(pipe
, plane_id
, 0),
736 PREOFF_YUV_TO_RGB_HI
);
737 if (plane_state
->hw
.color_range
== DRM_COLOR_YCBCR_FULL_RANGE
)
738 intel_de_write_fw(dev_priv
,
739 PLANE_INPUT_CSC_PREOFF(pipe
, plane_id
, 1),
742 intel_de_write_fw(dev_priv
,
743 PLANE_INPUT_CSC_PREOFF(pipe
, plane_id
, 1),
744 PREOFF_YUV_TO_RGB_ME
);
745 intel_de_write_fw(dev_priv
, PLANE_INPUT_CSC_PREOFF(pipe
, plane_id
, 2),
746 PREOFF_YUV_TO_RGB_LO
);
747 intel_de_write_fw(dev_priv
,
748 PLANE_INPUT_CSC_POSTOFF(pipe
, plane_id
, 0), 0x0);
749 intel_de_write_fw(dev_priv
,
750 PLANE_INPUT_CSC_POSTOFF(pipe
, plane_id
, 1), 0x0);
751 intel_de_write_fw(dev_priv
,
752 PLANE_INPUT_CSC_POSTOFF(pipe
, plane_id
, 2), 0x0);
756 skl_plane_async_flip(struct intel_plane
*plane
,
757 const struct intel_crtc_state
*crtc_state
,
758 const struct intel_plane_state
*plane_state
)
760 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
761 unsigned long irqflags
;
762 enum plane_id plane_id
= plane
->id
;
763 enum pipe pipe
= plane
->pipe
;
764 u32 surf_addr
= plane_state
->color_plane
[0].offset
;
765 u32 plane_ctl
= plane_state
->ctl
;
767 plane_ctl
|= skl_plane_ctl_crtc(crtc_state
);
769 spin_lock_irqsave(&dev_priv
->uncore
.lock
, irqflags
);
771 intel_de_write_fw(dev_priv
, PLANE_CTL(pipe
, plane_id
), plane_ctl
);
772 intel_de_write_fw(dev_priv
, PLANE_SURF(pipe
, plane_id
),
773 intel_plane_ggtt_offset(plane_state
) + surf_addr
);
775 spin_unlock_irqrestore(&dev_priv
->uncore
.lock
, irqflags
);
779 skl_program_plane(struct intel_plane
*plane
,
780 const struct intel_crtc_state
*crtc_state
,
781 const struct intel_plane_state
*plane_state
,
784 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
785 enum plane_id plane_id
= plane
->id
;
786 enum pipe pipe
= plane
->pipe
;
787 const struct drm_intel_sprite_colorkey
*key
= &plane_state
->ckey
;
788 u32 surf_addr
= plane_state
->color_plane
[color_plane
].offset
;
789 u32 stride
= skl_plane_stride(plane_state
, color_plane
);
790 const struct drm_framebuffer
*fb
= plane_state
->hw
.fb
;
791 int aux_plane
= intel_main_to_aux_plane(fb
, color_plane
);
792 int crtc_x
= plane_state
->uapi
.dst
.x1
;
793 int crtc_y
= plane_state
->uapi
.dst
.y1
;
794 u32 x
= plane_state
->color_plane
[color_plane
].x
;
795 u32 y
= plane_state
->color_plane
[color_plane
].y
;
796 u32 src_w
= drm_rect_width(&plane_state
->uapi
.src
) >> 16;
797 u32 src_h
= drm_rect_height(&plane_state
->uapi
.src
) >> 16;
798 u8 alpha
= plane_state
->hw
.alpha
>> 8;
799 u32 plane_color_ctl
= 0, aux_dist
= 0;
800 unsigned long irqflags
;
802 u32 plane_ctl
= plane_state
->ctl
;
804 plane_ctl
|= skl_plane_ctl_crtc(crtc_state
);
806 if (INTEL_GEN(dev_priv
) >= 10 || IS_GEMINILAKE(dev_priv
))
807 plane_color_ctl
= plane_state
->color_ctl
|
808 glk_plane_color_ctl_crtc(crtc_state
);
810 /* Sizes are 0 based */
814 keymax
= (key
->max_value
& 0xffffff) | PLANE_KEYMAX_ALPHA(alpha
);
816 keymsk
= key
->channel_mask
& 0x7ffffff;
818 keymsk
|= PLANE_KEYMSK_ALPHA_ENABLE
;
820 /* The scaler will handle the output position */
821 if (plane_state
->scaler_id
>= 0) {
827 aux_dist
= plane_state
->color_plane
[aux_plane
].offset
- surf_addr
;
829 if (INTEL_GEN(dev_priv
) < 12)
830 aux_dist
|= skl_plane_stride(plane_state
, aux_plane
);
833 spin_lock_irqsave(&dev_priv
->uncore
.lock
, irqflags
);
835 intel_de_write_fw(dev_priv
, PLANE_STRIDE(pipe
, plane_id
), stride
);
836 intel_de_write_fw(dev_priv
, PLANE_POS(pipe
, plane_id
),
837 (crtc_y
<< 16) | crtc_x
);
838 intel_de_write_fw(dev_priv
, PLANE_SIZE(pipe
, plane_id
),
839 (src_h
<< 16) | src_w
);
841 intel_de_write_fw(dev_priv
, PLANE_AUX_DIST(pipe
, plane_id
), aux_dist
);
843 if (icl_is_hdr_plane(dev_priv
, plane_id
))
844 intel_de_write_fw(dev_priv
, PLANE_CUS_CTL(pipe
, plane_id
),
845 plane_state
->cus_ctl
);
847 if (INTEL_GEN(dev_priv
) >= 10 || IS_GEMINILAKE(dev_priv
))
848 intel_de_write_fw(dev_priv
, PLANE_COLOR_CTL(pipe
, plane_id
),
851 if (fb
->format
->is_yuv
&& icl_is_hdr_plane(dev_priv
, plane_id
))
852 icl_program_input_csc(plane
, crtc_state
, plane_state
);
854 skl_write_plane_wm(plane
, crtc_state
);
856 intel_de_write_fw(dev_priv
, PLANE_KEYVAL(pipe
, plane_id
),
858 intel_de_write_fw(dev_priv
, PLANE_KEYMSK(pipe
, plane_id
), keymsk
);
859 intel_de_write_fw(dev_priv
, PLANE_KEYMAX(pipe
, plane_id
), keymax
);
861 intel_de_write_fw(dev_priv
, PLANE_OFFSET(pipe
, plane_id
),
864 if (INTEL_GEN(dev_priv
) < 11)
865 intel_de_write_fw(dev_priv
, PLANE_AUX_OFFSET(pipe
, plane_id
),
866 (plane_state
->color_plane
[1].y
<< 16) | plane_state
->color_plane
[1].x
);
868 if (!drm_atomic_crtc_needs_modeset(&crtc_state
->uapi
))
869 intel_psr2_program_plane_sel_fetch(plane
, crtc_state
, plane_state
, color_plane
);
872 * The control register self-arms if the plane was previously
873 * disabled. Try to make the plane enable atomic by writing
874 * the control register just before the surface register.
876 intel_de_write_fw(dev_priv
, PLANE_CTL(pipe
, plane_id
), plane_ctl
);
877 intel_de_write_fw(dev_priv
, PLANE_SURF(pipe
, plane_id
),
878 intel_plane_ggtt_offset(plane_state
) + surf_addr
);
880 if (plane_state
->scaler_id
>= 0)
881 skl_program_scaler(plane
, crtc_state
, plane_state
);
883 spin_unlock_irqrestore(&dev_priv
->uncore
.lock
, irqflags
);
887 skl_update_plane(struct intel_plane
*plane
,
888 const struct intel_crtc_state
*crtc_state
,
889 const struct intel_plane_state
*plane_state
)
893 if (plane_state
->planar_linked_plane
&& !plane_state
->planar_slave
)
894 /* Program the UV plane on planar master */
897 skl_program_plane(plane
, crtc_state
, plane_state
, color_plane
);
900 skl_disable_plane(struct intel_plane
*plane
,
901 const struct intel_crtc_state
*crtc_state
)
903 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
904 enum plane_id plane_id
= plane
->id
;
905 enum pipe pipe
= plane
->pipe
;
906 unsigned long irqflags
;
908 spin_lock_irqsave(&dev_priv
->uncore
.lock
, irqflags
);
910 if (icl_is_hdr_plane(dev_priv
, plane_id
))
911 intel_de_write_fw(dev_priv
, PLANE_CUS_CTL(pipe
, plane_id
), 0);
913 skl_write_plane_wm(plane
, crtc_state
);
915 intel_de_write_fw(dev_priv
, PLANE_CTL(pipe
, plane_id
), 0);
916 intel_de_write_fw(dev_priv
, PLANE_SURF(pipe
, plane_id
), 0);
918 spin_unlock_irqrestore(&dev_priv
->uncore
.lock
, irqflags
);
922 skl_plane_get_hw_state(struct intel_plane
*plane
,
925 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
926 enum intel_display_power_domain power_domain
;
927 enum plane_id plane_id
= plane
->id
;
928 intel_wakeref_t wakeref
;
931 power_domain
= POWER_DOMAIN_PIPE(plane
->pipe
);
932 wakeref
= intel_display_power_get_if_enabled(dev_priv
, power_domain
);
936 ret
= intel_de_read(dev_priv
, PLANE_CTL(plane
->pipe
, plane_id
)) & PLANE_CTL_ENABLE
;
940 intel_display_power_put(dev_priv
, power_domain
, wakeref
);
945 static void i9xx_plane_linear_gamma(u16 gamma
[8])
947 /* The points are not evenly spaced. */
948 static const u8 in
[8] = { 0, 1, 2, 4, 8, 16, 24, 32 };
951 for (i
= 0; i
< 8; i
++)
952 gamma
[i
] = (in
[i
] << 8) / 32;
956 chv_update_csc(const struct intel_plane_state
*plane_state
)
958 struct intel_plane
*plane
= to_intel_plane(plane_state
->uapi
.plane
);
959 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
960 const struct drm_framebuffer
*fb
= plane_state
->hw
.fb
;
961 enum plane_id plane_id
= plane
->id
;
963 * |r| | c0 c1 c2 | |cr|
964 * |g| = | c3 c4 c5 | x |y |
965 * |b| | c6 c7 c8 | |cb|
967 * Coefficients are s3.12.
969 * Cb and Cr apparently come in as signed already, and
970 * we always get full range data in on account of CLRC0/1.
972 static const s16 csc_matrix
[][9] = {
973 /* BT.601 full range YCbCr -> full range RGB */
974 [DRM_COLOR_YCBCR_BT601
] = {
979 /* BT.709 full range YCbCr -> full range RGB */
980 [DRM_COLOR_YCBCR_BT709
] = {
986 const s16
*csc
= csc_matrix
[plane_state
->hw
.color_encoding
];
988 /* Seems RGB data bypasses the CSC always */
989 if (!fb
->format
->is_yuv
)
992 intel_de_write_fw(dev_priv
, SPCSCYGOFF(plane_id
),
993 SPCSC_OOFF(0) | SPCSC_IOFF(0));
994 intel_de_write_fw(dev_priv
, SPCSCCBOFF(plane_id
),
995 SPCSC_OOFF(0) | SPCSC_IOFF(0));
996 intel_de_write_fw(dev_priv
, SPCSCCROFF(plane_id
),
997 SPCSC_OOFF(0) | SPCSC_IOFF(0));
999 intel_de_write_fw(dev_priv
, SPCSCC01(plane_id
),
1000 SPCSC_C1(csc
[1]) | SPCSC_C0(csc
[0]));
1001 intel_de_write_fw(dev_priv
, SPCSCC23(plane_id
),
1002 SPCSC_C1(csc
[3]) | SPCSC_C0(csc
[2]));
1003 intel_de_write_fw(dev_priv
, SPCSCC45(plane_id
),
1004 SPCSC_C1(csc
[5]) | SPCSC_C0(csc
[4]));
1005 intel_de_write_fw(dev_priv
, SPCSCC67(plane_id
),
1006 SPCSC_C1(csc
[7]) | SPCSC_C0(csc
[6]));
1007 intel_de_write_fw(dev_priv
, SPCSCC8(plane_id
), SPCSC_C0(csc
[8]));
1009 intel_de_write_fw(dev_priv
, SPCSCYGICLAMP(plane_id
),
1010 SPCSC_IMAX(1023) | SPCSC_IMIN(0));
1011 intel_de_write_fw(dev_priv
, SPCSCCBICLAMP(plane_id
),
1012 SPCSC_IMAX(512) | SPCSC_IMIN(-512));
1013 intel_de_write_fw(dev_priv
, SPCSCCRICLAMP(plane_id
),
1014 SPCSC_IMAX(512) | SPCSC_IMIN(-512));
1016 intel_de_write_fw(dev_priv
, SPCSCYGOCLAMP(plane_id
),
1017 SPCSC_OMAX(1023) | SPCSC_OMIN(0));
1018 intel_de_write_fw(dev_priv
, SPCSCCBOCLAMP(plane_id
),
1019 SPCSC_OMAX(1023) | SPCSC_OMIN(0));
1020 intel_de_write_fw(dev_priv
, SPCSCCROCLAMP(plane_id
),
1021 SPCSC_OMAX(1023) | SPCSC_OMIN(0));
1028 vlv_update_clrc(const struct intel_plane_state
*plane_state
)
1030 struct intel_plane
*plane
= to_intel_plane(plane_state
->uapi
.plane
);
1031 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
1032 const struct drm_framebuffer
*fb
= plane_state
->hw
.fb
;
1033 enum pipe pipe
= plane
->pipe
;
1034 enum plane_id plane_id
= plane
->id
;
1035 int contrast
, brightness
, sh_scale
, sh_sin
, sh_cos
;
1037 if (fb
->format
->is_yuv
&&
1038 plane_state
->hw
.color_range
== DRM_COLOR_YCBCR_LIMITED_RANGE
) {
1040 * Expand limited range to full range:
1041 * Contrast is applied first and is used to expand Y range.
1042 * Brightness is applied second and is used to remove the
1043 * offset from Y. Saturation/hue is used to expand CbCr range.
1045 contrast
= DIV_ROUND_CLOSEST(255 << 6, 235 - 16);
1046 brightness
= -DIV_ROUND_CLOSEST(16 * 255, 235 - 16);
1047 sh_scale
= DIV_ROUND_CLOSEST(128 << 7, 240 - 128);
1048 sh_sin
= SIN_0
* sh_scale
;
1049 sh_cos
= COS_0
* sh_scale
;
1051 /* Pass-through everything. */
1055 sh_sin
= SIN_0
* sh_scale
;
1056 sh_cos
= COS_0
* sh_scale
;
1059 /* FIXME these register are single buffered :( */
1060 intel_de_write_fw(dev_priv
, SPCLRC0(pipe
, plane_id
),
1061 SP_CONTRAST(contrast
) | SP_BRIGHTNESS(brightness
));
1062 intel_de_write_fw(dev_priv
, SPCLRC1(pipe
, plane_id
),
1063 SP_SH_SIN(sh_sin
) | SP_SH_COS(sh_cos
));
1067 vlv_plane_ratio(const struct intel_crtc_state
*crtc_state
,
1068 const struct intel_plane_state
*plane_state
,
1069 unsigned int *num
, unsigned int *den
)
1071 u8 active_planes
= crtc_state
->active_planes
& ~BIT(PLANE_CURSOR
);
1072 const struct drm_framebuffer
*fb
= plane_state
->hw
.fb
;
1073 unsigned int cpp
= fb
->format
->cpp
[0];
1076 * VLV bspec only considers cases where all three planes are
1077 * enabled, and cases where the primary and one sprite is enabled.
1078 * Let's assume the case with just two sprites enabled also
1079 * maps to the latter case.
1081 if (hweight8(active_planes
) == 3) {
1096 } else if (hweight8(active_planes
) == 2) {
1125 int vlv_plane_min_cdclk(const struct intel_crtc_state
*crtc_state
,
1126 const struct intel_plane_state
*plane_state
)
1128 unsigned int pixel_rate
;
1129 unsigned int num
, den
;
1132 * Note that crtc_state->pixel_rate accounts for both
1133 * horizontal and vertical panel fitter downscaling factors.
1134 * Pre-HSW bspec tells us to only consider the horizontal
1135 * downscaling factor here. We ignore that and just consider
1136 * both for simplicity.
1138 pixel_rate
= crtc_state
->pixel_rate
;
1140 vlv_plane_ratio(crtc_state
, plane_state
, &num
, &den
);
1142 return DIV_ROUND_UP(pixel_rate
* num
, den
);
1145 static u32
vlv_sprite_ctl_crtc(const struct intel_crtc_state
*crtc_state
)
1149 if (crtc_state
->gamma_enable
)
1150 sprctl
|= SP_GAMMA_ENABLE
;
1155 static u32
vlv_sprite_ctl(const struct intel_crtc_state
*crtc_state
,
1156 const struct intel_plane_state
*plane_state
)
1158 const struct drm_framebuffer
*fb
= plane_state
->hw
.fb
;
1159 unsigned int rotation
= plane_state
->hw
.rotation
;
1160 const struct drm_intel_sprite_colorkey
*key
= &plane_state
->ckey
;
1165 switch (fb
->format
->format
) {
1166 case DRM_FORMAT_YUYV
:
1167 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_YUYV
;
1169 case DRM_FORMAT_YVYU
:
1170 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_YVYU
;
1172 case DRM_FORMAT_UYVY
:
1173 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_UYVY
;
1175 case DRM_FORMAT_VYUY
:
1176 sprctl
|= SP_FORMAT_YUV422
| SP_YUV_ORDER_VYUY
;
1179 sprctl
|= SP_FORMAT_8BPP
;
1181 case DRM_FORMAT_RGB565
:
1182 sprctl
|= SP_FORMAT_BGR565
;
1184 case DRM_FORMAT_XRGB8888
:
1185 sprctl
|= SP_FORMAT_BGRX8888
;
1187 case DRM_FORMAT_ARGB8888
:
1188 sprctl
|= SP_FORMAT_BGRA8888
;
1190 case DRM_FORMAT_XBGR2101010
:
1191 sprctl
|= SP_FORMAT_RGBX1010102
;
1193 case DRM_FORMAT_ABGR2101010
:
1194 sprctl
|= SP_FORMAT_RGBA1010102
;
1196 case DRM_FORMAT_XRGB2101010
:
1197 sprctl
|= SP_FORMAT_BGRX1010102
;
1199 case DRM_FORMAT_ARGB2101010
:
1200 sprctl
|= SP_FORMAT_BGRA1010102
;
1202 case DRM_FORMAT_XBGR8888
:
1203 sprctl
|= SP_FORMAT_RGBX8888
;
1205 case DRM_FORMAT_ABGR8888
:
1206 sprctl
|= SP_FORMAT_RGBA8888
;
1209 MISSING_CASE(fb
->format
->format
);
1213 if (plane_state
->hw
.color_encoding
== DRM_COLOR_YCBCR_BT709
)
1214 sprctl
|= SP_YUV_FORMAT_BT709
;
1216 if (fb
->modifier
== I915_FORMAT_MOD_X_TILED
)
1219 if (rotation
& DRM_MODE_ROTATE_180
)
1220 sprctl
|= SP_ROTATE_180
;
1222 if (rotation
& DRM_MODE_REFLECT_X
)
1223 sprctl
|= SP_MIRROR
;
1225 if (key
->flags
& I915_SET_COLORKEY_SOURCE
)
1226 sprctl
|= SP_SOURCE_KEY
;
1231 static void vlv_update_gamma(const struct intel_plane_state
*plane_state
)
1233 struct intel_plane
*plane
= to_intel_plane(plane_state
->uapi
.plane
);
1234 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
1235 const struct drm_framebuffer
*fb
= plane_state
->hw
.fb
;
1236 enum pipe pipe
= plane
->pipe
;
1237 enum plane_id plane_id
= plane
->id
;
1241 /* Seems RGB data bypasses the gamma always */
1242 if (!fb
->format
->is_yuv
)
1245 i9xx_plane_linear_gamma(gamma
);
1247 /* FIXME these register are single buffered :( */
1248 /* The two end points are implicit (0.0 and 1.0) */
1249 for (i
= 1; i
< 8 - 1; i
++)
1250 intel_de_write_fw(dev_priv
, SPGAMC(pipe
, plane_id
, i
- 1),
1251 gamma
[i
] << 16 | gamma
[i
] << 8 | gamma
[i
]);
1255 vlv_update_plane(struct intel_plane
*plane
,
1256 const struct intel_crtc_state
*crtc_state
,
1257 const struct intel_plane_state
*plane_state
)
1259 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
1260 enum pipe pipe
= plane
->pipe
;
1261 enum plane_id plane_id
= plane
->id
;
1262 u32 sprsurf_offset
= plane_state
->color_plane
[0].offset
;
1264 const struct drm_intel_sprite_colorkey
*key
= &plane_state
->ckey
;
1265 int crtc_x
= plane_state
->uapi
.dst
.x1
;
1266 int crtc_y
= plane_state
->uapi
.dst
.y1
;
1267 u32 crtc_w
= drm_rect_width(&plane_state
->uapi
.dst
);
1268 u32 crtc_h
= drm_rect_height(&plane_state
->uapi
.dst
);
1269 u32 x
= plane_state
->color_plane
[0].x
;
1270 u32 y
= plane_state
->color_plane
[0].y
;
1271 unsigned long irqflags
;
1274 sprctl
= plane_state
->ctl
| vlv_sprite_ctl_crtc(crtc_state
);
1276 /* Sizes are 0 based */
1280 linear_offset
= intel_fb_xy_to_linear(x
, y
, plane_state
, 0);
1282 spin_lock_irqsave(&dev_priv
->uncore
.lock
, irqflags
);
1284 intel_de_write_fw(dev_priv
, SPSTRIDE(pipe
, plane_id
),
1285 plane_state
->color_plane
[0].stride
);
1286 intel_de_write_fw(dev_priv
, SPPOS(pipe
, plane_id
),
1287 (crtc_y
<< 16) | crtc_x
);
1288 intel_de_write_fw(dev_priv
, SPSIZE(pipe
, plane_id
),
1289 (crtc_h
<< 16) | crtc_w
);
1290 intel_de_write_fw(dev_priv
, SPCONSTALPHA(pipe
, plane_id
), 0);
1292 if (IS_CHERRYVIEW(dev_priv
) && pipe
== PIPE_B
)
1293 chv_update_csc(plane_state
);
1296 intel_de_write_fw(dev_priv
, SPKEYMINVAL(pipe
, plane_id
),
1298 intel_de_write_fw(dev_priv
, SPKEYMSK(pipe
, plane_id
),
1300 intel_de_write_fw(dev_priv
, SPKEYMAXVAL(pipe
, plane_id
),
1304 intel_de_write_fw(dev_priv
, SPLINOFF(pipe
, plane_id
), linear_offset
);
1305 intel_de_write_fw(dev_priv
, SPTILEOFF(pipe
, plane_id
), (y
<< 16) | x
);
1308 * The control register self-arms if the plane was previously
1309 * disabled. Try to make the plane enable atomic by writing
1310 * the control register just before the surface register.
1312 intel_de_write_fw(dev_priv
, SPCNTR(pipe
, plane_id
), sprctl
);
1313 intel_de_write_fw(dev_priv
, SPSURF(pipe
, plane_id
),
1314 intel_plane_ggtt_offset(plane_state
) + sprsurf_offset
);
1316 vlv_update_clrc(plane_state
);
1317 vlv_update_gamma(plane_state
);
1319 spin_unlock_irqrestore(&dev_priv
->uncore
.lock
, irqflags
);
1323 vlv_disable_plane(struct intel_plane
*plane
,
1324 const struct intel_crtc_state
*crtc_state
)
1326 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
1327 enum pipe pipe
= plane
->pipe
;
1328 enum plane_id plane_id
= plane
->id
;
1329 unsigned long irqflags
;
1331 spin_lock_irqsave(&dev_priv
->uncore
.lock
, irqflags
);
1333 intel_de_write_fw(dev_priv
, SPCNTR(pipe
, plane_id
), 0);
1334 intel_de_write_fw(dev_priv
, SPSURF(pipe
, plane_id
), 0);
1336 spin_unlock_irqrestore(&dev_priv
->uncore
.lock
, irqflags
);
1340 vlv_plane_get_hw_state(struct intel_plane
*plane
,
1343 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
1344 enum intel_display_power_domain power_domain
;
1345 enum plane_id plane_id
= plane
->id
;
1346 intel_wakeref_t wakeref
;
1349 power_domain
= POWER_DOMAIN_PIPE(plane
->pipe
);
1350 wakeref
= intel_display_power_get_if_enabled(dev_priv
, power_domain
);
1354 ret
= intel_de_read(dev_priv
, SPCNTR(plane
->pipe
, plane_id
)) & SP_ENABLE
;
1356 *pipe
= plane
->pipe
;
1358 intel_display_power_put(dev_priv
, power_domain
, wakeref
);
1363 static void ivb_plane_ratio(const struct intel_crtc_state
*crtc_state
,
1364 const struct intel_plane_state
*plane_state
,
1365 unsigned int *num
, unsigned int *den
)
1367 u8 active_planes
= crtc_state
->active_planes
& ~BIT(PLANE_CURSOR
);
1368 const struct drm_framebuffer
*fb
= plane_state
->hw
.fb
;
1369 unsigned int cpp
= fb
->format
->cpp
[0];
1371 if (hweight8(active_planes
) == 2) {
1400 static void ivb_plane_ratio_scaling(const struct intel_crtc_state
*crtc_state
,
1401 const struct intel_plane_state
*plane_state
,
1402 unsigned int *num
, unsigned int *den
)
1404 const struct drm_framebuffer
*fb
= plane_state
->hw
.fb
;
1405 unsigned int cpp
= fb
->format
->cpp
[0];
1427 int ivb_plane_min_cdclk(const struct intel_crtc_state
*crtc_state
,
1428 const struct intel_plane_state
*plane_state
)
1430 unsigned int pixel_rate
;
1431 unsigned int num
, den
;
1434 * Note that crtc_state->pixel_rate accounts for both
1435 * horizontal and vertical panel fitter downscaling factors.
1436 * Pre-HSW bspec tells us to only consider the horizontal
1437 * downscaling factor here. We ignore that and just consider
1438 * both for simplicity.
1440 pixel_rate
= crtc_state
->pixel_rate
;
1442 ivb_plane_ratio(crtc_state
, plane_state
, &num
, &den
);
1444 return DIV_ROUND_UP(pixel_rate
* num
, den
);
1447 static int ivb_sprite_min_cdclk(const struct intel_crtc_state
*crtc_state
,
1448 const struct intel_plane_state
*plane_state
)
1450 unsigned int src_w
, dst_w
, pixel_rate
;
1451 unsigned int num
, den
;
1454 * Note that crtc_state->pixel_rate accounts for both
1455 * horizontal and vertical panel fitter downscaling factors.
1456 * Pre-HSW bspec tells us to only consider the horizontal
1457 * downscaling factor here. We ignore that and just consider
1458 * both for simplicity.
1460 pixel_rate
= crtc_state
->pixel_rate
;
1462 src_w
= drm_rect_width(&plane_state
->uapi
.src
) >> 16;
1463 dst_w
= drm_rect_width(&plane_state
->uapi
.dst
);
1466 ivb_plane_ratio_scaling(crtc_state
, plane_state
, &num
, &den
);
1468 ivb_plane_ratio(crtc_state
, plane_state
, &num
, &den
);
1470 /* Horizontal downscaling limits the maximum pixel rate */
1471 dst_w
= min(src_w
, dst_w
);
1473 return DIV_ROUND_UP_ULL(mul_u32_u32(pixel_rate
, num
* src_w
),
1477 static void hsw_plane_ratio(const struct intel_crtc_state
*crtc_state
,
1478 const struct intel_plane_state
*plane_state
,
1479 unsigned int *num
, unsigned int *den
)
1481 u8 active_planes
= crtc_state
->active_planes
& ~BIT(PLANE_CURSOR
);
1482 const struct drm_framebuffer
*fb
= plane_state
->hw
.fb
;
1483 unsigned int cpp
= fb
->format
->cpp
[0];
1485 if (hweight8(active_planes
) == 2) {
1510 int hsw_plane_min_cdclk(const struct intel_crtc_state
*crtc_state
,
1511 const struct intel_plane_state
*plane_state
)
1513 unsigned int pixel_rate
= crtc_state
->pixel_rate
;
1514 unsigned int num
, den
;
1516 hsw_plane_ratio(crtc_state
, plane_state
, &num
, &den
);
1518 return DIV_ROUND_UP(pixel_rate
* num
, den
);
1521 static u32
ivb_sprite_ctl_crtc(const struct intel_crtc_state
*crtc_state
)
1525 if (crtc_state
->gamma_enable
)
1526 sprctl
|= SPRITE_GAMMA_ENABLE
;
1528 if (crtc_state
->csc_enable
)
1529 sprctl
|= SPRITE_PIPE_CSC_ENABLE
;
1534 static bool ivb_need_sprite_gamma(const struct intel_plane_state
*plane_state
)
1536 struct drm_i915_private
*dev_priv
=
1537 to_i915(plane_state
->uapi
.plane
->dev
);
1538 const struct drm_framebuffer
*fb
= plane_state
->hw
.fb
;
1540 return fb
->format
->cpp
[0] == 8 &&
1541 (IS_IVYBRIDGE(dev_priv
) || IS_HASWELL(dev_priv
));
1544 static u32
ivb_sprite_ctl(const struct intel_crtc_state
*crtc_state
,
1545 const struct intel_plane_state
*plane_state
)
1547 struct drm_i915_private
*dev_priv
=
1548 to_i915(plane_state
->uapi
.plane
->dev
);
1549 const struct drm_framebuffer
*fb
= plane_state
->hw
.fb
;
1550 unsigned int rotation
= plane_state
->hw
.rotation
;
1551 const struct drm_intel_sprite_colorkey
*key
= &plane_state
->ckey
;
1554 sprctl
= SPRITE_ENABLE
;
1556 if (IS_IVYBRIDGE(dev_priv
))
1557 sprctl
|= SPRITE_TRICKLE_FEED_DISABLE
;
1559 switch (fb
->format
->format
) {
1560 case DRM_FORMAT_XBGR8888
:
1561 sprctl
|= SPRITE_FORMAT_RGBX888
| SPRITE_RGB_ORDER_RGBX
;
1563 case DRM_FORMAT_XRGB8888
:
1564 sprctl
|= SPRITE_FORMAT_RGBX888
;
1566 case DRM_FORMAT_XBGR2101010
:
1567 sprctl
|= SPRITE_FORMAT_RGBX101010
| SPRITE_RGB_ORDER_RGBX
;
1569 case DRM_FORMAT_XRGB2101010
:
1570 sprctl
|= SPRITE_FORMAT_RGBX101010
;
1572 case DRM_FORMAT_XBGR16161616F
:
1573 sprctl
|= SPRITE_FORMAT_RGBX161616
| SPRITE_RGB_ORDER_RGBX
;
1575 case DRM_FORMAT_XRGB16161616F
:
1576 sprctl
|= SPRITE_FORMAT_RGBX161616
;
1578 case DRM_FORMAT_YUYV
:
1579 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_YUYV
;
1581 case DRM_FORMAT_YVYU
:
1582 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_YVYU
;
1584 case DRM_FORMAT_UYVY
:
1585 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_UYVY
;
1587 case DRM_FORMAT_VYUY
:
1588 sprctl
|= SPRITE_FORMAT_YUV422
| SPRITE_YUV_ORDER_VYUY
;
1591 MISSING_CASE(fb
->format
->format
);
1595 if (!ivb_need_sprite_gamma(plane_state
))
1596 sprctl
|= SPRITE_INT_GAMMA_DISABLE
;
1598 if (plane_state
->hw
.color_encoding
== DRM_COLOR_YCBCR_BT709
)
1599 sprctl
|= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709
;
1601 if (plane_state
->hw
.color_range
== DRM_COLOR_YCBCR_FULL_RANGE
)
1602 sprctl
|= SPRITE_YUV_RANGE_CORRECTION_DISABLE
;
1604 if (fb
->modifier
== I915_FORMAT_MOD_X_TILED
)
1605 sprctl
|= SPRITE_TILED
;
1607 if (rotation
& DRM_MODE_ROTATE_180
)
1608 sprctl
|= SPRITE_ROTATE_180
;
1610 if (key
->flags
& I915_SET_COLORKEY_DESTINATION
)
1611 sprctl
|= SPRITE_DEST_KEY
;
1612 else if (key
->flags
& I915_SET_COLORKEY_SOURCE
)
1613 sprctl
|= SPRITE_SOURCE_KEY
;
1618 static void ivb_sprite_linear_gamma(const struct intel_plane_state
*plane_state
,
1624 * WaFP16GammaEnabling:ivb,hsw
1625 * "Workaround : When using the 64-bit format, the sprite output
1626 * on each color channel has one quarter amplitude. It can be
1627 * brought up to full amplitude by using sprite internal gamma
1628 * correction, pipe gamma correction, or pipe color space
1629 * conversion to multiply the sprite output by four."
1633 for (i
= 0; i
< 16; i
++)
1634 gamma
[i
] = min((scale
* i
<< 10) / 16, (1 << 10) - 1);
1636 gamma
[i
] = min((scale
* i
<< 10) / 16, 1 << 10);
1643 static void ivb_update_gamma(const struct intel_plane_state
*plane_state
)
1645 struct intel_plane
*plane
= to_intel_plane(plane_state
->uapi
.plane
);
1646 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
1647 enum pipe pipe
= plane
->pipe
;
1651 if (!ivb_need_sprite_gamma(plane_state
))
1654 ivb_sprite_linear_gamma(plane_state
, gamma
);
1656 /* FIXME these register are single buffered :( */
1657 for (i
= 0; i
< 16; i
++)
1658 intel_de_write_fw(dev_priv
, SPRGAMC(pipe
, i
),
1659 gamma
[i
] << 20 | gamma
[i
] << 10 | gamma
[i
]);
1661 intel_de_write_fw(dev_priv
, SPRGAMC16(pipe
, 0), gamma
[i
]);
1662 intel_de_write_fw(dev_priv
, SPRGAMC16(pipe
, 1), gamma
[i
]);
1663 intel_de_write_fw(dev_priv
, SPRGAMC16(pipe
, 2), gamma
[i
]);
1666 intel_de_write_fw(dev_priv
, SPRGAMC17(pipe
, 0), gamma
[i
]);
1667 intel_de_write_fw(dev_priv
, SPRGAMC17(pipe
, 1), gamma
[i
]);
1668 intel_de_write_fw(dev_priv
, SPRGAMC17(pipe
, 2), gamma
[i
]);
1673 ivb_update_plane(struct intel_plane
*plane
,
1674 const struct intel_crtc_state
*crtc_state
,
1675 const struct intel_plane_state
*plane_state
)
1677 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
1678 enum pipe pipe
= plane
->pipe
;
1679 u32 sprsurf_offset
= plane_state
->color_plane
[0].offset
;
1681 const struct drm_intel_sprite_colorkey
*key
= &plane_state
->ckey
;
1682 int crtc_x
= plane_state
->uapi
.dst
.x1
;
1683 int crtc_y
= plane_state
->uapi
.dst
.y1
;
1684 u32 crtc_w
= drm_rect_width(&plane_state
->uapi
.dst
);
1685 u32 crtc_h
= drm_rect_height(&plane_state
->uapi
.dst
);
1686 u32 x
= plane_state
->color_plane
[0].x
;
1687 u32 y
= plane_state
->color_plane
[0].y
;
1688 u32 src_w
= drm_rect_width(&plane_state
->uapi
.src
) >> 16;
1689 u32 src_h
= drm_rect_height(&plane_state
->uapi
.src
) >> 16;
1690 u32 sprctl
, sprscale
= 0;
1691 unsigned long irqflags
;
1693 sprctl
= plane_state
->ctl
| ivb_sprite_ctl_crtc(crtc_state
);
1695 /* Sizes are 0 based */
1701 if (crtc_w
!= src_w
|| crtc_h
!= src_h
)
1702 sprscale
= SPRITE_SCALE_ENABLE
| (src_w
<< 16) | src_h
;
1704 linear_offset
= intel_fb_xy_to_linear(x
, y
, plane_state
, 0);
1706 spin_lock_irqsave(&dev_priv
->uncore
.lock
, irqflags
);
1708 intel_de_write_fw(dev_priv
, SPRSTRIDE(pipe
),
1709 plane_state
->color_plane
[0].stride
);
1710 intel_de_write_fw(dev_priv
, SPRPOS(pipe
), (crtc_y
<< 16) | crtc_x
);
1711 intel_de_write_fw(dev_priv
, SPRSIZE(pipe
), (crtc_h
<< 16) | crtc_w
);
1712 if (IS_IVYBRIDGE(dev_priv
))
1713 intel_de_write_fw(dev_priv
, SPRSCALE(pipe
), sprscale
);
1716 intel_de_write_fw(dev_priv
, SPRKEYVAL(pipe
), key
->min_value
);
1717 intel_de_write_fw(dev_priv
, SPRKEYMSK(pipe
),
1719 intel_de_write_fw(dev_priv
, SPRKEYMAX(pipe
), key
->max_value
);
1722 /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
1724 if (IS_HASWELL(dev_priv
) || IS_BROADWELL(dev_priv
)) {
1725 intel_de_write_fw(dev_priv
, SPROFFSET(pipe
), (y
<< 16) | x
);
1727 intel_de_write_fw(dev_priv
, SPRLINOFF(pipe
), linear_offset
);
1728 intel_de_write_fw(dev_priv
, SPRTILEOFF(pipe
), (y
<< 16) | x
);
1732 * The control register self-arms if the plane was previously
1733 * disabled. Try to make the plane enable atomic by writing
1734 * the control register just before the surface register.
1736 intel_de_write_fw(dev_priv
, SPRCTL(pipe
), sprctl
);
1737 intel_de_write_fw(dev_priv
, SPRSURF(pipe
),
1738 intel_plane_ggtt_offset(plane_state
) + sprsurf_offset
);
1740 ivb_update_gamma(plane_state
);
1742 spin_unlock_irqrestore(&dev_priv
->uncore
.lock
, irqflags
);
1746 ivb_disable_plane(struct intel_plane
*plane
,
1747 const struct intel_crtc_state
*crtc_state
)
1749 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
1750 enum pipe pipe
= plane
->pipe
;
1751 unsigned long irqflags
;
1753 spin_lock_irqsave(&dev_priv
->uncore
.lock
, irqflags
);
1755 intel_de_write_fw(dev_priv
, SPRCTL(pipe
), 0);
1756 /* Disable the scaler */
1757 if (IS_IVYBRIDGE(dev_priv
))
1758 intel_de_write_fw(dev_priv
, SPRSCALE(pipe
), 0);
1759 intel_de_write_fw(dev_priv
, SPRSURF(pipe
), 0);
1761 spin_unlock_irqrestore(&dev_priv
->uncore
.lock
, irqflags
);
1765 ivb_plane_get_hw_state(struct intel_plane
*plane
,
1768 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
1769 enum intel_display_power_domain power_domain
;
1770 intel_wakeref_t wakeref
;
1773 power_domain
= POWER_DOMAIN_PIPE(plane
->pipe
);
1774 wakeref
= intel_display_power_get_if_enabled(dev_priv
, power_domain
);
1778 ret
= intel_de_read(dev_priv
, SPRCTL(plane
->pipe
)) & SPRITE_ENABLE
;
1780 *pipe
= plane
->pipe
;
1782 intel_display_power_put(dev_priv
, power_domain
, wakeref
);
1787 static int g4x_sprite_min_cdclk(const struct intel_crtc_state
*crtc_state
,
1788 const struct intel_plane_state
*plane_state
)
1790 const struct drm_framebuffer
*fb
= plane_state
->hw
.fb
;
1791 unsigned int hscale
, pixel_rate
;
1792 unsigned int limit
, decimate
;
1795 * Note that crtc_state->pixel_rate accounts for both
1796 * horizontal and vertical panel fitter downscaling factors.
1797 * Pre-HSW bspec tells us to only consider the horizontal
1798 * downscaling factor here. We ignore that and just consider
1799 * both for simplicity.
1801 pixel_rate
= crtc_state
->pixel_rate
;
1803 /* Horizontal downscaling limits the maximum pixel rate */
1804 hscale
= drm_rect_calc_hscale(&plane_state
->uapi
.src
,
1805 &plane_state
->uapi
.dst
,
1807 hscale
= max(hscale
, 0x10000u
);
1809 /* Decimation steps at 2x,4x,8x,16x */
1810 decimate
= ilog2(hscale
>> 16);
1811 hscale
>>= decimate
;
1813 /* Starting limit is 90% of cdclk */
1816 /* -10% per decimation step */
1820 if (!fb
->format
->is_yuv
)
1824 * We should also do -10% if sprite scaling is enabled
1825 * on the other pipe, but we can't really check for that,
1829 return DIV_ROUND_UP_ULL(mul_u32_u32(pixel_rate
, 10 * hscale
),
1834 g4x_sprite_max_stride(struct intel_plane
*plane
,
1835 u32 pixel_format
, u64 modifier
,
1836 unsigned int rotation
)
1841 static u32
g4x_sprite_ctl_crtc(const struct intel_crtc_state
*crtc_state
)
1845 if (crtc_state
->gamma_enable
)
1846 dvscntr
|= DVS_GAMMA_ENABLE
;
1848 if (crtc_state
->csc_enable
)
1849 dvscntr
|= DVS_PIPE_CSC_ENABLE
;
1854 static u32
g4x_sprite_ctl(const struct intel_crtc_state
*crtc_state
,
1855 const struct intel_plane_state
*plane_state
)
1857 struct drm_i915_private
*dev_priv
=
1858 to_i915(plane_state
->uapi
.plane
->dev
);
1859 const struct drm_framebuffer
*fb
= plane_state
->hw
.fb
;
1860 unsigned int rotation
= plane_state
->hw
.rotation
;
1861 const struct drm_intel_sprite_colorkey
*key
= &plane_state
->ckey
;
1864 dvscntr
= DVS_ENABLE
;
1866 if (IS_GEN(dev_priv
, 6))
1867 dvscntr
|= DVS_TRICKLE_FEED_DISABLE
;
1869 switch (fb
->format
->format
) {
1870 case DRM_FORMAT_XBGR8888
:
1871 dvscntr
|= DVS_FORMAT_RGBX888
| DVS_RGB_ORDER_XBGR
;
1873 case DRM_FORMAT_XRGB8888
:
1874 dvscntr
|= DVS_FORMAT_RGBX888
;
1876 case DRM_FORMAT_XBGR2101010
:
1877 dvscntr
|= DVS_FORMAT_RGBX101010
| DVS_RGB_ORDER_XBGR
;
1879 case DRM_FORMAT_XRGB2101010
:
1880 dvscntr
|= DVS_FORMAT_RGBX101010
;
1882 case DRM_FORMAT_XBGR16161616F
:
1883 dvscntr
|= DVS_FORMAT_RGBX161616
| DVS_RGB_ORDER_XBGR
;
1885 case DRM_FORMAT_XRGB16161616F
:
1886 dvscntr
|= DVS_FORMAT_RGBX161616
;
1888 case DRM_FORMAT_YUYV
:
1889 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_YUYV
;
1891 case DRM_FORMAT_YVYU
:
1892 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_YVYU
;
1894 case DRM_FORMAT_UYVY
:
1895 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_UYVY
;
1897 case DRM_FORMAT_VYUY
:
1898 dvscntr
|= DVS_FORMAT_YUV422
| DVS_YUV_ORDER_VYUY
;
1901 MISSING_CASE(fb
->format
->format
);
1905 if (plane_state
->hw
.color_encoding
== DRM_COLOR_YCBCR_BT709
)
1906 dvscntr
|= DVS_YUV_FORMAT_BT709
;
1908 if (plane_state
->hw
.color_range
== DRM_COLOR_YCBCR_FULL_RANGE
)
1909 dvscntr
|= DVS_YUV_RANGE_CORRECTION_DISABLE
;
1911 if (fb
->modifier
== I915_FORMAT_MOD_X_TILED
)
1912 dvscntr
|= DVS_TILED
;
1914 if (rotation
& DRM_MODE_ROTATE_180
)
1915 dvscntr
|= DVS_ROTATE_180
;
1917 if (key
->flags
& I915_SET_COLORKEY_DESTINATION
)
1918 dvscntr
|= DVS_DEST_KEY
;
1919 else if (key
->flags
& I915_SET_COLORKEY_SOURCE
)
1920 dvscntr
|= DVS_SOURCE_KEY
;
1925 static void g4x_update_gamma(const struct intel_plane_state
*plane_state
)
1927 struct intel_plane
*plane
= to_intel_plane(plane_state
->uapi
.plane
);
1928 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
1929 const struct drm_framebuffer
*fb
= plane_state
->hw
.fb
;
1930 enum pipe pipe
= plane
->pipe
;
1934 /* Seems RGB data bypasses the gamma always */
1935 if (!fb
->format
->is_yuv
)
1938 i9xx_plane_linear_gamma(gamma
);
1940 /* FIXME these register are single buffered :( */
1941 /* The two end points are implicit (0.0 and 1.0) */
1942 for (i
= 1; i
< 8 - 1; i
++)
1943 intel_de_write_fw(dev_priv
, DVSGAMC_G4X(pipe
, i
- 1),
1944 gamma
[i
] << 16 | gamma
[i
] << 8 | gamma
[i
]);
1947 static void ilk_sprite_linear_gamma(u16 gamma
[17])
1951 for (i
= 0; i
< 17; i
++)
1952 gamma
[i
] = (i
<< 10) / 16;
1955 static void ilk_update_gamma(const struct intel_plane_state
*plane_state
)
1957 struct intel_plane
*plane
= to_intel_plane(plane_state
->uapi
.plane
);
1958 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
1959 const struct drm_framebuffer
*fb
= plane_state
->hw
.fb
;
1960 enum pipe pipe
= plane
->pipe
;
1964 /* Seems RGB data bypasses the gamma always */
1965 if (!fb
->format
->is_yuv
)
1968 ilk_sprite_linear_gamma(gamma
);
1970 /* FIXME these register are single buffered :( */
1971 for (i
= 0; i
< 16; i
++)
1972 intel_de_write_fw(dev_priv
, DVSGAMC_ILK(pipe
, i
),
1973 gamma
[i
] << 20 | gamma
[i
] << 10 | gamma
[i
]);
1975 intel_de_write_fw(dev_priv
, DVSGAMCMAX_ILK(pipe
, 0), gamma
[i
]);
1976 intel_de_write_fw(dev_priv
, DVSGAMCMAX_ILK(pipe
, 1), gamma
[i
]);
1977 intel_de_write_fw(dev_priv
, DVSGAMCMAX_ILK(pipe
, 2), gamma
[i
]);
1982 g4x_update_plane(struct intel_plane
*plane
,
1983 const struct intel_crtc_state
*crtc_state
,
1984 const struct intel_plane_state
*plane_state
)
1986 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
1987 enum pipe pipe
= plane
->pipe
;
1988 u32 dvssurf_offset
= plane_state
->color_plane
[0].offset
;
1990 const struct drm_intel_sprite_colorkey
*key
= &plane_state
->ckey
;
1991 int crtc_x
= plane_state
->uapi
.dst
.x1
;
1992 int crtc_y
= plane_state
->uapi
.dst
.y1
;
1993 u32 crtc_w
= drm_rect_width(&plane_state
->uapi
.dst
);
1994 u32 crtc_h
= drm_rect_height(&plane_state
->uapi
.dst
);
1995 u32 x
= plane_state
->color_plane
[0].x
;
1996 u32 y
= plane_state
->color_plane
[0].y
;
1997 u32 src_w
= drm_rect_width(&plane_state
->uapi
.src
) >> 16;
1998 u32 src_h
= drm_rect_height(&plane_state
->uapi
.src
) >> 16;
1999 u32 dvscntr
, dvsscale
= 0;
2000 unsigned long irqflags
;
2002 dvscntr
= plane_state
->ctl
| g4x_sprite_ctl_crtc(crtc_state
);
2004 /* Sizes are 0 based */
2010 if (crtc_w
!= src_w
|| crtc_h
!= src_h
)
2011 dvsscale
= DVS_SCALE_ENABLE
| (src_w
<< 16) | src_h
;
2013 linear_offset
= intel_fb_xy_to_linear(x
, y
, plane_state
, 0);
2015 spin_lock_irqsave(&dev_priv
->uncore
.lock
, irqflags
);
2017 intel_de_write_fw(dev_priv
, DVSSTRIDE(pipe
),
2018 plane_state
->color_plane
[0].stride
);
2019 intel_de_write_fw(dev_priv
, DVSPOS(pipe
), (crtc_y
<< 16) | crtc_x
);
2020 intel_de_write_fw(dev_priv
, DVSSIZE(pipe
), (crtc_h
<< 16) | crtc_w
);
2021 intel_de_write_fw(dev_priv
, DVSSCALE(pipe
), dvsscale
);
2024 intel_de_write_fw(dev_priv
, DVSKEYVAL(pipe
), key
->min_value
);
2025 intel_de_write_fw(dev_priv
, DVSKEYMSK(pipe
),
2027 intel_de_write_fw(dev_priv
, DVSKEYMAX(pipe
), key
->max_value
);
2030 intel_de_write_fw(dev_priv
, DVSLINOFF(pipe
), linear_offset
);
2031 intel_de_write_fw(dev_priv
, DVSTILEOFF(pipe
), (y
<< 16) | x
);
2034 * The control register self-arms if the plane was previously
2035 * disabled. Try to make the plane enable atomic by writing
2036 * the control register just before the surface register.
2038 intel_de_write_fw(dev_priv
, DVSCNTR(pipe
), dvscntr
);
2039 intel_de_write_fw(dev_priv
, DVSSURF(pipe
),
2040 intel_plane_ggtt_offset(plane_state
) + dvssurf_offset
);
2042 if (IS_G4X(dev_priv
))
2043 g4x_update_gamma(plane_state
);
2045 ilk_update_gamma(plane_state
);
2047 spin_unlock_irqrestore(&dev_priv
->uncore
.lock
, irqflags
);
2051 g4x_disable_plane(struct intel_plane
*plane
,
2052 const struct intel_crtc_state
*crtc_state
)
2054 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
2055 enum pipe pipe
= plane
->pipe
;
2056 unsigned long irqflags
;
2058 spin_lock_irqsave(&dev_priv
->uncore
.lock
, irqflags
);
2060 intel_de_write_fw(dev_priv
, DVSCNTR(pipe
), 0);
2061 /* Disable the scaler */
2062 intel_de_write_fw(dev_priv
, DVSSCALE(pipe
), 0);
2063 intel_de_write_fw(dev_priv
, DVSSURF(pipe
), 0);
2065 spin_unlock_irqrestore(&dev_priv
->uncore
.lock
, irqflags
);
2069 g4x_plane_get_hw_state(struct intel_plane
*plane
,
2072 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
2073 enum intel_display_power_domain power_domain
;
2074 intel_wakeref_t wakeref
;
2077 power_domain
= POWER_DOMAIN_PIPE(plane
->pipe
);
2078 wakeref
= intel_display_power_get_if_enabled(dev_priv
, power_domain
);
2082 ret
= intel_de_read(dev_priv
, DVSCNTR(plane
->pipe
)) & DVS_ENABLE
;
2084 *pipe
= plane
->pipe
;
2086 intel_display_power_put(dev_priv
, power_domain
, wakeref
);
2091 static bool intel_fb_scalable(const struct drm_framebuffer
*fb
)
2096 switch (fb
->format
->format
) {
2099 case DRM_FORMAT_XRGB16161616F
:
2100 case DRM_FORMAT_ARGB16161616F
:
2101 case DRM_FORMAT_XBGR16161616F
:
2102 case DRM_FORMAT_ABGR16161616F
:
2103 return INTEL_GEN(to_i915(fb
->dev
)) >= 11;
2110 g4x_sprite_check_scaling(struct intel_crtc_state
*crtc_state
,
2111 struct intel_plane_state
*plane_state
)
2113 const struct drm_framebuffer
*fb
= plane_state
->hw
.fb
;
2114 const struct drm_rect
*src
= &plane_state
->uapi
.src
;
2115 const struct drm_rect
*dst
= &plane_state
->uapi
.dst
;
2116 int src_x
, src_w
, src_h
, crtc_w
, crtc_h
;
2117 const struct drm_display_mode
*adjusted_mode
=
2118 &crtc_state
->hw
.adjusted_mode
;
2119 unsigned int stride
= plane_state
->color_plane
[0].stride
;
2120 unsigned int cpp
= fb
->format
->cpp
[0];
2121 unsigned int width_bytes
;
2122 int min_width
, min_height
;
2124 crtc_w
= drm_rect_width(dst
);
2125 crtc_h
= drm_rect_height(dst
);
2127 src_x
= src
->x1
>> 16;
2128 src_w
= drm_rect_width(src
) >> 16;
2129 src_h
= drm_rect_height(src
) >> 16;
2131 if (src_w
== crtc_w
&& src_h
== crtc_h
)
2136 if (adjusted_mode
->flags
& DRM_MODE_FLAG_INTERLACE
) {
2138 DRM_DEBUG_KMS("Source height must be even with interlaced modes\n");
2146 width_bytes
= ((src_x
* cpp
) & 63) + src_w
* cpp
;
2148 if (src_w
< min_width
|| src_h
< min_height
||
2149 src_w
> 2048 || src_h
> 2048) {
2150 DRM_DEBUG_KMS("Source dimensions (%dx%d) exceed hardware limits (%dx%d - %dx%d)\n",
2151 src_w
, src_h
, min_width
, min_height
, 2048, 2048);
2155 if (width_bytes
> 4096) {
2156 DRM_DEBUG_KMS("Fetch width (%d) exceeds hardware max with scaling (%u)\n",
2161 if (stride
> 4096) {
2162 DRM_DEBUG_KMS("Stride (%u) exceeds hardware max with scaling (%u)\n",
2171 g4x_sprite_check(struct intel_crtc_state
*crtc_state
,
2172 struct intel_plane_state
*plane_state
)
2174 struct intel_plane
*plane
= to_intel_plane(plane_state
->uapi
.plane
);
2175 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
2176 int min_scale
= DRM_PLANE_HELPER_NO_SCALING
;
2177 int max_scale
= DRM_PLANE_HELPER_NO_SCALING
;
2180 if (intel_fb_scalable(plane_state
->hw
.fb
)) {
2181 if (INTEL_GEN(dev_priv
) < 7) {
2183 max_scale
= 16 << 16;
2184 } else if (IS_IVYBRIDGE(dev_priv
)) {
2186 max_scale
= 2 << 16;
2190 ret
= intel_atomic_plane_check_clipping(plane_state
, crtc_state
,
2191 min_scale
, max_scale
, true);
2195 ret
= i9xx_check_plane_surface(plane_state
);
2199 if (!plane_state
->uapi
.visible
)
2202 ret
= intel_plane_check_src_coordinates(plane_state
);
2206 ret
= g4x_sprite_check_scaling(crtc_state
, plane_state
);
2210 if (INTEL_GEN(dev_priv
) >= 7)
2211 plane_state
->ctl
= ivb_sprite_ctl(crtc_state
, plane_state
);
2213 plane_state
->ctl
= g4x_sprite_ctl(crtc_state
, plane_state
);
2218 int chv_plane_check_rotation(const struct intel_plane_state
*plane_state
)
2220 struct intel_plane
*plane
= to_intel_plane(plane_state
->uapi
.plane
);
2221 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
2222 unsigned int rotation
= plane_state
->hw
.rotation
;
2224 /* CHV ignores the mirror bit when the rotate bit is set :( */
2225 if (IS_CHERRYVIEW(dev_priv
) &&
2226 rotation
& DRM_MODE_ROTATE_180
&&
2227 rotation
& DRM_MODE_REFLECT_X
) {
2228 drm_dbg_kms(&dev_priv
->drm
,
2229 "Cannot rotate and reflect at the same time\n");
2237 vlv_sprite_check(struct intel_crtc_state
*crtc_state
,
2238 struct intel_plane_state
*plane_state
)
2242 ret
= chv_plane_check_rotation(plane_state
);
2246 ret
= intel_atomic_plane_check_clipping(plane_state
, crtc_state
,
2247 DRM_PLANE_HELPER_NO_SCALING
,
2248 DRM_PLANE_HELPER_NO_SCALING
,
2253 ret
= i9xx_check_plane_surface(plane_state
);
2257 if (!plane_state
->uapi
.visible
)
2260 ret
= intel_plane_check_src_coordinates(plane_state
);
2264 plane_state
->ctl
= vlv_sprite_ctl(crtc_state
, plane_state
);
2269 static bool intel_format_is_p01x(u32 format
)
2272 case DRM_FORMAT_P010
:
2273 case DRM_FORMAT_P012
:
2274 case DRM_FORMAT_P016
:
2281 static int skl_plane_check_fb(const struct intel_crtc_state
*crtc_state
,
2282 const struct intel_plane_state
*plane_state
)
2284 struct intel_plane
*plane
= to_intel_plane(plane_state
->uapi
.plane
);
2285 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
2286 const struct drm_framebuffer
*fb
= plane_state
->hw
.fb
;
2287 unsigned int rotation
= plane_state
->hw
.rotation
;
2288 struct drm_format_name_buf format_name
;
2293 if (rotation
& ~(DRM_MODE_ROTATE_0
| DRM_MODE_ROTATE_180
) &&
2294 is_ccs_modifier(fb
->modifier
)) {
2295 drm_dbg_kms(&dev_priv
->drm
,
2296 "RC support only with 0/180 degree rotation (%x)\n",
2301 if (rotation
& DRM_MODE_REFLECT_X
&&
2302 fb
->modifier
== DRM_FORMAT_MOD_LINEAR
) {
2303 drm_dbg_kms(&dev_priv
->drm
,
2304 "horizontal flip is not supported with linear surface formats\n");
2308 if (drm_rotation_90_or_270(rotation
)) {
2309 if (fb
->modifier
!= I915_FORMAT_MOD_Y_TILED
&&
2310 fb
->modifier
!= I915_FORMAT_MOD_Yf_TILED
) {
2311 drm_dbg_kms(&dev_priv
->drm
,
2312 "Y/Yf tiling required for 90/270!\n");
2317 * 90/270 is not allowed with RGB64 16:16:16:16 and
2318 * Indexed 8-bit. RGB 16-bit 5:6:5 is allowed gen11 onwards.
2320 switch (fb
->format
->format
) {
2321 case DRM_FORMAT_RGB565
:
2322 if (INTEL_GEN(dev_priv
) >= 11)
2326 case DRM_FORMAT_XRGB16161616F
:
2327 case DRM_FORMAT_XBGR16161616F
:
2328 case DRM_FORMAT_ARGB16161616F
:
2329 case DRM_FORMAT_ABGR16161616F
:
2330 case DRM_FORMAT_Y210
:
2331 case DRM_FORMAT_Y212
:
2332 case DRM_FORMAT_Y216
:
2333 case DRM_FORMAT_XVYU12_16161616
:
2334 case DRM_FORMAT_XVYU16161616
:
2335 drm_dbg_kms(&dev_priv
->drm
,
2336 "Unsupported pixel format %s for 90/270!\n",
2337 drm_get_format_name(fb
->format
->format
,
2345 /* Y-tiling is not supported in IF-ID Interlace mode */
2346 if (crtc_state
->hw
.enable
&&
2347 crtc_state
->hw
.adjusted_mode
.flags
& DRM_MODE_FLAG_INTERLACE
&&
2348 (fb
->modifier
== I915_FORMAT_MOD_Y_TILED
||
2349 fb
->modifier
== I915_FORMAT_MOD_Yf_TILED
||
2350 fb
->modifier
== I915_FORMAT_MOD_Y_TILED_CCS
||
2351 fb
->modifier
== I915_FORMAT_MOD_Yf_TILED_CCS
||
2352 fb
->modifier
== I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS
||
2353 fb
->modifier
== I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS
)) {
2354 drm_dbg_kms(&dev_priv
->drm
,
2355 "Y/Yf tiling not supported in IF-ID mode\n");
2359 /* Wa_1606054188:tgl */
2360 if (IS_TIGERLAKE(dev_priv
) &&
2361 plane_state
->ckey
.flags
& I915_SET_COLORKEY_SOURCE
&&
2362 intel_format_is_p01x(fb
->format
->format
)) {
2363 drm_dbg_kms(&dev_priv
->drm
,
2364 "Source color keying not supported with P01x formats\n");
2371 static int skl_plane_check_dst_coordinates(const struct intel_crtc_state
*crtc_state
,
2372 const struct intel_plane_state
*plane_state
)
2374 struct drm_i915_private
*dev_priv
=
2375 to_i915(plane_state
->uapi
.plane
->dev
);
2376 int crtc_x
= plane_state
->uapi
.dst
.x1
;
2377 int crtc_w
= drm_rect_width(&plane_state
->uapi
.dst
);
2378 int pipe_src_w
= crtc_state
->pipe_src_w
;
2381 * Display WA #1175: cnl,glk
2382 * Planes other than the cursor may cause FIFO underflow and display
2383 * corruption if starting less than 4 pixels from the right edge of
2385 * Besides the above WA fix the similar problem, where planes other
2386 * than the cursor ending less than 4 pixels from the left edge of the
2387 * screen may cause FIFO underflow and display corruption.
2389 if ((IS_GEMINILAKE(dev_priv
) || IS_CANNONLAKE(dev_priv
)) &&
2390 (crtc_x
+ crtc_w
< 4 || crtc_x
> pipe_src_w
- 4)) {
2391 drm_dbg_kms(&dev_priv
->drm
,
2392 "requested plane X %s position %d invalid (valid range %d-%d)\n",
2393 crtc_x
+ crtc_w
< 4 ? "end" : "start",
2394 crtc_x
+ crtc_w
< 4 ? crtc_x
+ crtc_w
: crtc_x
,
2402 static int skl_plane_check_nv12_rotation(const struct intel_plane_state
*plane_state
)
2404 const struct drm_framebuffer
*fb
= plane_state
->hw
.fb
;
2405 unsigned int rotation
= plane_state
->hw
.rotation
;
2406 int src_w
= drm_rect_width(&plane_state
->uapi
.src
) >> 16;
2408 /* Display WA #1106 */
2409 if (intel_format_info_is_yuv_semiplanar(fb
->format
, fb
->modifier
) &&
2411 (rotation
== DRM_MODE_ROTATE_270
||
2412 rotation
== (DRM_MODE_REFLECT_X
| DRM_MODE_ROTATE_90
))) {
2413 DRM_DEBUG_KMS("src width must be multiple of 4 for rotated planar YUV\n");
2420 static int skl_plane_max_scale(struct drm_i915_private
*dev_priv
,
2421 const struct drm_framebuffer
*fb
)
2424 * We don't yet know the final source width nor
2425 * whether we can use the HQ scaler mode. Assume
2427 * FIXME need to properly check this later.
2429 if (INTEL_GEN(dev_priv
) >= 10 || IS_GEMINILAKE(dev_priv
) ||
2430 !intel_format_info_is_yuv_semiplanar(fb
->format
, fb
->modifier
))
2436 static int skl_plane_check(struct intel_crtc_state
*crtc_state
,
2437 struct intel_plane_state
*plane_state
)
2439 struct intel_plane
*plane
= to_intel_plane(plane_state
->uapi
.plane
);
2440 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
2441 const struct drm_framebuffer
*fb
= plane_state
->hw
.fb
;
2442 int min_scale
= DRM_PLANE_HELPER_NO_SCALING
;
2443 int max_scale
= DRM_PLANE_HELPER_NO_SCALING
;
2446 ret
= skl_plane_check_fb(crtc_state
, plane_state
);
2450 /* use scaler when colorkey is not required */
2451 if (!plane_state
->ckey
.flags
&& intel_fb_scalable(fb
)) {
2453 max_scale
= skl_plane_max_scale(dev_priv
, fb
);
2456 ret
= intel_atomic_plane_check_clipping(plane_state
, crtc_state
,
2457 min_scale
, max_scale
, true);
2461 ret
= skl_check_plane_surface(plane_state
);
2465 if (!plane_state
->uapi
.visible
)
2468 ret
= skl_plane_check_dst_coordinates(crtc_state
, plane_state
);
2472 ret
= intel_plane_check_src_coordinates(plane_state
);
2476 ret
= skl_plane_check_nv12_rotation(plane_state
);
2480 /* HW only has 8 bits pixel precision, disable plane if invisible */
2481 if (!(plane_state
->hw
.alpha
>> 8))
2482 plane_state
->uapi
.visible
= false;
2484 plane_state
->ctl
= skl_plane_ctl(crtc_state
, plane_state
);
2486 if (INTEL_GEN(dev_priv
) >= 10 || IS_GEMINILAKE(dev_priv
))
2487 plane_state
->color_ctl
= glk_plane_color_ctl(crtc_state
,
2490 if (intel_format_info_is_yuv_semiplanar(fb
->format
, fb
->modifier
) &&
2491 icl_is_hdr_plane(dev_priv
, plane
->id
))
2492 /* Enable and use MPEG-2 chroma siting */
2493 plane_state
->cus_ctl
= PLANE_CUS_ENABLE
|
2494 PLANE_CUS_HPHASE_0
|
2495 PLANE_CUS_VPHASE_SIGN_NEGATIVE
| PLANE_CUS_VPHASE_0_25
;
2497 plane_state
->cus_ctl
= 0;
2502 static bool has_dst_key_in_primary_plane(struct drm_i915_private
*dev_priv
)
2504 return INTEL_GEN(dev_priv
) >= 9;
2507 static void intel_plane_set_ckey(struct intel_plane_state
*plane_state
,
2508 const struct drm_intel_sprite_colorkey
*set
)
2510 struct intel_plane
*plane
= to_intel_plane(plane_state
->uapi
.plane
);
2511 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
2512 struct drm_intel_sprite_colorkey
*key
= &plane_state
->ckey
;
2517 * We want src key enabled on the
2518 * sprite and not on the primary.
2520 if (plane
->id
== PLANE_PRIMARY
&&
2521 set
->flags
& I915_SET_COLORKEY_SOURCE
)
2525 * On SKL+ we want dst key enabled on
2526 * the primary and not on the sprite.
2528 if (INTEL_GEN(dev_priv
) >= 9 && plane
->id
!= PLANE_PRIMARY
&&
2529 set
->flags
& I915_SET_COLORKEY_DESTINATION
)
2533 int intel_sprite_set_colorkey_ioctl(struct drm_device
*dev
, void *data
,
2534 struct drm_file
*file_priv
)
2536 struct drm_i915_private
*dev_priv
= to_i915(dev
);
2537 struct drm_intel_sprite_colorkey
*set
= data
;
2538 struct drm_plane
*plane
;
2539 struct drm_plane_state
*plane_state
;
2540 struct drm_atomic_state
*state
;
2541 struct drm_modeset_acquire_ctx ctx
;
2544 /* ignore the pointless "none" flag */
2545 set
->flags
&= ~I915_SET_COLORKEY_NONE
;
2547 if (set
->flags
& ~(I915_SET_COLORKEY_DESTINATION
| I915_SET_COLORKEY_SOURCE
))
2550 /* Make sure we don't try to enable both src & dest simultaneously */
2551 if ((set
->flags
& (I915_SET_COLORKEY_DESTINATION
| I915_SET_COLORKEY_SOURCE
)) == (I915_SET_COLORKEY_DESTINATION
| I915_SET_COLORKEY_SOURCE
))
2554 if ((IS_VALLEYVIEW(dev_priv
) || IS_CHERRYVIEW(dev_priv
)) &&
2555 set
->flags
& I915_SET_COLORKEY_DESTINATION
)
2558 plane
= drm_plane_find(dev
, file_priv
, set
->plane_id
);
2559 if (!plane
|| plane
->type
!= DRM_PLANE_TYPE_OVERLAY
)
2563 * SKL+ only plane 2 can do destination keying against plane 1.
2564 * Also multiple planes can't do destination keying on the same
2565 * pipe simultaneously.
2567 if (INTEL_GEN(dev_priv
) >= 9 &&
2568 to_intel_plane(plane
)->id
>= PLANE_SPRITE1
&&
2569 set
->flags
& I915_SET_COLORKEY_DESTINATION
)
2572 drm_modeset_acquire_init(&ctx
, 0);
2574 state
= drm_atomic_state_alloc(plane
->dev
);
2579 state
->acquire_ctx
= &ctx
;
2582 plane_state
= drm_atomic_get_plane_state(state
, plane
);
2583 ret
= PTR_ERR_OR_ZERO(plane_state
);
2585 intel_plane_set_ckey(to_intel_plane_state(plane_state
), set
);
2588 * On some platforms we have to configure
2589 * the dst colorkey on the primary plane.
2591 if (!ret
&& has_dst_key_in_primary_plane(dev_priv
)) {
2592 struct intel_crtc
*crtc
=
2593 intel_get_crtc_for_pipe(dev_priv
,
2594 to_intel_plane(plane
)->pipe
);
2596 plane_state
= drm_atomic_get_plane_state(state
,
2597 crtc
->base
.primary
);
2598 ret
= PTR_ERR_OR_ZERO(plane_state
);
2600 intel_plane_set_ckey(to_intel_plane_state(plane_state
), set
);
2604 ret
= drm_atomic_commit(state
);
2606 if (ret
!= -EDEADLK
)
2609 drm_atomic_state_clear(state
);
2610 drm_modeset_backoff(&ctx
);
2613 drm_atomic_state_put(state
);
2615 drm_modeset_drop_locks(&ctx
);
2616 drm_modeset_acquire_fini(&ctx
);
2620 static const u32 g4x_plane_formats
[] = {
2621 DRM_FORMAT_XRGB8888
,
2628 static const u64 i9xx_plane_format_modifiers
[] = {
2629 I915_FORMAT_MOD_X_TILED
,
2630 DRM_FORMAT_MOD_LINEAR
,
2631 DRM_FORMAT_MOD_INVALID
2634 static const u32 snb_plane_formats
[] = {
2635 DRM_FORMAT_XRGB8888
,
2636 DRM_FORMAT_XBGR8888
,
2637 DRM_FORMAT_XRGB2101010
,
2638 DRM_FORMAT_XBGR2101010
,
2639 DRM_FORMAT_XRGB16161616F
,
2640 DRM_FORMAT_XBGR16161616F
,
2647 static const u32 vlv_plane_formats
[] = {
2650 DRM_FORMAT_XRGB8888
,
2651 DRM_FORMAT_XBGR8888
,
2652 DRM_FORMAT_ARGB8888
,
2653 DRM_FORMAT_ABGR8888
,
2654 DRM_FORMAT_XBGR2101010
,
2655 DRM_FORMAT_ABGR2101010
,
2662 static const u32 chv_pipe_b_sprite_formats
[] = {
2665 DRM_FORMAT_XRGB8888
,
2666 DRM_FORMAT_XBGR8888
,
2667 DRM_FORMAT_ARGB8888
,
2668 DRM_FORMAT_ABGR8888
,
2669 DRM_FORMAT_XRGB2101010
,
2670 DRM_FORMAT_XBGR2101010
,
2671 DRM_FORMAT_ARGB2101010
,
2672 DRM_FORMAT_ABGR2101010
,
2679 static const u32 skl_plane_formats
[] = {
2682 DRM_FORMAT_XRGB8888
,
2683 DRM_FORMAT_XBGR8888
,
2684 DRM_FORMAT_ARGB8888
,
2685 DRM_FORMAT_ABGR8888
,
2686 DRM_FORMAT_XRGB2101010
,
2687 DRM_FORMAT_XBGR2101010
,
2688 DRM_FORMAT_XRGB16161616F
,
2689 DRM_FORMAT_XBGR16161616F
,
2694 DRM_FORMAT_XYUV8888
,
2697 static const u32 skl_planar_formats
[] = {
2700 DRM_FORMAT_XRGB8888
,
2701 DRM_FORMAT_XBGR8888
,
2702 DRM_FORMAT_ARGB8888
,
2703 DRM_FORMAT_ABGR8888
,
2704 DRM_FORMAT_XRGB2101010
,
2705 DRM_FORMAT_XBGR2101010
,
2706 DRM_FORMAT_XRGB16161616F
,
2707 DRM_FORMAT_XBGR16161616F
,
2713 DRM_FORMAT_XYUV8888
,
2716 static const u32 glk_planar_formats
[] = {
2719 DRM_FORMAT_XRGB8888
,
2720 DRM_FORMAT_XBGR8888
,
2721 DRM_FORMAT_ARGB8888
,
2722 DRM_FORMAT_ABGR8888
,
2723 DRM_FORMAT_XRGB2101010
,
2724 DRM_FORMAT_XBGR2101010
,
2725 DRM_FORMAT_XRGB16161616F
,
2726 DRM_FORMAT_XBGR16161616F
,
2732 DRM_FORMAT_XYUV8888
,
2738 static const u32 icl_sdr_y_plane_formats
[] = {
2741 DRM_FORMAT_XRGB8888
,
2742 DRM_FORMAT_XBGR8888
,
2743 DRM_FORMAT_ARGB8888
,
2744 DRM_FORMAT_ABGR8888
,
2745 DRM_FORMAT_XRGB2101010
,
2746 DRM_FORMAT_XBGR2101010
,
2747 DRM_FORMAT_ARGB2101010
,
2748 DRM_FORMAT_ABGR2101010
,
2756 DRM_FORMAT_XYUV8888
,
2757 DRM_FORMAT_XVYU2101010
,
2758 DRM_FORMAT_XVYU12_16161616
,
2759 DRM_FORMAT_XVYU16161616
,
2762 static const u32 icl_sdr_uv_plane_formats
[] = {
2765 DRM_FORMAT_XRGB8888
,
2766 DRM_FORMAT_XBGR8888
,
2767 DRM_FORMAT_ARGB8888
,
2768 DRM_FORMAT_ABGR8888
,
2769 DRM_FORMAT_XRGB2101010
,
2770 DRM_FORMAT_XBGR2101010
,
2771 DRM_FORMAT_ARGB2101010
,
2772 DRM_FORMAT_ABGR2101010
,
2784 DRM_FORMAT_XYUV8888
,
2785 DRM_FORMAT_XVYU2101010
,
2786 DRM_FORMAT_XVYU12_16161616
,
2787 DRM_FORMAT_XVYU16161616
,
2790 static const u32 icl_hdr_plane_formats
[] = {
2793 DRM_FORMAT_XRGB8888
,
2794 DRM_FORMAT_XBGR8888
,
2795 DRM_FORMAT_ARGB8888
,
2796 DRM_FORMAT_ABGR8888
,
2797 DRM_FORMAT_XRGB2101010
,
2798 DRM_FORMAT_XBGR2101010
,
2799 DRM_FORMAT_ARGB2101010
,
2800 DRM_FORMAT_ABGR2101010
,
2801 DRM_FORMAT_XRGB16161616F
,
2802 DRM_FORMAT_XBGR16161616F
,
2803 DRM_FORMAT_ARGB16161616F
,
2804 DRM_FORMAT_ABGR16161616F
,
2816 DRM_FORMAT_XYUV8888
,
2817 DRM_FORMAT_XVYU2101010
,
2818 DRM_FORMAT_XVYU12_16161616
,
2819 DRM_FORMAT_XVYU16161616
,
2822 static const u64 skl_plane_format_modifiers_noccs
[] = {
2823 I915_FORMAT_MOD_Yf_TILED
,
2824 I915_FORMAT_MOD_Y_TILED
,
2825 I915_FORMAT_MOD_X_TILED
,
2826 DRM_FORMAT_MOD_LINEAR
,
2827 DRM_FORMAT_MOD_INVALID
2830 static const u64 skl_plane_format_modifiers_ccs
[] = {
2831 I915_FORMAT_MOD_Yf_TILED_CCS
,
2832 I915_FORMAT_MOD_Y_TILED_CCS
,
2833 I915_FORMAT_MOD_Yf_TILED
,
2834 I915_FORMAT_MOD_Y_TILED
,
2835 I915_FORMAT_MOD_X_TILED
,
2836 DRM_FORMAT_MOD_LINEAR
,
2837 DRM_FORMAT_MOD_INVALID
2840 static const u64 gen12_plane_format_modifiers_mc_ccs
[] = {
2841 I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS
,
2842 I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS
,
2843 I915_FORMAT_MOD_Y_TILED
,
2844 I915_FORMAT_MOD_X_TILED
,
2845 DRM_FORMAT_MOD_LINEAR
,
2846 DRM_FORMAT_MOD_INVALID
2849 static const u64 gen12_plane_format_modifiers_rc_ccs
[] = {
2850 I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS
,
2851 I915_FORMAT_MOD_Y_TILED
,
2852 I915_FORMAT_MOD_X_TILED
,
2853 DRM_FORMAT_MOD_LINEAR
,
2854 DRM_FORMAT_MOD_INVALID
2857 static bool g4x_sprite_format_mod_supported(struct drm_plane
*_plane
,
2858 u32 format
, u64 modifier
)
2861 case DRM_FORMAT_MOD_LINEAR
:
2862 case I915_FORMAT_MOD_X_TILED
:
2869 case DRM_FORMAT_XRGB8888
:
2870 case DRM_FORMAT_YUYV
:
2871 case DRM_FORMAT_YVYU
:
2872 case DRM_FORMAT_UYVY
:
2873 case DRM_FORMAT_VYUY
:
2874 if (modifier
== DRM_FORMAT_MOD_LINEAR
||
2875 modifier
== I915_FORMAT_MOD_X_TILED
)
2883 static bool snb_sprite_format_mod_supported(struct drm_plane
*_plane
,
2884 u32 format
, u64 modifier
)
2887 case DRM_FORMAT_MOD_LINEAR
:
2888 case I915_FORMAT_MOD_X_TILED
:
2895 case DRM_FORMAT_XRGB8888
:
2896 case DRM_FORMAT_XBGR8888
:
2897 case DRM_FORMAT_XRGB2101010
:
2898 case DRM_FORMAT_XBGR2101010
:
2899 case DRM_FORMAT_XRGB16161616F
:
2900 case DRM_FORMAT_XBGR16161616F
:
2901 case DRM_FORMAT_YUYV
:
2902 case DRM_FORMAT_YVYU
:
2903 case DRM_FORMAT_UYVY
:
2904 case DRM_FORMAT_VYUY
:
2905 if (modifier
== DRM_FORMAT_MOD_LINEAR
||
2906 modifier
== I915_FORMAT_MOD_X_TILED
)
2914 static bool vlv_sprite_format_mod_supported(struct drm_plane
*_plane
,
2915 u32 format
, u64 modifier
)
2918 case DRM_FORMAT_MOD_LINEAR
:
2919 case I915_FORMAT_MOD_X_TILED
:
2927 case DRM_FORMAT_RGB565
:
2928 case DRM_FORMAT_ABGR8888
:
2929 case DRM_FORMAT_ARGB8888
:
2930 case DRM_FORMAT_XBGR8888
:
2931 case DRM_FORMAT_XRGB8888
:
2932 case DRM_FORMAT_XBGR2101010
:
2933 case DRM_FORMAT_ABGR2101010
:
2934 case DRM_FORMAT_XRGB2101010
:
2935 case DRM_FORMAT_ARGB2101010
:
2936 case DRM_FORMAT_YUYV
:
2937 case DRM_FORMAT_YVYU
:
2938 case DRM_FORMAT_UYVY
:
2939 case DRM_FORMAT_VYUY
:
2940 if (modifier
== DRM_FORMAT_MOD_LINEAR
||
2941 modifier
== I915_FORMAT_MOD_X_TILED
)
2949 static bool skl_plane_format_mod_supported(struct drm_plane
*_plane
,
2950 u32 format
, u64 modifier
)
2952 struct intel_plane
*plane
= to_intel_plane(_plane
);
2955 case DRM_FORMAT_MOD_LINEAR
:
2956 case I915_FORMAT_MOD_X_TILED
:
2957 case I915_FORMAT_MOD_Y_TILED
:
2958 case I915_FORMAT_MOD_Yf_TILED
:
2960 case I915_FORMAT_MOD_Y_TILED_CCS
:
2961 case I915_FORMAT_MOD_Yf_TILED_CCS
:
2962 if (!plane
->has_ccs
)
2970 case DRM_FORMAT_XRGB8888
:
2971 case DRM_FORMAT_XBGR8888
:
2972 case DRM_FORMAT_ARGB8888
:
2973 case DRM_FORMAT_ABGR8888
:
2974 if (is_ccs_modifier(modifier
))
2977 case DRM_FORMAT_RGB565
:
2978 case DRM_FORMAT_XRGB2101010
:
2979 case DRM_FORMAT_XBGR2101010
:
2980 case DRM_FORMAT_ARGB2101010
:
2981 case DRM_FORMAT_ABGR2101010
:
2982 case DRM_FORMAT_YUYV
:
2983 case DRM_FORMAT_YVYU
:
2984 case DRM_FORMAT_UYVY
:
2985 case DRM_FORMAT_VYUY
:
2986 case DRM_FORMAT_NV12
:
2987 case DRM_FORMAT_XYUV8888
:
2988 case DRM_FORMAT_P010
:
2989 case DRM_FORMAT_P012
:
2990 case DRM_FORMAT_P016
:
2991 case DRM_FORMAT_XVYU2101010
:
2992 if (modifier
== I915_FORMAT_MOD_Yf_TILED
)
2996 case DRM_FORMAT_XBGR16161616F
:
2997 case DRM_FORMAT_ABGR16161616F
:
2998 case DRM_FORMAT_XRGB16161616F
:
2999 case DRM_FORMAT_ARGB16161616F
:
3000 case DRM_FORMAT_Y210
:
3001 case DRM_FORMAT_Y212
:
3002 case DRM_FORMAT_Y216
:
3003 case DRM_FORMAT_XVYU12_16161616
:
3004 case DRM_FORMAT_XVYU16161616
:
3005 if (modifier
== DRM_FORMAT_MOD_LINEAR
||
3006 modifier
== I915_FORMAT_MOD_X_TILED
||
3007 modifier
== I915_FORMAT_MOD_Y_TILED
)
3015 static bool gen12_plane_supports_mc_ccs(struct drm_i915_private
*dev_priv
,
3016 enum plane_id plane_id
)
3018 /* Wa_14010477008:tgl[a0..c0],rkl[all],dg1[all] */
3019 if (IS_DG1(dev_priv
) || IS_ROCKETLAKE(dev_priv
) ||
3020 IS_TGL_DISP_REVID(dev_priv
, TGL_REVID_A0
, TGL_REVID_C0
))
3023 return plane_id
< PLANE_SPRITE4
;
3026 static bool gen12_plane_format_mod_supported(struct drm_plane
*_plane
,
3027 u32 format
, u64 modifier
)
3029 struct drm_i915_private
*dev_priv
= to_i915(_plane
->dev
);
3030 struct intel_plane
*plane
= to_intel_plane(_plane
);
3033 case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS
:
3034 if (!gen12_plane_supports_mc_ccs(dev_priv
, plane
->id
))
3037 case DRM_FORMAT_MOD_LINEAR
:
3038 case I915_FORMAT_MOD_X_TILED
:
3039 case I915_FORMAT_MOD_Y_TILED
:
3040 case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS
:
3047 case DRM_FORMAT_XRGB8888
:
3048 case DRM_FORMAT_XBGR8888
:
3049 case DRM_FORMAT_ARGB8888
:
3050 case DRM_FORMAT_ABGR8888
:
3051 if (is_ccs_modifier(modifier
))
3054 case DRM_FORMAT_YUYV
:
3055 case DRM_FORMAT_YVYU
:
3056 case DRM_FORMAT_UYVY
:
3057 case DRM_FORMAT_VYUY
:
3058 case DRM_FORMAT_NV12
:
3059 case DRM_FORMAT_XYUV8888
:
3060 case DRM_FORMAT_P010
:
3061 case DRM_FORMAT_P012
:
3062 case DRM_FORMAT_P016
:
3063 if (modifier
== I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS
)
3066 case DRM_FORMAT_RGB565
:
3067 case DRM_FORMAT_XRGB2101010
:
3068 case DRM_FORMAT_XBGR2101010
:
3069 case DRM_FORMAT_ARGB2101010
:
3070 case DRM_FORMAT_ABGR2101010
:
3071 case DRM_FORMAT_XVYU2101010
:
3073 case DRM_FORMAT_XBGR16161616F
:
3074 case DRM_FORMAT_ABGR16161616F
:
3075 case DRM_FORMAT_XRGB16161616F
:
3076 case DRM_FORMAT_ARGB16161616F
:
3077 case DRM_FORMAT_Y210
:
3078 case DRM_FORMAT_Y212
:
3079 case DRM_FORMAT_Y216
:
3080 case DRM_FORMAT_XVYU12_16161616
:
3081 case DRM_FORMAT_XVYU16161616
:
3082 if (modifier
== DRM_FORMAT_MOD_LINEAR
||
3083 modifier
== I915_FORMAT_MOD_X_TILED
||
3084 modifier
== I915_FORMAT_MOD_Y_TILED
)
3092 static const struct drm_plane_funcs g4x_sprite_funcs
= {
3093 .update_plane
= drm_atomic_helper_update_plane
,
3094 .disable_plane
= drm_atomic_helper_disable_plane
,
3095 .destroy
= intel_plane_destroy
,
3096 .atomic_duplicate_state
= intel_plane_duplicate_state
,
3097 .atomic_destroy_state
= intel_plane_destroy_state
,
3098 .format_mod_supported
= g4x_sprite_format_mod_supported
,
3101 static const struct drm_plane_funcs snb_sprite_funcs
= {
3102 .update_plane
= drm_atomic_helper_update_plane
,
3103 .disable_plane
= drm_atomic_helper_disable_plane
,
3104 .destroy
= intel_plane_destroy
,
3105 .atomic_duplicate_state
= intel_plane_duplicate_state
,
3106 .atomic_destroy_state
= intel_plane_destroy_state
,
3107 .format_mod_supported
= snb_sprite_format_mod_supported
,
3110 static const struct drm_plane_funcs vlv_sprite_funcs
= {
3111 .update_plane
= drm_atomic_helper_update_plane
,
3112 .disable_plane
= drm_atomic_helper_disable_plane
,
3113 .destroy
= intel_plane_destroy
,
3114 .atomic_duplicate_state
= intel_plane_duplicate_state
,
3115 .atomic_destroy_state
= intel_plane_destroy_state
,
3116 .format_mod_supported
= vlv_sprite_format_mod_supported
,
3119 static const struct drm_plane_funcs skl_plane_funcs
= {
3120 .update_plane
= drm_atomic_helper_update_plane
,
3121 .disable_plane
= drm_atomic_helper_disable_plane
,
3122 .destroy
= intel_plane_destroy
,
3123 .atomic_duplicate_state
= intel_plane_duplicate_state
,
3124 .atomic_destroy_state
= intel_plane_destroy_state
,
3125 .format_mod_supported
= skl_plane_format_mod_supported
,
3128 static const struct drm_plane_funcs gen12_plane_funcs
= {
3129 .update_plane
= drm_atomic_helper_update_plane
,
3130 .disable_plane
= drm_atomic_helper_disable_plane
,
3131 .destroy
= intel_plane_destroy
,
3132 .atomic_duplicate_state
= intel_plane_duplicate_state
,
3133 .atomic_destroy_state
= intel_plane_destroy_state
,
3134 .format_mod_supported
= gen12_plane_format_mod_supported
,
3137 static bool skl_plane_has_fbc(struct drm_i915_private
*dev_priv
,
3138 enum pipe pipe
, enum plane_id plane_id
)
3140 if (!HAS_FBC(dev_priv
))
3143 return pipe
== PIPE_A
&& plane_id
== PLANE_PRIMARY
;
3146 static bool skl_plane_has_planar(struct drm_i915_private
*dev_priv
,
3147 enum pipe pipe
, enum plane_id plane_id
)
3149 /* Display WA #0870: skl, bxt */
3150 if (IS_SKYLAKE(dev_priv
) || IS_BROXTON(dev_priv
))
3153 if (IS_GEN(dev_priv
, 9) && !IS_GEMINILAKE(dev_priv
) && pipe
== PIPE_C
)
3156 if (plane_id
!= PLANE_PRIMARY
&& plane_id
!= PLANE_SPRITE0
)
3162 static const u32
*skl_get_plane_formats(struct drm_i915_private
*dev_priv
,
3163 enum pipe pipe
, enum plane_id plane_id
,
3166 if (skl_plane_has_planar(dev_priv
, pipe
, plane_id
)) {
3167 *num_formats
= ARRAY_SIZE(skl_planar_formats
);
3168 return skl_planar_formats
;
3170 *num_formats
= ARRAY_SIZE(skl_plane_formats
);
3171 return skl_plane_formats
;
3175 static const u32
*glk_get_plane_formats(struct drm_i915_private
*dev_priv
,
3176 enum pipe pipe
, enum plane_id plane_id
,
3179 if (skl_plane_has_planar(dev_priv
, pipe
, plane_id
)) {
3180 *num_formats
= ARRAY_SIZE(glk_planar_formats
);
3181 return glk_planar_formats
;
3183 *num_formats
= ARRAY_SIZE(skl_plane_formats
);
3184 return skl_plane_formats
;
3188 static const u32
*icl_get_plane_formats(struct drm_i915_private
*dev_priv
,
3189 enum pipe pipe
, enum plane_id plane_id
,
3192 if (icl_is_hdr_plane(dev_priv
, plane_id
)) {
3193 *num_formats
= ARRAY_SIZE(icl_hdr_plane_formats
);
3194 return icl_hdr_plane_formats
;
3195 } else if (icl_is_nv12_y_plane(dev_priv
, plane_id
)) {
3196 *num_formats
= ARRAY_SIZE(icl_sdr_y_plane_formats
);
3197 return icl_sdr_y_plane_formats
;
3199 *num_formats
= ARRAY_SIZE(icl_sdr_uv_plane_formats
);
3200 return icl_sdr_uv_plane_formats
;
3204 static const u64
*gen12_get_plane_modifiers(struct drm_i915_private
*dev_priv
,
3205 enum plane_id plane_id
)
3207 if (gen12_plane_supports_mc_ccs(dev_priv
, plane_id
))
3208 return gen12_plane_format_modifiers_mc_ccs
;
3210 return gen12_plane_format_modifiers_rc_ccs
;
3213 static bool skl_plane_has_ccs(struct drm_i915_private
*dev_priv
,
3214 enum pipe pipe
, enum plane_id plane_id
)
3216 if (plane_id
== PLANE_CURSOR
)
3219 if (INTEL_GEN(dev_priv
) >= 10)
3222 if (IS_GEMINILAKE(dev_priv
))
3223 return pipe
!= PIPE_C
;
3225 return pipe
!= PIPE_C
&&
3226 (plane_id
== PLANE_PRIMARY
||
3227 plane_id
== PLANE_SPRITE0
);
3230 struct intel_plane
*
3231 skl_universal_plane_create(struct drm_i915_private
*dev_priv
,
3232 enum pipe pipe
, enum plane_id plane_id
)
3234 const struct drm_plane_funcs
*plane_funcs
;
3235 struct intel_plane
*plane
;
3236 enum drm_plane_type plane_type
;
3237 unsigned int supported_rotations
;
3238 unsigned int supported_csc
;
3239 const u64
*modifiers
;
3244 plane
= intel_plane_alloc();
3249 plane
->id
= plane_id
;
3250 plane
->frontbuffer_bit
= INTEL_FRONTBUFFER(pipe
, plane_id
);
3252 plane
->has_fbc
= skl_plane_has_fbc(dev_priv
, pipe
, plane_id
);
3253 if (plane
->has_fbc
) {
3254 struct intel_fbc
*fbc
= &dev_priv
->fbc
;
3256 fbc
->possible_framebuffer_bits
|= plane
->frontbuffer_bit
;
3259 if (INTEL_GEN(dev_priv
) >= 11) {
3260 plane
->min_width
= icl_plane_min_width
;
3261 plane
->max_width
= icl_plane_max_width
;
3262 plane
->max_height
= icl_plane_max_height
;
3263 } else if (INTEL_GEN(dev_priv
) >= 10 || IS_GEMINILAKE(dev_priv
)) {
3264 plane
->max_width
= glk_plane_max_width
;
3265 plane
->max_height
= skl_plane_max_height
;
3267 plane
->max_width
= skl_plane_max_width
;
3268 plane
->max_height
= skl_plane_max_height
;
3271 plane
->max_stride
= skl_plane_max_stride
;
3272 plane
->update_plane
= skl_update_plane
;
3273 plane
->disable_plane
= skl_disable_plane
;
3274 plane
->get_hw_state
= skl_plane_get_hw_state
;
3275 plane
->check_plane
= skl_plane_check
;
3276 plane
->min_cdclk
= skl_plane_min_cdclk
;
3277 plane
->async_flip
= skl_plane_async_flip
;
3279 if (INTEL_GEN(dev_priv
) >= 11)
3280 formats
= icl_get_plane_formats(dev_priv
, pipe
,
3281 plane_id
, &num_formats
);
3282 else if (INTEL_GEN(dev_priv
) >= 10 || IS_GEMINILAKE(dev_priv
))
3283 formats
= glk_get_plane_formats(dev_priv
, pipe
,
3284 plane_id
, &num_formats
);
3286 formats
= skl_get_plane_formats(dev_priv
, pipe
,
3287 plane_id
, &num_formats
);
3289 plane
->has_ccs
= skl_plane_has_ccs(dev_priv
, pipe
, plane_id
);
3290 if (INTEL_GEN(dev_priv
) >= 12) {
3291 modifiers
= gen12_get_plane_modifiers(dev_priv
, plane_id
);
3292 plane_funcs
= &gen12_plane_funcs
;
3295 modifiers
= skl_plane_format_modifiers_ccs
;
3297 modifiers
= skl_plane_format_modifiers_noccs
;
3298 plane_funcs
= &skl_plane_funcs
;
3301 if (plane_id
== PLANE_PRIMARY
)
3302 plane_type
= DRM_PLANE_TYPE_PRIMARY
;
3304 plane_type
= DRM_PLANE_TYPE_OVERLAY
;
3306 ret
= drm_universal_plane_init(&dev_priv
->drm
, &plane
->base
,
3308 formats
, num_formats
, modifiers
,
3310 "plane %d%c", plane_id
+ 1,
3315 supported_rotations
=
3316 DRM_MODE_ROTATE_0
| DRM_MODE_ROTATE_90
|
3317 DRM_MODE_ROTATE_180
| DRM_MODE_ROTATE_270
;
3319 if (INTEL_GEN(dev_priv
) >= 10)
3320 supported_rotations
|= DRM_MODE_REFLECT_X
;
3322 drm_plane_create_rotation_property(&plane
->base
,
3324 supported_rotations
);
3326 supported_csc
= BIT(DRM_COLOR_YCBCR_BT601
) | BIT(DRM_COLOR_YCBCR_BT709
);
3328 if (INTEL_GEN(dev_priv
) >= 10 || IS_GEMINILAKE(dev_priv
))
3329 supported_csc
|= BIT(DRM_COLOR_YCBCR_BT2020
);
3331 drm_plane_create_color_properties(&plane
->base
,
3333 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE
) |
3334 BIT(DRM_COLOR_YCBCR_FULL_RANGE
),
3335 DRM_COLOR_YCBCR_BT709
,
3336 DRM_COLOR_YCBCR_LIMITED_RANGE
);
3338 drm_plane_create_alpha_property(&plane
->base
);
3339 drm_plane_create_blend_mode_property(&plane
->base
,
3340 BIT(DRM_MODE_BLEND_PIXEL_NONE
) |
3341 BIT(DRM_MODE_BLEND_PREMULTI
) |
3342 BIT(DRM_MODE_BLEND_COVERAGE
));
3344 drm_plane_create_zpos_immutable_property(&plane
->base
, plane_id
);
3346 if (INTEL_GEN(dev_priv
) >= 12)
3347 drm_plane_enable_fb_damage_clips(&plane
->base
);
3349 if (INTEL_GEN(dev_priv
) >= 10)
3350 drm_plane_create_scaling_filter_property(&plane
->base
,
3351 BIT(DRM_SCALING_FILTER_DEFAULT
) |
3352 BIT(DRM_SCALING_FILTER_NEAREST_NEIGHBOR
));
3354 drm_plane_helper_add(&plane
->base
, &intel_plane_helper_funcs
);
3359 intel_plane_free(plane
);
3361 return ERR_PTR(ret
);
3364 struct intel_plane
*
3365 intel_sprite_plane_create(struct drm_i915_private
*dev_priv
,
3366 enum pipe pipe
, int sprite
)
3368 struct intel_plane
*plane
;
3369 const struct drm_plane_funcs
*plane_funcs
;
3370 unsigned int supported_rotations
;
3371 const u64
*modifiers
;
3376 if (INTEL_GEN(dev_priv
) >= 9)
3377 return skl_universal_plane_create(dev_priv
, pipe
,
3378 PLANE_SPRITE0
+ sprite
);
3380 plane
= intel_plane_alloc();
3384 if (IS_VALLEYVIEW(dev_priv
) || IS_CHERRYVIEW(dev_priv
)) {
3385 plane
->max_stride
= i9xx_plane_max_stride
;
3386 plane
->update_plane
= vlv_update_plane
;
3387 plane
->disable_plane
= vlv_disable_plane
;
3388 plane
->get_hw_state
= vlv_plane_get_hw_state
;
3389 plane
->check_plane
= vlv_sprite_check
;
3390 plane
->min_cdclk
= vlv_plane_min_cdclk
;
3392 if (IS_CHERRYVIEW(dev_priv
) && pipe
== PIPE_B
) {
3393 formats
= chv_pipe_b_sprite_formats
;
3394 num_formats
= ARRAY_SIZE(chv_pipe_b_sprite_formats
);
3396 formats
= vlv_plane_formats
;
3397 num_formats
= ARRAY_SIZE(vlv_plane_formats
);
3399 modifiers
= i9xx_plane_format_modifiers
;
3401 plane_funcs
= &vlv_sprite_funcs
;
3402 } else if (INTEL_GEN(dev_priv
) >= 7) {
3403 plane
->max_stride
= g4x_sprite_max_stride
;
3404 plane
->update_plane
= ivb_update_plane
;
3405 plane
->disable_plane
= ivb_disable_plane
;
3406 plane
->get_hw_state
= ivb_plane_get_hw_state
;
3407 plane
->check_plane
= g4x_sprite_check
;
3409 if (IS_BROADWELL(dev_priv
) || IS_HASWELL(dev_priv
))
3410 plane
->min_cdclk
= hsw_plane_min_cdclk
;
3412 plane
->min_cdclk
= ivb_sprite_min_cdclk
;
3414 formats
= snb_plane_formats
;
3415 num_formats
= ARRAY_SIZE(snb_plane_formats
);
3416 modifiers
= i9xx_plane_format_modifiers
;
3418 plane_funcs
= &snb_sprite_funcs
;
3420 plane
->max_stride
= g4x_sprite_max_stride
;
3421 plane
->update_plane
= g4x_update_plane
;
3422 plane
->disable_plane
= g4x_disable_plane
;
3423 plane
->get_hw_state
= g4x_plane_get_hw_state
;
3424 plane
->check_plane
= g4x_sprite_check
;
3425 plane
->min_cdclk
= g4x_sprite_min_cdclk
;
3427 modifiers
= i9xx_plane_format_modifiers
;
3428 if (IS_GEN(dev_priv
, 6)) {
3429 formats
= snb_plane_formats
;
3430 num_formats
= ARRAY_SIZE(snb_plane_formats
);
3432 plane_funcs
= &snb_sprite_funcs
;
3434 formats
= g4x_plane_formats
;
3435 num_formats
= ARRAY_SIZE(g4x_plane_formats
);
3437 plane_funcs
= &g4x_sprite_funcs
;
3441 if (IS_CHERRYVIEW(dev_priv
) && pipe
== PIPE_B
) {
3442 supported_rotations
=
3443 DRM_MODE_ROTATE_0
| DRM_MODE_ROTATE_180
|
3446 supported_rotations
=
3447 DRM_MODE_ROTATE_0
| DRM_MODE_ROTATE_180
;
3451 plane
->id
= PLANE_SPRITE0
+ sprite
;
3452 plane
->frontbuffer_bit
= INTEL_FRONTBUFFER(pipe
, plane
->id
);
3454 ret
= drm_universal_plane_init(&dev_priv
->drm
, &plane
->base
,
3456 formats
, num_formats
, modifiers
,
3457 DRM_PLANE_TYPE_OVERLAY
,
3458 "sprite %c", sprite_name(pipe
, sprite
));
3462 drm_plane_create_rotation_property(&plane
->base
,
3464 supported_rotations
);
3466 drm_plane_create_color_properties(&plane
->base
,
3467 BIT(DRM_COLOR_YCBCR_BT601
) |
3468 BIT(DRM_COLOR_YCBCR_BT709
),
3469 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE
) |
3470 BIT(DRM_COLOR_YCBCR_FULL_RANGE
),
3471 DRM_COLOR_YCBCR_BT709
,
3472 DRM_COLOR_YCBCR_LIMITED_RANGE
);
3475 drm_plane_create_zpos_immutable_property(&plane
->base
, zpos
);
3477 drm_plane_helper_add(&plane
->base
, &intel_plane_helper_funcs
);
3482 intel_plane_free(plane
);
3484 return ERR_PTR(ret
);