@@ -355,7 +355,8 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
new_crtc_state->active_planes |= BIT(plane->id);
if (new_plane_state->uapi.visible &&
- intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
+ intel_format_info_is_yuv_semiplanar(to_i915(fb->dev),
+ fb->format, fb->modifier))
new_crtc_state->nv12_planes |= BIT(plane->id);
if (new_plane_state->uapi.visible &&
@@ -8595,7 +8595,9 @@ static void intel_atomic_prepare_plane_clear_colors(struct intel_atomic_state *s
/*
* The layout of the fast clear color value expected by HW
- * (the DRM ABI requiring this value to be located in fb at offset 0 of plane#2):
+ * (the DRM ABI requiring this value to be located in fb at
+ * offset 0 of cc plane, plane#2 for non flat-ccs solutions and
+ * plane#1 for flat-ccs based solutions):
* - 4 x 4 bytes per-channel value
* (in surface type specific float/int format provided by the fb user)
* - 8 bytes native color value used by the display
@@ -427,7 +427,8 @@ bool intel_fb_plane_supports_modifier(struct intel_plane *plane, u64 modifier)
return false;
}
-static bool format_is_yuv_semiplanar(const struct intel_modifier_desc *md,
+static bool format_is_yuv_semiplanar(const struct drm_i915_private *i915,
+ const struct intel_modifier_desc *md,
const struct drm_format_info *info)
{
int yuv_planes;
@@ -435,7 +436,7 @@ static bool format_is_yuv_semiplanar(const struct intel_modifier_desc *md,
if (!info->is_yuv)
return false;
- if (is_ccs_type_modifier(md, INTEL_CCS_ANY))
+ if (is_ccs_type_modifier(md, INTEL_CCS_ANY) && !!HAS_FLAT_CCS(i915))
yuv_planes = 4;
else
yuv_planes = 2;
@@ -451,16 +452,18 @@ static bool format_is_yuv_semiplanar(const struct intel_modifier_desc *md,
* Returns:
* %true if @info / @modifier is YUV semiplanar.
*/
-bool intel_format_info_is_yuv_semiplanar(const struct drm_format_info *info,
+bool intel_format_info_is_yuv_semiplanar(const struct drm_i915_private *i915,
+ const struct drm_format_info *info,
u64 modifier)
{
- return format_is_yuv_semiplanar(lookup_modifier(modifier), info);
+ return format_is_yuv_semiplanar(i915, lookup_modifier(modifier), info);
}
-static u8 ccs_aux_plane_mask(const struct intel_modifier_desc *md,
+static u8 ccs_aux_plane_mask(const struct drm_i915_private *i915,
+ const struct intel_modifier_desc *md,
const struct drm_format_info *format)
{
- if (format_is_yuv_semiplanar(md, format))
+ if (format_is_yuv_semiplanar(i915, md, format))
return md->ccs.planar_aux_planes;
else
return md->ccs.packed_aux_planes;
@@ -478,7 +481,7 @@ bool intel_fb_is_ccs_aux_plane(const struct drm_framebuffer *fb, int color_plane
{
const struct intel_modifier_desc *md = lookup_modifier(fb->modifier);
- return ccs_aux_plane_mask(md, fb->format) & BIT(color_plane);
+ return ccs_aux_plane_mask(to_i915(fb->dev), md, fb->format) & BIT(color_plane);
}
/**
@@ -493,8 +496,11 @@ static bool intel_fb_is_gen12_ccs_aux_plane(const struct drm_framebuffer *fb, in
{
const struct intel_modifier_desc *md = lookup_modifier(fb->modifier);
+ if (HAS_FLAT_CCS(to_i915(fb->dev)))
+ return false;
+
return check_modifier_display_ver_range(md, 12, 13) &&
- ccs_aux_plane_mask(md, fb->format) & BIT(color_plane);
+ ccs_aux_plane_mask(to_i915(fb->dev), md, fb->format) & BIT(color_plane);
}
/**
@@ -524,8 +530,8 @@ static bool is_gen12_ccs_cc_plane(const struct drm_framebuffer *fb, int color_pl
static bool is_semiplanar_uv_plane(const struct drm_framebuffer *fb, int color_plane)
{
- return intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
- color_plane == 1;
+ return intel_format_info_is_yuv_semiplanar(to_i915(fb->dev), fb->format,
+ fb->modifier) && color_plane == 1;
}
bool is_surface_linear(const struct drm_framebuffer *fb, int color_plane)
@@ -590,10 +596,10 @@ int skl_main_to_aux_plane(const struct drm_framebuffer *fb, int main_plane)
{
struct drm_i915_private *i915 = to_i915(fb->dev);
- if (intel_fb_is_ccs_modifier(fb->modifier))
+ if (intel_fb_is_ccs_modifier(fb->modifier) && !HAS_FLAT_CCS(i915))
return main_to_ccs_plane(fb, main_plane);
else if (DISPLAY_VER(i915) < 11 &&
- intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
+ intel_format_info_is_yuv_semiplanar(i915, fb->format, fb->modifier))
return 1;
else
return 0;
@@ -42,7 +42,8 @@ const struct drm_format_info *
intel_fb_get_format_info(const struct drm_mode_fb_cmd2 *cmd);
bool
-intel_format_info_is_yuv_semiplanar(const struct drm_format_info *info,
+intel_format_info_is_yuv_semiplanar(const struct drm_i915_private *i915,
+ const struct drm_format_info *info,
u64 modifier);
bool is_surface_linear(const struct drm_framebuffer *fb, int color_plane);
@@ -148,7 +148,7 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
return 0;
}
- if (format && intel_format_info_is_yuv_semiplanar(format, modifier) &&
+ if (format && intel_format_info_is_yuv_semiplanar(dev_priv, format, modifier) &&
(src_h < SKL_MIN_YUV_420_SRC_H || src_w < SKL_MIN_YUV_420_SRC_W)) {
drm_dbg_kms(&dev_priv->drm,
"Planar YUV: src dimensions not met\n");
@@ -224,7 +224,7 @@ int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
/* Pre-gen11 and SDR planes always need a scaler for planar formats. */
if (!icl_is_hdr_plane(dev_priv, intel_plane->id) &&
- fb && intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
+ fb && intel_format_info_is_yuv_semiplanar(dev_priv, fb->format, fb->modifier))
need_scaler = true;
ret = skl_update_scaler(crtc_state, force_detach,
@@ -481,7 +481,7 @@ skl_program_plane_scaler(struct intel_plane *plane,
0, INT_MAX);
/* TODO: handle sub-pixel coordinates */
- if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
+ if (intel_format_info_is_yuv_semiplanar(dev_priv, fb->format, fb->modifier) &&
!icl_is_hdr_plane(dev_priv, plane->id)) {
y_hphase = skl_scaler_calc_phase(1, hscale, false);
y_vphase = skl_scaler_calc_phase(1, vscale, false);
@@ -823,8 +823,9 @@ static u32 icl_plane_ctl_flip(unsigned int reflect)
static u32 adlp_plane_ctl_arb_slots(const struct intel_plane_state *plane_state)
{
const struct drm_framebuffer *fb = plane_state->hw.fb;
+ struct drm_i915_private *i915 = to_i915(fb->dev);
- if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) {
+ if (intel_format_info_is_yuv_semiplanar(i915, fb->format, fb->modifier)) {
switch (fb->format->cpp[0]) {
case 2:
return PLANE_CTL_ARB_SLOTS(1);
@@ -1077,7 +1078,9 @@ skl_program_plane(struct intel_plane *plane,
intel_de_write_fw(dev_priv, PLANE_SIZE(pipe, plane_id),
(src_h << 16) | src_w);
- intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id), aux_dist);
+ /* FLAT CCS doesn't need to program AUX_DIST */
+ if (!HAS_FLAT_CCS(dev_priv))
+ intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id), aux_dist);
if (icl_is_hdr_plane(dev_priv, plane_id))
intel_de_write_fw(dev_priv, PLANE_CUS_CTL(pipe, plane_id),
@@ -1300,11 +1303,12 @@ static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_s
static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state)
{
const struct drm_framebuffer *fb = plane_state->hw.fb;
+ struct drm_i915_private *i915 = to_i915(fb->dev);
unsigned int rotation = plane_state->hw.rotation;
int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
/* Display WA #1106 */
- if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
+ if (intel_format_info_is_yuv_semiplanar(i915, fb->format, fb->modifier) &&
src_w & 3 &&
(rotation == DRM_MODE_ROTATE_270 ||
rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) {
@@ -1325,7 +1329,7 @@ static int skl_plane_max_scale(struct drm_i915_private *dev_priv,
* FIXME need to properly check this later.
*/
if (DISPLAY_VER(dev_priv) >= 10 ||
- !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
+ !intel_format_info_is_yuv_semiplanar(dev_priv, fb->format, fb->modifier))
return 0x30000 - 1;
else
return 0x20000 - 1;
@@ -1493,8 +1497,9 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
/*
* CCS AUX surface doesn't have its own x/y offsets, we must make sure
* they match with the main surface x/y offsets.
+ * On DG2 with Flat-CCS, there's no aux plane on fb so skip this checking.
*/
- if (intel_fb_is_ccs_modifier(fb->modifier)) {
+ if (intel_fb_is_ccs_modifier(fb->modifier) && !HAS_FLAT_CCS(dev_priv)) {
while (!skl_check_main_ccs_coordinates(plane_state, x, y,
offset, aux_plane)) {
if (offset == 0)
@@ -1558,7 +1563,7 @@ static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
offset = intel_plane_compute_aligned_offset(&x, &y,
plane_state, uv_plane);
- if (intel_fb_is_ccs_modifier(fb->modifier)) {
+ if (intel_fb_is_ccs_modifier(fb->modifier) && !HAS_FLAT_CCS(i915)) {
int ccs_plane = main_to_ccs_plane(fb, uv_plane);
u32 aux_offset = plane_state->view.color_plane[ccs_plane].offset;
u32 alignment = intel_surf_alignment(fb, uv_plane);
@@ -1662,7 +1667,7 @@ static int skl_check_plane_surface(struct intel_plane_state *plane_state)
return ret;
}
- if (intel_format_info_is_yuv_semiplanar(fb->format,
+ if (intel_format_info_is_yuv_semiplanar(to_i915(fb->dev), fb->format,
fb->modifier)) {
ret = skl_check_nv12_aux_surface(plane_state);
if (ret)
@@ -1765,7 +1770,7 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state,
plane_state->color_ctl = glk_plane_color_ctl(crtc_state,
plane_state);
- if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
+ if (intel_format_info_is_yuv_semiplanar(dev_priv, fb->format, fb->modifier) &&
icl_is_hdr_plane(dev_priv, plane->id))
/* Enable and use MPEG-2 chroma siting */
plane_state->cus_ctl = PLANE_CUS_ENABLE |
@@ -4926,7 +4926,8 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
return 0;
if (color_plane == 1 &&
- !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
+ !intel_format_info_is_yuv_semiplanar(to_i915(fb->dev), fb->format,
+ fb->modifier))
return 0;
/*
@@ -5367,11 +5368,11 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+ bool planar = intel_format_info_is_yuv_semiplanar(dev_priv, format, modifier);
u32 interm_pbpl;
/* only planar format has two planes */
- if (color_plane == 1 &&
- !intel_format_info_is_yuv_semiplanar(format, modifier)) {
+ if (color_plane == 1 && !planar) {
drm_dbg_kms(&dev_priv->drm,
"Non planar format have single plane\n");
return -EINVAL;
@@ -5385,7 +5386,7 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
wp->x_tiled = modifier == I915_FORMAT_MOD_X_TILED;
wp->rc_surface = modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
modifier == I915_FORMAT_MOD_Yf_TILED_CCS;
- wp->is_planar = intel_format_info_is_yuv_semiplanar(format, modifier);
+ wp->is_planar = planar;
wp->width = width;
if (color_plane == 1 && wp->is_planar)