[Intel-gfx] [PATCH 0/5] s/ADL/ALDERLAKE
Replace all occurences of ADL -> ALDERLAKE in platform and subplatform defines. This way there is a consistent pattern to how platforms are referred. While the change is minor and could be combined to have lesser patches, splitting to per subpaltform for easier cherrypicks, if needed. Anusha Srivatsa (5): drm/i915/adlp: s/ADLP/ALDERLAKE_P for display and graphics step drm/i915/rplp: s/ADLP/ALDERLAKE_P for RPLP defines drm/i915/rplu: s/ADLP/ALDERLAKE_P in RPLU defines drm/i915/adln: s/ADLP/ALDERLAKE_P in ADLN defines drm/i915/adls: s/ADLS/ALDERLAKE_S in platform and subplatform defines drivers/gpu/drm/i915/display/intel_cdclk.c | 4 ++-- drivers/gpu/drm/i915/display/intel_dpll_mgr.c| 2 +- drivers/gpu/drm/i915/display/intel_psr.c | 8 .../gpu/drm/i915/display/skl_universal_plane.c | 4 ++-- drivers/gpu/drm/i915/gt/uc/intel_guc_hwconfig.c | 2 +- drivers/gpu/drm/i915/gt/uc/intel_uc.c| 2 +- drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 16 drivers/gpu/drm/i915/intel_device_info.c | 2 +- drivers/gpu/drm/i915/intel_step.c| 6 +++--- 10 files changed, 24 insertions(+), 24 deletions(-) -- 2.25.1
[Intel-gfx] [PATCH 4/5] drm/i915/adln: s/ADLP/ALDERLAKE_P in ADLN defines
Follow consistent naming convention. Replace ADLP with ALDERLAKE_P Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/gt/uc/intel_guc_hwconfig.c | 2 +- drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c| 2 +- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/intel_step.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_hwconfig.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_hwconfig.c index 852bea0208ce..cc9569af7f0c 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_hwconfig.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_hwconfig.c @@ -94,7 +94,7 @@ static int guc_hwconfig_fill_buffer(struct intel_guc *guc, struct intel_hwconfig static bool has_table(struct drm_i915_private *i915) { - if (IS_ALDERLAKE_P(i915) && !IS_ADLP_N(i915)) + if (IS_ALDERLAKE_P(i915) && !IS_ALDERLAKE_P_N(i915)) return true; if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 55)) return true; diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c index dc5c96c503a9..0989003a10ed 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c @@ -276,7 +276,7 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw) * ADL-S, otherwise the GuC might attempt to fetch a config table that * does not exist. */ - if (IS_ADLP_N(i915)) + if (IS_ALDERLAKE_P_N(i915)) p = INTEL_ALDERLAKE_S; GEM_BUG_ON(uc_fw->type >= ARRAY_SIZE(blobs_all)); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d400cecb318b..4ef336f6f24b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -579,7 +579,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, IS_SUBPLATFORM(i915, INTEL_DG2, INTEL_SUBPLATFORM_G12) #define IS_ADLS_RPLS(i915) \ IS_SUBPLATFORM(i915, INTEL_ALDERLAKE_S, INTEL_SUBPLATFORM_RPL) -#define IS_ADLP_N(i915) \ +#define IS_ALDERLAKE_P_N(i915) \ IS_SUBPLATFORM(i915, INTEL_ALDERLAKE_P, INTEL_SUBPLATFORM_N) #define IS_ALDERLAKE_P_RPLP(i915) \ IS_SUBPLATFORM(i915, INTEL_ALDERLAKE_P, INTEL_SUBPLATFORM_RPL) diff --git a/drivers/gpu/drm/i915/intel_step.c b/drivers/gpu/drm/i915/intel_step.c index 10d86c525beb..0afe113b295a 100644 --- a/drivers/gpu/drm/i915/intel_step.c +++ b/drivers/gpu/drm/i915/intel_step.c @@ -192,7 +192,7 @@ void intel_step_init(struct drm_i915_private *i915) } else if (IS_XEHPSDV(i915)) { revids = xehpsdv_revids; size = ARRAY_SIZE(xehpsdv_revids); - } else if (IS_ADLP_N(i915)) { + } else if (IS_ALDERLAKE_P_N(i915)) { revids = adlp_n_revids; size = ARRAY_SIZE(adlp_n_revids); } else if (IS_ALDERLAKE_P_RPLP(i915)) { -- 2.25.1
[Intel-gfx] [PATCH 5/5] drm/i915/adls: s/ADLS/ALDERLAKE_S in platform and subplatform defines
Driver refers to the platfrom Alderlake S as ADLS in places and ALDERLAKE_S in some. Making the consistent change to avoid confusion of the right naming convention for the platform. Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/gt/uc/intel_uc.c| 2 +- drivers/gpu/drm/i915/i915_drv.h | 6 +++--- drivers/gpu/drm/i915/intel_device_info.c | 2 +- drivers/gpu/drm/i915/intel_step.c| 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c index c8b9cbb7ba3a..2bd908953e18 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c @@ -43,7 +43,7 @@ static void uc_expand_default_options(struct intel_uc *uc) } /* Intermediate platforms are HuC authentication only */ - if (IS_ALDERLAKE_S(i915) && !IS_ADLS_RPLS(i915)) { + if (IS_ALDERLAKE_S(i915) && !IS_ALDERLAKE_S_RPLS(i915)) { i915->params.enable_guc = ENABLE_GUC_LOAD_HUC; return; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4ef336f6f24b..3ef2eb9fde02 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -577,7 +577,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, IS_SUBPLATFORM(i915, INTEL_DG2, INTEL_SUBPLATFORM_G11) #define IS_DG2_G12(i915) \ IS_SUBPLATFORM(i915, INTEL_DG2, INTEL_SUBPLATFORM_G12) -#define IS_ADLS_RPLS(i915) \ +#define IS_ALDERLAKE_S_RPLS(i915) \ IS_SUBPLATFORM(i915, INTEL_ALDERLAKE_S, INTEL_SUBPLATFORM_RPL) #define IS_ALDERLAKE_P_N(i915) \ IS_SUBPLATFORM(i915, INTEL_ALDERLAKE_P, INTEL_SUBPLATFORM_N) @@ -661,11 +661,11 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, #define IS_RKL_DISPLAY_STEP(p, since, until) \ (IS_ROCKETLAKE(p) && IS_DISPLAY_STEP(p, since, until)) -#define IS_ADLS_DISPLAY_STEP(__i915, since, until) \ +#define IS_ALDERLAKE_S_DISPLAY_STEP(__i915, since, until) \ (IS_ALDERLAKE_S(__i915) && \ IS_DISPLAY_STEP(__i915, since, until)) -#define IS_ADLS_GRAPHICS_STEP(__i915, since, until) \ +#define IS_ALDERLAKE_S_GRAPHICS_STEP(__i915, since, until) \ (IS_ALDERLAKE_S(__i915) && \ IS_GRAPHICS_STEP(__i915, since, until)) diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c index 2f79d232b04a..559697c65664 100644 --- a/drivers/gpu/drm/i915/intel_device_info.c +++ b/drivers/gpu/drm/i915/intel_device_info.c @@ -416,7 +416,7 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv) enum pipe pipe; /* Wa_14011765242: adl-s A0,A1 */ - if (IS_ADLS_DISPLAY_STEP(dev_priv, STEP_A0, STEP_A2)) + if (IS_ALDERLAKE_S_DISPLAY_STEP(dev_priv, STEP_A0, STEP_A2)) for_each_pipe(dev_priv, pipe) display_runtime->num_scalers[pipe] = 0; else if (DISPLAY_VER(dev_priv) >= 11) { diff --git a/drivers/gpu/drm/i915/intel_step.c b/drivers/gpu/drm/i915/intel_step.c index 0afe113b295a..15c23c8982b9 100644 --- a/drivers/gpu/drm/i915/intel_step.c +++ b/drivers/gpu/drm/i915/intel_step.c @@ -201,7 +201,7 @@ void intel_step_init(struct drm_i915_private *i915) } else if (IS_ALDERLAKE_P(i915)) { revids = adlp_revids; size = ARRAY_SIZE(adlp_revids); - } else if (IS_ADLS_RPLS(i915)) { + } else if (IS_ALDERLAKE_S_RPLS(i915)) { revids = adls_rpls_revids; size = ARRAY_SIZE(adls_rpls_revids); } else if (IS_ALDERLAKE_S(i915)) { -- 2.25.1
[Intel-gfx] [PATCH 2/5] drm/i915/rplp: s/ADLP/ALDERLAKE_P for RPLP defines
Follow consistent naming convention. Replace ADLP with ALDERLAKE_P. Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/intel_step.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 1a50b8b2f00d..43414cdc137c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -581,7 +581,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, IS_SUBPLATFORM(i915, INTEL_ALDERLAKE_S, INTEL_SUBPLATFORM_RPL) #define IS_ADLP_N(i915) \ IS_SUBPLATFORM(i915, INTEL_ALDERLAKE_P, INTEL_SUBPLATFORM_N) -#define IS_ADLP_RPLP(i915) \ +#define IS_ALDERLAKE_P_RPLP(i915) \ IS_SUBPLATFORM(i915, INTEL_ALDERLAKE_P, INTEL_SUBPLATFORM_RPL) #define IS_ADLP_RPLU(i915) \ IS_SUBPLATFORM(i915, INTEL_ALDERLAKE_P, INTEL_SUBPLATFORM_RPLU) diff --git a/drivers/gpu/drm/i915/intel_step.c b/drivers/gpu/drm/i915/intel_step.c index 8a9ff6227e53..10d86c525beb 100644 --- a/drivers/gpu/drm/i915/intel_step.c +++ b/drivers/gpu/drm/i915/intel_step.c @@ -195,7 +195,7 @@ void intel_step_init(struct drm_i915_private *i915) } else if (IS_ADLP_N(i915)) { revids = adlp_n_revids; size = ARRAY_SIZE(adlp_n_revids); - } else if (IS_ADLP_RPLP(i915)) { + } else if (IS_ALDERLAKE_P_RPLP(i915)) { revids = adlp_rplp_revids; size = ARRAY_SIZE(adlp_rplp_revids); } else if (IS_ALDERLAKE_P(i915)) { -- 2.25.1
[Intel-gfx] [PATCH 1/5] drm/i915/adlp: s/ADLP/ALDERLAKE_P for display and graphics step
Driver refers to the platfrom Alderlake P as ADLP in places and ALDERLAKE_P in some. Making the consistent change to avoid confusion of the right naming convention for the platform. Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 2 +- drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 2 +- drivers/gpu/drm/i915/display/intel_psr.c | 8 drivers/gpu/drm/i915/display/skl_universal_plane.c | 4 ++-- drivers/gpu/drm/i915/i915_drv.h| 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 6bed75f1541a..013678caaca8 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -3541,7 +3541,7 @@ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv) } else if (IS_ALDERLAKE_P(dev_priv)) { dev_priv->display.funcs.cdclk = _cdclk_funcs; /* Wa_22011320316:adl-p[a0] */ - if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0)) + if (IS_ALDERLAKE_P_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0)) dev_priv->display.cdclk.table = adlp_a_step_cdclk_table; else if (IS_ADLP_RPLU(dev_priv)) dev_priv->display.cdclk.table = rplu_cdclk_table; diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index 6b2d8a1e2aa9..81f3ce5a0a1e 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -3781,7 +3781,7 @@ static void adlp_cmtg_clock_gating_wa(struct drm_i915_private *i915, struct inte { u32 val; - if (!IS_ADLP_DISPLAY_STEP(i915, STEP_A0, STEP_B0) || + if (!IS_ALDERLAKE_P_DISPLAY_STEP(i915, STEP_A0, STEP_B0) || pll->info->id != DPLL_ID_ICL_DPLL0) return; /* diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index ea0389c5f656..c25457dae315 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -639,7 +639,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp) } /* Wa_22012278275:adl-p */ - if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_E0)) { + if (IS_ALDERLAKE_P_DISPLAY_STEP(dev_priv, STEP_A0, STEP_E0)) { static const u8 map[] = { 2, /* 5 lines */ 1, /* 6 lines */ @@ -807,7 +807,7 @@ tgl_dc3co_exitline_compute_config(struct intel_dp *intel_dp, return; /* Wa_16011303918:adl-p */ - if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0)) + if (IS_ALDERLAKE_P_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0)) return; /* @@ -975,7 +975,7 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp, return false; } - if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0)) { + if (IS_ALDERLAKE_P_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0)) { drm_dbg_kms(_priv->drm, "PSR2 not completely functional in this stepping\n"); return false; } @@ -1033,7 +1033,7 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp, /* Wa_16011303918:adl-p */ if (crtc_state->vrr.enable && - IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0)) { + IS_ALDERLAKE_P_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0)) { drm_dbg_kms(_priv->drm, "PSR2 not enabled, not compatible with HW stepping + VRR\n"); return false; diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 36070d86550f..2019e0a87bd3 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -2174,7 +2174,7 @@ static bool skl_plane_has_rc_ccs(struct drm_i915_private *i915, return false; /* Wa_22011186057 */ - if (IS_ADLP_DISPLAY_STEP(i915, STEP_A0, STEP_B0)) + if (IS_ALDERLAKE_P_DISPLAY_STEP(i915, STEP_A0, STEP_B0)) return false; if (DISPLAY_VER(i915) >= 11) @@ -2200,7 +2200,7 @@ static bool gen12_plane_has_mc_ccs(struct drm_i915_private *i915, return false; /* Wa_22011186057 */ - if (IS_ADLP_DISPLAY_STEP(i915, STEP_A0, STEP_B0)) + if (IS_ALDERLAKE_P_DISPLAY_STEP(i915, STEP_A0, STEP_B0)) return false; /* Wa_14013215631 */ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f1205ed3ba71..1a50b8b2f00d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -669,11 +669,1
[Intel-gfx] [PATCH 3/5] drm/i915/rplu: s/ADLP/ALDERLAKE_P in RPLU defines
Follow consistent naming convention. Replace ADLP with ALDERLAKE_P Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 2 +- drivers/gpu/drm/i915/i915_drv.h| 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 013678caaca8..4420de5ffe9c 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -3543,7 +3543,7 @@ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv) /* Wa_22011320316:adl-p[a0] */ if (IS_ALDERLAKE_P_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0)) dev_priv->display.cdclk.table = adlp_a_step_cdclk_table; - else if (IS_ADLP_RPLU(dev_priv)) + else if (IS_ALDERLAKE_P_RPLU(dev_priv)) dev_priv->display.cdclk.table = rplu_cdclk_table; else dev_priv->display.cdclk.table = adlp_cdclk_table; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 43414cdc137c..d400cecb318b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -583,7 +583,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, IS_SUBPLATFORM(i915, INTEL_ALDERLAKE_P, INTEL_SUBPLATFORM_N) #define IS_ALDERLAKE_P_RPLP(i915) \ IS_SUBPLATFORM(i915, INTEL_ALDERLAKE_P, INTEL_SUBPLATFORM_RPL) -#define IS_ADLP_RPLU(i915) \ +#define IS_ALDERLAKE_P_RPLU(i915) \ IS_SUBPLATFORM(i915, INTEL_ALDERLAKE_P, INTEL_SUBPLATFORM_RPLU) #define IS_HSW_EARLY_SDV(i915) (IS_HASWELL(i915) && \ (INTEL_DEVID(i915) & 0xFF00) == 0x0C00) -- 2.25.1
[Intel-gfx] [PATCH] drm/i915/display: Add missing CDCLK Squash support for MTL
MTL supports both squash and crawl. Cc: Clint Taylor Cc: Lucas De Marchi Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/i915_pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index cf3b28d71d2b..d82f118809e9 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -1118,6 +1118,7 @@ static const struct intel_device_info pvc_info = { XE_LPD_FEATURES,\ .__runtime.display.ip.ver = 14, \ .display.has_cdclk_crawl = 1, \ + .display.has_cdclk_squash = 1, \ .__runtime.fbc_mask = BIT(INTEL_FBC_A) | BIT(INTEL_FBC_B) static const struct intel_gt_definition xelpmp_extra_gt[] = { -- 2.25.1
[Intel-gfx] [PATCH 3/3] drm/i915/display: Add CDCLK Support for MTL
As per bSpec MTL has 38.4 MHz Reference clock. Adding the cdclk tables and cdclk_funcs that MTL will use. v2: Revert to using bxt_get_cdclk() BSpec: 65243 Cc: Clint Taylor Signed-off-by: Anusha Srivatsa Reviewed-by: Clint Taylor --- drivers/gpu/drm/i915/display/intel_cdclk.c | 22 +- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 1280a08b9c72..32fbabf531fe 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1346,6 +1346,16 @@ static const struct intel_cdclk_vals dg2_cdclk_table[] = { {} }; +static const struct intel_cdclk_vals mtl_cdclk_table[] = { + { .refclk = 38400, .cdclk = 172800, .divider = 2, .ratio = 16, .waveform = 0xad5a }, + { .refclk = 38400, .cdclk = 192000, .divider = 2, .ratio = 16, .waveform = 0xb6b6 }, + { .refclk = 38400, .cdclk = 307200, .divider = 2, .ratio = 16, .waveform = 0x }, + { .refclk = 38400, .cdclk = 48, .divider = 2, .ratio = 25, .waveform = 0x }, + { .refclk = 38400, .cdclk = 556800, .divider = 2, .ratio = 29, .waveform = 0x }, + { .refclk = 38400, .cdclk = 652800, .divider = 2, .ratio = 34, .waveform = 0x }, + {} +}; + static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk) { const struct intel_cdclk_vals *table = dev_priv->display.cdclk.table; @@ -3190,6 +3200,13 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv) return freq; } +static const struct intel_cdclk_funcs mtl_cdclk_funcs = { + .get_cdclk = bxt_get_cdclk, + .set_cdclk = bxt_set_cdclk, + .modeset_calc_cdclk = bxt_modeset_calc_cdclk, + .calc_voltage_level = tgl_calc_voltage_level, +}; + static const struct intel_cdclk_funcs tgl_cdclk_funcs = { .get_cdclk = bxt_get_cdclk, .set_cdclk = bxt_set_cdclk, @@ -3325,7 +3342,10 @@ static const struct intel_cdclk_funcs i830_cdclk_funcs = { */ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv) { - if (IS_DG2(dev_priv)) { + if (IS_METEORLAKE(dev_priv)) { + dev_priv->display.funcs.cdclk = _cdclk_funcs; + dev_priv->display.cdclk.table = mtl_cdclk_table; + } else if (IS_DG2(dev_priv)) { dev_priv->display.funcs.cdclk = _cdclk_funcs; dev_priv->display.cdclk.table = dg2_cdclk_table; } else if (IS_ALDERLAKE_P(dev_priv)) { -- 2.25.1
[Intel-gfx] [PATCH 1/3] drm/i915/display: Add missing checks for cdclk crawling
cdclk_sanitize() function was written assuming vco was a signed integer. vco gets assigned to -1 (essentially ~0) for the case where PLL might be enabled and vco is not a frequency that will ever get used. In such a scenario the right thing to do is disable the PLL and re-enable it again with a valid frequency. However the vco is declared as a unsigned variable. With the above assumption, driver takes crawl path when not needed. Add explicit check to not crawl in the case of an invalid PLL. v2: Move the check from .h to .c (MattR) - Move check to bxt_set_cdclk() instead of intel_modeset_calc_cdclk() which is directly in the path of the sanitize() function (Ville) v3: remove unwanted parenthesis(Ville) Cc: Ville Syrjälä Cc: Matt Roper Suggested-by: Ville Syrjälä Signed-off-by: Anusha Srivatsa Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/display/intel_cdclk.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index b74e36d76013..25d01271dc09 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1717,6 +1717,16 @@ static void dg2_cdclk_squash_program(struct drm_i915_private *i915, intel_de_write(i915, CDCLK_SQUASH_CTL, squash_ctl); } +static bool cdclk_pll_is_unknown(unsigned int vco) +{ + /* +* Ensure driver does not take the crawl path for the +* case when the vco is set to ~0 in the +* sanitize path. +*/ + return vco == ~0; +} + static void bxt_set_cdclk(struct drm_i915_private *dev_priv, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) @@ -1749,7 +1759,8 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, return; } - if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0) { + if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0 && + !cdclk_pll_is_unknown(dev_priv->display.cdclk.hw.vco)) { if (dev_priv->display.cdclk.hw.vco != vco) adlp_cdclk_pll_crawl(dev_priv, vco); } else if (DISPLAY_VER(dev_priv) >= 11) -- 2.25.1
[Intel-gfx] [PATCH 2/3] drm/i915/display: Do both crawl and squash when changing cdclk
From: Ville Syrjälä For MTL, changing cdclk from between certain frequencies has both squash and crawl. Use the current cdclk config and the new(desired) cdclk config to construtc a mid cdclk config. Set the cdclk twice: - Current cdclk -> mid cdclk - mid cdclk -> desired cdclk Driver should not take some Pcode mailbox communication in the cdclk path for platforms that are Display version 14 and later. v2: Add check in intel_modeset_calc_cdclk() to avoid cdclk change via modeset for platforms that support squash_crawl sequences(Ville) v3: Add checks for: - scenario where only slow clock is used and cdclk is actually 0 (bringing up display). - PLLs are on before looking up the waveform. - Squash and crawl capability checks.(Ville) v4: Rebase - Move checks to be more consistent (Ville) - Add comments (Bala) v5: - Further small changes. Move checks around. - Make if-else better looking (Ville) v6: MTl should not follow PUnit mailbox communication as the rest of gen11+ platforms.(Anusha) Cc: Clint Taylor Cc: Balasubramani Vivekanandan Signed-off-by: Anusha Srivatsa Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/display/intel_cdclk.c | 181 + 1 file changed, 150 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 25d01271dc09..1280a08b9c72 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1727,37 +1727,79 @@ static bool cdclk_pll_is_unknown(unsigned int vco) return vco == ~0; } -static void bxt_set_cdclk(struct drm_i915_private *dev_priv, - const struct intel_cdclk_config *cdclk_config, - enum pipe pipe) +static int cdclk_squash_divider(u16 waveform) +{ + return hweight16(waveform ?: 0x); +} + +static bool cdclk_compute_crawl_and_squash_midpoint(struct drm_i915_private *i915, + const struct intel_cdclk_config *old_cdclk_config, + const struct intel_cdclk_config *new_cdclk_config, + struct intel_cdclk_config *mid_cdclk_config) +{ + u16 old_waveform, new_waveform, mid_waveform; + int size = 16; + int div = 2; + + /* Return for vco ~0 (-1) and follow complete PLL disable and enable */ + if (cdclk_pll_is_unknown(old_cdclk_config->vco)) + return false; + + /* Return if both Squash and Crawl are not present */ + if (!HAS_CDCLK_CRAWL(i915) || !HAS_CDCLK_SQUASH(i915)) + return false; + + old_waveform = cdclk_squash_waveform(i915, old_cdclk_config->cdclk); + new_waveform = cdclk_squash_waveform(i915, new_cdclk_config->cdclk); + + /* Return if Squash only or Crawl only is the desired action */ + if (old_cdclk_config->vco == 0 || new_cdclk_config->vco == 0 || + old_cdclk_config->vco == new_cdclk_config->vco || + old_waveform == new_waveform) + return false; + + *mid_cdclk_config = *new_cdclk_config; + + /* +* Populate the mid_cdclk_config accordingly. +* - If moving to a higher cdclk, the desired action is squashing. +* The mid cdclk config should have the new (squash) waveform. +* - If moving to a lower cdclk, the desired action is crawling. +* The mid cdclk config should have the new vco. +*/ + + if (cdclk_squash_divider(new_waveform) > cdclk_squash_divider(old_waveform)) { + mid_cdclk_config->vco = old_cdclk_config->vco; + mid_waveform = new_waveform; + } else { + mid_cdclk_config->vco = new_cdclk_config->vco; + mid_waveform = old_waveform; + } + + mid_cdclk_config->cdclk = DIV_ROUND_CLOSEST(cdclk_squash_divider(mid_waveform) * + mid_cdclk_config->vco, size * div); + + /* make sure the mid clock came out sane */ + + drm_WARN_ON(>drm, mid_cdclk_config->cdclk < + min(old_cdclk_config->cdclk, new_cdclk_config->cdclk)); + drm_WARN_ON(>drm, mid_cdclk_config->cdclk > + i915->display.cdclk.max_cdclk_freq); + drm_WARN_ON(>drm, cdclk_squash_waveform(i915, mid_cdclk_config->cdclk) != + mid_waveform); + + return true; +} + +static void _bxt_set_cdclk(struct drm_i915_private *dev_priv, + const struct intel_cdclk_config *cdclk_config, + enum pipe pipe) { int cdclk = cdclk_config->cdclk; int vco = cdclk_config->vco; u32 val; u16 waveform; int clock; - int ret; - - /* Inform power controller of upcoming frequency change. */ -
[Intel-gfx] [PATCH 1/3] drm/i915/display: Add missing checks for cdclk crawling
cdclk_sanitize() function was written assuming vco was a signed integer. vco gets assigned to -1 (essentially ~0) for the case where PLL might be enabled and vco is not a frequency that will ever get used. In such a scenario the right thing to do is disable the PLL and re-enable it again with a valid frequency. However the vco is declared as a unsigned variable. With the above assumption, driver takes crawl path when not needed. Add explicit check to not crawl in the case of an invalid PLL. v2: Move the check from .h to .c (MattR) - Move check to bxt_set_cdclk() instead of intel_modeset_calc_cdclk() which is directly in the path of the sanitize() function (Ville) v3: remove unwanted parenthesis(Ville) Cc: Ville Syrjälä Cc: Matt Roper Suggested-by: Ville Syrjälä Signed-off-by: Anusha Srivatsa Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/display/intel_cdclk.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index b74e36d76013..25d01271dc09 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1717,6 +1717,16 @@ static void dg2_cdclk_squash_program(struct drm_i915_private *i915, intel_de_write(i915, CDCLK_SQUASH_CTL, squash_ctl); } +static bool cdclk_pll_is_unknown(unsigned int vco) +{ + /* +* Ensure driver does not take the crawl path for the +* case when the vco is set to ~0 in the +* sanitize path. +*/ + return vco == ~0; +} + static void bxt_set_cdclk(struct drm_i915_private *dev_priv, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) @@ -1749,7 +1759,8 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, return; } - if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0) { + if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0 && + !cdclk_pll_is_unknown(dev_priv->display.cdclk.hw.vco)) { if (dev_priv->display.cdclk.hw.vco != vco) adlp_cdclk_pll_crawl(dev_priv, vco); } else if (DISPLAY_VER(dev_priv) >= 11) -- 2.25.1
[Intel-gfx] [PATCH 3/3] drm/i915/display: Add CDCLK Support for MTL
As per bSpec MTL has 38.4 MHz Reference clock. Adding the cdclk tables and cdclk_funcs that MTL will use. v2: Revert to using bxt_get_cdclk() BSpec: 65243 Cc: Clint Taylor Signed-off-by: Anusha Srivatsa Reviewed-by: Clint Taylor --- drivers/gpu/drm/i915/display/intel_cdclk.c | 22 +- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index ddbe94aac293..f540869c5b29 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1346,6 +1346,16 @@ static const struct intel_cdclk_vals dg2_cdclk_table[] = { {} }; +static const struct intel_cdclk_vals mtl_cdclk_table[] = { + { .refclk = 38400, .cdclk = 172800, .divider = 2, .ratio = 16, .waveform = 0xad5a }, + { .refclk = 38400, .cdclk = 192000, .divider = 2, .ratio = 16, .waveform = 0xb6b6 }, + { .refclk = 38400, .cdclk = 307200, .divider = 2, .ratio = 16, .waveform = 0x }, + { .refclk = 38400, .cdclk = 48, .divider = 2, .ratio = 25, .waveform = 0x }, + { .refclk = 38400, .cdclk = 556800, .divider = 2, .ratio = 29, .waveform = 0x }, + { .refclk = 38400, .cdclk = 652800, .divider = 2, .ratio = 34, .waveform = 0x }, + {} +}; + static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk) { const struct intel_cdclk_vals *table = dev_priv->display.cdclk.table; @@ -3186,6 +3196,13 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv) return freq; } +static const struct intel_cdclk_funcs mtl_cdclk_funcs = { + .get_cdclk = bxt_get_cdclk, + .set_cdclk = bxt_set_cdclk, + .modeset_calc_cdclk = bxt_modeset_calc_cdclk, + .calc_voltage_level = tgl_calc_voltage_level, +}; + static const struct intel_cdclk_funcs tgl_cdclk_funcs = { .get_cdclk = bxt_get_cdclk, .set_cdclk = bxt_set_cdclk, @@ -3321,7 +3338,10 @@ static const struct intel_cdclk_funcs i830_cdclk_funcs = { */ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv) { - if (IS_DG2(dev_priv)) { + if (IS_METEORLAKE(dev_priv)) { + dev_priv->display.funcs.cdclk = _cdclk_funcs; + dev_priv->display.cdclk.table = mtl_cdclk_table; + } else if (IS_DG2(dev_priv)) { dev_priv->display.funcs.cdclk = _cdclk_funcs; dev_priv->display.cdclk.table = dg2_cdclk_table; } else if (IS_ALDERLAKE_P(dev_priv)) { -- 2.25.1
[Intel-gfx] [PATCH 2/3] drm/i915/display: Do both crawl and squash when changing cdclk
From: Ville Syrjälä For MTL, changing cdclk from between certain frequencies has both squash and crawl. Use the current cdclk config and the new(desired) cdclk config to construct a mid cdclk config. Set the cdclk twice: - Current cdclk -> mid cdclk - mid cdclk -> desired cdclk Driver should not take some Pcode mailbox communication in the cdclk path for platforms that are Display version 14 and later. v2: Add check in intel_modeset_calc_cdclk() to avoid cdclk change via modeset for platforms that support squash_crawl sequences(Ville) v3: Add checks for: - scenario where only slow clock is used and cdclk is actually 0 (bringing up display). - PLLs are on before looking up the waveform. - Squash and crawl capability checks.(Ville) v4: Rebase - Move checks to be more consistent (Ville) - Add comments (Bala) v5: - Further small changes. Move checks around. - Make if-else better looking (Ville) v6: MTl should not follow PUnit mailbox communication as the rest of gen11+ platforms.(Anusha) Cc: Clint Taylor Cc: Balasubramani Vivekanandan Signed-off-by: Anusha Srivatsa Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/display/intel_cdclk.c | 177 + 1 file changed, 146 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 25d01271dc09..ddbe94aac293 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1727,37 +1727,77 @@ static bool cdclk_pll_is_unknown(unsigned int vco) return vco == ~0; } -static void bxt_set_cdclk(struct drm_i915_private *dev_priv, - const struct intel_cdclk_config *cdclk_config, - enum pipe pipe) +static int cdclk_squash_divider(u16 waveform) +{ + return hweight16(waveform ?: 0x); +} + +static bool cdclk_compute_crawl_and_squash_midpoint(struct drm_i915_private *i915, + const struct intel_cdclk_config *old_cdclk_config, + const struct intel_cdclk_config *new_cdclk_config, + struct intel_cdclk_config *mid_cdclk_config) +{ + u16 old_waveform, new_waveform, mid_waveform; + int size = 16; + int div = 2; + + drm_WARN_ON(>drm, cdclk_pll_is_unknown(old_cdclk_config->vco)); + + /* Return if both Squash and Crawl are not present */ + if (!HAS_CDCLK_CRAWL(i915) || !HAS_CDCLK_SQUASH(i915)) + return false; + + old_waveform = cdclk_squash_waveform(i915, old_cdclk_config->cdclk); + new_waveform = cdclk_squash_waveform(i915, new_cdclk_config->cdclk); + + /* Return if Squash only or Crawl only is the desired action */ + if (old_cdclk_config->vco == 0 || new_cdclk_config->vco == 0 || + old_cdclk_config->vco == new_cdclk_config->vco || + old_waveform == new_waveform) + return false; + + *mid_cdclk_config = *new_cdclk_config; + + /* +* Populate the mid_cdclk_config accordingly. +* - If moving to a higher cdclk, the desired action is squashing. +* The mid cdclk config should have the new (squash) waveform. +* - If moving to a lower cdclk, the desired action is crawling. +* The mid cdclk config should have the new vco. +*/ + + if (cdclk_squash_divider(new_waveform) > cdclk_squash_divider(old_waveform)) { + mid_cdclk_config->vco = old_cdclk_config->vco; + mid_waveform = new_waveform; + } else { + mid_cdclk_config->vco = new_cdclk_config->vco; + mid_waveform = old_waveform; + } + + mid_cdclk_config->cdclk = DIV_ROUND_CLOSEST(cdclk_squash_divider(mid_waveform) * + mid_cdclk_config->vco, size * div); + + /* make sure the mid clock came out sane */ + + drm_WARN_ON(>drm, mid_cdclk_config->cdclk < + min(old_cdclk_config->cdclk, new_cdclk_config->cdclk)); + drm_WARN_ON(>drm, mid_cdclk_config->cdclk > + i915->display.cdclk.max_cdclk_freq); + drm_WARN_ON(>drm, cdclk_squash_waveform(i915, mid_cdclk_config->cdclk) != + mid_waveform); + + return true; +} + +static void _bxt_set_cdclk(struct drm_i915_private *dev_priv, + const struct intel_cdclk_config *cdclk_config, + enum pipe pipe) { int cdclk = cdclk_config->cdclk; int vco = cdclk_config->vco; u32 val; u16 waveform; int clock; - int ret; - - /* Inform power controller of upcoming frequency change. */ - if (DISPLAY_VER(dev_priv) >= 11) - ret = skl_pcode_request(_priv->uncore
[Intel-gfx] [PATCH 2/3] drm/i915/display: Do both crawl and squash when changing cdclk
From: Ville Syrjälä For MTL, changing cdclk from between certain frequencies has both squash and crawl. Use the current cdclk config and the new(desired) cdclk config to construtc a mid cdclk config. Set the cdclk twice: - Current cdclk -> mid cdclk - mid cdclk -> desired cdclk Driver should not take some Pcode mailbox communication in the cdclk path for platforms that are Display 14 and later. v2: Add check in intel_modeset_calc_cdclk() to avoid cdclk change via modeset for platforms that support squash_crawl sequences(Ville) v3: Add checks for: - scenario where only slow clock is used and cdclk is actually 0 (bringing up display). - PLLs are on before looking up the waveform. - Squash and crawl capability checks.(Ville) v4: Rebase - Move checks to be more consistent (Ville) - Add comments (Bala) v5: - Further small changes. Move checks around. - Make if-else better looking (Ville) v6: MTl should not follow PUnit mailbox communication as the rest of gen11+ platforms.(Anusha) Cc: Clint Taylor Cc: Balasubramani Vivekanandan Signed-off-by: Anusha Srivatsa Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/display/intel_cdclk.c | 175 + 1 file changed, 144 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 25d01271dc09..6e122d56428c 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1727,37 +1727,75 @@ static bool cdclk_pll_is_unknown(unsigned int vco) return vco == ~0; } -static void bxt_set_cdclk(struct drm_i915_private *dev_priv, - const struct intel_cdclk_config *cdclk_config, - enum pipe pipe) +static int cdclk_squash_divider(u16 waveform) +{ + return hweight16(waveform ?: 0x); +} + +static bool cdclk_compute_crawl_and_squash_midpoint(struct drm_i915_private *i915, + const struct intel_cdclk_config *old_cdclk_config, + const struct intel_cdclk_config *new_cdclk_config, + struct intel_cdclk_config *mid_cdclk_config) +{ + u16 old_waveform, new_waveform, mid_waveform; + int size = 16; + int div = 2; + + /* Return if both Squash and Crawl are not present */ + if (!HAS_CDCLK_CRAWL(i915) || !HAS_CDCLK_SQUASH(i915)) + return false; + + old_waveform = cdclk_squash_waveform(i915, old_cdclk_config->cdclk); + new_waveform = cdclk_squash_waveform(i915, new_cdclk_config->cdclk); + + /* Return if Squash only or Crawl only is the desired action */ + if (old_cdclk_config->vco <= 0 || new_cdclk_config->vco <= 0 || + old_cdclk_config->vco == new_cdclk_config->vco || + old_waveform == new_waveform) + return false; + + *mid_cdclk_config = *new_cdclk_config; + + /* +* Populate the mid_cdclk_config accordingly. +* - If moving to a higher cdclk, the desired action is squashing. +* The mid cdclk config should have the new (squash) waveform. +* - If moving to a lower cdclk, the desired action is crawling. +* The mid cdclk config should have the new vco. +*/ + + if (cdclk_squash_divider(new_waveform) > cdclk_squash_divider(old_waveform)) { + mid_cdclk_config->vco = old_cdclk_config->vco; + mid_waveform = new_waveform; + } else { + mid_cdclk_config->vco = new_cdclk_config->vco; + mid_waveform = old_waveform; + } + + mid_cdclk_config->cdclk = DIV_ROUND_CLOSEST(cdclk_squash_divider(mid_waveform) * + mid_cdclk_config->vco, size * div); + + /* make sure the mid clock came out sane */ + + drm_WARN_ON(>drm, mid_cdclk_config->cdclk < + min(old_cdclk_config->cdclk, new_cdclk_config->cdclk)); + drm_WARN_ON(>drm, mid_cdclk_config->cdclk > + i915->display.cdclk.max_cdclk_freq); + drm_WARN_ON(>drm, cdclk_squash_waveform(i915, mid_cdclk_config->cdclk) != + mid_waveform); + + return true; +} + +static void _bxt_set_cdclk(struct drm_i915_private *dev_priv, + const struct intel_cdclk_config *cdclk_config, + enum pipe pipe) { int cdclk = cdclk_config->cdclk; int vco = cdclk_config->vco; u32 val; u16 waveform; int clock; - int ret; - - /* Inform power controller of upcoming frequency change. */ - if (DISPLAY_VER(dev_priv) >= 11) - ret = skl_pcode_request(_priv->uncore, SKL_PCODE_CDCLK_CONTROL, -
[Intel-gfx] [PATCH 3/3] drm/i915/display: Add CDCLK Support for MTL
As per bSpec MTL has 38.4 MHz Reference clock. Adding the cdclk tables and cdclk_funcs that MTL will use. v2: Revert to using bxt_get_cdclk() BSpec: 65243 Cc: Clint Taylor Signed-off-by: Anusha Srivatsa Reviewed-by: Clint Taylor --- drivers/gpu/drm/i915/display/intel_cdclk.c | 22 +- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 6e122d56428c..6694e83287d9 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1346,6 +1346,16 @@ static const struct intel_cdclk_vals dg2_cdclk_table[] = { {} }; +static const struct intel_cdclk_vals mtl_cdclk_table[] = { + { .refclk = 38400, .cdclk = 172800, .divider = 2, .ratio = 16, .waveform = 0xad5a }, + { .refclk = 38400, .cdclk = 192000, .divider = 2, .ratio = 16, .waveform = 0xb6b6 }, + { .refclk = 38400, .cdclk = 307200, .divider = 2, .ratio = 16, .waveform = 0x }, + { .refclk = 38400, .cdclk = 48, .divider = 2, .ratio = 25, .waveform = 0x }, + { .refclk = 38400, .cdclk = 556800, .divider = 2, .ratio = 29, .waveform = 0x }, + { .refclk = 38400, .cdclk = 652800, .divider = 2, .ratio = 34, .waveform = 0x }, + {} +}; + static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk) { const struct intel_cdclk_vals *table = dev_priv->display.cdclk.table; @@ -3184,6 +3194,13 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv) return freq; } +static const struct intel_cdclk_funcs mtl_cdclk_funcs = { + .get_cdclk = bxt_get_cdclk, + .set_cdclk = bxt_set_cdclk, + .modeset_calc_cdclk = bxt_modeset_calc_cdclk, + .calc_voltage_level = tgl_calc_voltage_level, +}; + static const struct intel_cdclk_funcs tgl_cdclk_funcs = { .get_cdclk = bxt_get_cdclk, .set_cdclk = bxt_set_cdclk, @@ -3319,7 +3336,10 @@ static const struct intel_cdclk_funcs i830_cdclk_funcs = { */ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv) { - if (IS_DG2(dev_priv)) { + if (IS_METEORLAKE(dev_priv)) { + dev_priv->display.funcs.cdclk = _cdclk_funcs; + dev_priv->display.cdclk.table = mtl_cdclk_table; + } else if (IS_DG2(dev_priv)) { dev_priv->display.funcs.cdclk = _cdclk_funcs; dev_priv->display.cdclk.table = dg2_cdclk_table; } else if (IS_ALDERLAKE_P(dev_priv)) { -- 2.25.1
[Intel-gfx] [PATCH 1/3] drm/i915/display: Add missing checks for cdclk crawling
cdclk_sanitize() function was written assuming vco was a signed integer. vco gets assigned to -1 (essentially ~0) for the case where PLL might be enabled and vco is not a frequency that will ever get used. In such a scenario the right thing to do is disable the PLL and re-enable it again with a valid frequency. However the vco is declared as a unsigned variable. With the above assumption, driver takes crawl path when not needed. Add explicit check to not crawl in the case of an invalid PLL. v2: Move the check from .h to .c (MattR) - Move check to bxt_set_cdclk() instead of intel_modeset_calc_cdclk() which is directly in the path of the sanitize() function (Ville) v3: remove unwanted parenthesis(Ville) Cc: Ville Syrjälä Cc: Matt Roper Suggested-by: Ville Syrjälä Signed-off-by: Anusha Srivatsa Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/display/intel_cdclk.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index b74e36d76013..25d01271dc09 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1717,6 +1717,16 @@ static void dg2_cdclk_squash_program(struct drm_i915_private *i915, intel_de_write(i915, CDCLK_SQUASH_CTL, squash_ctl); } +static bool cdclk_pll_is_unknown(unsigned int vco) +{ + /* +* Ensure driver does not take the crawl path for the +* case when the vco is set to ~0 in the +* sanitize path. +*/ + return vco == ~0; +} + static void bxt_set_cdclk(struct drm_i915_private *dev_priv, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) @@ -1749,7 +1759,8 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, return; } - if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0) { + if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0 && + !cdclk_pll_is_unknown(dev_priv->display.cdclk.hw.vco)) { if (dev_priv->display.cdclk.hw.vco != vco) adlp_cdclk_pll_crawl(dev_priv, vco); } else if (DISPLAY_VER(dev_priv) >= 11) -- 2.25.1
[Intel-gfx] [PATCH 2/3] drm/i915/display: Do both crawl and squash when changing cdclk
From: Ville Syrjälä For MTL, changing cdclk from between certain frequencies has both squash and crawl. Use the current cdclk config and the new(desired) cdclk config to construtc a mid cdclk config. Set the cdclk twice: - Current cdclk -> mid cdclk - mid cdclk -> desired cdclk v2: Add check in intel_modeset_calc_cdclk() to avoid cdclk change via modeset for platforms that support squash_crawl sequences(Ville) v3: Add checks for: - scenario where only slow clock is used and cdclk is actually 0 (bringing up display). - PLLs are on before looking up the waveform. - Squash and crawl capability checks.(Ville) v4: Rebase - Move checks to be more consistent (Ville) - Add comments (Bala) v5: - Further small changes. Move checks around. - Make if-else better looking (Ville) v6: MTl should not follow PUnit mailbox communication as the rest of gen11+ platforms.(Anusha) v7: (MattR) - s/cdclk_crawl_and_squash/cdclk_compute_crawl_squash_midpoint - Cleanup Pcode checks in bxt_set_cdclk() - Correct unsigned/signed checks Cc: Matt Roper Signed-off-by: Anusha Srivatsa Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/display/intel_cdclk.c | 163 - 1 file changed, 124 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 25d01271dc09..4db7103fe5d6 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1727,37 +1727,74 @@ static bool cdclk_pll_is_unknown(unsigned int vco) return vco == ~0; } -static void bxt_set_cdclk(struct drm_i915_private *dev_priv, - const struct intel_cdclk_config *cdclk_config, - enum pipe pipe) +static int cdclk_squash_divider(u16 waveform) +{ + return hweight16(waveform ?: 0x); +} + +static bool cdclk_compute_crawl_and_squash_midpoint(struct drm_i915_private *i915, + const struct intel_cdclk_config *old_cdclk_config, + const struct intel_cdclk_config *new_cdclk_config, + struct intel_cdclk_config *mid_cdclk_config) +{ + u16 old_waveform, new_waveform, mid_waveform; + int size = 16; + int div = 2; + + /* Return if both Squash and Crawl are not present */ + if (!HAS_CDCLK_CRAWL(i915) || !HAS_CDCLK_SQUASH(i915)) + return false; + + old_waveform = cdclk_squash_waveform(i915, old_cdclk_config->cdclk); + new_waveform = cdclk_squash_waveform(i915, new_cdclk_config->cdclk); + + /* Return if Squash only or Crawl only is the desired action */ + if (old_cdclk_config->vco == 0 || new_cdclk_config->vco == 0 || + old_cdclk_config->vco == new_cdclk_config->vco || + old_waveform == new_waveform) + return false; + + *mid_cdclk_config = *new_cdclk_config; + + /* Populate the mid_cdclk_config accordingly. +* - If moving to a higher cdclk, the desired action is squashing. +* The mid cdclk config should have the new (squash) waveform. +* - If moving to a lower cdclk, the desired action is crawling. +* The mid cdclk config should have the new vco. +*/ + + if (cdclk_squash_divider(new_waveform) > cdclk_squash_divider(old_waveform)) { + mid_cdclk_config->vco = old_cdclk_config->vco; + mid_waveform = new_waveform; + } else { + mid_cdclk_config->vco = new_cdclk_config->vco; + mid_waveform = old_waveform; + } + + mid_cdclk_config->cdclk = DIV_ROUND_CLOSEST(cdclk_squash_divider(mid_waveform) * + mid_cdclk_config->vco, size * div); + + /* make sure the mid clock came out sane */ + + drm_WARN_ON(>drm, mid_cdclk_config->cdclk < + min(old_cdclk_config->cdclk, new_cdclk_config->cdclk)); + drm_WARN_ON(>drm, mid_cdclk_config->cdclk > + i915->display.cdclk.max_cdclk_freq); + drm_WARN_ON(>drm, cdclk_squash_waveform(i915, mid_cdclk_config->cdclk) != + mid_waveform); + + return true; +} + +static void _bxt_set_cdclk(struct drm_i915_private *dev_priv, + const struct intel_cdclk_config *cdclk_config, + enum pipe pipe) { int cdclk = cdclk_config->cdclk; int vco = cdclk_config->vco; u32 val; u16 waveform; int clock; - int ret; - - /* Inform power controller of upcoming frequency change. */ - if (DISPLAY_VER(dev_priv) >= 11) - ret = skl_pcode_request(_priv->uncore, SKL_PCODE_CDCLK_CONTROL, - SKL_CD
[Intel-gfx] [PATCH 3/3] drm/i915/display: Add CDCLK Support for MTL
As per bSpec MTL has 38.4 MHz Reference clock. Adding the cdclk tables and cdclk_funcs that MTL will use. v2: Revert to using bxt_get_cdclk() BSpec: 65243 Cc: Clint Taylor Signed-off-by: Anusha Srivatsa Reviewed-by: Clint Taylor --- drivers/gpu/drm/i915/display/intel_cdclk.c | 22 +- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 4db7103fe5d6..a672ce927f04 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1346,6 +1346,16 @@ static const struct intel_cdclk_vals dg2_cdclk_table[] = { {} }; +static const struct intel_cdclk_vals mtl_cdclk_table[] = { + { .refclk = 38400, .cdclk = 172800, .divider = 2, .ratio = 16, .waveform = 0xad5a }, + { .refclk = 38400, .cdclk = 192000, .divider = 2, .ratio = 16, .waveform = 0xb6b6 }, + { .refclk = 38400, .cdclk = 307200, .divider = 2, .ratio = 16, .waveform = 0x }, + { .refclk = 38400, .cdclk = 48, .divider = 2, .ratio = 25, .waveform = 0x }, + { .refclk = 38400, .cdclk = 556800, .divider = 2, .ratio = 29, .waveform = 0x }, + { .refclk = 38400, .cdclk = 652800, .divider = 2, .ratio = 34, .waveform = 0x }, + {} +}; + static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk) { const struct intel_cdclk_vals *table = dev_priv->display.cdclk.table; @@ -3156,6 +3166,13 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv) return freq; } +static const struct intel_cdclk_funcs mtl_cdclk_funcs = { + .get_cdclk = bxt_get_cdclk, + .set_cdclk = bxt_set_cdclk, + .modeset_calc_cdclk = bxt_modeset_calc_cdclk, + .calc_voltage_level = tgl_calc_voltage_level, +}; + static const struct intel_cdclk_funcs tgl_cdclk_funcs = { .get_cdclk = bxt_get_cdclk, .set_cdclk = bxt_set_cdclk, @@ -3291,7 +3308,10 @@ static const struct intel_cdclk_funcs i830_cdclk_funcs = { */ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv) { - if (IS_DG2(dev_priv)) { + if (IS_METEORLAKE(dev_priv)) { + dev_priv->display.funcs.cdclk = _cdclk_funcs; + dev_priv->display.cdclk.table = mtl_cdclk_table; + } else if (IS_DG2(dev_priv)) { dev_priv->display.funcs.cdclk = _cdclk_funcs; dev_priv->display.cdclk.table = dg2_cdclk_table; } else if (IS_ALDERLAKE_P(dev_priv)) { -- 2.25.1
[Intel-gfx] [PATCH 1/3] drm/i915/display: Add missing checks for cdclk crawling
cdclk_sanitize() function was written assuming vco was a signed integer. vco gets assigned to -1 (essentially ~0) for the case where PLL might be enabled and vco is not a frequency that will ever get used. In such a scenario the right thing to do is disable the PLL and re-enable it again with a valid frequency. However the vco is declared as a unsigned variable. With the above assumption, driver takes crawl path when not needed. Add explicit check to not crawl in the case of an invalid PLL. v2: Move the check from .h to .c (MattR) - Move check to bxt_set_cdclk() instead of intel_modeset_calc_cdclk() which is directly in the path of the sanitize() function (Ville) v3: remove unwanted parenthesis(Ville) Cc: Ville Syrjälä Cc: Matt Roper Suggested-by: Ville Syrjälä Signed-off-by: Anusha Srivatsa Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/display/intel_cdclk.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index b74e36d76013..25d01271dc09 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1717,6 +1717,16 @@ static void dg2_cdclk_squash_program(struct drm_i915_private *i915, intel_de_write(i915, CDCLK_SQUASH_CTL, squash_ctl); } +static bool cdclk_pll_is_unknown(unsigned int vco) +{ + /* +* Ensure driver does not take the crawl path for the +* case when the vco is set to ~0 in the +* sanitize path. +*/ + return vco == ~0; +} + static void bxt_set_cdclk(struct drm_i915_private *dev_priv, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) @@ -1749,7 +1759,8 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, return; } - if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0) { + if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0 && + !cdclk_pll_is_unknown(dev_priv->display.cdclk.hw.vco)) { if (dev_priv->display.cdclk.hw.vco != vco) adlp_cdclk_pll_crawl(dev_priv, vco); } else if (DISPLAY_VER(dev_priv) >= 11) -- 2.25.1
[Intel-gfx] [PATCH] drm/i915/display: Add missing checks for cdclk crawling
cdclk_sanitize() function was written assuming vco was a signed integer. vco gets assigned to -1 (essentially ~0) for the case where PLL might be enabled and vco is not a frequency that will ever get used. In such a scenario the right thing to do is disable the PLL and re-enable it again with a valid frequency. However the vco is declared as a unsigned variable. With the above assumption, driver takes crawl path when not needed. Add explicit check to not crawl in the case of an invalid PLL. v2: Move the check from .h to .c (MattR) - Move check to bxt_set_cdclk() instead of intel_modeset_calc_cdclk() which is directly in the path of the sanitize() function (Ville) Cc: Ville Syrjälä Cc: Matt Roper Suggested-by: Ville Syrjälä Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 8a9031012d74..2d9b7ba58358 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1716,6 +1716,16 @@ static void dg2_cdclk_squash_program(struct drm_i915_private *i915, intel_de_write(i915, CDCLK_SQUASH_CTL, squash_ctl); } +static bool cdclk_pll_is_unknown(unsigned int vco) +{ + /* +* Ensure driver does not take the crawl path for the +* case when the vco is set to ~0 in the +* sanitize path. +*/ + return (vco == ~0); +} + static void bxt_set_cdclk(struct drm_i915_private *dev_priv, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) @@ -1748,7 +1758,8 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, return; } - if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0) { + if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0 && + (!cdclk_pll_is_unknown(dev_priv->display.cdclk.hw.vco))) { if (dev_priv->display.cdclk.hw.vco != vco) adlp_cdclk_pll_crawl(dev_priv, vco); } else if (DISPLAY_VER(dev_priv) >= 11) -- 2.25.1
[Intel-gfx] [PATCH] drm/i915/display: Add missing checks for cdclk crawling
cdclk_sanitize() function was written assuming vco was a signed integer. vco gets assigned to -1 (essentially ~0) for the case where PLL might be enabled and vco is not a frequency that will ever get used. In such a scenario the right thing to do is disable the PLL and re-enable it again with a valid frequency. However the vco is declared as a unsigned variable. With the above assumption, driver takes crawl path when not needed. Add explicit check to not crawl in the case of an invalid PLL. Cc: Matt Roper Suggested-by: Ville Syrjälä Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 2 ++ drivers/gpu/drm/i915/display/intel_cdclk.h | 1 + 2 files changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 8a9031012d74..91112d266763 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1962,6 +1962,8 @@ static bool intel_cdclk_can_crawl(struct drm_i915_private *dev_priv, if (!HAS_CDCLK_CRAWL(dev_priv)) return false; + if (intel_pll_is_unknown(a->vco)) + return false; /* * The vco and cd2x divider will change independently * from each, so we disallow cd2x change when crawling. diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.h b/drivers/gpu/drm/i915/display/intel_cdclk.h index c674879a84a5..6eb83d806f11 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.h +++ b/drivers/gpu/drm/i915/display/intel_cdclk.h @@ -80,6 +80,7 @@ intel_atomic_get_cdclk_state(struct intel_atomic_state *state); to_intel_cdclk_state(intel_atomic_get_old_global_obj_state(state, _i915(state->base.dev)->display.cdclk.obj)) #define intel_atomic_get_new_cdclk_state(state) \ to_intel_cdclk_state(intel_atomic_get_new_global_obj_state(state, _i915(state->base.dev)->display.cdclk.obj)) +#define intel_pll_is_unknown(vco) ((vco) == ~0) int intel_cdclk_init(struct drm_i915_private *dev_priv); -- 2.25.1
[Intel-gfx] [PATCH 2/2] drm/i915/display: Add CDCLK Support for MTL
As per bSpec MTL has 38.4 MHz Reference clock. Adding the cdclk tables and cdclk_funcs that MTL will use. v2: Revert to using bxt_get_cdclk() BSpec: 65243 Cc: Clint Taylor Signed-off-by: Anusha Srivatsa Reviewed-by: Clint Taylor --- drivers/gpu/drm/i915/display/intel_cdclk.c | 22 +- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index d1e0763513be..e7374fd92da9 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1345,6 +1345,16 @@ static const struct intel_cdclk_vals dg2_cdclk_table[] = { {} }; +static const struct intel_cdclk_vals mtl_cdclk_table[] = { + { .refclk = 38400, .cdclk = 172800, .divider = 2, .ratio = 16, .waveform = 0xad5a }, + { .refclk = 38400, .cdclk = 192000, .divider = 2, .ratio = 16, .waveform = 0xb6b6 }, + { .refclk = 38400, .cdclk = 307200, .divider = 2, .ratio = 16, .waveform = 0x }, + { .refclk = 38400, .cdclk = 48, .divider = 2, .ratio = 25, .waveform = 0x }, + { .refclk = 38400, .cdclk = 556800, .divider = 2, .ratio = 29, .waveform = 0x }, + { .refclk = 38400, .cdclk = 652800, .divider = 2, .ratio = 34, .waveform = 0x }, + {} +}; + static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk) { const struct intel_cdclk_vals *table = dev_priv->display.cdclk.table; @@ -3164,6 +3174,13 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv) return freq; } +static const struct intel_cdclk_funcs mtl_cdclk_funcs = { + .get_cdclk = bxt_get_cdclk, + .set_cdclk = bxt_set_cdclk, + .modeset_calc_cdclk = bxt_modeset_calc_cdclk, + .calc_voltage_level = tgl_calc_voltage_level, +}; + static const struct intel_cdclk_funcs tgl_cdclk_funcs = { .get_cdclk = bxt_get_cdclk, .set_cdclk = bxt_set_cdclk, @@ -3299,7 +3316,10 @@ static const struct intel_cdclk_funcs i830_cdclk_funcs = { */ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv) { - if (IS_DG2(dev_priv)) { + if (IS_METEORLAKE(dev_priv)) { + dev_priv->display.funcs.cdclk = _cdclk_funcs; + dev_priv->display.cdclk.table = mtl_cdclk_table; + } else if (IS_DG2(dev_priv)) { dev_priv->display.funcs.cdclk = _cdclk_funcs; dev_priv->display.cdclk.table = dg2_cdclk_table; } else if (IS_ALDERLAKE_P(dev_priv)) { -- 2.25.1
[Intel-gfx] [PATCH 1/2] drm/i915/display: Do both crawl and squash when changing cdclk
From: Ville Syrjälä For MTL, changing cdclk from between certain frequencies has both squash and crawl. Use the current cdclk config and the new(desired) cdclk config to construtc a mid cdclk config. Set the cdclk twice: - Current cdclk -> mid cdclk - mid cdclk -> desired cdclk v2: Add check in intel_modeset_calc_cdclk() to avoid cdclk change via modeset for platforms that support squash_crawl sequences(Ville) v3: Add checks for: - scenario where only slow clock is used and cdclk is actually 0 (bringing up display). - PLLs are on before looking up the waveform. - Squash and crawl capability checks.(Ville) v4: Rebase - Move checks to be more consistent (Ville) - Add comments (Bala) v5: - Further small changes. Move checks around. - Make if-else better looking (Ville) v6: MTl should not follow PUnit mailbox communication as the rest of gen11+ platforms.(Anusha) Cc: Clint Taylor Cc: Balasubramani Vivekanandan Signed-off-by: Anusha Srivatsa Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/display/intel_cdclk.c | 161 + 1 file changed, 133 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index eada931cb1c8..d1e0763513be 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1716,37 +1716,74 @@ static void dg2_cdclk_squash_program(struct drm_i915_private *i915, intel_de_write(i915, CDCLK_SQUASH_CTL, squash_ctl); } -static void bxt_set_cdclk(struct drm_i915_private *dev_priv, - const struct intel_cdclk_config *cdclk_config, - enum pipe pipe) +static int cdclk_squash_divider(u16 waveform) +{ + return hweight16(waveform ?: 0x); +} + +static bool cdclk_crawl_and_squash(struct drm_i915_private *i915, + const struct intel_cdclk_config *old_cdclk_config, + const struct intel_cdclk_config *new_cdclk_config, + struct intel_cdclk_config *mid_cdclk_config) +{ + u16 old_waveform, new_waveform, mid_waveform; + int size = 16; + int div = 2; + + /* Return if both Squash and Crawl are not present */ + if (!HAS_CDCLK_CRAWL(i915) || !HAS_CDCLK_SQUASH(i915)) + return false; + + old_waveform = cdclk_squash_waveform(i915, old_cdclk_config->cdclk); + new_waveform = cdclk_squash_waveform(i915, new_cdclk_config->cdclk); + + /* Return if Squash only or Crawl only is the desired action */ + if (old_cdclk_config->vco <= 0 || new_cdclk_config->vco <= 0 || + old_cdclk_config->vco == new_cdclk_config->vco || + old_waveform == new_waveform) + return false; + + *mid_cdclk_config = *new_cdclk_config; + + /* Populate the mid_cdclk_config accordingly. +* - If moving to a higher cdclk, the desired action is squashing. +* The mid cdclk config should have the new (squash) waveform. +* - If moving to a lower cdclk, the desired action is crawling. +* The mid cdclk config should have the new vco. +*/ + + if (cdclk_squash_divider(new_waveform) > cdclk_squash_divider(old_waveform)) { + mid_cdclk_config->vco = old_cdclk_config->vco; + mid_waveform = new_waveform; + } else { + mid_cdclk_config->vco = new_cdclk_config->vco; + mid_waveform = old_waveform; + } + + mid_cdclk_config->cdclk = DIV_ROUND_CLOSEST(cdclk_squash_divider(mid_waveform) * + mid_cdclk_config->vco, size * div); + + /* make sure the mid clock came out sane */ + + drm_WARN_ON(>drm, mid_cdclk_config->cdclk < + min(old_cdclk_config->cdclk, new_cdclk_config->cdclk)); + drm_WARN_ON(>drm, mid_cdclk_config->cdclk > + i915->display.cdclk.max_cdclk_freq); + drm_WARN_ON(>drm, cdclk_squash_waveform(i915, mid_cdclk_config->cdclk) != + mid_waveform); + + return true; +} + +static void _bxt_set_cdclk(struct drm_i915_private *dev_priv, + const struct intel_cdclk_config *cdclk_config, + enum pipe pipe) { int cdclk = cdclk_config->cdclk; int vco = cdclk_config->vco; u32 val; u16 waveform; int clock; - int ret; - - /* Inform power controller of upcoming frequency change. */ - if (DISPLAY_VER(dev_priv) >= 11) - ret = skl_pcode_request(_priv->uncore, SKL_PCODE_CDCLK_CONTROL, - SKL_CDCLK_PREPARE_FOR_CHANGE, - SKL_CDCLK_READY_FOR_CHANGE, - SKL_CDCLK_READY_FOR_CHANGE
[Intel-gfx] [PATCH 2/2] drm/i915/display: Add CDCLK Support for MTL
As per bSpec MTL has 38.4 MHz Reference clock. Adding the cdclk tables and cdclk_funcs that MTL will use. v2: Revert to using bxt_get_cdclk() BSpec: 65243 Cc: Clint Taylor Signed-off-by: Anusha Srivatsa Reviewed-by: Clint Taylor --- drivers/gpu/drm/i915/display/intel_cdclk.c | 22 +- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index d79cf282faa8..54ac7f9a1253 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1345,6 +1345,16 @@ static const struct intel_cdclk_vals dg2_cdclk_table[] = { {} }; +static const struct intel_cdclk_vals mtl_cdclk_table[] = { + { .refclk = 38400, .cdclk = 172800, .divider = 2, .ratio = 16, .waveform = 0xad5a }, + { .refclk = 38400, .cdclk = 192000, .divider = 2, .ratio = 16, .waveform = 0xb6b6 }, + { .refclk = 38400, .cdclk = 307200, .divider = 2, .ratio = 16, .waveform = 0x }, + { .refclk = 38400, .cdclk = 48, .divider = 2, .ratio = 25, .waveform = 0x }, + { .refclk = 38400, .cdclk = 556800, .divider = 2, .ratio = 29, .waveform = 0x }, + { .refclk = 38400, .cdclk = 652800, .divider = 2, .ratio = 34, .waveform = 0x }, + {} +}; + static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk) { const struct intel_cdclk_vals *table = dev_priv->display.cdclk.table; @@ -3159,6 +3169,13 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv) return freq; } +static const struct intel_cdclk_funcs mtl_cdclk_funcs = { + .get_cdclk = bxt_get_cdclk, + .set_cdclk = bxt_set_cdclk, + .modeset_calc_cdclk = bxt_modeset_calc_cdclk, + .calc_voltage_level = tgl_calc_voltage_level, +}; + static const struct intel_cdclk_funcs tgl_cdclk_funcs = { .get_cdclk = bxt_get_cdclk, .set_cdclk = bxt_set_cdclk, @@ -3294,7 +3311,10 @@ static const struct intel_cdclk_funcs i830_cdclk_funcs = { */ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv) { - if (IS_DG2(dev_priv)) { + if (IS_METEORLAKE(dev_priv)) { + dev_priv->display.funcs.cdclk = _cdclk_funcs; + dev_priv->display.cdclk.table = mtl_cdclk_table; + } else if (IS_DG2(dev_priv)) { dev_priv->display.funcs.cdclk = _cdclk_funcs; dev_priv->display.cdclk.table = dg2_cdclk_table; } else if (IS_ALDERLAKE_P(dev_priv)) { -- 2.25.1
[Intel-gfx] [PATCH 1/2] drm/i915/display: Do both crawl and squash when changing cdclk
From: Ville Syrjälä For MTL, changing cdclk from between certain frequencies has both squash and crawl. Use the current cdclk config and the new(desired) cdclk config to construtc a mid cdclk config. Set the cdclk twice: - Current cdclk -> mid cdclk - mid cdclk -> desired cdclk v2: Add check in intel_modeset_calc_cdclk() to avoid cdclk change via modeset for platforms that support squash_crawl sequences(Ville) v3: Add checks for: - scenario where only slow clock is used and cdclk is actually 0 (bringing up display). - PLLs are on before looking up the waveform. - Squash and crawl capability checks.(Ville) v4: Rebase - Move checks to be more consistent (Ville) - Add comments (Bala) v5: - Further small changes. Move checks around. - Make if-else better looking (Ville) Cc: Balasubramani Vivekanandan Signed-off-by: Anusha Srivatsa Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/display/intel_cdclk.c | 156 + 1 file changed, 128 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index eada931cb1c8..d79cf282faa8 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1716,37 +1716,74 @@ static void dg2_cdclk_squash_program(struct drm_i915_private *i915, intel_de_write(i915, CDCLK_SQUASH_CTL, squash_ctl); } -static void bxt_set_cdclk(struct drm_i915_private *dev_priv, - const struct intel_cdclk_config *cdclk_config, - enum pipe pipe) +static int cdclk_squash_divider(u16 waveform) +{ + return hweight16(waveform ?: 0x); +} + +static bool cdclk_crawl_and_squash(struct drm_i915_private *i915, + const struct intel_cdclk_config *old_cdclk_config, + const struct intel_cdclk_config *new_cdclk_config, + struct intel_cdclk_config *mid_cdclk_config) +{ + u16 old_waveform, new_waveform, mid_waveform; + int size = 16; + int div = 2; + + /* Return if both Squash and Crawl are not present */ + if (!HAS_CDCLK_CRAWL(i915) || !HAS_CDCLK_SQUASH(i915)) + return false; + + old_waveform = cdclk_squash_waveform(i915, old_cdclk_config->cdclk); + new_waveform = cdclk_squash_waveform(i915, new_cdclk_config->cdclk); + + /* Return if Squash only or Crawl only is the desired action */ + if (old_cdclk_config->vco <= 0 || new_cdclk_config->vco <= 0 || + old_cdclk_config->vco == new_cdclk_config->vco || + old_waveform == new_waveform) + return false; + + *mid_cdclk_config = *new_cdclk_config; + + /* Populate the mid_cdclk_config accordingly. +* - If moving to a higher cdclk, the desired action is squashing. +* The mid cdclk config should have the new (squash) waveform. +* - If moving to a lower cdclk, the desired action is crawling. +* The mid cdclk config should have the new vco. +*/ + + if (cdclk_squash_divider(new_waveform) > cdclk_squash_divider(old_waveform)) { + mid_cdclk_config->vco = old_cdclk_config->vco; + mid_waveform = new_waveform; + } else { + mid_cdclk_config->vco = new_cdclk_config->vco; + mid_waveform = old_waveform; + } + + mid_cdclk_config->cdclk = DIV_ROUND_CLOSEST(cdclk_squash_divider(mid_waveform) * + mid_cdclk_config->vco, size * div); + + /* make sure the mid clock came out sane */ + + drm_WARN_ON(>drm, mid_cdclk_config->cdclk < + min(old_cdclk_config->cdclk, new_cdclk_config->cdclk)); + drm_WARN_ON(>drm, mid_cdclk_config->cdclk > + i915->display.cdclk.max_cdclk_freq); + drm_WARN_ON(>drm, cdclk_squash_waveform(i915, mid_cdclk_config->cdclk) != + mid_waveform); + + return true; +} + +static void _bxt_set_cdclk(struct drm_i915_private *dev_priv, + const struct intel_cdclk_config *cdclk_config, + enum pipe pipe) { int cdclk = cdclk_config->cdclk; int vco = cdclk_config->vco; u32 val; u16 waveform; int clock; - int ret; - - /* Inform power controller of upcoming frequency change. */ - if (DISPLAY_VER(dev_priv) >= 11) - ret = skl_pcode_request(_priv->uncore, SKL_PCODE_CDCLK_CONTROL, - SKL_CDCLK_PREPARE_FOR_CHANGE, - SKL_CDCLK_READY_FOR_CHANGE, - SKL_CDCLK_READY_FOR_CHANGE, 3); - else - /* -* BSpec requires us to wait up to
[Intel-gfx] [PATCH 2/2] drm/i915/display: Add CDCLK Support for MTL
As per bSpec MTL has 38.4 MHz Reference clock. Addin gthe cdclk tables and cdclk_funcs that MTL will use. v2: Revert to using bxt_get_cdclk() BSpec: 65243 Cc: Clint Taylor Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 22 +- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index d79cf282faa8..54ac7f9a1253 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1345,6 +1345,16 @@ static const struct intel_cdclk_vals dg2_cdclk_table[] = { {} }; +static const struct intel_cdclk_vals mtl_cdclk_table[] = { + { .refclk = 38400, .cdclk = 172800, .divider = 2, .ratio = 16, .waveform = 0xad5a }, + { .refclk = 38400, .cdclk = 192000, .divider = 2, .ratio = 16, .waveform = 0xb6b6 }, + { .refclk = 38400, .cdclk = 307200, .divider = 2, .ratio = 16, .waveform = 0x }, + { .refclk = 38400, .cdclk = 48, .divider = 2, .ratio = 25, .waveform = 0x }, + { .refclk = 38400, .cdclk = 556800, .divider = 2, .ratio = 29, .waveform = 0x }, + { .refclk = 38400, .cdclk = 652800, .divider = 2, .ratio = 34, .waveform = 0x }, + {} +}; + static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk) { const struct intel_cdclk_vals *table = dev_priv->display.cdclk.table; @@ -3159,6 +3169,13 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv) return freq; } +static const struct intel_cdclk_funcs mtl_cdclk_funcs = { + .get_cdclk = bxt_get_cdclk, + .set_cdclk = bxt_set_cdclk, + .modeset_calc_cdclk = bxt_modeset_calc_cdclk, + .calc_voltage_level = tgl_calc_voltage_level, +}; + static const struct intel_cdclk_funcs tgl_cdclk_funcs = { .get_cdclk = bxt_get_cdclk, .set_cdclk = bxt_set_cdclk, @@ -3294,7 +3311,10 @@ static const struct intel_cdclk_funcs i830_cdclk_funcs = { */ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv) { - if (IS_DG2(dev_priv)) { + if (IS_METEORLAKE(dev_priv)) { + dev_priv->display.funcs.cdclk = _cdclk_funcs; + dev_priv->display.cdclk.table = mtl_cdclk_table; + } else if (IS_DG2(dev_priv)) { dev_priv->display.funcs.cdclk = _cdclk_funcs; dev_priv->display.cdclk.table = dg2_cdclk_table; } else if (IS_ALDERLAKE_P(dev_priv)) { -- 2.25.1
[Intel-gfx] [PATCH 1/2] drm/i915/display: Do both crawl and squash when changing cdclk
From: Ville Syrjälä For MTL, changing cdclk from between certain frequencies has both squash and crawl. Use the current cdclk config and the new(desired) cdclk config to construtc a mid cdclk config. Set the cdclk twice: - Current cdclk -> mid cdclk - mid cdclk -> desired cdclk v2: Add check in intel_modeset_calc_cdclk() to avoid cdclk change via modeset for platforms that support squash_crawl sequences(Ville) v3: Add checks for: - scenario where only slow clock is used and cdclk is actually 0 (bringing up display). - PLLs are on before looking up the waveform. - Squash and crawl capability checks.(Ville) v4: Rebase - Move checks to be more consistent (Ville) - Add comments (Bala) v5: - Further small changes. Move checks around. - Make if-else better looking (Ville) Cc: Balasubramani Vivekanandan Signed-off-by: Anusha Srivatsa Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/display/intel_cdclk.c | 156 + 1 file changed, 128 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index eada931cb1c8..d79cf282faa8 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1716,37 +1716,74 @@ static void dg2_cdclk_squash_program(struct drm_i915_private *i915, intel_de_write(i915, CDCLK_SQUASH_CTL, squash_ctl); } -static void bxt_set_cdclk(struct drm_i915_private *dev_priv, - const struct intel_cdclk_config *cdclk_config, - enum pipe pipe) +static int cdclk_squash_divider(u16 waveform) +{ + return hweight16(waveform ?: 0x); +} + +static bool cdclk_crawl_and_squash(struct drm_i915_private *i915, + const struct intel_cdclk_config *old_cdclk_config, + const struct intel_cdclk_config *new_cdclk_config, + struct intel_cdclk_config *mid_cdclk_config) +{ + u16 old_waveform, new_waveform, mid_waveform; + int size = 16; + int div = 2; + + /* Return if both Squash and Crawl are not present */ + if (!HAS_CDCLK_CRAWL(i915) || !HAS_CDCLK_SQUASH(i915)) + return false; + + old_waveform = cdclk_squash_waveform(i915, old_cdclk_config->cdclk); + new_waveform = cdclk_squash_waveform(i915, new_cdclk_config->cdclk); + + /* Return if Squash only or Crawl only is the desired action */ + if (old_cdclk_config->vco <= 0 || new_cdclk_config->vco <= 0 || + old_cdclk_config->vco == new_cdclk_config->vco || + old_waveform == new_waveform) + return false; + + *mid_cdclk_config = *new_cdclk_config; + + /* Populate the mid_cdclk_config accordingly. +* - If moving to a higher cdclk, the desired action is squashing. +* The mid cdclk config should have the new (squash) waveform. +* - If moving to a lower cdclk, the desired action is crawling. +* The mid cdclk config should have the new vco. +*/ + + if (cdclk_squash_divider(new_waveform) > cdclk_squash_divider(old_waveform)) { + mid_cdclk_config->vco = old_cdclk_config->vco; + mid_waveform = new_waveform; + } else { + mid_cdclk_config->vco = new_cdclk_config->vco; + mid_waveform = old_waveform; + } + + mid_cdclk_config->cdclk = DIV_ROUND_CLOSEST(cdclk_squash_divider(mid_waveform) * + mid_cdclk_config->vco, size * div); + + /* make sure the mid clock came out sane */ + + drm_WARN_ON(>drm, mid_cdclk_config->cdclk < + min(old_cdclk_config->cdclk, new_cdclk_config->cdclk)); + drm_WARN_ON(>drm, mid_cdclk_config->cdclk > + i915->display.cdclk.max_cdclk_freq); + drm_WARN_ON(>drm, cdclk_squash_waveform(i915, mid_cdclk_config->cdclk) != + mid_waveform); + + return true; +} + +static void _bxt_set_cdclk(struct drm_i915_private *dev_priv, + const struct intel_cdclk_config *cdclk_config, + enum pipe pipe) { int cdclk = cdclk_config->cdclk; int vco = cdclk_config->vco; u32 val; u16 waveform; int clock; - int ret; - - /* Inform power controller of upcoming frequency change. */ - if (DISPLAY_VER(dev_priv) >= 11) - ret = skl_pcode_request(_priv->uncore, SKL_PCODE_CDCLK_CONTROL, - SKL_CDCLK_PREPARE_FOR_CHANGE, - SKL_CDCLK_READY_FOR_CHANGE, - SKL_CDCLK_READY_FOR_CHANGE, 3); - else - /* -* BSpec requires us to wait up to
[Intel-gfx] [PATCH 2/2] drm/i915/display: Add CDCLK Support for MTL
As per bSpec MTL has 38.4 MHz Reference clock. MTL does support squasher like DG2 but only for lower frequencies. Change the has_cdclk_squasher() helper to reflect this. v2: Revert to using bxt_get_cdclk() BSpec: 65243 Cc: Clint Taylor Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 22 +- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 6a775367f02a..28253cb310ca 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1345,6 +1345,16 @@ static const struct intel_cdclk_vals dg2_cdclk_table[] = { {} }; +static const struct intel_cdclk_vals mtl_cdclk_table[] = { + { .refclk = 38400, .cdclk = 172800, .divider = 2, .ratio = 16, .waveform = 0xad5a }, + { .refclk = 38400, .cdclk = 192000, .divider = 2, .ratio = 16, .waveform = 0xb6b6 }, + { .refclk = 38400, .cdclk = 307200, .divider = 2, .ratio = 16, .waveform = 0x }, + { .refclk = 38400, .cdclk = 48, .divider = 2, .ratio = 25, .waveform = 0x }, + { .refclk = 38400, .cdclk = 556800, .divider = 2, .ratio = 29, .waveform = 0x }, + { .refclk = 38400, .cdclk = 652800, .divider = 2, .ratio = 34, .waveform = 0x }, + {} +}; + static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk) { const struct intel_cdclk_vals *table = dev_priv->display.cdclk.table; @@ -3160,6 +3170,13 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv) return freq; } +static const struct intel_cdclk_funcs mtl_cdclk_funcs = { + .get_cdclk = bxt_get_cdclk, + .set_cdclk = bxt_set_cdclk, + .modeset_calc_cdclk = bxt_modeset_calc_cdclk, + .calc_voltage_level = tgl_calc_voltage_level, +}; + static const struct intel_cdclk_funcs tgl_cdclk_funcs = { .get_cdclk = bxt_get_cdclk, .set_cdclk = bxt_set_cdclk, @@ -3295,7 +3312,10 @@ static const struct intel_cdclk_funcs i830_cdclk_funcs = { */ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv) { - if (IS_DG2(dev_priv)) { + if (IS_METEORLAKE(dev_priv)) { + dev_priv->display.funcs.cdclk = _cdclk_funcs; + dev_priv->display.cdclk.table = mtl_cdclk_table; + } else if (IS_DG2(dev_priv)) { dev_priv->display.funcs.cdclk = _cdclk_funcs; dev_priv->display.cdclk.table = dg2_cdclk_table; } else if (IS_ALDERLAKE_P(dev_priv)) { -- 2.25.1
[Intel-gfx] [PATCH 1/2] drm/i915/display: Do both crawl and squash when changing cdclk
From: Ville Syrjälä For MTL, changing cdclk from between certain frequencies has both squash and crawl. Use the current cdclk config and the new(desired) cdclk config to construtc a mid cdclk config. Set the cdclk twice: - Current cdclk -> mid cdclk - mid cdclk -> desired cdclk v2: Add check in intel_modeset_calc_cdclk() to avoid cdclk change via modeset for platforms that support squash_crawl sequences(Ville) v3: Add checks for: - scenario where only slow clock is used and cdclk is actually 0 (bringing up display). - PLLs are on before looking up the waveform. - Squash and crawl capability checks.(Ville) v4: Rebase - Move checks to be more consistent (Ville) - Add comments (Bala) Cc: Balasubramani Vivekanandan Signed-off-by: Anusha Srivatsa Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/display/intel_cdclk.c | 157 + 1 file changed, 129 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index eada931cb1c8..6a775367f02a 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1716,37 +1716,74 @@ static void dg2_cdclk_squash_program(struct drm_i915_private *i915, intel_de_write(i915, CDCLK_SQUASH_CTL, squash_ctl); } -static void bxt_set_cdclk(struct drm_i915_private *dev_priv, - const struct intel_cdclk_config *cdclk_config, - enum pipe pipe) +static int cdclk_squash_divider(u16 waveform) +{ + return hweight16(waveform ?: 0x); +} + +static bool cdclk_crawl_and_squash(struct drm_i915_private *i915, + const struct intel_cdclk_config *old_cdclk_config, + const struct intel_cdclk_config *new_cdclk_config, + struct intel_cdclk_config *mid_cdclk_config) +{ + u16 old_waveform, new_waveform, mid_waveform; + int size = 16; + int div = 2; + + /* Return if both Squash and Crawl are not present */ + if (!HAS_CDCLK_CRAWL(i915) || !HAS_CDCLK_SQUASH(i915)) + return false; + + /* Return if Squash only or Crawl only is the desired action */ + if (old_cdclk_config->vco <= 0 || new_cdclk_config->vco <= 0 || + old_cdclk_config->vco == new_cdclk_config->vco || + old_waveform == new_waveform) + return false; + + old_waveform = cdclk_squash_waveform(i915, old_cdclk_config->cdclk); + new_waveform = cdclk_squash_waveform(i915, new_cdclk_config->cdclk); + + *mid_cdclk_config = *new_cdclk_config; + + /* Populate the mid_cdclk_config accordingly. +* - If moving to a higher cdclk, the desired action is squashing. +* The mid cdclk config should have the new (squash) waveform. +* - If moving to a lower cdclk, the desired action is crawling. +* The mid cdclk config should have the new vco. +*/ + + if (cdclk_squash_divider(new_waveform) > cdclk_squash_divider(old_waveform)) { + mid_cdclk_config->vco = old_cdclk_config->vco; + mid_waveform = new_waveform; + } else { + mid_cdclk_config->vco = new_cdclk_config->vco; + mid_waveform = old_waveform; + } + + mid_cdclk_config->cdclk = DIV_ROUND_CLOSEST(cdclk_squash_divider(mid_waveform) * + mid_cdclk_config->vco, size * div); + + /* make sure the mid clock came out sane */ + + drm_WARN_ON(>drm, mid_cdclk_config->cdclk < + min(old_cdclk_config->cdclk, new_cdclk_config->cdclk)); + drm_WARN_ON(>drm, mid_cdclk_config->cdclk > + i915->display.cdclk.max_cdclk_freq); + drm_WARN_ON(>drm, cdclk_squash_waveform(i915, mid_cdclk_config->cdclk) != + mid_waveform); + + return true; +} + +static void _bxt_set_cdclk(struct drm_i915_private *dev_priv, + const struct intel_cdclk_config *cdclk_config, + enum pipe pipe) { int cdclk = cdclk_config->cdclk; int vco = cdclk_config->vco; u32 val; u16 waveform; int clock; - int ret; - - /* Inform power controller of upcoming frequency change. */ - if (DISPLAY_VER(dev_priv) >= 11) - ret = skl_pcode_request(_priv->uncore, SKL_PCODE_CDCLK_CONTROL, - SKL_CDCLK_PREPARE_FOR_CHANGE, - SKL_CDCLK_READY_FOR_CHANGE, - SKL_CDCLK_READY_FOR_CHANGE, 3); - else - /* -* BSpec requires us to wait up to 150usec, but that leads to -* timeouts; the 2ms used here is base
[Intel-gfx] [CI 4/4] drm/i915/display: Move squash_ctl register programming to its own function
No functional change. Introduce dg2_cdclk_squash_program and move squash_ctl register programming bits to this. v2: s/dg2_cdclk_squash_programming/dg2_cdclk_squash_program (Jani) Cc: Jani Nikula Cc: Balasubramani Vivekanandan Cc: Ville Syrjälä Signed-off-by: Anusha Srivatsa Reviewed-by: Balasubramani Vivekanandan --- drivers/gpu/drm/i915/display/intel_cdclk.c | 23 +- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 9cd02b85ee51..eada931cb1c8 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1704,6 +1704,18 @@ static void bxt_cdclk_pll_update(struct drm_i915_private *i915, int vco) bxt_de_pll_enable(i915, vco); } +static void dg2_cdclk_squash_program(struct drm_i915_private *i915, +u16 waveform) +{ + u32 squash_ctl = 0; + + if (waveform) + squash_ctl = CDCLK_SQUASH_ENABLE | +CDCLK_SQUASH_WINDOW_SIZE(0xf) | waveform; + + intel_de_write(i915, CDCLK_SQUASH_CTL, squash_ctl); +} + static void bxt_set_cdclk(struct drm_i915_private *dev_priv, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) @@ -1751,15 +1763,8 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, else clock = cdclk; - if (HAS_CDCLK_SQUASH(dev_priv)) { - u32 squash_ctl = 0; - - if (waveform) - squash_ctl = CDCLK_SQUASH_ENABLE | - CDCLK_SQUASH_WINDOW_SIZE(0xf) | waveform; - - intel_de_write(dev_priv, CDCLK_SQUASH_CTL, squash_ctl); - } + if (HAS_CDCLK_SQUASH(dev_priv)) + dg2_cdclk_squash_program(dev_priv, waveform); val = bxt_cdclk_cd2x_div_sel(dev_priv, clock, vco) | bxt_cdclk_cd2x_pipe(dev_priv, pipe) | -- 2.25.1
[Intel-gfx] [CI 3/4] drm/i915/display: Move chunks of code out of bxt_set_cdclk()
No functional change. Moving segments out to simplify bxt_set_cdlck() v2: s/bxt_cdclk_pll/bxt_cdclk_pll_update (Jani) Cc: Jani Nikula Cc: Balasubramani Vivekanandan Cc: Ville Syrjälä Signed-off-by: Anusha Srivatsa Reviewed-by: Balasubramani Vivekanandan --- drivers/gpu/drm/i915/display/intel_cdclk.c | 39 +- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 45babbc6290f..9cd02b85ee51 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1684,6 +1684,26 @@ static u32 cdclk_squash_waveform(struct drm_i915_private *dev_priv, return 0x; } +static void icl_cdclk_pll_update(struct drm_i915_private *i915, int vco) +{ + if (i915->display.cdclk.hw.vco != 0 && + i915->display.cdclk.hw.vco != vco) + icl_cdclk_pll_disable(i915); + + if (i915->display.cdclk.hw.vco != vco) + icl_cdclk_pll_enable(i915, vco); +} + +static void bxt_cdclk_pll_update(struct drm_i915_private *i915, int vco) +{ + if (i915->display.cdclk.hw.vco != 0 && + i915->display.cdclk.hw.vco != vco) + bxt_de_pll_disable(i915); + + if (i915->display.cdclk.hw.vco != vco) + bxt_de_pll_enable(i915, vco); +} + static void bxt_set_cdclk(struct drm_i915_private *dev_priv, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) @@ -1719,21 +1739,10 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0) { if (dev_priv->display.cdclk.hw.vco != vco) adlp_cdclk_pll_crawl(dev_priv, vco); - } else if (DISPLAY_VER(dev_priv) >= 11) { - if (dev_priv->display.cdclk.hw.vco != 0 && - dev_priv->display.cdclk.hw.vco != vco) - icl_cdclk_pll_disable(dev_priv); - - if (dev_priv->display.cdclk.hw.vco != vco) - icl_cdclk_pll_enable(dev_priv, vco); - } else { - if (dev_priv->display.cdclk.hw.vco != 0 && - dev_priv->display.cdclk.hw.vco != vco) - bxt_de_pll_disable(dev_priv); - - if (dev_priv->display.cdclk.hw.vco != vco) - bxt_de_pll_enable(dev_priv, vco); - } + } else if (DISPLAY_VER(dev_priv) >= 11) + icl_cdclk_pll_update(dev_priv, vco); + else + bxt_cdclk_pll_update(dev_priv, vco); waveform = cdclk_squash_waveform(dev_priv, cdclk); -- 2.25.1
[Intel-gfx] [CI 1/4] drm/i915/display: Change terminology for cdclk actions
No functional changes. Changing terminology in some print statements. s/has_cdclk_squasher/has_cdclk_squash, s/crawler/crawl and s/squasher/squash. Cc: Balasubramani Vivekanandan Cc: Ville Syrjälä Signed-off-by: Anusha Srivatsa Reviewed-by: Balasubramani Vivekanandan --- drivers/gpu/drm/i915/display/intel_cdclk.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index ad401357ab66..0f5add2fc51b 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1220,7 +1220,7 @@ static void skl_cdclk_uninit_hw(struct drm_i915_private *dev_priv) skl_set_cdclk(dev_priv, _config, INVALID_PIPE); } -static bool has_cdclk_squasher(struct drm_i915_private *i915) +static bool has_cdclk_squash(struct drm_i915_private *i915) { return IS_DG2(i915); } @@ -1520,7 +1520,7 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv, return; } - if (has_cdclk_squasher(dev_priv)) + if (has_cdclk_squash(dev_priv)) squash_ctl = intel_de_read(dev_priv, CDCLK_SQUASH_CTL); if (squash_ctl & CDCLK_SQUASH_ENABLE) { @@ -1747,7 +1747,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, else clock = cdclk; - if (has_cdclk_squasher(dev_priv)) { + if (has_cdclk_squash(dev_priv)) { u32 squash_ctl = 0; if (waveform) @@ -1845,7 +1845,7 @@ static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv) expected = skl_cdclk_decimal(cdclk); /* Figure out what CD2X divider we should be using for this cdclk */ - if (has_cdclk_squasher(dev_priv)) + if (has_cdclk_squash(dev_priv)) clock = dev_priv->display.cdclk.hw.vco / 2; else clock = dev_priv->display.cdclk.hw.cdclk; @@ -1976,7 +1976,7 @@ static bool intel_cdclk_can_squash(struct drm_i915_private *dev_priv, * the moment all platforms with squasher use a fixed cd2x * divider. */ - if (!has_cdclk_squasher(dev_priv)) + if (!has_cdclk_squash(dev_priv)) return false; return a->cdclk != b->cdclk && @@ -2028,7 +2028,7 @@ static bool intel_cdclk_can_cd2x_update(struct drm_i915_private *dev_priv, * the moment all platforms with squasher use a fixed cd2x * divider. */ - if (has_cdclk_squasher(dev_priv)) + if (has_cdclk_squash(dev_priv)) return false; return a->cdclk != b->cdclk && @@ -2754,12 +2754,12 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state) _cdclk_state->actual, _cdclk_state->actual)) { drm_dbg_kms(_priv->drm, - "Can change cdclk via squasher\n"); + "Can change cdclk via squashing\n"); } else if (intel_cdclk_can_crawl(dev_priv, _cdclk_state->actual, _cdclk_state->actual)) { drm_dbg_kms(_priv->drm, - "Can change cdclk via crawl\n"); + "Can change cdclk via crawling\n"); } else if (pipe != INVALID_PIPE) { new_cdclk_state->pipe = pipe; -- 2.25.1
[Intel-gfx] [CI 2/4] drm/i915/display: Introduce HAS_CDCLK_SQUASH macro
Driver had discrepancy in how cdclk squash and crawl support were checked. Like crawl, add squash as a 1 bit feature flag to the display section of DG2. Cc: Balasubramani Vivekanandan Cc: Ville Syrjälä Signed-off-by: Anusha Srivatsa Reviewed-by: Balasubramani Vivekanandan --- drivers/gpu/drm/i915/display/intel_cdclk.c | 15 +-- drivers/gpu/drm/i915/i915_drv.h| 1 + drivers/gpu/drm/i915/i915_pci.c| 1 + drivers/gpu/drm/i915/intel_device_info.h | 1 + 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 0f5add2fc51b..45babbc6290f 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1220,11 +1220,6 @@ static void skl_cdclk_uninit_hw(struct drm_i915_private *dev_priv) skl_set_cdclk(dev_priv, _config, INVALID_PIPE); } -static bool has_cdclk_squash(struct drm_i915_private *i915) -{ - return IS_DG2(i915); -} - struct intel_cdclk_vals { u32 cdclk; u16 refclk; @@ -1520,7 +1515,7 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv, return; } - if (has_cdclk_squash(dev_priv)) + if (HAS_CDCLK_SQUASH(dev_priv)) squash_ctl = intel_de_read(dev_priv, CDCLK_SQUASH_CTL); if (squash_ctl & CDCLK_SQUASH_ENABLE) { @@ -1747,7 +1742,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, else clock = cdclk; - if (has_cdclk_squash(dev_priv)) { + if (HAS_CDCLK_SQUASH(dev_priv)) { u32 squash_ctl = 0; if (waveform) @@ -1845,7 +1840,7 @@ static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv) expected = skl_cdclk_decimal(cdclk); /* Figure out what CD2X divider we should be using for this cdclk */ - if (has_cdclk_squash(dev_priv)) + if (HAS_CDCLK_SQUASH(dev_priv)) clock = dev_priv->display.cdclk.hw.vco / 2; else clock = dev_priv->display.cdclk.hw.cdclk; @@ -1976,7 +1971,7 @@ static bool intel_cdclk_can_squash(struct drm_i915_private *dev_priv, * the moment all platforms with squasher use a fixed cd2x * divider. */ - if (!has_cdclk_squash(dev_priv)) + if (!HAS_CDCLK_SQUASH(dev_priv)) return false; return a->cdclk != b->cdclk && @@ -2028,7 +2023,7 @@ static bool intel_cdclk_can_cd2x_update(struct drm_i915_private *dev_priv, * the moment all platforms with squasher use a fixed cd2x * divider. */ - if (has_cdclk_squash(dev_priv)) + if (HAS_CDCLK_SQUASH(dev_priv)) return false; return a->cdclk != b->cdclk && diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d7b8eb9d4117..db51050e3ba2 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -869,6 +869,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, #define HAS_DOUBLE_BUFFERED_M_N(dev_priv) (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) #define HAS_CDCLK_CRAWL(dev_priv) (INTEL_INFO(dev_priv)->display.has_cdclk_crawl) +#define HAS_CDCLK_SQUASH(dev_priv) (INTEL_INFO(dev_priv)->display.has_cdclk_squash) #define HAS_DDI(dev_priv) (INTEL_INFO(dev_priv)->display.has_ddi) #define HAS_FPGA_DBG_UNCLAIMED(dev_priv) (INTEL_INFO(dev_priv)->display.has_fpga_dbg) #define HAS_PSR(dev_priv) (INTEL_INFO(dev_priv)->display.has_psr) diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 19bf5ef6a20d..a88e1439a426 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -1064,6 +1064,7 @@ static const struct intel_device_info xehpsdv_info = { .has_guc_deprivilege = 1, \ .has_heci_pxp = 1, \ .has_media_ratio_mode = 1, \ + .display.has_cdclk_squash = 1, \ .__runtime.platform_engine_mask = \ BIT(RCS0) | BIT(BCS0) | \ BIT(VECS0) | BIT(VECS1) | \ diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h index cdf78728dcad..67d8759c802c 100644 --- a/drivers/gpu/drm/i915/intel_device_info.h +++ b/drivers/gpu/drm/i915/intel_device_info.h @@ -180,6 +180,7 @@ enum intel_ppgtt_type { /* Keep in alphabetical order */ \ func(cursor_needs_physical); \ func(has_cdclk_crawl); \ + func(has_cdclk_squash); \ func(has_ddi); \ func(has_dp_mst); \ func(has_dsb); \ -- 2.25.1
[Intel-gfx] [PATCH 4/4] drm/i915/display: Move squash_ctl register programming to its own function
No functional change. Introduce dg2_cdclk_squash_program and move squash_ctl register programming bits to this. v2: s/dg2_cdclk_squash_programming/dg2_cdclk_squash_program (Jani) Cc: Jani Nikula Cc: Balasubramani Vivekanandan Cc: Ville Syrjälä Signed-off-by: Anusha Srivatsa Reviewed-by: Balasubramani Vivekanandan --- drivers/gpu/drm/i915/display/intel_cdclk.c | 23 +- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 3893779e0c23..e21cd0fbe29a 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1705,6 +1705,18 @@ static void bxt_cdclk_pll_update(struct drm_i915_private *i915, int vco) } +static void dg2_cdclk_squash_program(struct drm_i915_private *i915, +u16 waveform) +{ + u32 squash_ctl = 0; + + if (waveform) + squash_ctl = CDCLK_SQUASH_ENABLE | +CDCLK_SQUASH_WINDOW_SIZE(0xf) | waveform; + + intel_de_write(i915, CDCLK_SQUASH_CTL, squash_ctl); +} + static void bxt_set_cdclk(struct drm_i915_private *dev_priv, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) @@ -1752,15 +1764,8 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, else clock = cdclk; - if (HAS_CDCLK_SQUASH(dev_priv)) { - u32 squash_ctl = 0; - - if (waveform) - squash_ctl = CDCLK_SQUASH_ENABLE | - CDCLK_SQUASH_WINDOW_SIZE(0xf) | waveform; - - intel_de_write(dev_priv, CDCLK_SQUASH_CTL, squash_ctl); - } + if (HAS_CDCLK_SQUASH(dev_priv)) + dg2_cdclk_squash_program(dev_priv, waveform); val = bxt_cdclk_cd2x_div_sel(dev_priv, clock, vco) | bxt_cdclk_cd2x_pipe(dev_priv, pipe) | -- 2.25.1
[Intel-gfx] [PATCH 2/4] drm/i915/display: Introduce HAS_CDCLK_SQUASH macro
Driver had discrepancy in how cdclk squash and crawl support were checked. Like crawl, add squash as a 1 bit feature flag to the display section of DG2. Cc: Balasubramani Vivekanandan Cc: Ville Syrjälä Signed-off-by: Anusha Srivatsa Reviewed-by: Balasubramani Vivekanandan --- drivers/gpu/drm/i915/display/intel_cdclk.c | 15 +-- drivers/gpu/drm/i915/i915_drv.h| 1 + drivers/gpu/drm/i915/i915_pci.c| 1 + drivers/gpu/drm/i915/intel_device_info.h | 1 + 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 0f5add2fc51b..45babbc6290f 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1220,11 +1220,6 @@ static void skl_cdclk_uninit_hw(struct drm_i915_private *dev_priv) skl_set_cdclk(dev_priv, _config, INVALID_PIPE); } -static bool has_cdclk_squash(struct drm_i915_private *i915) -{ - return IS_DG2(i915); -} - struct intel_cdclk_vals { u32 cdclk; u16 refclk; @@ -1520,7 +1515,7 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv, return; } - if (has_cdclk_squash(dev_priv)) + if (HAS_CDCLK_SQUASH(dev_priv)) squash_ctl = intel_de_read(dev_priv, CDCLK_SQUASH_CTL); if (squash_ctl & CDCLK_SQUASH_ENABLE) { @@ -1747,7 +1742,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, else clock = cdclk; - if (has_cdclk_squash(dev_priv)) { + if (HAS_CDCLK_SQUASH(dev_priv)) { u32 squash_ctl = 0; if (waveform) @@ -1845,7 +1840,7 @@ static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv) expected = skl_cdclk_decimal(cdclk); /* Figure out what CD2X divider we should be using for this cdclk */ - if (has_cdclk_squash(dev_priv)) + if (HAS_CDCLK_SQUASH(dev_priv)) clock = dev_priv->display.cdclk.hw.vco / 2; else clock = dev_priv->display.cdclk.hw.cdclk; @@ -1976,7 +1971,7 @@ static bool intel_cdclk_can_squash(struct drm_i915_private *dev_priv, * the moment all platforms with squasher use a fixed cd2x * divider. */ - if (!has_cdclk_squash(dev_priv)) + if (!HAS_CDCLK_SQUASH(dev_priv)) return false; return a->cdclk != b->cdclk && @@ -2028,7 +2023,7 @@ static bool intel_cdclk_can_cd2x_update(struct drm_i915_private *dev_priv, * the moment all platforms with squasher use a fixed cd2x * divider. */ - if (has_cdclk_squash(dev_priv)) + if (HAS_CDCLK_SQUASH(dev_priv)) return false; return a->cdclk != b->cdclk && diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d7b8eb9d4117..db51050e3ba2 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -869,6 +869,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, #define HAS_DOUBLE_BUFFERED_M_N(dev_priv) (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) #define HAS_CDCLK_CRAWL(dev_priv) (INTEL_INFO(dev_priv)->display.has_cdclk_crawl) +#define HAS_CDCLK_SQUASH(dev_priv) (INTEL_INFO(dev_priv)->display.has_cdclk_squash) #define HAS_DDI(dev_priv) (INTEL_INFO(dev_priv)->display.has_ddi) #define HAS_FPGA_DBG_UNCLAIMED(dev_priv) (INTEL_INFO(dev_priv)->display.has_fpga_dbg) #define HAS_PSR(dev_priv) (INTEL_INFO(dev_priv)->display.has_psr) diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 19bf5ef6a20d..a88e1439a426 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -1064,6 +1064,7 @@ static const struct intel_device_info xehpsdv_info = { .has_guc_deprivilege = 1, \ .has_heci_pxp = 1, \ .has_media_ratio_mode = 1, \ + .display.has_cdclk_squash = 1, \ .__runtime.platform_engine_mask = \ BIT(RCS0) | BIT(BCS0) | \ BIT(VECS0) | BIT(VECS1) | \ diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h index cdf78728dcad..67d8759c802c 100644 --- a/drivers/gpu/drm/i915/intel_device_info.h +++ b/drivers/gpu/drm/i915/intel_device_info.h @@ -180,6 +180,7 @@ enum intel_ppgtt_type { /* Keep in alphabetical order */ \ func(cursor_needs_physical); \ func(has_cdclk_crawl); \ + func(has_cdclk_squash); \ func(has_ddi); \ func(has_dp_mst); \ func(has_dsb); \ -- 2.25.1
[Intel-gfx] [PATCH 1/4] drm/i915/display: Change terminology for cdclk actions
No functional changes. Changing terminology in some print statements. s/has_cdclk_squasher/has_cdclk_squash, s/crawler/crawl and s/squasher/squash. Cc: Balasubramani Vivekanandan Cc: Ville Syrjälä Signed-off-by: Anusha Srivatsa Reviewed-by: Balasubramani Vivekanandan --- drivers/gpu/drm/i915/display/intel_cdclk.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index ad401357ab66..0f5add2fc51b 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1220,7 +1220,7 @@ static void skl_cdclk_uninit_hw(struct drm_i915_private *dev_priv) skl_set_cdclk(dev_priv, _config, INVALID_PIPE); } -static bool has_cdclk_squasher(struct drm_i915_private *i915) +static bool has_cdclk_squash(struct drm_i915_private *i915) { return IS_DG2(i915); } @@ -1520,7 +1520,7 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv, return; } - if (has_cdclk_squasher(dev_priv)) + if (has_cdclk_squash(dev_priv)) squash_ctl = intel_de_read(dev_priv, CDCLK_SQUASH_CTL); if (squash_ctl & CDCLK_SQUASH_ENABLE) { @@ -1747,7 +1747,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, else clock = cdclk; - if (has_cdclk_squasher(dev_priv)) { + if (has_cdclk_squash(dev_priv)) { u32 squash_ctl = 0; if (waveform) @@ -1845,7 +1845,7 @@ static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv) expected = skl_cdclk_decimal(cdclk); /* Figure out what CD2X divider we should be using for this cdclk */ - if (has_cdclk_squasher(dev_priv)) + if (has_cdclk_squash(dev_priv)) clock = dev_priv->display.cdclk.hw.vco / 2; else clock = dev_priv->display.cdclk.hw.cdclk; @@ -1976,7 +1976,7 @@ static bool intel_cdclk_can_squash(struct drm_i915_private *dev_priv, * the moment all platforms with squasher use a fixed cd2x * divider. */ - if (!has_cdclk_squasher(dev_priv)) + if (!has_cdclk_squash(dev_priv)) return false; return a->cdclk != b->cdclk && @@ -2028,7 +2028,7 @@ static bool intel_cdclk_can_cd2x_update(struct drm_i915_private *dev_priv, * the moment all platforms with squasher use a fixed cd2x * divider. */ - if (has_cdclk_squasher(dev_priv)) + if (has_cdclk_squash(dev_priv)) return false; return a->cdclk != b->cdclk && @@ -2754,12 +2754,12 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state) _cdclk_state->actual, _cdclk_state->actual)) { drm_dbg_kms(_priv->drm, - "Can change cdclk via squasher\n"); + "Can change cdclk via squashing\n"); } else if (intel_cdclk_can_crawl(dev_priv, _cdclk_state->actual, _cdclk_state->actual)) { drm_dbg_kms(_priv->drm, - "Can change cdclk via crawl\n"); + "Can change cdclk via crawling\n"); } else if (pipe != INVALID_PIPE) { new_cdclk_state->pipe = pipe; -- 2.25.1
[Intel-gfx] [PATCH 3/4] drm/i915/display: Move chunks of code out of bxt_set_cdclk()
No functional change. Moving segments out to simplify bxt_set_cdlck() v2: s/bxt_cdclk_pll/bxt_cdclk_pll_update (Jani) Cc: Jani Nikula Cc: Balasubramani Vivekanandan Cc: Ville Syrjälä Signed-off-by: Anusha Srivatsa Reviewed-by: Balasubramani Vivekanandan --- drivers/gpu/drm/i915/display/intel_cdclk.c | 40 ++ 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 45babbc6290f..3893779e0c23 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1684,6 +1684,27 @@ static u32 cdclk_squash_waveform(struct drm_i915_private *dev_priv, return 0x; } +static void icl_cdclk_pll_update(struct drm_i915_private *i915, int vco) +{ + if (i915->display.cdclk.hw.vco != 0 && + i915->display.cdclk.hw.vco != vco) + icl_cdclk_pll_disable(i915); + + if (i915->display.cdclk.hw.vco != vco) + icl_cdclk_pll_enable(i915, vco); +} + +static void bxt_cdclk_pll_update(struct drm_i915_private *i915, int vco) +{ + if (i915->display.cdclk.hw.vco != 0 && + i915->display.cdclk.hw.vco != vco) + bxt_de_pll_disable(i915); + + if (i915->display.cdclk.hw.vco != vco) + bxt_de_pll_enable(i915, vco); + +} + static void bxt_set_cdclk(struct drm_i915_private *dev_priv, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) @@ -1719,21 +1740,10 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0) { if (dev_priv->display.cdclk.hw.vco != vco) adlp_cdclk_pll_crawl(dev_priv, vco); - } else if (DISPLAY_VER(dev_priv) >= 11) { - if (dev_priv->display.cdclk.hw.vco != 0 && - dev_priv->display.cdclk.hw.vco != vco) - icl_cdclk_pll_disable(dev_priv); - - if (dev_priv->display.cdclk.hw.vco != vco) - icl_cdclk_pll_enable(dev_priv, vco); - } else { - if (dev_priv->display.cdclk.hw.vco != 0 && - dev_priv->display.cdclk.hw.vco != vco) - bxt_de_pll_disable(dev_priv); - - if (dev_priv->display.cdclk.hw.vco != vco) - bxt_de_pll_enable(dev_priv, vco); - } + } else if (DISPLAY_VER(dev_priv) >= 11) + icl_cdclk_pll_update(dev_priv, vco); + else + bxt_cdclk_pll_update(dev_priv, vco); waveform = cdclk_squash_waveform(dev_priv, cdclk); -- 2.25.1
[Intel-gfx] [PATCH 1/4] drm/i915/display: Change terminology for cdclk actions
No functional changes. Changing terminolgy in some print statements. s/has_cdclk_squasher/has_cdclk_squash, s/crawler/crawl and s/squasher/squash. Cc: Balasubramani Vivekanandan Cc: Ville Syrjälä Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index ad401357ab66..0f5add2fc51b 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1220,7 +1220,7 @@ static void skl_cdclk_uninit_hw(struct drm_i915_private *dev_priv) skl_set_cdclk(dev_priv, _config, INVALID_PIPE); } -static bool has_cdclk_squasher(struct drm_i915_private *i915) +static bool has_cdclk_squash(struct drm_i915_private *i915) { return IS_DG2(i915); } @@ -1520,7 +1520,7 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv, return; } - if (has_cdclk_squasher(dev_priv)) + if (has_cdclk_squash(dev_priv)) squash_ctl = intel_de_read(dev_priv, CDCLK_SQUASH_CTL); if (squash_ctl & CDCLK_SQUASH_ENABLE) { @@ -1747,7 +1747,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, else clock = cdclk; - if (has_cdclk_squasher(dev_priv)) { + if (has_cdclk_squash(dev_priv)) { u32 squash_ctl = 0; if (waveform) @@ -1845,7 +1845,7 @@ static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv) expected = skl_cdclk_decimal(cdclk); /* Figure out what CD2X divider we should be using for this cdclk */ - if (has_cdclk_squasher(dev_priv)) + if (has_cdclk_squash(dev_priv)) clock = dev_priv->display.cdclk.hw.vco / 2; else clock = dev_priv->display.cdclk.hw.cdclk; @@ -1976,7 +1976,7 @@ static bool intel_cdclk_can_squash(struct drm_i915_private *dev_priv, * the moment all platforms with squasher use a fixed cd2x * divider. */ - if (!has_cdclk_squasher(dev_priv)) + if (!has_cdclk_squash(dev_priv)) return false; return a->cdclk != b->cdclk && @@ -2028,7 +2028,7 @@ static bool intel_cdclk_can_cd2x_update(struct drm_i915_private *dev_priv, * the moment all platforms with squasher use a fixed cd2x * divider. */ - if (has_cdclk_squasher(dev_priv)) + if (has_cdclk_squash(dev_priv)) return false; return a->cdclk != b->cdclk && @@ -2754,12 +2754,12 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state) _cdclk_state->actual, _cdclk_state->actual)) { drm_dbg_kms(_priv->drm, - "Can change cdclk via squasher\n"); + "Can change cdclk via squashing\n"); } else if (intel_cdclk_can_crawl(dev_priv, _cdclk_state->actual, _cdclk_state->actual)) { drm_dbg_kms(_priv->drm, - "Can change cdclk via crawl\n"); + "Can change cdclk via crawling\n"); } else if (pipe != INVALID_PIPE) { new_cdclk_state->pipe = pipe; -- 2.25.1
[Intel-gfx] [PATCH 4/4] drm/i915/display: Move squash_ctl register programming to its own function
No functional change. Introduce dg2_cdclk_squash_program and move squash_ctl register programming bits to this. v2: s/dg2_cdclk_squash_programming/dg2_cdclk_squash_program (Jani) Cc: Jani Nikula Cc: Balasubramani Vivekanandan Cc: Ville Syrjälä Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 23 +- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 3893779e0c23..e21cd0fbe29a 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1705,6 +1705,18 @@ static void bxt_cdclk_pll_update(struct drm_i915_private *i915, int vco) } +static void dg2_cdclk_squash_program(struct drm_i915_private *i915, +u16 waveform) +{ + u32 squash_ctl = 0; + + if (waveform) + squash_ctl = CDCLK_SQUASH_ENABLE | +CDCLK_SQUASH_WINDOW_SIZE(0xf) | waveform; + + intel_de_write(i915, CDCLK_SQUASH_CTL, squash_ctl); +} + static void bxt_set_cdclk(struct drm_i915_private *dev_priv, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) @@ -1752,15 +1764,8 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, else clock = cdclk; - if (HAS_CDCLK_SQUASH(dev_priv)) { - u32 squash_ctl = 0; - - if (waveform) - squash_ctl = CDCLK_SQUASH_ENABLE | - CDCLK_SQUASH_WINDOW_SIZE(0xf) | waveform; - - intel_de_write(dev_priv, CDCLK_SQUASH_CTL, squash_ctl); - } + if (HAS_CDCLK_SQUASH(dev_priv)) + dg2_cdclk_squash_program(dev_priv, waveform); val = bxt_cdclk_cd2x_div_sel(dev_priv, clock, vco) | bxt_cdclk_cd2x_pipe(dev_priv, pipe) | -- 2.25.1
[Intel-gfx] [PATCH 3/4] drm/i915/display: Move chunks of code out of bxt_set_cdclk()
No functional change. Moving segments out to simplify bxt_set_cdlck() v2: s/bxt_cdclk_pll/bxt_cdclk_pll_update (Jani) Cc: Jani Nikula Cc: Balasubramani Vivekanandan Cc: Ville Syrjälä Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 40 ++ 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 45babbc6290f..3893779e0c23 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1684,6 +1684,27 @@ static u32 cdclk_squash_waveform(struct drm_i915_private *dev_priv, return 0x; } +static void icl_cdclk_pll_update(struct drm_i915_private *i915, int vco) +{ + if (i915->display.cdclk.hw.vco != 0 && + i915->display.cdclk.hw.vco != vco) + icl_cdclk_pll_disable(i915); + + if (i915->display.cdclk.hw.vco != vco) + icl_cdclk_pll_enable(i915, vco); +} + +static void bxt_cdclk_pll_update(struct drm_i915_private *i915, int vco) +{ + if (i915->display.cdclk.hw.vco != 0 && + i915->display.cdclk.hw.vco != vco) + bxt_de_pll_disable(i915); + + if (i915->display.cdclk.hw.vco != vco) + bxt_de_pll_enable(i915, vco); + +} + static void bxt_set_cdclk(struct drm_i915_private *dev_priv, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) @@ -1719,21 +1740,10 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0) { if (dev_priv->display.cdclk.hw.vco != vco) adlp_cdclk_pll_crawl(dev_priv, vco); - } else if (DISPLAY_VER(dev_priv) >= 11) { - if (dev_priv->display.cdclk.hw.vco != 0 && - dev_priv->display.cdclk.hw.vco != vco) - icl_cdclk_pll_disable(dev_priv); - - if (dev_priv->display.cdclk.hw.vco != vco) - icl_cdclk_pll_enable(dev_priv, vco); - } else { - if (dev_priv->display.cdclk.hw.vco != 0 && - dev_priv->display.cdclk.hw.vco != vco) - bxt_de_pll_disable(dev_priv); - - if (dev_priv->display.cdclk.hw.vco != vco) - bxt_de_pll_enable(dev_priv, vco); - } + } else if (DISPLAY_VER(dev_priv) >= 11) + icl_cdclk_pll_update(dev_priv, vco); + else + bxt_cdclk_pll_update(dev_priv, vco); waveform = cdclk_squash_waveform(dev_priv, cdclk); -- 2.25.1
[Intel-gfx] [PATCH 2/4] drm/i915/display: Introduce HAS_CDCLK_SQUASH macro
Driver had discrepancy in how cdclk squash and crawl support were checked. Like crawl, add squash as a 1 bit feature flag to the display section of DG2. Cc: Balasubramani Vivekanandan Cc: Ville Syrjälä Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 15 +-- drivers/gpu/drm/i915/i915_drv.h| 1 + drivers/gpu/drm/i915/i915_pci.c| 1 + drivers/gpu/drm/i915/intel_device_info.h | 1 + 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 0f5add2fc51b..45babbc6290f 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1220,11 +1220,6 @@ static void skl_cdclk_uninit_hw(struct drm_i915_private *dev_priv) skl_set_cdclk(dev_priv, _config, INVALID_PIPE); } -static bool has_cdclk_squash(struct drm_i915_private *i915) -{ - return IS_DG2(i915); -} - struct intel_cdclk_vals { u32 cdclk; u16 refclk; @@ -1520,7 +1515,7 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv, return; } - if (has_cdclk_squash(dev_priv)) + if (HAS_CDCLK_SQUASH(dev_priv)) squash_ctl = intel_de_read(dev_priv, CDCLK_SQUASH_CTL); if (squash_ctl & CDCLK_SQUASH_ENABLE) { @@ -1747,7 +1742,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, else clock = cdclk; - if (has_cdclk_squash(dev_priv)) { + if (HAS_CDCLK_SQUASH(dev_priv)) { u32 squash_ctl = 0; if (waveform) @@ -1845,7 +1840,7 @@ static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv) expected = skl_cdclk_decimal(cdclk); /* Figure out what CD2X divider we should be using for this cdclk */ - if (has_cdclk_squash(dev_priv)) + if (HAS_CDCLK_SQUASH(dev_priv)) clock = dev_priv->display.cdclk.hw.vco / 2; else clock = dev_priv->display.cdclk.hw.cdclk; @@ -1976,7 +1971,7 @@ static bool intel_cdclk_can_squash(struct drm_i915_private *dev_priv, * the moment all platforms with squasher use a fixed cd2x * divider. */ - if (!has_cdclk_squash(dev_priv)) + if (!HAS_CDCLK_SQUASH(dev_priv)) return false; return a->cdclk != b->cdclk && @@ -2028,7 +2023,7 @@ static bool intel_cdclk_can_cd2x_update(struct drm_i915_private *dev_priv, * the moment all platforms with squasher use a fixed cd2x * divider. */ - if (has_cdclk_squash(dev_priv)) + if (HAS_CDCLK_SQUASH(dev_priv)) return false; return a->cdclk != b->cdclk && diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d7b8eb9d4117..db51050e3ba2 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -869,6 +869,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, #define HAS_DOUBLE_BUFFERED_M_N(dev_priv) (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) #define HAS_CDCLK_CRAWL(dev_priv) (INTEL_INFO(dev_priv)->display.has_cdclk_crawl) +#define HAS_CDCLK_SQUASH(dev_priv) (INTEL_INFO(dev_priv)->display.has_cdclk_squash) #define HAS_DDI(dev_priv) (INTEL_INFO(dev_priv)->display.has_ddi) #define HAS_FPGA_DBG_UNCLAIMED(dev_priv) (INTEL_INFO(dev_priv)->display.has_fpga_dbg) #define HAS_PSR(dev_priv) (INTEL_INFO(dev_priv)->display.has_psr) diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 19bf5ef6a20d..a88e1439a426 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -1064,6 +1064,7 @@ static const struct intel_device_info xehpsdv_info = { .has_guc_deprivilege = 1, \ .has_heci_pxp = 1, \ .has_media_ratio_mode = 1, \ + .display.has_cdclk_squash = 1, \ .__runtime.platform_engine_mask = \ BIT(RCS0) | BIT(BCS0) | \ BIT(VECS0) | BIT(VECS1) | \ diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h index cdf78728dcad..67d8759c802c 100644 --- a/drivers/gpu/drm/i915/intel_device_info.h +++ b/drivers/gpu/drm/i915/intel_device_info.h @@ -180,6 +180,7 @@ enum intel_ppgtt_type { /* Keep in alphabetical order */ \ func(cursor_needs_physical); \ func(has_cdclk_crawl); \ + func(has_cdclk_squash); \ func(has_ddi); \ func(has_dp_mst); \ func(has_dsb); \ -- 2.25.1
[Intel-gfx] [PATCH 0/4] Prep series - CDCLK code churn
No functional changes. The series is more of a prep series for the mid_cdclk_config series: https://patchwork.freedesktop.org/series/109694/ Main change: - Change usage of "crawler" and "squasher". Use crawling and squashing instead. - Handle both squash and crawl similar in terms of checking if the platform supports them or not. With the changes introduced, both are a display feature flag. - Move code from bxt_set_cdclk() to make it more modularized and easy to read and understand. v2: Change function names to align with rest of the driver. No major changes. Cc: Balasubramani Vivekanandan Cc: Ville Syrjälä Anusha Srivatsa (4): drm/i915/display: Change terminology for cdclk actions drm/i915/display: Introduce HAS_CDCLK_SQUASH macro drm/i915/display: Move chunks of code out of bxt_set_cdclk() drm/i915/display: Move squash_ctl register programming to its own function drivers/gpu/drm/i915/display/intel_cdclk.c | 80 -- drivers/gpu/drm/i915/i915_drv.h| 1 + drivers/gpu/drm/i915/i915_pci.c| 1 + drivers/gpu/drm/i915/intel_device_info.h | 1 + 4 files changed, 48 insertions(+), 35 deletions(-) -- 2.25.1
[Intel-gfx] [PATCH 2/4] drm/i915/display: Introduce HAS_CDCLK_SQUASH macro
Driver had discrepancy in how cdclk squash and crawl support were checked. Like crawl, add squash as a 1 bit feature flag to the display section of DG2. Cc: Balasubramani Vivekanandan Cc: Ville Syrjälä Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 15 +-- drivers/gpu/drm/i915/i915_drv.h| 1 + drivers/gpu/drm/i915/i915_pci.c| 1 + drivers/gpu/drm/i915/intel_device_info.h | 1 + 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 0f5add2fc51b..45babbc6290f 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1220,11 +1220,6 @@ static void skl_cdclk_uninit_hw(struct drm_i915_private *dev_priv) skl_set_cdclk(dev_priv, _config, INVALID_PIPE); } -static bool has_cdclk_squash(struct drm_i915_private *i915) -{ - return IS_DG2(i915); -} - struct intel_cdclk_vals { u32 cdclk; u16 refclk; @@ -1520,7 +1515,7 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv, return; } - if (has_cdclk_squash(dev_priv)) + if (HAS_CDCLK_SQUASH(dev_priv)) squash_ctl = intel_de_read(dev_priv, CDCLK_SQUASH_CTL); if (squash_ctl & CDCLK_SQUASH_ENABLE) { @@ -1747,7 +1742,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, else clock = cdclk; - if (has_cdclk_squash(dev_priv)) { + if (HAS_CDCLK_SQUASH(dev_priv)) { u32 squash_ctl = 0; if (waveform) @@ -1845,7 +1840,7 @@ static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv) expected = skl_cdclk_decimal(cdclk); /* Figure out what CD2X divider we should be using for this cdclk */ - if (has_cdclk_squash(dev_priv)) + if (HAS_CDCLK_SQUASH(dev_priv)) clock = dev_priv->display.cdclk.hw.vco / 2; else clock = dev_priv->display.cdclk.hw.cdclk; @@ -1976,7 +1971,7 @@ static bool intel_cdclk_can_squash(struct drm_i915_private *dev_priv, * the moment all platforms with squasher use a fixed cd2x * divider. */ - if (!has_cdclk_squash(dev_priv)) + if (!HAS_CDCLK_SQUASH(dev_priv)) return false; return a->cdclk != b->cdclk && @@ -2028,7 +2023,7 @@ static bool intel_cdclk_can_cd2x_update(struct drm_i915_private *dev_priv, * the moment all platforms with squasher use a fixed cd2x * divider. */ - if (has_cdclk_squash(dev_priv)) + if (HAS_CDCLK_SQUASH(dev_priv)) return false; return a->cdclk != b->cdclk && diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d7b8eb9d4117..db51050e3ba2 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -869,6 +869,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, #define HAS_DOUBLE_BUFFERED_M_N(dev_priv) (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) #define HAS_CDCLK_CRAWL(dev_priv) (INTEL_INFO(dev_priv)->display.has_cdclk_crawl) +#define HAS_CDCLK_SQUASH(dev_priv) (INTEL_INFO(dev_priv)->display.has_cdclk_squash) #define HAS_DDI(dev_priv) (INTEL_INFO(dev_priv)->display.has_ddi) #define HAS_FPGA_DBG_UNCLAIMED(dev_priv) (INTEL_INFO(dev_priv)->display.has_fpga_dbg) #define HAS_PSR(dev_priv) (INTEL_INFO(dev_priv)->display.has_psr) diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 19bf5ef6a20d..a88e1439a426 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -1064,6 +1064,7 @@ static const struct intel_device_info xehpsdv_info = { .has_guc_deprivilege = 1, \ .has_heci_pxp = 1, \ .has_media_ratio_mode = 1, \ + .display.has_cdclk_squash = 1, \ .__runtime.platform_engine_mask = \ BIT(RCS0) | BIT(BCS0) | \ BIT(VECS0) | BIT(VECS1) | \ diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h index cdf78728dcad..67d8759c802c 100644 --- a/drivers/gpu/drm/i915/intel_device_info.h +++ b/drivers/gpu/drm/i915/intel_device_info.h @@ -180,6 +180,7 @@ enum intel_ppgtt_type { /* Keep in alphabetical order */ \ func(cursor_needs_physical); \ func(has_cdclk_crawl); \ + func(has_cdclk_squash); \ func(has_ddi); \ func(has_dp_mst); \ func(has_dsb); \ -- 2.25.1
[Intel-gfx] [PATCH 4/4] drm/i915/display: Move squash_ctl register programming to its own function
No functional change. Introduce dg2_cdclk_squash_programming and move squash_ctl register programming bits to this. Cc: Balasubramani Vivekanandan Cc: Ville Syrjälä Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 23 +- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 8701796788e3..b692186c8f02 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1705,6 +1705,18 @@ static void bxt_cdclk_pll(struct drm_i915_private *i915, int vco) } +static void dg2_cdclk_squash_programming(struct drm_i915_private *i915, +u16 waveform) +{ + u32 squash_ctl = 0; + + if (waveform) + squash_ctl = CDCLK_SQUASH_ENABLE | +CDCLK_SQUASH_WINDOW_SIZE(0xf) | waveform; + + intel_de_write(i915, CDCLK_SQUASH_CTL, squash_ctl); +} + static void bxt_set_cdclk(struct drm_i915_private *dev_priv, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) @@ -1752,15 +1764,8 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, else clock = cdclk; - if (HAS_CDCLK_SQUASH(dev_priv)) { - u32 squash_ctl = 0; - - if (waveform) - squash_ctl = CDCLK_SQUASH_ENABLE | - CDCLK_SQUASH_WINDOW_SIZE(0xf) | waveform; - - intel_de_write(dev_priv, CDCLK_SQUASH_CTL, squash_ctl); - } + if (HAS_CDCLK_SQUASH(dev_priv)) + dg2_cdclk_squash_programming(dev_priv, waveform); val = bxt_cdclk_cd2x_div_sel(dev_priv, clock, vco) | bxt_cdclk_cd2x_pipe(dev_priv, pipe) | -- 2.25.1
[Intel-gfx] [PATCH 0/4] Prep series - CDCLK code churn
No functional changes. The series is more of a prep series for the mid_cdclk_config series: https://patchwork.freedesktop.org/series/109694/ Main change: - Change usage of "crawler" and "squasher". Use crawling and squashing instead. - Handle bot hsquash and cralw similar in terms of checking if the platform supports them or not. With the changes introduced, both are a display feature flag. - Move code from bxt_set_cdclk() to make it more modularized and easy to read and understand. Cc: Balasubramani Vivekanandan Cc: Ville Syrjälä Anusha Srivatsa (4): drm/i915/display: Change terminology for cdclk actions drm/i915/display: Introduce HAS_CDCLK_SQUASH macro drm/i915/display: Move chunks of code out of bxt_set_cdclk() drm/i915/display: Move squash_ctl register programming to its own function drivers/gpu/drm/i915/display/intel_cdclk.c | 80 -- drivers/gpu/drm/i915/i915_drv.h| 1 + drivers/gpu/drm/i915/i915_pci.c| 1 + drivers/gpu/drm/i915/intel_device_info.h | 1 + 4 files changed, 48 insertions(+), 35 deletions(-) -- 2.25.1
[Intel-gfx] [PATCH 3/4] drm/i915/display: Move chunks of code out of bxt_set_cdclk()
No functional change. Moving segments out to simplify bxt_set_cdlck() Cc: Balasubramani Vivekanandan Cc: Ville Syrjälä Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 40 ++ 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 45babbc6290f..8701796788e3 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1684,6 +1684,27 @@ static u32 cdclk_squash_waveform(struct drm_i915_private *dev_priv, return 0x; } +static void icl_cdclk_pll(struct drm_i915_private *i915, int vco) +{ + if (i915->display.cdclk.hw.vco != 0 && + i915->display.cdclk.hw.vco != vco) + icl_cdclk_pll_disable(i915); + + if (i915->display.cdclk.hw.vco != vco) + icl_cdclk_pll_enable(i915, vco); +} + +static void bxt_cdclk_pll(struct drm_i915_private *i915, int vco) +{ + if (i915->display.cdclk.hw.vco != 0 && + i915->display.cdclk.hw.vco != vco) + bxt_de_pll_disable(i915); + + if (i915->display.cdclk.hw.vco != vco) + bxt_de_pll_enable(i915, vco); + +} + static void bxt_set_cdclk(struct drm_i915_private *dev_priv, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) @@ -1719,21 +1740,10 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0) { if (dev_priv->display.cdclk.hw.vco != vco) adlp_cdclk_pll_crawl(dev_priv, vco); - } else if (DISPLAY_VER(dev_priv) >= 11) { - if (dev_priv->display.cdclk.hw.vco != 0 && - dev_priv->display.cdclk.hw.vco != vco) - icl_cdclk_pll_disable(dev_priv); - - if (dev_priv->display.cdclk.hw.vco != vco) - icl_cdclk_pll_enable(dev_priv, vco); - } else { - if (dev_priv->display.cdclk.hw.vco != 0 && - dev_priv->display.cdclk.hw.vco != vco) - bxt_de_pll_disable(dev_priv); - - if (dev_priv->display.cdclk.hw.vco != vco) - bxt_de_pll_enable(dev_priv, vco); - } + } else if (DISPLAY_VER(dev_priv) >= 11) + icl_cdclk_pll(dev_priv, vco); + else + bxt_cdclk_pll(dev_priv, vco); waveform = cdclk_squash_waveform(dev_priv, cdclk); -- 2.25.1
[Intel-gfx] [PATCH 1/4] drm/i915/display: Change terminology for cdclk actions
No functional changes. Changing terminolgy in some print statements. s/has_cdclk_squasher/has_cdclk_squash, s/crawler/crawl and s/squasher/squash. Cc: Balasubramani Vivekanandan Cc: Ville Syrjälä Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index ad401357ab66..0f5add2fc51b 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1220,7 +1220,7 @@ static void skl_cdclk_uninit_hw(struct drm_i915_private *dev_priv) skl_set_cdclk(dev_priv, _config, INVALID_PIPE); } -static bool has_cdclk_squasher(struct drm_i915_private *i915) +static bool has_cdclk_squash(struct drm_i915_private *i915) { return IS_DG2(i915); } @@ -1520,7 +1520,7 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv, return; } - if (has_cdclk_squasher(dev_priv)) + if (has_cdclk_squash(dev_priv)) squash_ctl = intel_de_read(dev_priv, CDCLK_SQUASH_CTL); if (squash_ctl & CDCLK_SQUASH_ENABLE) { @@ -1747,7 +1747,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, else clock = cdclk; - if (has_cdclk_squasher(dev_priv)) { + if (has_cdclk_squash(dev_priv)) { u32 squash_ctl = 0; if (waveform) @@ -1845,7 +1845,7 @@ static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv) expected = skl_cdclk_decimal(cdclk); /* Figure out what CD2X divider we should be using for this cdclk */ - if (has_cdclk_squasher(dev_priv)) + if (has_cdclk_squash(dev_priv)) clock = dev_priv->display.cdclk.hw.vco / 2; else clock = dev_priv->display.cdclk.hw.cdclk; @@ -1976,7 +1976,7 @@ static bool intel_cdclk_can_squash(struct drm_i915_private *dev_priv, * the moment all platforms with squasher use a fixed cd2x * divider. */ - if (!has_cdclk_squasher(dev_priv)) + if (!has_cdclk_squash(dev_priv)) return false; return a->cdclk != b->cdclk && @@ -2028,7 +2028,7 @@ static bool intel_cdclk_can_cd2x_update(struct drm_i915_private *dev_priv, * the moment all platforms with squasher use a fixed cd2x * divider. */ - if (has_cdclk_squasher(dev_priv)) + if (has_cdclk_squash(dev_priv)) return false; return a->cdclk != b->cdclk && @@ -2754,12 +2754,12 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state) _cdclk_state->actual, _cdclk_state->actual)) { drm_dbg_kms(_priv->drm, - "Can change cdclk via squasher\n"); + "Can change cdclk via squashing\n"); } else if (intel_cdclk_can_crawl(dev_priv, _cdclk_state->actual, _cdclk_state->actual)) { drm_dbg_kms(_priv->drm, - "Can change cdclk via crawl\n"); + "Can change cdclk via crawling\n"); } else if (pipe != INVALID_PIPE) { new_cdclk_state->pipe = pipe; -- 2.25.1
[Intel-gfx] [PATCH 1/2] drm/i915/display: Do both crawl and squash when changing cdclk
From: Ville Syrjälä For MTL, changing cdclk from between certain frequencies has both squash and crawl. Use the current cdclk config and the new(desired) cdclk config to construtc a mid cdclk config. Set the cdclk twice: - Current cdclk -> mid cdclk - mid cdclk -> desired cdclk v2: Add check in intel_modeset_calc_cdclk() to avoid cdclk change via modeset for platforms that support squash_crawl sequences(Ville) v3: Add checks for: - scenario where only slow clock is used and cdclk is actually 0 (bringing up display). - PLLs are on before looking up the waveform. - Squash and crawl capability checks.(Ville) Signed-off-by: Anusha Srivatsa Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/display/intel_cdclk.c | 157 + 1 file changed, 128 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index ad401357ab66..430b4cb0a8ab 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1675,7 +1675,7 @@ static u32 cdclk_squash_waveform(struct drm_i915_private *dev_priv, const struct intel_cdclk_vals *table = dev_priv->display.cdclk.table; int i; - if (cdclk == dev_priv->display.cdclk.hw.bypass) + if (cdclk == dev_priv->display.cdclk.hw.bypass || cdclk == 0) return 0; for (i = 0; table[i].refclk; i++) @@ -1689,37 +1689,72 @@ static u32 cdclk_squash_waveform(struct drm_i915_private *dev_priv, return 0x; } -static void bxt_set_cdclk(struct drm_i915_private *dev_priv, - const struct intel_cdclk_config *cdclk_config, - enum pipe pipe) +static int cdclk_squash_divider(u16 waveform) +{ + return hweight16(waveform ?: 0x); +} + +static bool cdclk_crawl_and_squash(struct drm_i915_private *i915, + const struct intel_cdclk_config *old_cdclk_config, + const struct intel_cdclk_config *new_cdclk_config, + struct intel_cdclk_config *mid_cdclk_config) +{ + u16 old_waveform = cdclk_squash_waveform(i915, old_cdclk_config->cdclk); + u16 new_waveform = cdclk_squash_waveform(i915, new_cdclk_config->cdclk); + u16 mid_waveform; + int size = 16; + int div = 2; + + /* Return if both Squash and Crawl are not present */ + if (!HAS_CDCLK_CRAWL(i915) || !has_cdclk_squasher(i915)) + return false; + + /* Return if Squash only or Crawl only is the desired action */ + if (old_cdclk_config->vco <= 0 || new_cdclk_config->vco <= 0 || + old_cdclk_config->vco == new_cdclk_config->vco || + old_waveform == new_waveform) + return false; + + *mid_cdclk_config = *new_cdclk_config; + + /* If moving to a higher cdclk(squash) the mid cdclk config +* should have the new (squash) waveform. +* If moving to a lower cdclk (crawl) the mid cdclk config +* should have the new vco. +*/ + + if (cdclk_squash_divider(new_waveform) > cdclk_squash_divider(old_waveform)) { + mid_cdclk_config->vco = old_cdclk_config->vco; + mid_waveform = new_waveform; + } else { + mid_cdclk_config->vco = new_cdclk_config->vco; + mid_waveform = old_waveform; + } + + mid_cdclk_config->cdclk = DIV_ROUND_CLOSEST(cdclk_squash_divider(mid_waveform) * + mid_cdclk_config->vco, size * div); + + /* make sure the mid clock came out sane */ + + drm_WARN_ON(>drm, mid_cdclk_config->cdclk < + min(old_cdclk_config->cdclk, new_cdclk_config->cdclk)); + drm_WARN_ON(>drm, mid_cdclk_config->cdclk > + i915->display.cdclk.max_cdclk_freq); + drm_WARN_ON(>drm, cdclk_squash_waveform(i915, mid_cdclk_config->cdclk) != + mid_waveform); + + return true; +} + +static void _bxt_set_cdclk(struct drm_i915_private *dev_priv, + const struct intel_cdclk_config *cdclk_config, + enum pipe pipe) { int cdclk = cdclk_config->cdclk; int vco = cdclk_config->vco; u32 val; u16 waveform; int clock; - int ret; - - /* Inform power controller of upcoming frequency change. */ - if (DISPLAY_VER(dev_priv) >= 11) - ret = skl_pcode_request(_priv->uncore, SKL_PCODE_CDCLK_CONTROL, - SKL_CDCLK_PREPARE_FOR_CHANGE, - SKL_CDCLK_READY_FOR_CHANGE, - SKL_CDCLK_READY_FOR_CHANGE, 3); - else - /* -* BSpec requires us to wa
[Intel-gfx] [PATCH 2/2] drm/i915/display: Add CDCLK Support for MTL
As per bSpec MTL has 38.4 MHz Reference clock. MTL does support squasher like DG2 but only for lower frequencies. Change the has_cdclk_squasher() helper to reflect this. v2: Revert to using bxt_get_cdclk() BSpec: 65243 Cc: Radhakrishna Sripada Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 24 -- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 430b4cb0a8ab..f44cffeb1f94 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1222,7 +1222,7 @@ static void skl_cdclk_uninit_hw(struct drm_i915_private *dev_priv) static bool has_cdclk_squasher(struct drm_i915_private *i915) { - return IS_DG2(i915); + return DISPLAY_VER(i915) >= 14 || IS_DG2(i915); } struct intel_cdclk_vals { @@ -1350,6 +1350,16 @@ static const struct intel_cdclk_vals dg2_cdclk_table[] = { {} }; +static const struct intel_cdclk_vals mtl_cdclk_table[] = { + { .refclk = 38400, .cdclk = 172800, .divider = 2, .ratio = 16, .waveform = 0xad5a }, + { .refclk = 38400, .cdclk = 192000, .divider = 2, .ratio = 16, .waveform = 0xb6b6 }, + { .refclk = 38400, .cdclk = 307200, .divider = 2, .ratio = 16, .waveform = 0x }, + { .refclk = 38400, .cdclk = 48, .divider = 2, .ratio = 25, .waveform = 0x }, + { .refclk = 38400, .cdclk = 556800, .divider = 2, .ratio = 29, .waveform = 0x }, + { .refclk = 38400, .cdclk = 652800, .divider = 2, .ratio = 34, .waveform = 0x }, + {} +}; + static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk) { const struct intel_cdclk_vals *table = dev_priv->display.cdclk.table; @@ -3149,6 +3159,13 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv) return freq; } +static const struct intel_cdclk_funcs mtl_cdclk_funcs = { + .get_cdclk = bxt_get_cdclk, + .set_cdclk = bxt_set_cdclk, + .modeset_calc_cdclk = bxt_modeset_calc_cdclk, + .calc_voltage_level = tgl_calc_voltage_level, +}; + static const struct intel_cdclk_funcs tgl_cdclk_funcs = { .get_cdclk = bxt_get_cdclk, .set_cdclk = bxt_set_cdclk, @@ -3284,7 +3301,10 @@ static const struct intel_cdclk_funcs i830_cdclk_funcs = { */ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv) { - if (IS_DG2(dev_priv)) { + if (IS_METEORLAKE(dev_priv)) { + dev_priv->display.funcs.cdclk = _cdclk_funcs; + dev_priv->display.cdclk.table = mtl_cdclk_table; + } else if (IS_DG2(dev_priv)) { dev_priv->display.funcs.cdclk = _cdclk_funcs; dev_priv->display.cdclk.table = dg2_cdclk_table; } else if (IS_ALDERLAKE_P(dev_priv)) { -- 2.25.1
[Intel-gfx] [PATCH] drm/i915/display: Add DC5 counter and DMC debugfs entries for MTL
MTL and dgfx use the same DC5 counter. While at it, this patch also adds the corresponding debugfs entries. Some cleanup wrt dc3co register which makes the code more readable. Driver loads all firmware that it finds in the firmware binary but platform doesn't *need* all of them. Cleaning the previous debugs entries to reflect which firmware is needed and if the needed firmware is loaded or not. MTL needs both Pipe A and Pipe B DMC to be loaded along with Main DMC. BSpec: 49788 Cc: Lucas De Marchi Cc: Radhakrishna Sripada Signed-off-by: Anusha Srivatsa Reviewed-by: Lucas De Marchi --- drivers/gpu/drm/i915/display/intel_dmc.c | 22 ++ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index e52ecc0738a6..081a4d0083b1 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -1065,12 +1065,13 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused) seq_printf(m, "fw loaded: %s\n", str_yes_no(intel_dmc_has_payload(i915))); seq_printf(m, "path: %s\n", dmc->fw_path); - seq_printf(m, "Pipe A fw support: %s\n", + seq_printf(m, "Pipe A fw needed: %s\n", str_yes_no(GRAPHICS_VER(i915) >= 12)); seq_printf(m, "Pipe A fw loaded: %s\n", str_yes_no(dmc->dmc_info[DMC_FW_PIPEA].payload)); - seq_printf(m, "Pipe B fw support: %s\n", - str_yes_no(IS_ALDERLAKE_P(i915))); + seq_printf(m, "Pipe B fw needed: %s\n", + str_yes_no(IS_ALDERLAKE_P(i915) || + DISPLAY_VER(i915) >= 14)); seq_printf(m, "Pipe B fw loaded: %s\n", str_yes_no(dmc->dmc_info[DMC_FW_PIPEB].payload)); @@ -1081,22 +1082,19 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused) DMC_VERSION_MINOR(dmc->version)); if (DISPLAY_VER(i915) >= 12) { - if (IS_DGFX(i915)) { + i915_reg_t dc3co_reg; + + if (IS_DGFX(i915) || DISPLAY_VER(i915) >= 14) { + dc3co_reg = DG1_DMC_DEBUG3; dc5_reg = DG1_DMC_DEBUG_DC5_COUNT; } else { + dc3co_reg = TGL_DMC_DEBUG3; dc5_reg = TGL_DMC_DEBUG_DC5_COUNT; dc6_reg = TGL_DMC_DEBUG_DC6_COUNT; } - /* -* NOTE: DMC_DEBUG3 is a general purpose reg. -* According to B.Specs:49196 DMC f/w reuses DC5/6 counter -* reg for DC3CO debugging and validation, -* but TGL DMC f/w is using DMC_DEBUG3 reg for DC3CO counter. -*/ seq_printf(m, "DC3CO count: %d\n", - intel_de_read(i915, IS_DGFX(i915) ? -DG1_DMC_DEBUG3 : TGL_DMC_DEBUG3)); + intel_de_read(i915, dc3co_reg)); } else { dc5_reg = IS_BROXTON(i915) ? BXT_DMC_DC3_DC5_COUNT : SKL_DMC_DC3_DC5_COUNT; -- 2.25.1
[Intel-gfx] [PATCH] drm/i915/display: Add DC5 counter and DMC debugfs entries for MTL
MTL and dgfx use the same DC5 counter. While at it, this patch also adds the corresponding debugfs entries. Some cleanup wrt dc3co register which makes the code more readable. Driver loads all firmware that it finds in the firmware binary but platform doesn't *need* all of them. Cleaning the previous debugs entries to reflect which firmware is needed and if the needed firmware is loaded or not. MTL needs both Pipe A and Pipe B DMC to be loaded along with Main DMC. BSpec: 49788 Cc: Lucas De Marchi Cc: Radhakrishna Sripada Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_dmc.c | 22 ++ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index e52ecc0738a6..081a4d0083b1 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -1065,12 +1065,13 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused) seq_printf(m, "fw loaded: %s\n", str_yes_no(intel_dmc_has_payload(i915))); seq_printf(m, "path: %s\n", dmc->fw_path); - seq_printf(m, "Pipe A fw support: %s\n", + seq_printf(m, "Pipe A fw needed: %s\n", str_yes_no(GRAPHICS_VER(i915) >= 12)); seq_printf(m, "Pipe A fw loaded: %s\n", str_yes_no(dmc->dmc_info[DMC_FW_PIPEA].payload)); - seq_printf(m, "Pipe B fw support: %s\n", - str_yes_no(IS_ALDERLAKE_P(i915))); + seq_printf(m, "Pipe B fw needed: %s\n", + str_yes_no(IS_ALDERLAKE_P(i915) || + DISPLAY_VER(i915) >= 14)); seq_printf(m, "Pipe B fw loaded: %s\n", str_yes_no(dmc->dmc_info[DMC_FW_PIPEB].payload)); @@ -1081,22 +1082,19 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused) DMC_VERSION_MINOR(dmc->version)); if (DISPLAY_VER(i915) >= 12) { - if (IS_DGFX(i915)) { + i915_reg_t dc3co_reg; + + if (IS_DGFX(i915) || DISPLAY_VER(i915) >= 14) { + dc3co_reg = DG1_DMC_DEBUG3; dc5_reg = DG1_DMC_DEBUG_DC5_COUNT; } else { + dc3co_reg = TGL_DMC_DEBUG3; dc5_reg = TGL_DMC_DEBUG_DC5_COUNT; dc6_reg = TGL_DMC_DEBUG_DC6_COUNT; } - /* -* NOTE: DMC_DEBUG3 is a general purpose reg. -* According to B.Specs:49196 DMC f/w reuses DC5/6 counter -* reg for DC3CO debugging and validation, -* but TGL DMC f/w is using DMC_DEBUG3 reg for DC3CO counter. -*/ seq_printf(m, "DC3CO count: %d\n", - intel_de_read(i915, IS_DGFX(i915) ? -DG1_DMC_DEBUG3 : TGL_DMC_DEBUG3)); + intel_de_read(i915, dc3co_reg)); } else { dc5_reg = IS_BROXTON(i915) ? BXT_DMC_DC3_DC5_COUNT : SKL_DMC_DC3_DC5_COUNT; -- 2.25.1
[Intel-gfx] [PATCH 1/2] drm/i915/display: Do both crawl and squash when changing cdclk
From: Ville Syrjälä For MTL, changing cdclk from between certain frequencies has both squash and crawl. Use the current cdclk config and the new(desired) cdclk config to construtc a mid cdclk config. Set the cdclk twice: - Current cdclk -> mid cdclk - mid cdclk -> desired cdclk v2: Add check in intel_modeset_calc_cdclk() to avoid cdclk change via modeset for platforms that support squash_crawl sequences(Ville) Signed-off-by: Anusha Srivatsa Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/display/intel_cdclk.c | 144 + 1 file changed, 116 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index a12e86d92783..f7bc1013b149 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1689,37 +1689,68 @@ static u32 cdclk_squash_waveform(struct drm_i915_private *dev_priv, return 0x; } -static void bxt_set_cdclk(struct drm_i915_private *dev_priv, - const struct intel_cdclk_config *cdclk_config, - enum pipe pipe) +static int cdclk_squash_divider(u16 waveform) +{ + return hweight16(waveform ?: 0x); +} + +static bool cdclk_crawl_and_squash(struct drm_i915_private *i915, + const struct intel_cdclk_config *old_cdclk_config, + const struct intel_cdclk_config *new_cdclk_config, + struct intel_cdclk_config *mid_cdclk_config) +{ + u16 old_waveform = cdclk_squash_waveform(i915, old_cdclk_config->cdclk); + u16 new_waveform = cdclk_squash_waveform(i915, new_cdclk_config->cdclk); + u16 mid_waveform; + int size = 16; + int div = 2; + + /* Return if Squash only or Crawl only is the desired action */ + if (old_cdclk_config->vco <= 0 || new_cdclk_config->vco <= 0 || + old_cdclk_config->vco == new_cdclk_config->vco || + old_waveform == new_waveform) + return false; + + *mid_cdclk_config = *new_cdclk_config; + + /* If moving to a higher cdclk(squash) the mid cdclk config +* should have the new (squash) waveform. +* If moving to a lower cdclk (crawl) the mid cdclk config +* should have the new vco. +*/ + + if (cdclk_squash_divider(new_waveform) > cdclk_squash_divider(old_waveform)) { + mid_cdclk_config->vco = old_cdclk_config->vco; + mid_waveform = new_waveform; + } else { + mid_cdclk_config->vco = new_cdclk_config->vco; + mid_waveform = old_waveform; + } + + mid_cdclk_config->cdclk = DIV_ROUND_CLOSEST(cdclk_squash_divider(mid_waveform) * + mid_cdclk_config->vco, size * div); + + /* make sure the mid clock came out sane */ + + drm_WARN_ON(>drm, mid_cdclk_config->cdclk < + min(old_cdclk_config->cdclk, new_cdclk_config->cdclk)); + drm_WARN_ON(>drm, mid_cdclk_config->cdclk > + i915->display.cdclk.max_cdclk_freq); + drm_WARN_ON(>drm, cdclk_squash_waveform(i915, mid_cdclk_config->cdclk) != + mid_waveform); + + return true; +} + +static void _bxt_set_cdclk(struct drm_i915_private *dev_priv, + const struct intel_cdclk_config *cdclk_config, + enum pipe pipe) { int cdclk = cdclk_config->cdclk; int vco = cdclk_config->vco; u32 val; u16 waveform; int clock; - int ret; - - /* Inform power controller of upcoming frequency change. */ - if (DISPLAY_VER(dev_priv) >= 11) - ret = skl_pcode_request(_priv->uncore, SKL_PCODE_CDCLK_CONTROL, - SKL_CDCLK_PREPARE_FOR_CHANGE, - SKL_CDCLK_READY_FOR_CHANGE, - SKL_CDCLK_READY_FOR_CHANGE, 3); - else - /* -* BSpec requires us to wait up to 150usec, but that leads to -* timeouts; the 2ms used here is based on experiment. -*/ - ret = snb_pcode_write_timeout(_priv->uncore, - HSW_PCODE_DE_WRITE_FREQ_REQ, - 0x8000, 150, 2); - if (ret) { - drm_err(_priv->drm, - "Failed to inform PCU about cdclk change (err %d, freq %d)\n", - ret, cdclk); - return; - } if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0) { if (dev_priv->display.cdclk.hw.vco != vco) @@ -1772,6 +1803,44 @@ stati
[Intel-gfx] [PATCH 2/2] drm/i915/display: Add CDCLK Support for MTL
As per bSpec MTL has 38.4 MHz Reference clock. MTL does support squasher like DG2 but only for lower frequencies. Change the has_cdclk_squasher() helper to reflect this. v2: Revert to using bxt_get_cdclk() BSpec: 65243 Cc: Radhakrishna Sripada Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 25 -- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index f7bc1013b149..b467aade750a 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1222,7 +1222,7 @@ static void skl_cdclk_uninit_hw(struct drm_i915_private *dev_priv) static bool has_cdclk_squasher(struct drm_i915_private *i915) { - return IS_DG2(i915); + return DISPLAY_VER(i915) >= 14 || IS_DG2(i915); } struct intel_cdclk_vals { @@ -1350,6 +1350,16 @@ static const struct intel_cdclk_vals dg2_cdclk_table[] = { {} }; +static const struct intel_cdclk_vals mtl_cdclk_table[] = { + { .refclk = 38400, .cdclk = 172800, .divider = 2, .ratio = 16, .waveform = 0xad5a }, + { .refclk = 38400, .cdclk = 192000, .divider = 2, .ratio = 16, .waveform = 0xb6b6 }, + { .refclk = 38400, .cdclk = 307200, .divider = 2, .ratio = 16, .waveform = 0x }, + { .refclk = 38400, .cdclk = 48, .divider = 2, .ratio = 25, .waveform = 0x }, + { .refclk = 38400, .cdclk = 556800, .divider = 2, .ratio = 29, .waveform = 0x }, + { .refclk = 38400, .cdclk = 652800, .divider = 2, .ratio = 34, .waveform = 0x }, + {} +}; + static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk) { const struct intel_cdclk_vals *table = dev_priv->display.cdclk.table; @@ -3138,6 +3148,13 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv) return freq; } +static const struct intel_cdclk_funcs mtl_cdclk_funcs = { + .get_cdclk = bxt_get_cdclk, + .set_cdclk = bxt_set_cdclk, + .modeset_calc_cdclk = bxt_modeset_calc_cdclk, + .calc_voltage_level = tgl_calc_voltage_level, +}; + static const struct intel_cdclk_funcs tgl_cdclk_funcs = { .get_cdclk = bxt_get_cdclk, .set_cdclk = bxt_set_cdclk, @@ -3273,7 +3290,11 @@ static const struct intel_cdclk_funcs i830_cdclk_funcs = { */ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv) { - if (IS_DG2(dev_priv)) { + + if (IS_METEORLAKE(dev_priv)) { + dev_priv->display.funcs.cdclk = _cdclk_funcs; + dev_priv->display.cdclk.table = mtl_cdclk_table; + } else if (IS_DG2(dev_priv)) { dev_priv->display.funcs.cdclk = _cdclk_funcs; dev_priv->display.cdclk.table = dg2_cdclk_table; } else if (IS_ALDERLAKE_P(dev_priv)) { -- 2.25.1
[Intel-gfx] [PATCH 2/2] drm/i915/display: Add CDCLK Support for MTL
As per bSpec MTL has 38.4 MHz Reference clock. MTL does support squasher like DG2 but only for lower frequencies. Change the has_cdclk_squasher() helper to reflect this. bxt_get_cdclk() is not properly calculating HW clock for MTL, because the squash formula is only prepared for DG2. Apart from adding the cdclk table, align cdclk support with the new cdclk_crawl_and_squash() introduced in previous patch. BSpec: 65243 Cc: Radhakrishna Sripada Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 95 +- 1 file changed, 93 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index f7bc1013b149..6271eed0d7cf 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1222,7 +1222,7 @@ static void skl_cdclk_uninit_hw(struct drm_i915_private *dev_priv) static bool has_cdclk_squasher(struct drm_i915_private *i915) { - return IS_DG2(i915); + return DISPLAY_VER(i915) >= 14 || IS_DG2(i915); } struct intel_cdclk_vals { @@ -1350,6 +1350,16 @@ static const struct intel_cdclk_vals dg2_cdclk_table[] = { {} }; +static const struct intel_cdclk_vals mtl_cdclk_table[] = { + { .refclk = 38400, .cdclk = 172800, .divider = 2, .ratio = 16, .waveform = 0xad5a }, + { .refclk = 38400, .cdclk = 192000, .divider = 2, .ratio = 16, .waveform = 0xb6b6 }, + { .refclk = 38400, .cdclk = 307200, .divider = 2, .ratio = 16, .waveform = 0x }, + { .refclk = 38400, .cdclk = 48, .divider = 2, .ratio = 25, .waveform = 0x }, + { .refclk = 38400, .cdclk = 556800, .divider = 2, .ratio = 29, .waveform = 0x }, + { .refclk = 38400, .cdclk = 652800, .divider = 2, .ratio = 34, .waveform = 0x }, + {} +}; + static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk) { const struct intel_cdclk_vals *table = dev_priv->display.cdclk.table; @@ -1479,6 +1489,76 @@ static void bxt_de_pll_readout(struct drm_i915_private *dev_priv, cdclk_config->vco = ratio * cdclk_config->ref; } +static void mtl_get_cdclk(struct drm_i915_private *i915, + struct intel_cdclk_config *cdclk_config) +{ + const struct intel_cdclk_vals *table = i915->display.cdclk.table; + u32 squash_ctl, divider, waveform; + int div, i, ratio; + + bxt_de_pll_readout(i915, cdclk_config); + + cdclk_config->bypass = cdclk_config->ref / 2; + + if (cdclk_config->vco == 0) { + cdclk_config->cdclk = cdclk_config->bypass; + goto out; + } + + divider = intel_de_read(i915, CDCLK_CTL) & BXT_CDCLK_CD2X_DIV_SEL_MASK; + switch (divider) { + case BXT_CDCLK_CD2X_DIV_SEL_1: + div = 2; + break; + case BXT_CDCLK_CD2X_DIV_SEL_1_5: + div = 3; + break; + case BXT_CDCLK_CD2X_DIV_SEL_2: + div = 4; + break; + case BXT_CDCLK_CD2X_DIV_SEL_4: + div = 8; + break; + default: + MISSING_CASE(divider); + return; + } + + squash_ctl = intel_de_read(i915, CDCLK_SQUASH_CTL); + if (squash_ctl & CDCLK_SQUASH_ENABLE) + waveform = squash_ctl & CDCLK_SQUASH_WAVEFORM_MASK; + else + waveform = 0; + + ratio = cdclk_config->vco / cdclk_config->ref; + + for (i = 0, cdclk_config->cdclk = 0; table[i].refclk; i++) { + if (table[i].refclk != cdclk_config->ref) + continue; + + if (table[i].divider != div) + continue; + + if (table[i].waveform != waveform) + continue; + + if (table[i].ratio != ratio) + continue; + + cdclk_config->cdclk = table[i].cdclk; + break; + } + +out: + /* +* Can't read this out :( Let's assume it's +* at least what the CDCLK frequency requires. +*/ + cdclk_config->voltage_level = + intel_cdclk_calc_voltage_level(i915, cdclk_config->cdclk); +} + + static void bxt_get_cdclk(struct drm_i915_private *dev_priv, struct intel_cdclk_config *cdclk_config) { @@ -3138,6 +3218,13 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv) return freq; } +static const struct intel_cdclk_funcs mtl_cdclk_funcs = { + .get_cdclk = mtl_get_cdclk, + .set_cdclk = bxt_set_cdclk, + .modeset_calc_cdclk = bxt_modeset_calc_cdclk, + .calc_voltage_level = tgl_calc_voltage_level, +}; + static const struct intel_cdclk_funcs tgl_cdclk_funcs = { .get_cdclk = bxt_get_cdclk, .set_cdclk = bxt_set_cdclk, @@ -3273,7 +3360,11 @@ static
[Intel-gfx] [PATCH 1/2] drm/i915/display: Do both crawl and squash when changing cdclk
From: Ville Syrjälä For MTL, changing cdclk from between certain frequencies has both squash and crawl. Use the current cdclk config and the new(desired) cdclk config to construtc a mid cdclk config. Set the cdclk twice: - Current cdclk -> mid cdclk - mid cdclk -> desired cdclk v2: Add check in intel_modeset_calc_cdclk() to avoid cdclk change via modeset for platforms that support squash_crawl sequences(Ville) Signed-off-by: Anusha Srivatsa Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/display/intel_cdclk.c | 144 + 1 file changed, 116 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index a12e86d92783..f7bc1013b149 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1689,37 +1689,68 @@ static u32 cdclk_squash_waveform(struct drm_i915_private *dev_priv, return 0x; } -static void bxt_set_cdclk(struct drm_i915_private *dev_priv, - const struct intel_cdclk_config *cdclk_config, - enum pipe pipe) +static int cdclk_squash_divider(u16 waveform) +{ + return hweight16(waveform ?: 0x); +} + +static bool cdclk_crawl_and_squash(struct drm_i915_private *i915, + const struct intel_cdclk_config *old_cdclk_config, + const struct intel_cdclk_config *new_cdclk_config, + struct intel_cdclk_config *mid_cdclk_config) +{ + u16 old_waveform = cdclk_squash_waveform(i915, old_cdclk_config->cdclk); + u16 new_waveform = cdclk_squash_waveform(i915, new_cdclk_config->cdclk); + u16 mid_waveform; + int size = 16; + int div = 2; + + /* Return if Squash only or Crawl only is the desired action */ + if (old_cdclk_config->vco <= 0 || new_cdclk_config->vco <= 0 || + old_cdclk_config->vco == new_cdclk_config->vco || + old_waveform == new_waveform) + return false; + + *mid_cdclk_config = *new_cdclk_config; + + /* If moving to a higher cdclk(squash) the mid cdclk config +* should have the new (squash) waveform. +* If moving to a lower cdclk (crawl) the mid cdclk config +* should have the new vco. +*/ + + if (cdclk_squash_divider(new_waveform) > cdclk_squash_divider(old_waveform)) { + mid_cdclk_config->vco = old_cdclk_config->vco; + mid_waveform = new_waveform; + } else { + mid_cdclk_config->vco = new_cdclk_config->vco; + mid_waveform = old_waveform; + } + + mid_cdclk_config->cdclk = DIV_ROUND_CLOSEST(cdclk_squash_divider(mid_waveform) * + mid_cdclk_config->vco, size * div); + + /* make sure the mid clock came out sane */ + + drm_WARN_ON(>drm, mid_cdclk_config->cdclk < + min(old_cdclk_config->cdclk, new_cdclk_config->cdclk)); + drm_WARN_ON(>drm, mid_cdclk_config->cdclk > + i915->display.cdclk.max_cdclk_freq); + drm_WARN_ON(>drm, cdclk_squash_waveform(i915, mid_cdclk_config->cdclk) != + mid_waveform); + + return true; +} + +static void _bxt_set_cdclk(struct drm_i915_private *dev_priv, + const struct intel_cdclk_config *cdclk_config, + enum pipe pipe) { int cdclk = cdclk_config->cdclk; int vco = cdclk_config->vco; u32 val; u16 waveform; int clock; - int ret; - - /* Inform power controller of upcoming frequency change. */ - if (DISPLAY_VER(dev_priv) >= 11) - ret = skl_pcode_request(_priv->uncore, SKL_PCODE_CDCLK_CONTROL, - SKL_CDCLK_PREPARE_FOR_CHANGE, - SKL_CDCLK_READY_FOR_CHANGE, - SKL_CDCLK_READY_FOR_CHANGE, 3); - else - /* -* BSpec requires us to wait up to 150usec, but that leads to -* timeouts; the 2ms used here is based on experiment. -*/ - ret = snb_pcode_write_timeout(_priv->uncore, - HSW_PCODE_DE_WRITE_FREQ_REQ, - 0x8000, 150, 2); - if (ret) { - drm_err(_priv->drm, - "Failed to inform PCU about cdclk change (err %d, freq %d)\n", - ret, cdclk); - return; - } if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0) { if (dev_priv->display.cdclk.hw.vco != vco) @@ -1772,6 +1803,44 @@ stati
[Intel-gfx] [PATCH] drm/i915/display: Do both crawl and squash when changing cdclk
From: Ville Syrjälä For MTL, changing cdclk from between certain frequencies has both squash and crawl. Use the current cdclk config and the new(desired) cdclk config to construtc a mid cdclk config. Set the cdclk twice: - Current cdclk -> mid cdclk - mid cdclk -> desired cdclk v2: Add check in intel_modeset_calc_cdclk() to avoid cdclk change via modeset for platforms that support squash_crawl sequences(Ville) Signed-off-by: Anusha Srivatsa Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/display/intel_cdclk.c | 144 + 1 file changed, 116 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index a12e86d92783..f7bc1013b149 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1689,37 +1689,68 @@ static u32 cdclk_squash_waveform(struct drm_i915_private *dev_priv, return 0x; } -static void bxt_set_cdclk(struct drm_i915_private *dev_priv, - const struct intel_cdclk_config *cdclk_config, - enum pipe pipe) +static int cdclk_squash_divider(u16 waveform) +{ + return hweight16(waveform ?: 0x); +} + +static bool cdclk_crawl_and_squash(struct drm_i915_private *i915, + const struct intel_cdclk_config *old_cdclk_config, + const struct intel_cdclk_config *new_cdclk_config, + struct intel_cdclk_config *mid_cdclk_config) +{ + u16 old_waveform = cdclk_squash_waveform(i915, old_cdclk_config->cdclk); + u16 new_waveform = cdclk_squash_waveform(i915, new_cdclk_config->cdclk); + u16 mid_waveform; + int size = 16; + int div = 2; + + /* Return if Squash only or Crawl only is the desired action */ + if (old_cdclk_config->vco <= 0 || new_cdclk_config->vco <= 0 || + old_cdclk_config->vco == new_cdclk_config->vco || + old_waveform == new_waveform) + return false; + + *mid_cdclk_config = *new_cdclk_config; + + /* If moving to a higher cdclk(squash) the mid cdclk config +* should have the new (squash) waveform. +* If moving to a lower cdclk (crawl) the mid cdclk config +* should have the new vco. +*/ + + if (cdclk_squash_divider(new_waveform) > cdclk_squash_divider(old_waveform)) { + mid_cdclk_config->vco = old_cdclk_config->vco; + mid_waveform = new_waveform; + } else { + mid_cdclk_config->vco = new_cdclk_config->vco; + mid_waveform = old_waveform; + } + + mid_cdclk_config->cdclk = DIV_ROUND_CLOSEST(cdclk_squash_divider(mid_waveform) * + mid_cdclk_config->vco, size * div); + + /* make sure the mid clock came out sane */ + + drm_WARN_ON(>drm, mid_cdclk_config->cdclk < + min(old_cdclk_config->cdclk, new_cdclk_config->cdclk)); + drm_WARN_ON(>drm, mid_cdclk_config->cdclk > + i915->display.cdclk.max_cdclk_freq); + drm_WARN_ON(>drm, cdclk_squash_waveform(i915, mid_cdclk_config->cdclk) != + mid_waveform); + + return true; +} + +static void _bxt_set_cdclk(struct drm_i915_private *dev_priv, + const struct intel_cdclk_config *cdclk_config, + enum pipe pipe) { int cdclk = cdclk_config->cdclk; int vco = cdclk_config->vco; u32 val; u16 waveform; int clock; - int ret; - - /* Inform power controller of upcoming frequency change. */ - if (DISPLAY_VER(dev_priv) >= 11) - ret = skl_pcode_request(_priv->uncore, SKL_PCODE_CDCLK_CONTROL, - SKL_CDCLK_PREPARE_FOR_CHANGE, - SKL_CDCLK_READY_FOR_CHANGE, - SKL_CDCLK_READY_FOR_CHANGE, 3); - else - /* -* BSpec requires us to wait up to 150usec, but that leads to -* timeouts; the 2ms used here is based on experiment. -*/ - ret = snb_pcode_write_timeout(_priv->uncore, - HSW_PCODE_DE_WRITE_FREQ_REQ, - 0x8000, 150, 2); - if (ret) { - drm_err(_priv->drm, - "Failed to inform PCU about cdclk change (err %d, freq %d)\n", - ret, cdclk); - return; - } if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0) { if (dev_priv->display.cdclk.hw.vco != vco) @@ -1772,6 +1803,44 @@ stati
[Intel-gfx] [PATCH] drm/i915/display: Do both crawl and squash when changing cdclk
From: Ville Syrjälä For MTL, changing cdclk from between certain frequencies has both squash and crawl. Use the current cdclk config and the new(desired) cdclk config to construct a mid cdclk config. Set the cdclk twice: - Current cdclk -> mid cdclk - mid cdclk -> desired cdclk Signed-off-by: Anusha Srivatsa Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/display/intel_cdclk.c | 121 - 1 file changed, 96 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index a12e86d92783..e7faded38e66 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1689,37 +1689,70 @@ static u32 cdclk_squash_waveform(struct drm_i915_private *dev_priv, return 0x; } -static void bxt_set_cdclk(struct drm_i915_private *dev_priv, - const struct intel_cdclk_config *cdclk_config, - enum pipe pipe) +static int cdclk_squash_divider(u16 waveform) +{ + return hweight16(waveform ?: 0x); +} + +static bool cdclk_crawl_and_squash(struct drm_i915_private *i915, + const struct intel_cdclk_config *old_cdclk_config, + const struct intel_cdclk_config *new_cdclk_config, + struct intel_cdclk_config *mid_cdclk_config) +{ + u16 old_waveform = cdclk_squash_waveform(i915, old_cdclk_config->cdclk); + u16 new_waveform = cdclk_squash_waveform(i915, new_cdclk_config->cdclk); + u16 mid_waveform; + int size = 16; + int div = 2; + + if (!HAS_CDCLK_CRAWL(i915) || !has_cdclk_squasher(i915)) + return false; + + /* Return if Squash only or Crawl only is the desired action */ + if (old_cdclk_config->vco <= 0 || new_cdclk_config->vco <= 0 || + old_cdclk_config->vco == new_cdclk_config->vco || + old_waveform == new_waveform) + return false; + + *mid_cdclk_config = *new_cdclk_config; + + /* If moving to a higher cdclk(squash) the mid cdclk config +* should have the new (squash) waveform. +* If moving to a lower cdclk (crawl) the mid cdclk config +* should have the new vco. +*/ + + if (cdclk_squash_divider(new_waveform) > cdclk_squash_divider(old_waveform)) { + mid_cdclk_config->vco = old_cdclk_config->vco; + mid_waveform = new_waveform; + } else { + mid_cdclk_config->vco = new_cdclk_config->vco; + mid_waveform = old_waveform; + } + + mid_cdclk_config->cdclk = DIV_ROUND_CLOSEST(cdclk_squash_divider(mid_waveform) * + mid_cdclk_config->vco, size * div); + + /* make sure the mid clock came out sane */ + drm_WARN_ON(>drm, mid_cdclk_config->cdclk < + min(old_cdclk_config->cdclk, new_cdclk_config->cdclk)); + drm_WARN_ON(>drm, mid_cdclk_config->cdclk > + i915->display.cdclk.max_cdclk_freq); + drm_WARN_ON(>drm, cdclk_squash_waveform(i915, mid_cdclk_config->cdclk) != + mid_waveform); + + return true; +} + +static void _bxt_set_cdclk(struct drm_i915_private *dev_priv, + const struct intel_cdclk_config *cdclk_config, + enum pipe pipe) { int cdclk = cdclk_config->cdclk; int vco = cdclk_config->vco; u32 val; u16 waveform; int clock; - int ret; - - /* Inform power controller of upcoming frequency change. */ - if (DISPLAY_VER(dev_priv) >= 11) - ret = skl_pcode_request(_priv->uncore, SKL_PCODE_CDCLK_CONTROL, - SKL_CDCLK_PREPARE_FOR_CHANGE, - SKL_CDCLK_READY_FOR_CHANGE, - SKL_CDCLK_READY_FOR_CHANGE, 3); - else - /* -* BSpec requires us to wait up to 150usec, but that leads to -* timeouts; the 2ms used here is based on experiment. -*/ - ret = snb_pcode_write_timeout(_priv->uncore, - HSW_PCODE_DE_WRITE_FREQ_REQ, - 0x8000, 150, 2); - if (ret) { - drm_err(_priv->drm, - "Failed to inform PCU about cdclk change (err %d, freq %d)\n", - ret, cdclk); - return; - } if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0) { if (dev_priv->display.cdclk.hw.vco != vco) @@ -1772,6 +1805,44 @@ static void bxt_set_cdclk(struct drm_i915
[Intel-gfx] [PATCH 6/6] drm/i915/display: Dump the new cdclk config values
Add a helper function to get stringify values of the desired cdclk action and dump it with rest of the cdclk config values Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 18 -- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index bc627daade3e..12f5e4d23245 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1688,6 +1688,19 @@ static u32 cdclk_squash_waveform(struct drm_i915_private *dev_priv, return 0x; } +static const char *cdclk_sequence_to_string(enum cdclk_sequence cdclk_sequence) +{ + switch (cdclk_sequence) { + case CDCLK_SQUASH_ONLY: + return "Squash only"; + case CDCLK_CRAWL_ONLY: + return "Crawl only"; + case CDCLK_LEGACY: + return "Legacy method"; + default: + return "Not a valid cdclk sequence"; + } +} static void dg2_prog_squash_ctl(struct drm_i915_private *i915, u16 waveform) { @@ -2083,10 +2096,11 @@ void intel_cdclk_dump_config(struct drm_i915_private *i915, const struct intel_cdclk_config *cdclk_config, const char *context) { - drm_dbg_kms(>drm, "%s %d kHz, VCO %d kHz, ref %d kHz, bypass %d kHz, voltage level %d\n", + drm_dbg_kms(>drm, "%s %d kHz, VCO %d kHz, ref %d kHz, bypass %d kHz, voltage level %d, %s action\n", context, cdclk_config->cdclk, cdclk_config->vco, cdclk_config->ref, cdclk_config->bypass, - cdclk_config->voltage_level); + cdclk_config->voltage_level, + cdclk_sequence_to_string(cdclk_config->steps->action)); } /** -- 2.25.1
[Intel-gfx] [PATCH 1/6] drm/i915/display Add dg2_prog_squash_ctl() helper
Modularising steps and moving them out of bxt_set_cdclk(). Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 23 +- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index ed05070b7307..220d32adbd12 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1689,6 +1689,18 @@ static u32 cdclk_squash_waveform(struct drm_i915_private *dev_priv, return 0x; } +static void dg2_prog_squash_ctl(struct drm_i915_private *i915, u16 waveform) +{ + u32 squash_ctl = 0; + + if (waveform) { + squash_ctl |= CDCLK_SQUASH_ENABLE; + squash_ctl |= CDCLK_SQUASH_WINDOW_SIZE(0xf) | waveform; + } + + intel_de_write(i915, CDCLK_SQUASH_CTL, squash_ctl); +} + static void bxt_set_cdclk(struct drm_i915_private *dev_priv, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) @@ -1747,15 +1759,8 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, else clock = cdclk; - if (has_cdclk_squasher(dev_priv)) { - u32 squash_ctl = 0; - - if (waveform) - squash_ctl = CDCLK_SQUASH_ENABLE | - CDCLK_SQUASH_WINDOW_SIZE(0xf) | waveform; - - intel_de_write(dev_priv, CDCLK_SQUASH_CTL, squash_ctl); - } + if (has_cdclk_squasher(dev_priv)) + dg2_prog_squash_ctl(dev_priv, waveform); val = bxt_cdclk_cd2x_div_sel(dev_priv, clock, vco) | bxt_cdclk_cd2x_pipe(dev_priv, pipe) | -- 2.25.1
[Intel-gfx] [PATCH 5/6] drm/i915/display: Embed the new struct steps for modeset
Populate the new struct steps for the legacy modeset case. Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 18 +- drivers/gpu/drm/i915/display/intel_cdclk.h | 2 +- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index bb5bbb1ad982..bc627daade3e 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -2015,8 +2015,16 @@ static bool intel_cdclk_can_squash(struct drm_i915_private *dev_priv, * requires all pipes to be off, false if not. */ bool intel_cdclk_needs_modeset(const struct intel_cdclk_config *a, - const struct intel_cdclk_config *b) + struct intel_cdclk_config *b) { + struct cdclk_step *cdclk_transition = b->steps; + + if (a->cdclk != b->cdclk || a->vco != b->vco || + a->ref != b->ref) { + cdclk_transition->action = CDCLK_LEGACY; + cdclk_transition->cdclk = b->cdclk; + } + return a->cdclk != b->cdclk || a->vco != b->vco || a->ref != b->ref; @@ -2065,7 +2073,7 @@ static bool intel_cdclk_can_cd2x_update(struct drm_i915_private *dev_priv, * True if the CDCLK configurations don't match, false if they do. */ static bool intel_cdclk_changed(const struct intel_cdclk_config *a, - const struct intel_cdclk_config *b) + struct intel_cdclk_config *b) { return intel_cdclk_needs_modeset(a, b) || a->voltage_level != b->voltage_level; @@ -2091,7 +2099,7 @@ void intel_cdclk_dump_config(struct drm_i915_private *i915, * if necessary. */ static void intel_set_cdclk(struct drm_i915_private *dev_priv, - const struct intel_cdclk_config *cdclk_config, + struct intel_cdclk_config *cdclk_config, enum pipe pipe) { struct intel_encoder *encoder; @@ -2163,7 +2171,7 @@ intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state) struct drm_i915_private *dev_priv = to_i915(state->base.dev); const struct intel_cdclk_state *old_cdclk_state = intel_atomic_get_old_cdclk_state(state); - const struct intel_cdclk_state *new_cdclk_state = + struct intel_cdclk_state *new_cdclk_state = intel_atomic_get_new_cdclk_state(state); enum pipe pipe = new_cdclk_state->pipe; @@ -2192,7 +2200,7 @@ intel_set_cdclk_post_plane_update(struct intel_atomic_state *state) struct drm_i915_private *dev_priv = to_i915(state->base.dev); const struct intel_cdclk_state *old_cdclk_state = intel_atomic_get_old_cdclk_state(state); - const struct intel_cdclk_state *new_cdclk_state = + struct intel_cdclk_state *new_cdclk_state = intel_atomic_get_new_cdclk_state(state); enum pipe pipe = new_cdclk_state->pipe; diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.h b/drivers/gpu/drm/i915/display/intel_cdclk.h index 3869f93e8ad2..442dd580c0c7 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.h +++ b/drivers/gpu/drm/i915/display/intel_cdclk.h @@ -75,7 +75,7 @@ void intel_update_max_cdclk(struct drm_i915_private *dev_priv); void intel_update_cdclk(struct drm_i915_private *dev_priv); u32 intel_read_rawclk(struct drm_i915_private *dev_priv); bool intel_cdclk_needs_modeset(const struct intel_cdclk_config *a, - const struct intel_cdclk_config *b); + struct intel_cdclk_config *b); void intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state); void intel_set_cdclk_post_plane_update(struct intel_atomic_state *state); void intel_cdclk_dump_config(struct drm_i915_private *i915, -- 2.25.1
[Intel-gfx] [PATCH 2/6] drm/i915/display: add cdclk action struct to cdclk_config
The struct has the action to be performed - squash, crawl or modeset and the corresponding cdclk which is the desired cdclk. This is the structure that gets populated during atomic check once it is determined what the cdclk change looks like Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.h | 14 ++ 1 file changed, 14 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.h b/drivers/gpu/drm/i915/display/intel_cdclk.h index c674879a84a5..3869f93e8ad2 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.h +++ b/drivers/gpu/drm/i915/display/intel_cdclk.h @@ -11,13 +11,27 @@ #include "intel_display.h" #include "intel_global_state.h" +#defineMAX_CDCLK_ACTIONS 1 + struct drm_i915_private; struct intel_atomic_state; struct intel_crtc_state; +enum cdclk_sequence { + CDCLK_INVALID_ACTION = -1, + + CDCLK_SQUASH_ONLY = 0, + CDCLK_CRAWL_ONLY, + CDCLK_LEGACY, +}; + struct intel_cdclk_config { unsigned int cdclk, vco, ref, bypass; u8 voltage_level; + struct cdclk_step { + enum cdclk_sequence action; + u32 cdclk; + } steps[MAX_CDCLK_ACTIONS]; }; struct intel_cdclk_state { -- 2.25.1
[Intel-gfx] [PATCH 3/6] drm/i915/display: Embed the new struct steps for squashing
Populate the new struct steps for squash case. Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 220d32adbd12..d2e81134b6f2 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1973,8 +1973,9 @@ static bool intel_cdclk_can_crawl(struct drm_i915_private *dev_priv, static bool intel_cdclk_can_squash(struct drm_i915_private *dev_priv, const struct intel_cdclk_config *a, - const struct intel_cdclk_config *b) + struct intel_cdclk_config *b) { + struct cdclk_step *cdclk_transition = b->steps; /* * FIXME should store a bit more state in intel_cdclk_config * to differentiate squasher vs. cd2x divider properly. For @@ -1984,6 +1985,12 @@ static bool intel_cdclk_can_squash(struct drm_i915_private *dev_priv, if (!has_cdclk_squasher(dev_priv)) return false; + if (a->cdclk != b->cdclk && a->vco != 0 && + a->vco == b->vco && a->ref == b->ref) { + cdclk_transition->action = CDCLK_SQUASH_ONLY; + cdclk_transition->cdclk = b->cdclk; + } + return a->cdclk != b->cdclk && a->vco != 0 && a->vco == b->vco && -- 2.25.1
[Intel-gfx] [PATCH 4/6] drm/i915/display: Embed the new struct steps for crawling
Populate the new struct steps for crawl case. Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index d2e81134b6f2..bb5bbb1ad982 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1951,8 +1951,9 @@ void intel_cdclk_uninit_hw(struct drm_i915_private *i915) static bool intel_cdclk_can_crawl(struct drm_i915_private *dev_priv, const struct intel_cdclk_config *a, - const struct intel_cdclk_config *b) + struct intel_cdclk_config *b) { + struct cdclk_step *cdclk_transition = b->steps; int a_div, b_div; if (!HAS_CDCLK_CRAWL(dev_priv)) @@ -1965,6 +1966,12 @@ static bool intel_cdclk_can_crawl(struct drm_i915_private *dev_priv, a_div = DIV_ROUND_CLOSEST(a->vco, a->cdclk); b_div = DIV_ROUND_CLOSEST(b->vco, b->cdclk); + if (a->vco != 0 && b->vco != 0 && a->vco != b->vco && + a_div == b_div && a->ref == b->ref) { + cdclk_transition->action = CDCLK_CRAWL_ONLY; + cdclk_transition->cdclk = b->cdclk; + } + return a->vco != 0 && b->vco != 0 && a->vco != b->vco && a_div == b_div && -- 2.25.1
[Intel-gfx] [PATCH 0/6] Introduce struct cdclk_step
This is a prep series for the actual cdclk refactoring that will be sent following this. Idea is to have a struct - cdclk_step that holds the following: - cdclk action (squash, crawl or modeset) - cdclk frequency which gets populated in atomic check. Driver uses the populated values during atomic commit to do the suitable sequence of actions like programming squash ctl registers in case of squashing or PLL sequence incase of modeset and so on. This series just addresses the initial idea. The actual plumming in the atomic commit phase will be sent shortly. Cc: Ville Syrjälä Cc: Uma Shankar Cc: Rodrigo Vivi Anusha Srivatsa (6): drm/i915/display Add dg2_prog_squash_ctl() helper drm/i915/display: add cdclk action struct to cdclk_config drm/i915/display: Embed the new struct steps for squashing drm/i915/display: Embed the new struct steps for crawling drm/i915/display: Embed the new struct steps for modeset drm/i915/display: Dump the new cdclk config values drivers/gpu/drm/i915/display/intel_cdclk.c | 77 +- drivers/gpu/drm/i915/display/intel_cdclk.h | 16 - 2 files changed, 74 insertions(+), 19 deletions(-) -- 2.25.1
[Intel-gfx] [PATCH 3/4] drm/i915/display: s/intel_cdclk_can_crawl/intel_cdclk_crawl
Apart from checking if crawling can be performed, accommodate accessing in-flight cdclk state for any changes that are needed during commit phase. v2: Move crawling steps to a switch case (anusha) Cc: Matt Roper Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 45 +- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index f98fd48fe905..7bba10635c5e 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -38,6 +38,7 @@ #include "intel_psr.h" #include "vlv_sideband.h" +#define ADLP_CDCLK_CRAWL(dev_priv, vco)(HAS_CDCLK_CRAWL(dev_priv) && dev_priv->cdclk.hw.vco > 0 && vco > 0) /** * DOC: CDCLK / RAWCLK * @@ -1727,10 +1728,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, return; } - if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->cdclk.hw.vco > 0 && vco > 0) { - if (dev_priv->cdclk.hw.vco != vco) - adlp_cdclk_pll_crawl(dev_priv, vco); - } else if (DISPLAY_VER(dev_priv) >= 11) { + if (!ADLP_CDCLK_CRAWL(dev_priv, vco) && DISPLAY_VER(dev_priv) >= 11) { if (dev_priv->cdclk.hw.vco != 0 && dev_priv->cdclk.hw.vco != vco) icl_cdclk_pll_disable(dev_priv); @@ -1748,18 +1746,21 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, waveform = cdclk_squash_waveform(dev_priv, cdclk); - if (waveform && has_cdclk_squasher(dev_priv)) { - clock = vco / 2; + if ((waveform && has_cdclk_squasher(dev_priv)) || ADLP_CDCLK_CRAWL(dev_priv, vco)) { for (i = 0; i < MAX_CDCLK_ACTIONS; i++) { switch (cdclk_steps[i].action) { + case INTEL_CDCLK_CRAWL: + adlp_cdclk_pll_crawl(dev_priv, vco); + clock = cdclk; + break; case INTEL_CDCLK_SQUASH: waveform = cdclk_squash_waveform(dev_priv, cdclk_steps[i].cdclk); squash_ctl = CDCLK_SQUASH_ENABLE | CDCLK_SQUASH_WINDOW_SIZE(0xf) | waveform; intel_de_write(dev_priv, CDCLK_SQUASH_CTL, squash_ctl); + clock = vco / 2; break; case INTEL_CDCLK_NOOP: - case INTEL_CDCLK_CRAWL: case INTEL_CDCLK_MODESET: break; default: @@ -1956,10 +1957,11 @@ void intel_cdclk_uninit_hw(struct drm_i915_private *i915) skl_cdclk_uninit_hw(i915); } -static bool intel_cdclk_can_crawl(struct drm_i915_private *dev_priv, - const struct intel_cdclk_config *a, - const struct intel_cdclk_config *b) +static bool intel_cdclk_crawl(struct drm_i915_private *dev_priv, + const struct intel_cdclk_state *a, + struct intel_cdclk_state *b) { + struct cdclk_step *cdclk_transition = b->steps; int a_div, b_div; if (!HAS_CDCLK_CRAWL(dev_priv)) @@ -1969,13 +1971,18 @@ static bool intel_cdclk_can_crawl(struct drm_i915_private *dev_priv, * The vco and cd2x divider will change independently * from each, so we disallow cd2x change when crawling. */ - a_div = DIV_ROUND_CLOSEST(a->vco, a->cdclk); - b_div = DIV_ROUND_CLOSEST(b->vco, b->cdclk); + a_div = DIV_ROUND_CLOSEST(a->actual.vco, a->actual.cdclk); + b_div = DIV_ROUND_CLOSEST(b->actual.vco, b->actual.cdclk); - return a->vco != 0 && b->vco != 0 && - a->vco != b->vco && - a_div == b_div && - a->ref == b->ref; + cdclk_transition[0].action = INTEL_CDCLK_CRAWL; + cdclk_transition[0].cdclk = b->actual.cdclk; + cdclk_transition[1].action = INTEL_CDCLK_NOOP; + cdclk_transition[1].cdclk = b->actual.cdclk; + + return a->actual.vco != 0 && b->actual.vco != 0 && + a->actual.vco != b->actual.vco && + a_div == b_div && + a->actual.ref == b->actual.ref; } static bool intel_cdclk_squash(struct drm_i915_private *dev_priv, @@ -2781,9 +2788,9 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state) new_cdclk_state)) { drm_dbg_kms(_priv->drm,
[Intel-gfx] [PATCH 2/4] drm/i915/squash: s/intel_cdclk_can_squash/intel_cdclk_squash
Apart from checking if squashing can be performed, accommodate accessing in-flight cdclk state for any changes that are needed during commit phase. v2: Move squashing bits to switch case.(Anusha) Cc: Jani Nikula Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 62 ++ 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 86a22c3766e5..f98fd48fe905 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1693,12 +1693,18 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) { + struct intel_cdclk_state *cdclk_state = to_intel_cdclk_state(dev_priv->cdclk.obj.state); + struct intel_atomic_state *state = cdclk_state->base.state; + struct intel_cdclk_state *new_cdclk_state = intel_atomic_get_new_cdclk_state(state); + struct cdclk_step *cdclk_steps = new_cdclk_state->steps; int cdclk = cdclk_config->cdclk; int vco = cdclk_config->vco; + u32 squash_ctl = 0; u32 val; u16 waveform; int clock; int ret; + int i; /* Inform power controller of upcoming frequency change. */ if (DISPLAY_VER(dev_priv) >= 11) @@ -1742,21 +1748,27 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, waveform = cdclk_squash_waveform(dev_priv, cdclk); - if (waveform) + if (waveform && has_cdclk_squasher(dev_priv)) { clock = vco / 2; - else + for (i = 0; i < MAX_CDCLK_ACTIONS; i++) { + switch (cdclk_steps[i].action) { + case INTEL_CDCLK_SQUASH: + waveform = cdclk_squash_waveform(dev_priv, cdclk_steps[i].cdclk); + squash_ctl = CDCLK_SQUASH_ENABLE | +CDCLK_SQUASH_WINDOW_SIZE(0xf) | waveform; + intel_de_write(dev_priv, CDCLK_SQUASH_CTL, squash_ctl); + break; + case INTEL_CDCLK_NOOP: + case INTEL_CDCLK_CRAWL: + case INTEL_CDCLK_MODESET: + break; + default: + break; + } + } + } else clock = cdclk; - if (has_cdclk_squasher(dev_priv)) { - u32 squash_ctl = 0; - - if (waveform) - squash_ctl = CDCLK_SQUASH_ENABLE | - CDCLK_SQUASH_WINDOW_SIZE(0xf) | waveform; - - intel_de_write(dev_priv, CDCLK_SQUASH_CTL, squash_ctl); - } - val = bxt_cdclk_cd2x_div_sel(dev_priv, clock, vco) | bxt_cdclk_cd2x_pipe(dev_priv, pipe) | skl_cdclk_decimal(cdclk); @@ -1966,10 +1978,11 @@ static bool intel_cdclk_can_crawl(struct drm_i915_private *dev_priv, a->ref == b->ref; } -static bool intel_cdclk_can_squash(struct drm_i915_private *dev_priv, - const struct intel_cdclk_config *a, - const struct intel_cdclk_config *b) +static bool intel_cdclk_squash(struct drm_i915_private *dev_priv, + const struct intel_cdclk_state *a, + struct intel_cdclk_state *b) { + struct cdclk_step *cdclk_transition = b->steps; /* * FIXME should store a bit more state in intel_cdclk_config * to differentiate squasher vs. cd2x divider properly. For @@ -1978,11 +1991,16 @@ static bool intel_cdclk_can_squash(struct drm_i915_private *dev_priv, */ if (!has_cdclk_squasher(dev_priv)) return false; + + cdclk_transition[0].action = INTEL_CDCLK_SQUASH; + cdclk_transition[0].cdclk = b->actual.cdclk; + cdclk_transition[1].action = INTEL_CDCLK_NOOP; + cdclk_transition[1].cdclk = b->actual.cdclk; - return a->cdclk != b->cdclk && - a->vco != 0 && - a->vco == b->vco && - a->ref == b->ref; + return a->actual.cdclk != b->actual.cdclk && + a->actual.vco != 0 && + a->actual.vco == b->actual.vco && + a->actual.ref == b->actual.ref; } /** @@ -2758,9 +2776,9 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state) pipe = INVALID_PIPE; } - if (intel_cdclk_can_squash(dev_priv, - _cdclk_state->actual, -
[Intel-gfx] [PATCH 4/4] drm/i915/display: Add cdclk checks to atomic check
Checking cdclk conditions during atomic check and preparing for commit phase so we can have atomic commit as simple as possible. Add the specific steps to be taken during cdclk changes, prepare for squashing, crawling and modeset scenarios. v2: Add intel_cdclk_modeset() similar to intel_cdclk_squash() and intel_cdclk_crawl(). Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 61 ++ 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 7bba10635c5e..cb58fc857484 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -38,7 +38,6 @@ #include "intel_psr.h" #include "vlv_sideband.h" -#define ADLP_CDCLK_CRAWL(dev_priv, vco)(HAS_CDCLK_CRAWL(dev_priv) && dev_priv->cdclk.hw.vco > 0 && vco > 0) /** * DOC: CDCLK / RAWCLK * @@ -1728,27 +1727,10 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, return; } - if (!ADLP_CDCLK_CRAWL(dev_priv, vco) && DISPLAY_VER(dev_priv) >= 11) { - if (dev_priv->cdclk.hw.vco != 0 && - dev_priv->cdclk.hw.vco != vco) - icl_cdclk_pll_disable(dev_priv); - - if (dev_priv->cdclk.hw.vco != vco) - icl_cdclk_pll_enable(dev_priv, vco); - } else { - if (dev_priv->cdclk.hw.vco != 0 && - dev_priv->cdclk.hw.vco != vco) - bxt_de_pll_disable(dev_priv); - - if (dev_priv->cdclk.hw.vco != vco) - bxt_de_pll_enable(dev_priv, vco); - } - waveform = cdclk_squash_waveform(dev_priv, cdclk); - if ((waveform && has_cdclk_squasher(dev_priv)) || ADLP_CDCLK_CRAWL(dev_priv, vco)) { - for (i = 0; i < MAX_CDCLK_ACTIONS; i++) { - switch (cdclk_steps[i].action) { + for (i = 0; i < MAX_CDCLK_ACTIONS; i++) { + switch (cdclk_steps[i].action) { case INTEL_CDCLK_CRAWL: adlp_cdclk_pll_crawl(dev_priv, vco); clock = cdclk; @@ -1760,15 +1742,28 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, intel_de_write(dev_priv, CDCLK_SQUASH_CTL, squash_ctl); clock = vco / 2; break; - case INTEL_CDCLK_NOOP: case INTEL_CDCLK_MODESET: + if (DISPLAY_VER(dev_priv) >= 11) { + if (dev_priv->cdclk.hw.vco != 0 && + dev_priv->cdclk.hw.vco != vco) + icl_cdclk_pll_disable(dev_priv); + if (dev_priv->cdclk.hw.vco != vco) + icl_cdclk_pll_enable(dev_priv, vco); + } else { + if (dev_priv->cdclk.hw.vco != 0 && + dev_priv->cdclk.hw.vco != vco) + bxt_de_pll_disable(dev_priv); + if (dev_priv->cdclk.hw.vco != vco) + bxt_de_pll_enable(dev_priv, vco); + } + clock = cdclk; + break; + case INTEL_CDCLK_NOOP: break; default: break; } } - } else - clock = cdclk; val = bxt_cdclk_cd2x_div_sel(dev_priv, clock, vco) | bxt_cdclk_cd2x_pipe(dev_priv, pipe) | @@ -2010,6 +2005,24 @@ static bool intel_cdclk_squash(struct drm_i915_private *dev_priv, a->actual.ref == b->actual.ref; } +static void intel_cdclk_modeset(struct drm_i915_private *i915, + const struct intel_cdclk_config *a, + const struct intel_cdclk_config *b) +{ + struct intel_cdclk_state *new_cdclk_state; + struct cdclk_step *cdclk_transition; + struct intel_cdclk_state *cdclk_state = to_intel_cdclk_state(i915->cdclk.obj.state); + struct intel_atomic_state *state = cdclk_state->base.state; + + new_cdclk_state = intel_atomic_get_new_cdclk_state(state); + cdclk_transition = new_cdclk_state->steps; + + cdclk_transition[0].action = INTEL_CDCLK_MODESET; + cdclk_transition[0].cdclk = b->cdclk; + cdclk
[Intel-gfx] [PATCH 1/4] drm/i915/display: Add CDCLK actions to intel_cdclk_state
This is a prep patch for what the rest of the series does. Add existing actions that change cdclk - squash, crawl, modeset to intel_cdclk_state so we have access to the cdclk values that are in transition. Cc: Jani Nikula Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.h | 13 + 1 file changed, 13 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.h b/drivers/gpu/drm/i915/display/intel_cdclk.h index b535cf6a7d9e..43835688ee02 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.h +++ b/drivers/gpu/drm/i915/display/intel_cdclk.h @@ -15,6 +15,14 @@ struct drm_i915_private; struct intel_atomic_state; struct intel_crtc_state; +enum cdclk_actions { + INTEL_CDCLK_MODESET = 0, + INTEL_CDCLK_SQUASH, + INTEL_CDCLK_CRAWL, + INTEL_CDCLK_NOOP, + MAX_CDCLK_ACTIONS +}; + struct intel_cdclk_config { unsigned int cdclk, vco, ref, bypass; u8 voltage_level; @@ -51,6 +59,11 @@ struct intel_cdclk_state { /* bitmask of active pipes */ u8 active_pipes; + + struct cdclk_step { + enum cdclk_actions action; + u32 cdclk; + } steps[MAX_CDCLK_ACTIONS]; }; int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state); -- 2.25.1
[Intel-gfx] [PATCH 0/4] CDCLK churn: move checks to atomic check
The intention is to check for squashing, crawling and modeset conditions at atomic check phase and prepare for commit phase. This basically means the in-flight cdclk state is available. intel_cdclk_can_squash(), intel_cdclk_can_crawl() and intel_cdclk_needs_modeset() have changes to accommodate this. Anusha Srivatsa (4): drm/i915/display: Add CDCLK actions to intel_cdclk_state drm/i915/squash: s/intel_cdclk_can_squash/intel_cdclk_squash drm/i915/display: s/intel_cdclk_can_crawl/intel_cdclk_crawl drm/i915/display: Add cdclk checks to atomic check drivers/gpu/drm/i915/display/intel_cdclk.c | 150 + drivers/gpu/drm/i915/display/intel_cdclk.h | 13 ++ 2 files changed, 108 insertions(+), 55 deletions(-) -- 2.25.1
[Intel-gfx] [CI] drm/i915/dg2: Add support for DC5 state
With the latest DMC in place, enabling DC5 on DG2. Cc: Imre Deak Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_display_power.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 13aaa3247a5a..3f84af6beff3 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -908,7 +908,7 @@ static u32 get_allowed_dc_mask(const struct drm_i915_private *dev_priv, return 0; if (IS_DG2(dev_priv)) - max_dc = 0; + max_dc = 1; else if (IS_DG1(dev_priv)) max_dc = 3; else if (DISPLAY_VER(dev_priv) >= 12) -- 2.25.1
[Intel-gfx] [PATCH] drm/i915/dg2: Add support for DC5 state
With the latest DMC in place, enabling DC5 on DG2. Cc: Imre Deak Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_display_power.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 13aaa3247a5a..3f84af6beff3 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -908,7 +908,7 @@ static u32 get_allowed_dc_mask(const struct drm_i915_private *dev_priv, return 0; if (IS_DG2(dev_priv)) - max_dc = 0; + max_dc = 1; else if (IS_DG1(dev_priv)) max_dc = 3; else if (DISPLAY_VER(dev_priv) >= 12) -- 2.25.1
[Intel-gfx] [PATCH 4/4] drm/i915/display: Add cdclk checks to atomic check
Checking cdclk conditions during atomic check and preparing for commit phase so we can have atomic commit as simple as possible. Add the specific steps to be taken during cdclk changes, prepare for squashing, crawling and modeset scenarios. v2: Add intel_cdclk_modeset() similar to intel_cdclk_squash() and intel_cdclk_crawl(). Cc: Matt Roper Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 108 +++-- 1 file changed, 77 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index cb6e419562dd..2efc1f09abab 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1693,12 +1693,23 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) { + struct intel_atomic_state *state; + struct intel_cdclk_state *new_cdclk_state; + struct cdclk_step *cdclk_steps; + struct intel_cdclk_state *cdclk_state; int cdclk = cdclk_config->cdclk; int vco = cdclk_config->vco; + u32 squash_ctl = 0; u32 val; u16 waveform; int clock; int ret; + int i; + + cdclk_state = to_intel_cdclk_state(dev_priv->cdclk.obj.state); + state = cdclk_state->base.state; + new_cdclk_state = intel_atomic_get_new_cdclk_state(state); + cdclk_steps = new_cdclk_state->steps; /* Inform power controller of upcoming frequency change. */ if (DISPLAY_VER(dev_priv) >= 11) @@ -1721,40 +1732,42 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, return; } - if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->cdclk.hw.vco > 0 && vco > 0) { - if (dev_priv->cdclk.hw.vco != vco) + for (i = 0; i < MAX_CDCLK_ACTIONS; i++) { + switch (cdclk_steps[i].action) { + case INTEL_CDCLK_MODESET: + if (DISPLAY_VER(dev_priv) >= 11) { + if (dev_priv->cdclk.hw.vco != 0 && + dev_priv->cdclk.hw.vco != vco) + icl_cdclk_pll_disable(dev_priv); + + if (dev_priv->cdclk.hw.vco != vco) + icl_cdclk_pll_enable(dev_priv, vco); + } else { + if (dev_priv->cdclk.hw.vco != 0 && + dev_priv->cdclk.hw.vco != vco) + bxt_de_pll_disable(dev_priv); + + if (dev_priv->cdclk.hw.vco != vco) + bxt_de_pll_enable(dev_priv, vco); + } + clock = cdclk; + break; + case INTEL_CDCLK_CRAWL: adlp_cdclk_pll_crawl(dev_priv, vco); - } else if (DISPLAY_VER(dev_priv) >= 11) { - if (dev_priv->cdclk.hw.vco != 0 && - dev_priv->cdclk.hw.vco != vco) - icl_cdclk_pll_disable(dev_priv); - - if (dev_priv->cdclk.hw.vco != vco) - icl_cdclk_pll_enable(dev_priv, vco); - } else { - if (dev_priv->cdclk.hw.vco != 0 && - dev_priv->cdclk.hw.vco != vco) - bxt_de_pll_disable(dev_priv); - - if (dev_priv->cdclk.hw.vco != vco) - bxt_de_pll_enable(dev_priv, vco); - } - - waveform = cdclk_squash_waveform(dev_priv, cdclk); - - if (waveform) - clock = vco / 2; - else - clock = cdclk; - - if (has_cdclk_squasher(dev_priv)) { - u32 squash_ctl = 0; - - if (waveform) + clock = cdclk; + break; + case INTEL_CDCLK_SQUASH: + waveform = cdclk_squash_waveform(dev_priv, cdclk_steps[i].cdclk); + clock = vco / 2; squash_ctl = CDCLK_SQUASH_ENABLE | CDCLK_SQUASH_WINDOW_SIZE(0xf) | waveform; - - intel_de_write(dev_priv, CDCLK_SQUASH_CTL, squash_ctl); + intel_de_write(dev_priv, CDCLK_SQUASH_CTL, squash_ctl); + break; + case INTEL_CDCLK_NOOP: + break; + default: + break; + } } val = bxt_cdclk_cd2x_div_sel(dev_priv, clock, vco) | @@ -1949,6 +1962,7 @@ static bool intel_cdclk_crawl(struct drm_i915_private *dev_priv, struct intel_cdclk_state *b)
[Intel-gfx] [PATCH 3/4] drm/i915/display: s/intel_cdclk_can_crawl/intel_cdclk_crawl
Apart from checking if crawling can be performed, accommodate accessing in-flight cdclk state for any changes that are needed during commit phase. Cc: Matt Roper Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 22 +++--- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 4081b880a6ef..cb6e419562dd 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1944,9 +1944,9 @@ void intel_cdclk_uninit_hw(struct drm_i915_private *i915) skl_cdclk_uninit_hw(i915); } -static bool intel_cdclk_can_crawl(struct drm_i915_private *dev_priv, - const struct intel_cdclk_config *a, - const struct intel_cdclk_config *b) +static bool intel_cdclk_crawl(struct drm_i915_private *dev_priv, + const struct intel_cdclk_state *a, + struct intel_cdclk_state *b) { int a_div, b_div; @@ -1957,13 +1957,13 @@ static bool intel_cdclk_can_crawl(struct drm_i915_private *dev_priv, * The vco and cd2x divider will change independently * from each, so we disallow cd2x change when crawling. */ - a_div = DIV_ROUND_CLOSEST(a->vco, a->cdclk); - b_div = DIV_ROUND_CLOSEST(b->vco, b->cdclk); + a_div = DIV_ROUND_CLOSEST(a->actual.vco, a->actual.cdclk); + b_div = DIV_ROUND_CLOSEST(b->actual.vco, b->actual.cdclk); - return a->vco != 0 && b->vco != 0 && - a->vco != b->vco && + return a->actual.vco != 0 && b->actual.vco != 0 && + a->actual.vco != b->actual.vco && a_div == b_div && - a->ref == b->ref; + a->actual.ref == b->actual.ref; } static bool intel_cdclk_squash(struct drm_i915_private *dev_priv, @@ -2764,9 +2764,9 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state) new_cdclk_state)) { drm_dbg_kms(_priv->drm, "Can change cdclk via squasher\n"); - } else if (intel_cdclk_can_crawl(dev_priv, -_cdclk_state->actual, -_cdclk_state->actual)) { + } else if (intel_cdclk_crawl(dev_priv, +old_cdclk_state, +new_cdclk_state)) { drm_dbg_kms(_priv->drm, "Can change cdclk via crawl\n"); } else if (pipe != INVALID_PIPE) { -- 2.25.1
[Intel-gfx] [PATCH 2/4] drm/i915/display: s/intel_cdclk_can_squash/intel_cdclk_squash
Apart from checking if squashing can be performed, accommodate accessing in-flight cdclk state for any changes that are needed during commit phase. Cc: Matt Roper Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 21 +++-- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 86a22c3766e5..4081b880a6ef 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1966,10 +1966,11 @@ static bool intel_cdclk_can_crawl(struct drm_i915_private *dev_priv, a->ref == b->ref; } -static bool intel_cdclk_can_squash(struct drm_i915_private *dev_priv, - const struct intel_cdclk_config *a, - const struct intel_cdclk_config *b) +static bool intel_cdclk_squash(struct drm_i915_private *dev_priv, + const struct intel_cdclk_state *a, + struct intel_cdclk_state *b) { + /* * FIXME should store a bit more state in intel_cdclk_config * to differentiate squasher vs. cd2x divider properly. For @@ -1979,10 +1980,10 @@ static bool intel_cdclk_can_squash(struct drm_i915_private *dev_priv, if (!has_cdclk_squasher(dev_priv)) return false; - return a->cdclk != b->cdclk && - a->vco != 0 && - a->vco == b->vco && - a->ref == b->ref; + return a->actual.cdclk != b->actual.cdclk && + a->actual.vco != 0 && + a->actual.vco == b->actual.vco && + a->actual.ref == b->actual.ref; } /** @@ -2758,9 +2759,9 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state) pipe = INVALID_PIPE; } - if (intel_cdclk_can_squash(dev_priv, - _cdclk_state->actual, - _cdclk_state->actual)) { + if (intel_cdclk_squash(dev_priv, + old_cdclk_state, + new_cdclk_state)) { drm_dbg_kms(_priv->drm, "Can change cdclk via squasher\n"); } else if (intel_cdclk_can_crawl(dev_priv, -- 2.25.1
[Intel-gfx] [PATCH 1/4] drm/i915/display: Add CDCLK actions to intel_cdclk_state
This is a prep patch for what the rest of the series does. Add existing actions that change cdclk - squash, crawl, modeset to intel_cdclk_state so we have access to the cdclk values that are in transition. Cc: Matt Roper Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_cdclk.h | 13 + 1 file changed, 13 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.h b/drivers/gpu/drm/i915/display/intel_cdclk.h index b535cf6a7d9e..43835688ee02 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.h +++ b/drivers/gpu/drm/i915/display/intel_cdclk.h @@ -15,6 +15,14 @@ struct drm_i915_private; struct intel_atomic_state; struct intel_crtc_state; +enum cdclk_actions { + INTEL_CDCLK_MODESET = 0, + INTEL_CDCLK_SQUASH, + INTEL_CDCLK_CRAWL, + INTEL_CDCLK_NOOP, + MAX_CDCLK_ACTIONS +}; + struct intel_cdclk_config { unsigned int cdclk, vco, ref, bypass; u8 voltage_level; @@ -51,6 +59,11 @@ struct intel_cdclk_state { /* bitmask of active pipes */ u8 active_pipes; + + struct cdclk_step { + enum cdclk_actions action; + u32 cdclk; + } steps[MAX_CDCLK_ACTIONS]; }; int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state); -- 2.25.1
[Intel-gfx] [PATCH 0/4] Move CDCLK checks to atomic check phase
The intention is to check for squashing, crawling conditions at atomic check phase and prepare for commit phase. This basically means the in-flight cdclk state is available. intel_cdclk_can_squash(), intel_cdclk_can_crawl() and intel_cdclk_needs_modeset() have changes to accommodate this. Cc: Matt Roper Anusha Srivatsa (4): drm/i915/display: Add CDCLK actions to intel_cdclk_state drm/i915/display: s/intel_cdclk_can_squash/intel_cdclk_squash drm/i915/display: s/intel_cdclk_can_crawl/intel_cdclk_crawl drm/i915/display: Add cdclk checks to atomic check drivers/gpu/drm/i915/display/intel_cdclk.c | 151 ++--- drivers/gpu/drm/i915/display/intel_cdclk.h | 13 ++ 2 files changed, 112 insertions(+), 52 deletions(-) -- 2.25.1
[Intel-gfx] [PATCH 0/4] Add CDCLK checks to atomic check phase
The intention is to check for squashing, crawling conditions at atomic check phase and prepare for commit phase. This basically means the in-flight cdclk state is available. intel_cdclk_can_squash(), intel_cdclk_can_crawl() and intel_cdclk_needs_modeset() have changes to accommodate this. Anusha Srivatsa (4): drm/i915/display: Add CDCLK actions to intel_cdclk_state drm/i915/display: s/intel_cdclk_can_squash/intel_cdclk_squash drm/i915/display: s/intel_cdclk_can_crawl/intel_cdclk_crawl drm/i915/display: Add cdclk checks to atomic check drivers/gpu/drm/i915/display/intel_cdclk.c | 151 ++--- drivers/gpu/drm/i915/display/intel_cdclk.h | 13 ++ 2 files changed, 112 insertions(+), 52 deletions(-) -- 2.25.1
[Intel-gfx] [PATCH] drm/i915/display: Cleanup intel_phy_is_combo()
Cleanup the intel_phy_is_combo to accommodate for cases where combo phy is not available. v2: retain comment that explains DG2 returning false from intel_phy_is_combo() (Arun) Cc: Arun R Murthy Cc: Matt Roper Signed-off-by: Anusha Srivatsa Reviewed-by: Matt Roper Reviewed-by: Arun R Murthy --- drivers/gpu/drm/i915/display/intel_display.c | 14 ++ 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index a0f84cbe974f..b9d0be7753a8 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2082,22 +2082,20 @@ bool intel_phy_is_combo(struct drm_i915_private *dev_priv, enum phy phy) { if (phy == PHY_NONE) return false; - else if (IS_DG2(dev_priv)) - /* -* DG2 outputs labelled as "combo PHY" in the bspec use -* SNPS PHYs with completely different programming, -* hence we always return false here. -*/ - return false; else if (IS_ALDERLAKE_S(dev_priv)) return phy <= PHY_E; else if (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv)) return phy <= PHY_D; else if (IS_JSL_EHL(dev_priv)) return phy <= PHY_C; - else if (DISPLAY_VER(dev_priv) >= 11) + else if (IS_ALDERLAKE_P(dev_priv) || IS_DISPLAY_VER(dev_priv, 11, 12)) return phy <= PHY_B; else + /* +* DG2 outputs labelled as "combo PHY" in the bspec use +* SNPS PHYs with completely different programming, +* hence we always return false here. +*/ return false; } -- 2.25.1
[Intel-gfx] [PATCH] drm/i915: Pass drm_i915_private struct instead of gt for gen11_gu_misc_irq_handler/ack()
gen11_gu_misc_irq_handler() and gen11_gu_misc_ack() do nothing tile specific. v2: gen11_gu_misc_irq_ack() tile agnostic like gen11_gu_misc_irq_handler() (Tvrtko) Cc: Tvrtko Ursulin Cc: Matt Roper Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/i915_irq.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 73cebc6aa650..eb37b6bacaac 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2653,9 +2653,9 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) } static u32 -gen11_gu_misc_irq_ack(struct intel_gt *gt, const u32 master_ctl) +gen11_gu_misc_irq_ack(struct drm_i915_private *i915, const u32 master_ctl) { - void __iomem * const regs = gt->uncore->regs; + void __iomem * const regs = i915->uncore.regs; u32 iir; if (!(master_ctl & GEN11_GU_MISC_IRQ)) @@ -2669,10 +2669,10 @@ gen11_gu_misc_irq_ack(struct intel_gt *gt, const u32 master_ctl) } static void -gen11_gu_misc_irq_handler(struct intel_gt *gt, const u32 iir) +gen11_gu_misc_irq_handler(struct drm_i915_private *i915, const u32 iir) { if (iir & GEN11_GU_MISC_GSE) - intel_opregion_asle_intr(gt->i915); + intel_opregion_asle_intr(i915); } static inline u32 gen11_master_intr_disable(void __iomem * const regs) @@ -2736,11 +2736,11 @@ static irqreturn_t gen11_irq_handler(int irq, void *arg) if (master_ctl & GEN11_DISPLAY_IRQ) gen11_display_irq_handler(i915); - gu_misc_iir = gen11_gu_misc_irq_ack(gt, master_ctl); + gu_misc_iir = gen11_gu_misc_irq_ack(i915, master_ctl); gen11_master_intr_enable(regs); - gen11_gu_misc_irq_handler(gt, gu_misc_iir); + gen11_gu_misc_irq_handler(i915, gu_misc_iir); pmu_irq_stats(i915, IRQ_HANDLED); @@ -2801,11 +2801,11 @@ static irqreturn_t dg1_irq_handler(int irq, void *arg) if (master_ctl & GEN11_DISPLAY_IRQ) gen11_display_irq_handler(i915); - gu_misc_iir = gen11_gu_misc_irq_ack(gt, master_ctl); + gu_misc_iir = gen11_gu_misc_irq_ack(i915, master_ctl); dg1_master_intr_enable(regs); - gen11_gu_misc_irq_handler(gt, gu_misc_iir); + gen11_gu_misc_irq_handler(i915, gu_misc_iir); pmu_irq_stats(i915, IRQ_HANDLED); -- 2.25.1
[Intel-gfx] [PATCH] drm/i915/display: Cleanup intel_phy_is_combo()
No functional change. Cleanup the intel_phy_is_combo to accommodate for cases where combo phy is not available. v2: retain comment that explains DG2 returning false from intel_phy_is_combo() (Arun) Cc: Arun R Murthy Cc: Matt Roper Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_display.c | 14 ++ 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index a0f84cbe974f..b9d0be7753a8 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2082,22 +2082,20 @@ bool intel_phy_is_combo(struct drm_i915_private *dev_priv, enum phy phy) { if (phy == PHY_NONE) return false; - else if (IS_DG2(dev_priv)) - /* -* DG2 outputs labelled as "combo PHY" in the bspec use -* SNPS PHYs with completely different programming, -* hence we always return false here. -*/ - return false; else if (IS_ALDERLAKE_S(dev_priv)) return phy <= PHY_E; else if (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv)) return phy <= PHY_D; else if (IS_JSL_EHL(dev_priv)) return phy <= PHY_C; - else if (DISPLAY_VER(dev_priv) >= 11) + else if (IS_ALDERLAKE_P(dev_priv) || IS_DISPLAY_VER(dev_priv, 11, 12)) return phy <= PHY_B; else + /* +* DG2 outputs labelled as "combo PHY" in the bspec use +* SNPS PHYs with completely different programming, +* hence we always return false here. +*/ return false; } -- 2.25.1
[Intel-gfx] [PATCH] drm/i915/display: Cleanup intel_phy_is_combo()
No functional change. Cleanup the intel_phy_is_combo to accomodate for cases where combo phy is not available. Cc: Matt Roper Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_display.c | 9 + 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index a0f84cbe974f..b69208cf9a5e 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2082,20 +2082,13 @@ bool intel_phy_is_combo(struct drm_i915_private *dev_priv, enum phy phy) { if (phy == PHY_NONE) return false; - else if (IS_DG2(dev_priv)) - /* -* DG2 outputs labelled as "combo PHY" in the bspec use -* SNPS PHYs with completely different programming, -* hence we always return false here. -*/ - return false; else if (IS_ALDERLAKE_S(dev_priv)) return phy <= PHY_E; else if (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv)) return phy <= PHY_D; else if (IS_JSL_EHL(dev_priv)) return phy <= PHY_C; - else if (DISPLAY_VER(dev_priv) >= 11) + else if (IS_ALDERLAKE_P(dev_priv) || IS_DISPLAY_VER(dev_priv, 11, 12)) return phy <= PHY_B; else return false; -- 2.25.1
[Intel-gfx] [PATCH] drm/i915: Pass drm_i915_private struct instead of gt for gen11_gu_misc_irq_handler()
gen11_gu_misc_irq_handler() does not do anything tile specific. Cc: Matt Roper Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/i915_irq.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 73cebc6aa650..c304af777d58 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2669,10 +2669,10 @@ gen11_gu_misc_irq_ack(struct intel_gt *gt, const u32 master_ctl) } static void -gen11_gu_misc_irq_handler(struct intel_gt *gt, const u32 iir) +gen11_gu_misc_irq_handler(struct drm_i915_private *i915, const u32 iir) { if (iir & GEN11_GU_MISC_GSE) - intel_opregion_asle_intr(gt->i915); + intel_opregion_asle_intr(i915); } static inline u32 gen11_master_intr_disable(void __iomem * const regs) @@ -2740,7 +2740,7 @@ static irqreturn_t gen11_irq_handler(int irq, void *arg) gen11_master_intr_enable(regs); - gen11_gu_misc_irq_handler(gt, gu_misc_iir); + gen11_gu_misc_irq_handler(i915, gu_misc_iir); pmu_irq_stats(i915, IRQ_HANDLED); @@ -2805,7 +2805,7 @@ static irqreturn_t dg1_irq_handler(int irq, void *arg) dg1_master_intr_enable(regs); - gen11_gu_misc_irq_handler(gt, gu_misc_iir); + gen11_gu_misc_irq_handler(i915, gu_misc_iir); pmu_irq_stats(i915, IRQ_HANDLED); -- 2.25.1
[Intel-gfx] [PATCH] drm/i915/dg2: Enable DC5
Enable DC5 on dg2. Cc: Imre Deak Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_display_power.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index fb17439bd4f8..f58e277fdadf 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -908,7 +908,7 @@ static u32 get_allowed_dc_mask(const struct drm_i915_private *dev_priv, return 0; if (IS_DG2(dev_priv)) - max_dc = 0; + max_dc = 1; else if (IS_DG1(dev_priv)) max_dc = 3; else if (DISPLAY_VER(dev_priv) >= 12) -- 2.25.1
[Intel-gfx] [CI] drm/i915/dmc: Add MMIO range restrictions
Bspec has added some steps that check forDMC MMIO range before programming them v2: Fix for CI v3: move register defines to .h (Anusha) - Check MMIO restrictions per pipe - Add MMIO restricton for v1 dmc header as well (Lucas) v4: s/_PICK/_PICK_EVEN and use it only for Pipe DMC scenario. - clean up sanity check logic.(Lucas) - Add MMIO range for RKL as well.(Anusha) v5: Use DISPLAY_VER instead of per platform check (Lucas) BSpec: 49193 Cc: Cc: Lucas De Marchi Signed-off-by: Anusha Srivatsa Reviewed-by: Lucas De Marchi --- drivers/gpu/drm/i915/display/intel_dmc.c | 44 +++ drivers/gpu/drm/i915/display/intel_dmc_regs.h | 18 +++- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 2f01aca4d981..34d00f5aff25 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -378,6 +378,44 @@ static void dmc_set_fw_offset(struct intel_dmc *dmc, } } +static bool dmc_mmio_addr_sanity_check(struct intel_dmc *dmc, + const u32 *mmioaddr, u32 mmio_count, + int header_ver, u8 dmc_id) +{ + struct drm_i915_private *i915 = container_of(dmc, typeof(*i915), dmc); + u32 start_range, end_range; + int i; + + if (dmc_id >= DMC_FW_MAX) { + drm_warn(>drm, "Unsupported firmware id %u\n", dmc_id); + return false; + } + + if (header_ver == 1) { + start_range = DMC_MMIO_START_RANGE; + end_range = DMC_MMIO_END_RANGE; + } else if (dmc_id == DMC_FW_MAIN) { + start_range = TGL_MAIN_MMIO_START; + end_range = TGL_MAIN_MMIO_END; + } else if (DISPLAY_VER(i915) >= 13) { + start_range = ADLP_PIPE_MMIO_START; + end_range = ADLP_PIPE_MMIO_END; + } else if (DISPLAY_VER(i915) >= 12) { + start_range = TGL_PIPE_MMIO_START(dmc_id); + end_range = TGL_PIPE_MMIO_END(dmc_id); + } else { + drm_warn(>drm, "Unknown mmio range for sanity check"); + return false; + } + + for (i = 0; i < mmio_count; i++) { + if (mmioaddr[i] < start_range || mmioaddr[i] > end_range) + return false; + } + + return true; +} + static u32 parse_dmc_fw_header(struct intel_dmc *dmc, const struct intel_dmc_header_base *dmc_header, size_t rem_size, u8 dmc_id) @@ -447,6 +485,12 @@ static u32 parse_dmc_fw_header(struct intel_dmc *dmc, return 0; } + if (!dmc_mmio_addr_sanity_check(dmc, mmioaddr, mmio_count, + dmc_header->header_ver, dmc_id)) { + drm_err(>drm, "DMC firmware has Wrong MMIO Addresses\n"); + return 0; + } + for (i = 0; i < mmio_count; i++) { dmc_info->mmioaddr[i] = _MMIO(mmioaddr[i]); dmc_info->mmiodata[i] = mmiodata[i]; diff --git a/drivers/gpu/drm/i915/display/intel_dmc_regs.h b/drivers/gpu/drm/i915/display/intel_dmc_regs.h index d65e698832eb..67e14eb96a7a 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_regs.h +++ b/drivers/gpu/drm/i915/display/intel_dmc_regs.h @@ -16,7 +16,23 @@ #define DMC_LAST_WRITE _MMIO(0x8F034) #define DMC_LAST_WRITE_VALUE 0xc003b400 #define DMC_MMIO_START_RANGE 0x8 -#define DMC_MMIO_END_RANGE 0x8 +#define DMC_MMIO_END_RANGE 0x8 +#define DMC_V1_MMIO_START_RANGE0x8 +#define TGL_MAIN_MMIO_START0x8F000 +#define TGL_MAIN_MMIO_END 0x8 +#define _TGL_PIPEA_MMIO_START 0x92000 +#define _TGL_PIPEA_MMIO_END0x93FFF +#define _TGL_PIPEB_MMIO_START 0x96000 +#define _TGL_PIPEB_MMIO_END0x97FFF +#define ADLP_PIPE_MMIO_START 0x5F000 +#define ADLP_PIPE_MMIO_END 0x5 + +#define TGL_PIPE_MMIO_START(dmc_id)_PICK_EVEN(((dmc_id) - 1), _TGL_PIPEA_MMIO_START,\ + _TGL_PIPEB_MMIO_START) + +#define TGL_PIPE_MMIO_END(dmc_id) _PICK_EVEN(((dmc_id) - 1), _TGL_PIPEA_MMIO_END,\ + _TGL_PIPEB_MMIO_END) + #define SKL_DMC_DC3_DC5_COUNT _MMIO(0x80030) #define SKL_DMC_DC5_DC6_COUNT _MMIO(0x8002C) #define BXT_DMC_DC3_DC5_COUNT _MMIO(0x80038) -- 2.25.1
[Intel-gfx] [PATCH] drm/i915/dmc: Add MMIO range restrictions
Bspec has added some steps that check forDMC MMIO range before programming them v2: Fix for CI v3: move register defines to .h (Anusha) - Check MMIO restrictions per pipe - Add MMIO restricton for v1 dmc header as well (Lucas) v4: s/_PICK/_PICK_EVEN and use it only for Pipe DMC scenario. - clean up sanity check logic.(Lucas) - Add MMIO range for RKL as well.(Anusha) v5: Use DISPLAY_VER instead of per platform check (Lucas) BSpec: 49193 Cc: Cc: Lucas De Marchi Signed-off-by: Anusha Srivatsa Reviewed-by: Lucas De Marchi --- drivers/gpu/drm/i915/display/intel_dmc.c | 42 +++ drivers/gpu/drm/i915/display/intel_dmc_regs.h | 18 +++- 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 2f01aca4d981..f545cc7367e3 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -378,6 +378,43 @@ static void dmc_set_fw_offset(struct intel_dmc *dmc, } } +static bool dmc_mmio_addr_sanity_check(struct intel_dmc *dmc, const u32 *mmioaddr, + u32 mmio_count, int header_ver, u8 dmc_id) +{ + struct drm_i915_private *i915 = container_of(dmc, typeof(*i915), dmc); + u32 start_range, end_range; + int i; + + if (dmc_id >= DMC_FW_MAX) { + drm_warn(>drm, "Unsupported firmware id %u\n", dmc_id); + return false; + } + + if (header_ver == 1) { + start_range = DMC_MMIO_START_RANGE; + end_range = DMC_MMIO_END_RANGE; + } else if (dmc_id == DMC_FW_MAIN) { + start_range = TGL_MAIN_MMIO_START; + end_range = TGL_MAIN_MMIO_END; + } else if (DISPLAY_VER(i915) >= 13) { + start_range = ADLP_PIPE_MMIO_START; + end_range = ADLP_PIPE_MMIO_END; + } else if (DISPLAY_VER(i915) >= 12) { + start_range = TGL_PIPE_MMIO_START(dmc_id); + end_range = TGL_PIPE_MMIO_END(dmc_id); + } else { + drm_warn(>drm, "Unknown mmio range for sanity check"); + return false; + } + + for (i = 0; i < mmio_count; i++) { + if (mmioaddr[i] < start_range || mmioaddr[i] > end_range) + return false; + } + + return true; +} + static u32 parse_dmc_fw_header(struct intel_dmc *dmc, const struct intel_dmc_header_base *dmc_header, size_t rem_size, u8 dmc_id) @@ -447,6 +484,11 @@ static u32 parse_dmc_fw_header(struct intel_dmc *dmc, return 0; } + if (!dmc_mmio_addr_sanity_check(dmc, mmioaddr, mmio_count, dmc_header->header_ver, dmc_id)) { + drm_err(>drm, "DMC firmware has Wrong MMIO Addresses\n"); + return 0; + } + for (i = 0; i < mmio_count; i++) { dmc_info->mmioaddr[i] = _MMIO(mmioaddr[i]); dmc_info->mmiodata[i] = mmiodata[i]; diff --git a/drivers/gpu/drm/i915/display/intel_dmc_regs.h b/drivers/gpu/drm/i915/display/intel_dmc_regs.h index d65e698832eb..67e14eb96a7a 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_regs.h +++ b/drivers/gpu/drm/i915/display/intel_dmc_regs.h @@ -16,7 +16,23 @@ #define DMC_LAST_WRITE _MMIO(0x8F034) #define DMC_LAST_WRITE_VALUE 0xc003b400 #define DMC_MMIO_START_RANGE 0x8 -#define DMC_MMIO_END_RANGE 0x8 +#define DMC_MMIO_END_RANGE 0x8 +#define DMC_V1_MMIO_START_RANGE0x8 +#define TGL_MAIN_MMIO_START0x8F000 +#define TGL_MAIN_MMIO_END 0x8 +#define _TGL_PIPEA_MMIO_START 0x92000 +#define _TGL_PIPEA_MMIO_END0x93FFF +#define _TGL_PIPEB_MMIO_START 0x96000 +#define _TGL_PIPEB_MMIO_END0x97FFF +#define ADLP_PIPE_MMIO_START 0x5F000 +#define ADLP_PIPE_MMIO_END 0x5 + +#define TGL_PIPE_MMIO_START(dmc_id)_PICK_EVEN(((dmc_id) - 1), _TGL_PIPEA_MMIO_START,\ + _TGL_PIPEB_MMIO_START) + +#define TGL_PIPE_MMIO_END(dmc_id) _PICK_EVEN(((dmc_id) - 1), _TGL_PIPEA_MMIO_END,\ + _TGL_PIPEB_MMIO_END) + #define SKL_DMC_DC3_DC5_COUNT _MMIO(0x80030) #define SKL_DMC_DC5_DC6_COUNT _MMIO(0x8002C) #define BXT_DMC_DC3_DC5_COUNT _MMIO(0x80038) -- 2.25.1
[Intel-gfx] [PATCH] drm/i915/dmc: Load DMC on DG2
Add Support for DC states on Dg2. v2: Add dc9 as the max supported DC states and disable DC5. v3: set max_dc to 0. (Imre) v4: Add FIXME (Rodrigo) Cc: Imre Deak Cc: Rodrigo Vivi Signed-off-by: Anusha Srivatsa Reviewed-by: Rodrigo Vivi (v1) --- drivers/gpu/drm/i915/display/intel_display_power.c | 11 +-- drivers/gpu/drm/i915/display/intel_dmc.c | 10 +- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 1d9bd5808849..2271f88e9a25 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -906,8 +906,15 @@ static u32 get_allowed_dc_mask(const struct drm_i915_private *dev_priv, if (!HAS_DISPLAY(dev_priv)) return 0; - - if (IS_DG1(dev_priv)) + /* FIXME: change max_dc back to 3 once +* we have DC5 bugs resolved. Till then, +* DG2 will use only DC9. Though DC9 does +* not depend on DMC, loading it in order +* to unblock runtime PM +*/ + if (IS_DG2(dev_priv)) + max_dc = 0; + else if (IS_DG1(dev_priv)) max_dc = 3; else if (DISPLAY_VER(dev_priv) >= 12) max_dc = 4; diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 257cf662f9f4..2f01aca4d981 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -52,6 +52,10 @@ #define DISPLAY_VER12_DMC_MAX_FW_SIZE ICL_DMC_MAX_FW_SIZE +#define DG2_DMC_PATH DMC_PATH(dg2, 2, 06) +#define DG2_DMC_VERSION_REQUIRED DMC_VERSION(2, 06) +MODULE_FIRMWARE(DG2_DMC_PATH); + #define ADLP_DMC_PATH DMC_PATH(adlp, 2, 16) #define ADLP_DMC_VERSION_REQUIRED DMC_VERSION(2, 16) MODULE_FIRMWARE(ADLP_DMC_PATH); @@ -688,7 +692,11 @@ void intel_dmc_ucode_init(struct drm_i915_private *dev_priv) */ intel_dmc_runtime_pm_get(dev_priv); - if (IS_ALDERLAKE_P(dev_priv)) { + if (IS_DG2(dev_priv)) { + dmc->fw_path = DG2_DMC_PATH; + dmc->required_version = DG2_DMC_VERSION_REQUIRED; + dmc->max_fw_size = DISPLAY_VER13_DMC_MAX_FW_SIZE; + } else if (IS_ALDERLAKE_P(dev_priv)) { dmc->fw_path = ADLP_DMC_PATH; dmc->required_version = ADLP_DMC_VERSION_REQUIRED; dmc->max_fw_size = DISPLAY_VER13_DMC_MAX_FW_SIZE; -- 2.25.1
[Intel-gfx] [PATCH 0/1] DG2 DMC Support
While DG2 supports DC5 and DC9, some of the tests in fast-feedback blew up DG2 when the tests forced transition from dc5->dc9 on suspend and dc9->dc5 on resume. Some local experiments performed with Rodrigo on a RIL system showed promising results when dc5 was completely diabled and i915 took only dc9 paths. Sending this so we can check the CI results to confirm the findings from local testing which will hopefully help narrow down the root cause of MMIO BAR lost issue Cc: Rodrigo Vivi Cc: Imre Deak Anusha Srivatsa (1): drm/i915/dmc: Load DMC on DG2 drivers/gpu/drm/i915/display/intel_display_power.c | 4 +++- drivers/gpu/drm/i915/display/intel_dmc.c | 10 +- 2 files changed, 12 insertions(+), 2 deletions(-) -- 2.25.1
[Intel-gfx] [PATCH] drm/i915/dmc: Load DMC on DG2
Add Support for DC states on Dg2. v2: Add dc9 as the max supported DC states and disable DC5. v3: set max_dc to 0. (Imre) v4: Add FIXME (Rodrigo) Cc: Imre Deak Cc: Rodrigo Vivi Signed-off-by: Anusha Srivatsa Reviewed-by: Rodrigo Vivi (v1) --- drivers/gpu/drm/i915/display/intel_display_power.c | 11 +-- drivers/gpu/drm/i915/display/intel_dmc.c | 10 +- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 1d9bd5808849..2271f88e9a25 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -906,8 +906,15 @@ static u32 get_allowed_dc_mask(const struct drm_i915_private *dev_priv, if (!HAS_DISPLAY(dev_priv)) return 0; - - if (IS_DG1(dev_priv)) + /* FIXME: change max_dc back to 3 once +* we have DC5 bugs resolved. Till then, +* DG2 will use only DC9. Though DC9 does +* not depend on DMC, loading it in order +* to unblock runtime PM +*/ + if (IS_DG2(dev_priv)) + max_dc = 0; + else if (IS_DG1(dev_priv)) max_dc = 3; else if (DISPLAY_VER(dev_priv) >= 12) max_dc = 4; diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 257cf662f9f4..2f01aca4d981 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -52,6 +52,10 @@ #define DISPLAY_VER12_DMC_MAX_FW_SIZE ICL_DMC_MAX_FW_SIZE +#define DG2_DMC_PATH DMC_PATH(dg2, 2, 06) +#define DG2_DMC_VERSION_REQUIRED DMC_VERSION(2, 06) +MODULE_FIRMWARE(DG2_DMC_PATH); + #define ADLP_DMC_PATH DMC_PATH(adlp, 2, 16) #define ADLP_DMC_VERSION_REQUIRED DMC_VERSION(2, 16) MODULE_FIRMWARE(ADLP_DMC_PATH); @@ -688,7 +692,11 @@ void intel_dmc_ucode_init(struct drm_i915_private *dev_priv) */ intel_dmc_runtime_pm_get(dev_priv); - if (IS_ALDERLAKE_P(dev_priv)) { + if (IS_DG2(dev_priv)) { + dmc->fw_path = DG2_DMC_PATH; + dmc->required_version = DG2_DMC_VERSION_REQUIRED; + dmc->max_fw_size = DISPLAY_VER13_DMC_MAX_FW_SIZE; + } else if (IS_ALDERLAKE_P(dev_priv)) { dmc->fw_path = ADLP_DMC_PATH; dmc->required_version = ADLP_DMC_VERSION_REQUIRED; dmc->max_fw_size = DISPLAY_VER13_DMC_MAX_FW_SIZE; -- 2.25.1
[Intel-gfx] [PATCH 0/1] DG2 DMC Support
While DG2 supports DC5 and DC9, some of the tests in fast-feedback blew up DG2 when the tests forced transition from dc5->dc9 on suspend and dc9->dc5 on resume. Some local experiments performed with Rodrigo on a RIL system showed promising results when dc5 was completely diabled and i915 took only dc9 paths. Sending this so we can check the CI results to confirm the findings from local testing which will hopefully help narrow down the root cause of MMIO BAR lost issue Cc: Rodrigo Vivi Cc: Imre Deak Anusha Srivatsa (1): drm/i915/dmc: Load DMC on DG2 drivers/gpu/drm/i915/display/intel_display_power.c | 4 +++- drivers/gpu/drm/i915/display/intel_dmc.c | 10 +- 2 files changed, 12 insertions(+), 2 deletions(-) -- 2.25.1
[Intel-gfx] [PATCH] drm/i915/dmc: Load DMC on DG2
Add Support for DC states on Dg2. v2: Add dc9 as the max supported DC states and disable DC5. v3: set max_dc to 0. (Imre) Cc: Imre Deak Cc: Rodrigo Vivi Signed-off-by: Anusha Srivatsa Reviewed-by: Rodrigo Vivi (v1) --- drivers/gpu/drm/i915/display/intel_display_power.c | 4 +++- drivers/gpu/drm/i915/display/intel_dmc.c | 10 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 1d9bd5808849..15b15f434fcf 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -907,7 +907,9 @@ static u32 get_allowed_dc_mask(const struct drm_i915_private *dev_priv, if (!HAS_DISPLAY(dev_priv)) return 0; - if (IS_DG1(dev_priv)) + if (IS_DG2(dev_priv)) + max_dc = 0; + else if (IS_DG1(dev_priv)) max_dc = 3; else if (DISPLAY_VER(dev_priv) >= 12) max_dc = 4; diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 257cf662f9f4..2f01aca4d981 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -52,6 +52,10 @@ #define DISPLAY_VER12_DMC_MAX_FW_SIZE ICL_DMC_MAX_FW_SIZE +#define DG2_DMC_PATH DMC_PATH(dg2, 2, 06) +#define DG2_DMC_VERSION_REQUIRED DMC_VERSION(2, 06) +MODULE_FIRMWARE(DG2_DMC_PATH); + #define ADLP_DMC_PATH DMC_PATH(adlp, 2, 16) #define ADLP_DMC_VERSION_REQUIRED DMC_VERSION(2, 16) MODULE_FIRMWARE(ADLP_DMC_PATH); @@ -688,7 +692,11 @@ void intel_dmc_ucode_init(struct drm_i915_private *dev_priv) */ intel_dmc_runtime_pm_get(dev_priv); - if (IS_ALDERLAKE_P(dev_priv)) { + if (IS_DG2(dev_priv)) { + dmc->fw_path = DG2_DMC_PATH; + dmc->required_version = DG2_DMC_VERSION_REQUIRED; + dmc->max_fw_size = DISPLAY_VER13_DMC_MAX_FW_SIZE; + } else if (IS_ALDERLAKE_P(dev_priv)) { dmc->fw_path = ADLP_DMC_PATH; dmc->required_version = ADLP_DMC_VERSION_REQUIRED; dmc->max_fw_size = DISPLAY_VER13_DMC_MAX_FW_SIZE; -- 2.25.1
[Intel-gfx] [PATCH 0/1] DG2 DMC Support
While DG2 supports DC5 and DC9, some of the tests in fast-feedback blew up DG2 when the tests forced transition from dc5->dc9 on suspend and dc9->dc5 on resume. Some local experiments performed with Rodrigo on a RIL system showed promising results when dc5 was completely diabled and i915 took only dc9 paths. Sending this so we can check the CI results to confirm the findings from local testing which will hopefully help narrow down the root cause of MMIO BAR lost issue Cc: Rodrigo Vivi Cc: Imre Deak Anusha Srivatsa (1): drm/i915/dmc: Load DMC on DG2 drivers/gpu/drm/i915/display/intel_display_power.c | 4 +++- drivers/gpu/drm/i915/display/intel_dmc.c | 10 +- 2 files changed, 12 insertions(+), 2 deletions(-) -- 2.25.1
[Intel-gfx] [PATCH 0/1] DG2 DMC Support
While DG2 supports DC5 and DC9, some of the tests in fast-feedback blew up DG2 when the tests forced transition from dc5->dc9 on suspend and dc9->dc5 on resume. Some local experiments performed with Rodrigo on a RIL system showed promising results when dc5 was completely diabled and i915 took only dc9 paths. Sending this so we can check the CI results to confirm the findings from local testing which will hopefully help narrow down the root cause of MMIO BAR lost issue Cc: Rodrigo Vivi Cc: Imre Deak Anusha Srivatsa (1): drm/i915/dmc: Load DMC on DG2 drivers/gpu/drm/i915/display/intel_display_power.c | 4 +++- drivers/gpu/drm/i915/display/intel_dmc.c | 10 +- 2 files changed, 12 insertions(+), 2 deletions(-) -- 2.25.1
[Intel-gfx] [PATCH] drm/i915/dmc: Load DMC on DG2
Add Support for DC states on Dg2. v2: Add dc9 as the max supported DC states and disable DC5. v3: set max_dc to 0. (Imre) Cc: Imre Deak Cc: Rodrigo Vivi Signed-off-by: Anusha Srivatsa Reviewed-by: Rodrigo Vivi (v1) --- drivers/gpu/drm/i915/display/intel_display_power.c | 4 +++- drivers/gpu/drm/i915/display/intel_dmc.c | 10 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 1d9bd5808849..15b15f434fcf 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -907,7 +907,9 @@ static u32 get_allowed_dc_mask(const struct drm_i915_private *dev_priv, if (!HAS_DISPLAY(dev_priv)) return 0; - if (IS_DG1(dev_priv)) + if (IS_DG2(dev_priv)) + max_dc = 0; + else if (IS_DG1(dev_priv)) max_dc = 3; else if (DISPLAY_VER(dev_priv) >= 12) max_dc = 4; diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 257cf662f9f4..2f01aca4d981 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -52,6 +52,10 @@ #define DISPLAY_VER12_DMC_MAX_FW_SIZE ICL_DMC_MAX_FW_SIZE +#define DG2_DMC_PATH DMC_PATH(dg2, 2, 06) +#define DG2_DMC_VERSION_REQUIRED DMC_VERSION(2, 06) +MODULE_FIRMWARE(DG2_DMC_PATH); + #define ADLP_DMC_PATH DMC_PATH(adlp, 2, 16) #define ADLP_DMC_VERSION_REQUIRED DMC_VERSION(2, 16) MODULE_FIRMWARE(ADLP_DMC_PATH); @@ -688,7 +692,11 @@ void intel_dmc_ucode_init(struct drm_i915_private *dev_priv) */ intel_dmc_runtime_pm_get(dev_priv); - if (IS_ALDERLAKE_P(dev_priv)) { + if (IS_DG2(dev_priv)) { + dmc->fw_path = DG2_DMC_PATH; + dmc->required_version = DG2_DMC_VERSION_REQUIRED; + dmc->max_fw_size = DISPLAY_VER13_DMC_MAX_FW_SIZE; + } else if (IS_ALDERLAKE_P(dev_priv)) { dmc->fw_path = ADLP_DMC_PATH; dmc->required_version = ADLP_DMC_VERSION_REQUIRED; dmc->max_fw_size = DISPLAY_VER13_DMC_MAX_FW_SIZE; -- 2.25.1
[Intel-gfx] [PATCH] drm/i915/dmc: Load DMC on DG2
Add Support for DC states on Dg2. v2: Add dc9 as the max supported DC states and disable DC5. v3: set max_dc to 0. (Imre) Cc: Imre Deak Cc: Rodrigo Vivi Signed-off-by: Anusha Srivatsa Reviewed-by: Rodrigo Vivi (v1) --- drivers/gpu/drm/i915/display/intel_display_power.c | 4 +++- drivers/gpu/drm/i915/display/intel_dmc.c | 10 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 1d9bd5808849..15b15f434fcf 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -907,7 +907,9 @@ static u32 get_allowed_dc_mask(const struct drm_i915_private *dev_priv, if (!HAS_DISPLAY(dev_priv)) return 0; - if (IS_DG1(dev_priv)) + if (IS_DG2(dev_priv)) + max_dc = 0; + else if (IS_DG1(dev_priv)) max_dc = 3; else if (DISPLAY_VER(dev_priv) >= 12) max_dc = 4; diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 257cf662f9f4..2f01aca4d981 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -52,6 +52,10 @@ #define DISPLAY_VER12_DMC_MAX_FW_SIZE ICL_DMC_MAX_FW_SIZE +#define DG2_DMC_PATH DMC_PATH(dg2, 2, 06) +#define DG2_DMC_VERSION_REQUIRED DMC_VERSION(2, 06) +MODULE_FIRMWARE(DG2_DMC_PATH); + #define ADLP_DMC_PATH DMC_PATH(adlp, 2, 16) #define ADLP_DMC_VERSION_REQUIRED DMC_VERSION(2, 16) MODULE_FIRMWARE(ADLP_DMC_PATH); @@ -688,7 +692,11 @@ void intel_dmc_ucode_init(struct drm_i915_private *dev_priv) */ intel_dmc_runtime_pm_get(dev_priv); - if (IS_ALDERLAKE_P(dev_priv)) { + if (IS_DG2(dev_priv)) { + dmc->fw_path = DG2_DMC_PATH; + dmc->required_version = DG2_DMC_VERSION_REQUIRED; + dmc->max_fw_size = DISPLAY_VER13_DMC_MAX_FW_SIZE; + } else if (IS_ALDERLAKE_P(dev_priv)) { dmc->fw_path = ADLP_DMC_PATH; dmc->required_version = ADLP_DMC_VERSION_REQUIRED; dmc->max_fw_size = DISPLAY_VER13_DMC_MAX_FW_SIZE; -- 2.25.1
[Intel-gfx] [PATCH 0/1] DG2 DMC Support
While DG2 supports DC5 and DC9, some of the tests in fast-feedback blew up DG2 when the tests forced transition from dc5->dc9 on suspend and dc9->dc5 on resume. Some local experiments performed with Rodrigo on a RIL system showed promising results when dc5 was completely diabled and i915 took only dc9 paths. Sending this so we can check the CI results to confirm the findings from local testing which will hopefully help narrow down the root cause of MMIO BAR lost issue Cc: Rodrigo Vivi Cc: Imre Deak Anusha Srivatsa (1): drm/i915/dmc: Load DMC on DG2 drivers/gpu/drm/i915/display/intel_display_power.c | 4 +++- drivers/gpu/drm/i915/display/intel_dmc.c | 10 +- 2 files changed, 12 insertions(+), 2 deletions(-) -- 2.25.1
[Intel-gfx] [PATCH] drm/i915/dmc: Add MMIO range restrictions
Bspec has added some steps that check forDMC MMIO range before programming them v2: Fix for CI v3: move register defines to .h (Anusha) - Check MMIO restrictions per pipe - Add MMIO restricton for v1 dmc header as well (Lucas) v4: s/_PICK/_PICK_EVEN and use it only for Pipe DMC scenario. - clean up sanity check logic.(Lucas) - Add MMIO range for RKL as well.(Anusha) v5: Use DISPLAY_VER instead of per platform check (Lucas) BSpec: 49193 Cc: Cc: Lucas De Marchi Signed-off-by: Anusha Srivatsa Reviewed-by: Lucas De Marchi --- drivers/gpu/drm/i915/display/intel_dmc.c | 42 +++ drivers/gpu/drm/i915/display/intel_dmc_regs.h | 18 +++- 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 257cf662f9f4..e7437ed2597e 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -374,6 +374,43 @@ static void dmc_set_fw_offset(struct intel_dmc *dmc, } } +static bool dmc_mmio_addr_sanity_check(struct intel_dmc *dmc, const u32 *mmioaddr, + u32 mmio_count, int header_ver, u8 dmc_id) +{ + struct drm_i915_private *i915 = container_of(dmc, typeof(*i915), dmc); + u32 start_range, end_range; + int i; + + if (dmc_id >= DMC_FW_MAX) { + drm_warn(>drm, "Unsupported firmware id %u\n", dmc_id); + return false; + } + + if (header_ver == 1) { + start_range = DMC_MMIO_START_RANGE; + end_range = DMC_MMIO_END_RANGE; + } else if (dmc_id == DMC_FW_MAIN) { + start_range = TGL_MAIN_MMIO_START; + end_range = TGL_MAIN_MMIO_END; + } else if (DISPLAY_VER(i915) >= 13) { + start_range = ADLP_PIPE_MMIO_START; + end_range = ADLP_PIPE_MMIO_END; + } else if (DISPLAY_VER(i915) >= 12) { + start_range = TGL_PIPE_MMIO_START(dmc_id); + end_range = TGL_PIPE_MMIO_END(dmc_id); + } else { + drm_warn(>drm, "Unknown mmio range for sanity check"); + return false; + } + + for (i = 0; i < mmio_count; i++) { + if (mmioaddr[i] < start_range || mmioaddr[i] > end_range) + return false; + } + + return true; +} + static u32 parse_dmc_fw_header(struct intel_dmc *dmc, const struct intel_dmc_header_base *dmc_header, size_t rem_size, u8 dmc_id) @@ -443,6 +480,11 @@ static u32 parse_dmc_fw_header(struct intel_dmc *dmc, return 0; } + if (!dmc_mmio_addr_sanity_check(dmc, mmioaddr, mmio_count, dmc_header->header_ver, dmc_id)) { + drm_err(>drm, "DMC firmware has Wrong MMIO Addresses\n"); + return 0; + } + for (i = 0; i < mmio_count; i++) { dmc_info->mmioaddr[i] = _MMIO(mmioaddr[i]); dmc_info->mmiodata[i] = mmiodata[i]; diff --git a/drivers/gpu/drm/i915/display/intel_dmc_regs.h b/drivers/gpu/drm/i915/display/intel_dmc_regs.h index d65e698832eb..67e14eb96a7a 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_regs.h +++ b/drivers/gpu/drm/i915/display/intel_dmc_regs.h @@ -16,7 +16,23 @@ #define DMC_LAST_WRITE _MMIO(0x8F034) #define DMC_LAST_WRITE_VALUE 0xc003b400 #define DMC_MMIO_START_RANGE 0x8 -#define DMC_MMIO_END_RANGE 0x8 +#define DMC_MMIO_END_RANGE 0x8 +#define DMC_V1_MMIO_START_RANGE0x8 +#define TGL_MAIN_MMIO_START0x8F000 +#define TGL_MAIN_MMIO_END 0x8 +#define _TGL_PIPEA_MMIO_START 0x92000 +#define _TGL_PIPEA_MMIO_END0x93FFF +#define _TGL_PIPEB_MMIO_START 0x96000 +#define _TGL_PIPEB_MMIO_END0x97FFF +#define ADLP_PIPE_MMIO_START 0x5F000 +#define ADLP_PIPE_MMIO_END 0x5 + +#define TGL_PIPE_MMIO_START(dmc_id)_PICK_EVEN(((dmc_id) - 1), _TGL_PIPEA_MMIO_START,\ + _TGL_PIPEB_MMIO_START) + +#define TGL_PIPE_MMIO_END(dmc_id) _PICK_EVEN(((dmc_id) - 1), _TGL_PIPEA_MMIO_END,\ + _TGL_PIPEB_MMIO_END) + #define SKL_DMC_DC3_DC5_COUNT _MMIO(0x80030) #define SKL_DMC_DC5_DC6_COUNT _MMIO(0x8002C) #define BXT_DMC_DC3_DC5_COUNT _MMIO(0x80038) -- 2.25.1
[Intel-gfx] [PATCH] drm/i915/dmc: Add MMIO range restrictions
Bspec has added some steps that check forDMC MMIO range before programming them v2: Fix for CI v3: move register defines to .h (Anusha) - Check MMIO restrictions per pipe - Add MMIO restricton for v1 dmc header as well (Lucas) v4: s/_PICK/_PICK_EVEN and use it only for Pipe DMC scenario. - clean up sanity check logic.(Lucas) - Add MMIO range for RKL as well.(Anusha) BSpec: 49193 Cc: Cc: Lucas De Marchi Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_dmc.c | 43 +++ drivers/gpu/drm/i915/display/intel_dmc_regs.h | 18 +++- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 257cf662f9f4..e37ba75e68da 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -374,6 +374,44 @@ static void dmc_set_fw_offset(struct intel_dmc *dmc, } } +static bool dmc_mmio_addr_sanity_check(struct intel_dmc *dmc, const u32 *mmioaddr, + u32 mmio_count, int header_ver, u8 dmc_id) +{ + struct drm_i915_private *i915 = container_of(dmc, typeof(*i915), dmc); + u32 start_range, end_range; + int i; + + if (dmc_id >= DMC_FW_MAX || dmc_id < DMC_FW_MAIN) { + drm_warn(>drm, "Unsupported firmware id %u\n", dmc_id); + return false; + } + + if (header_ver == 1) { + start_range = DMC_MMIO_START_RANGE; + end_range = DMC_MMIO_END_RANGE; + } else if (dmc_id == DMC_FW_MAIN) { + start_range = TGL_MAIN_MMIO_START; + end_range = TGL_MAIN_MMIO_END; + } else if (IS_DG2(i915) || IS_ALDERLAKE_P(i915)) { + start_range = ADLP_PIPE_MMIO_START; + end_range = ADLP_PIPE_MMIO_END; + } else if (IS_TIGERLAKE(i915) || IS_DG1(i915) || IS_ALDERLAKE_S(i915) || + IS_ROCKETLAKE(i915)) { + start_range = TGL_PIPE_MMIO_START(dmc_id); + end_range = TGL_PIPE_MMIO_END(dmc_id); + } else { + drm_warn(>drm, "Unknown mmio range for sanity check"); + return false; + } + + for (i = 0; i < mmio_count; i++) { + if (mmioaddr[i] < start_range || mmioaddr[i] > end_range) + return false; + } + + return true; +} + static u32 parse_dmc_fw_header(struct intel_dmc *dmc, const struct intel_dmc_header_base *dmc_header, size_t rem_size, u8 dmc_id) @@ -443,6 +481,11 @@ static u32 parse_dmc_fw_header(struct intel_dmc *dmc, return 0; } + if (!dmc_mmio_addr_sanity_check(dmc, mmioaddr, mmio_count, dmc_header->header_ver, dmc_id)) { + drm_err(>drm, "DMC firmware has Wrong MMIO Addresses\n"); + return 0; + } + for (i = 0; i < mmio_count; i++) { dmc_info->mmioaddr[i] = _MMIO(mmioaddr[i]); dmc_info->mmiodata[i] = mmiodata[i]; diff --git a/drivers/gpu/drm/i915/display/intel_dmc_regs.h b/drivers/gpu/drm/i915/display/intel_dmc_regs.h index d65e698832eb..67e14eb96a7a 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_regs.h +++ b/drivers/gpu/drm/i915/display/intel_dmc_regs.h @@ -16,7 +16,23 @@ #define DMC_LAST_WRITE _MMIO(0x8F034) #define DMC_LAST_WRITE_VALUE 0xc003b400 #define DMC_MMIO_START_RANGE 0x8 -#define DMC_MMIO_END_RANGE 0x8 +#define DMC_MMIO_END_RANGE 0x8 +#define DMC_V1_MMIO_START_RANGE0x8 +#define TGL_MAIN_MMIO_START0x8F000 +#define TGL_MAIN_MMIO_END 0x8 +#define _TGL_PIPEA_MMIO_START 0x92000 +#define _TGL_PIPEA_MMIO_END0x93FFF +#define _TGL_PIPEB_MMIO_START 0x96000 +#define _TGL_PIPEB_MMIO_END0x97FFF +#define ADLP_PIPE_MMIO_START 0x5F000 +#define ADLP_PIPE_MMIO_END 0x5 + +#define TGL_PIPE_MMIO_START(dmc_id)_PICK_EVEN(((dmc_id) - 1), _TGL_PIPEA_MMIO_START,\ + _TGL_PIPEB_MMIO_START) + +#define TGL_PIPE_MMIO_END(dmc_id) _PICK_EVEN(((dmc_id) - 1), _TGL_PIPEA_MMIO_END,\ + _TGL_PIPEB_MMIO_END) + #define SKL_DMC_DC3_DC5_COUNT _MMIO(0x80030) #define SKL_DMC_DC5_DC6_COUNT _MMIO(0x8002C) #define BXT_DMC_DC3_DC5_COUNT _MMIO(0x80038) -- 2.25.1
[Intel-gfx] [PATCH 0/1] DG2 DMC Support
While DG2 supports DC5 and DC9, some of the tests in fast-feedback blew up DG2 when the tests forced transition from dc5->dc9 on suspend and dc9->dc5 on resume. Some local experiments performed with Rodrigo on a RIL system showed promising results when dc5 was completely diabled and i915 took only dc9 paths. Sending this so we can check the CI results to confirm the findings from local testing which will hopefully help narrow down the root cause of MMIO BAR lost issue Cc: Rodrigo Vivi Cc: Imre Deak Anusha Srivatsa (1): drm/i915/dmc: Load DMC on DG2 drivers/gpu/drm/i915/display/intel_display_power.c | 4 +++- drivers/gpu/drm/i915/display/intel_dmc.c | 10 +- 2 files changed, 12 insertions(+), 2 deletions(-) -- 2.25.1
[Intel-gfx] [PATCH 1/1] drm/i915/dmc: Load DMC on DG2
Add Support for DC states on Dg2. v2: Add dc9 as the max supported DC states and disable DC5. Cc: Rodrigo Vivi Signed-off-by: Anusha Srivatsa Reviewed-by: Rodrigo Vivi (v1) --- drivers/gpu/drm/i915/display/intel_display_power.c | 4 +++- drivers/gpu/drm/i915/display/intel_dmc.c | 10 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 1d9bd5808849..022d63cf68dd 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -907,7 +907,9 @@ static u32 get_allowed_dc_mask(const struct drm_i915_private *dev_priv, if (!HAS_DISPLAY(dev_priv)) return 0; - if (IS_DG1(dev_priv)) + if (IS_DG2(dev_priv)) + max_dc = DC_STATE_EN_DC9; + else if (IS_DG1(dev_priv)) max_dc = 3; else if (DISPLAY_VER(dev_priv) >= 12) max_dc = 4; diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 257cf662f9f4..2f01aca4d981 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -52,6 +52,10 @@ #define DISPLAY_VER12_DMC_MAX_FW_SIZE ICL_DMC_MAX_FW_SIZE +#define DG2_DMC_PATH DMC_PATH(dg2, 2, 06) +#define DG2_DMC_VERSION_REQUIRED DMC_VERSION(2, 06) +MODULE_FIRMWARE(DG2_DMC_PATH); + #define ADLP_DMC_PATH DMC_PATH(adlp, 2, 16) #define ADLP_DMC_VERSION_REQUIRED DMC_VERSION(2, 16) MODULE_FIRMWARE(ADLP_DMC_PATH); @@ -688,7 +692,11 @@ void intel_dmc_ucode_init(struct drm_i915_private *dev_priv) */ intel_dmc_runtime_pm_get(dev_priv); - if (IS_ALDERLAKE_P(dev_priv)) { + if (IS_DG2(dev_priv)) { + dmc->fw_path = DG2_DMC_PATH; + dmc->required_version = DG2_DMC_VERSION_REQUIRED; + dmc->max_fw_size = DISPLAY_VER13_DMC_MAX_FW_SIZE; + } else if (IS_ALDERLAKE_P(dev_priv)) { dmc->fw_path = ADLP_DMC_PATH; dmc->required_version = ADLP_DMC_VERSION_REQUIRED; dmc->max_fw_size = DISPLAY_VER13_DMC_MAX_FW_SIZE; -- 2.25.1
[Intel-gfx] [PATCH] drm/i915/dmc: Add MMIO range restrictions
Bspec has added some steps that check forDMC MMIO range before programming them v2: Fix for CI v3: move register defines to .h (Anusha) - Check MMIO restrictions per pipe - Add MMIO restricton for v1 dmc header as well (Lucas) v4: s/_PICK/_PICK_EVEN and use it only for Pipe DMC scenario. - clean up sanity check logic.(Lucas) - Add MMIO range for RKL as well.(Anusha) BSpec: 49193 Cc: Cc: Lucas De Marchi Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/display/intel_dmc.c | 43 +++ drivers/gpu/drm/i915/display/intel_dmc_regs.h | 18 +++- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 257cf662f9f4..12d5cb850e39 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -374,6 +374,44 @@ static void dmc_set_fw_offset(struct intel_dmc *dmc, } } +static bool dmc_mmio_addr_sanity_check(struct intel_dmc *dmc, const u32 *mmioaddr, + u32 mmio_count, int header_ver, u8 dmc_id) +{ + struct drm_i915_private *i915 = container_of(dmc, typeof(*i915), dmc); + u32 start_range, end_range; + int i; + + if (dmc_id >= DMC_FW_MAX || dmc_id < DMC_FW_MAIN) { + drm_warn(>drm, "Unsupported firmware id %u\n", dmc_id); + return false; + } + + if (header_ver == 1) { + start_range = DMC_MMIO_START_RANGE; + end_range = DMC_MMIO_END_RANGE; + } else if (dmc_id == DMC_FW_MAIN) { + start_range = TGL_MAIN_MMIO_START; + end_range = TGL_MAIN_MMIO_END; + } else if (IS_DG2(i915) || IS_ALDERLAKE_P(i915)) { + start_range = ADLP_PIPE_MMIO_START; + end_range = ADLP_PIPE_MMIO_END; + } else if (IS_TIGERLAKE(i915) || IS_DG1(i915) || IS_ALDERLAKE_S(i915) || + IS_ROCKETLAKE(dev_priv)) { + start_range = TGL_PIPE_MMIO_START(dmc_id); + end_range = TGL_PIPE_MMIO_END(dmc_id); + } else { + drm_warn(>drm, "Unknown mmio range for sanity check"); + return false; + } + + for (i = 0; i < mmio_count; i++) { + if (mmioaddr[i] < start_range || mmioaddr[i] > end_range) + return false; + } + + return true; +} + static u32 parse_dmc_fw_header(struct intel_dmc *dmc, const struct intel_dmc_header_base *dmc_header, size_t rem_size, u8 dmc_id) @@ -443,6 +481,11 @@ static u32 parse_dmc_fw_header(struct intel_dmc *dmc, return 0; } + if (!dmc_mmio_addr_sanity_check(dmc, mmioaddr, mmio_count, dmc_header->header_ver, dmc_id)) { + drm_err(>drm, "DMC firmware has Wrong MMIO Addresses\n"); + return 0; + } + for (i = 0; i < mmio_count; i++) { dmc_info->mmioaddr[i] = _MMIO(mmioaddr[i]); dmc_info->mmiodata[i] = mmiodata[i]; diff --git a/drivers/gpu/drm/i915/display/intel_dmc_regs.h b/drivers/gpu/drm/i915/display/intel_dmc_regs.h index d65e698832eb..67e14eb96a7a 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_regs.h +++ b/drivers/gpu/drm/i915/display/intel_dmc_regs.h @@ -16,7 +16,23 @@ #define DMC_LAST_WRITE _MMIO(0x8F034) #define DMC_LAST_WRITE_VALUE 0xc003b400 #define DMC_MMIO_START_RANGE 0x8 -#define DMC_MMIO_END_RANGE 0x8 +#define DMC_MMIO_END_RANGE 0x8 +#define DMC_V1_MMIO_START_RANGE0x8 +#define TGL_MAIN_MMIO_START0x8F000 +#define TGL_MAIN_MMIO_END 0x8 +#define _TGL_PIPEA_MMIO_START 0x92000 +#define _TGL_PIPEA_MMIO_END0x93FFF +#define _TGL_PIPEB_MMIO_START 0x96000 +#define _TGL_PIPEB_MMIO_END0x97FFF +#define ADLP_PIPE_MMIO_START 0x5F000 +#define ADLP_PIPE_MMIO_END 0x5 + +#define TGL_PIPE_MMIO_START(dmc_id)_PICK_EVEN(((dmc_id) - 1), _TGL_PIPEA_MMIO_START,\ + _TGL_PIPEB_MMIO_START) + +#define TGL_PIPE_MMIO_END(dmc_id) _PICK_EVEN(((dmc_id) - 1), _TGL_PIPEA_MMIO_END,\ + _TGL_PIPEB_MMIO_END) + #define SKL_DMC_DC3_DC5_COUNT _MMIO(0x80030) #define SKL_DMC_DC5_DC6_COUNT _MMIO(0x8002C) #define BXT_DMC_DC3_DC5_COUNT _MMIO(0x80038) -- 2.25.1