From: Anshuman Gupta <anshuman.gupta@xxxxxxxxx> Handles the plane programing for flat ccs and clear color modifiers for DG2 Signed-off-by: Anshuman Gupta <anshuman.gupta@xxxxxxxxx> Signed-off-by: Juha-Pekka Heikkilä <juha-pekka.heikkila@xxxxxxxxx> Signed-off-by: Ramalingam C <ramalingam.c@xxxxxxxxx> --- .../gpu/drm/i915/display/intel_atomic_plane.c | 3 +- drivers/gpu/drm/i915/display/intel_display.c | 4 ++- drivers/gpu/drm/i915/display/intel_fb.c | 30 +++++++++++-------- drivers/gpu/drm/i915/display/intel_fb.h | 3 +- drivers/gpu/drm/i915/display/skl_scaler.c | 6 ++-- .../drm/i915/display/skl_universal_plane.c | 21 ++++++++----- drivers/gpu/drm/i915/intel_pm.c | 9 +++--- 7 files changed, 46 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index f61a48e1a562..545784fb7bc9 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -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 && diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 9b3913d73213..80626aec3747 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -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 diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 484ae1fd0e94..534018563cdb 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -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; diff --git a/drivers/gpu/drm/i915/display/intel_fb.h b/drivers/gpu/drm/i915/display/intel_fb.h index 042ad81f8608..750f3f3a70b7 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.h +++ b/drivers/gpu/drm/i915/display/intel_fb.h @@ -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); diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index c2e94118566b..1bc0d98b252b 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -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); diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 136b3f74a290..13cd95a7d827 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -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 | diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 1ac1af0a7f2d..b3d29ea9fe77 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -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) -- 2.20.1