summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlvin Lee <Alvin.Lee2@amd.com>2026-08-26 13:49:58 -0400
committerAlex Deucher <alexander.deucher@amd.com>2026-09-10 12:02:13 -0400
commit00eaae7bca217987fda68795d2fa61d5b9f5931e (patch)
tree3aa87d017906f0831ae4ecfb03b09c709aeac59c
parent606dc2492b8ca657118b4c4b1443a20a2bfa9a7c (diff)
downloadlinux-next-00eaae7bca217987fda68795d2fa61d5b9f5931e.tar.gz
linux-next-00eaae7bca217987fda68795d2fa61d5b9f5931e.zip
drm/amd/display: Add override capability for UTM table params
[Why & How] Add calls for overriding UTM table params from PMFW. This is for debug and test purposes only when PMFW has not yet populated the table values correctly. Reviewed-by: Wenjing Liu <wenjing.liu@amd.com> Signed-off-by: Alvin Lee <Alvin.Lee2@amd.com> Signed-off-by: Ray Wu <ray.wu@amd.com> Tested-by: Dan Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dalsmc.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_clk_mgr.c70
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_smu_driver_if.h44
3 files changed, 88 insertions, 28 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dalsmc.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dalsmc.h
index 6954a54dad89..9b109959bd7f 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dalsmc.h
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dalsmc.h
@@ -112,7 +112,7 @@ typedef struct {
* TABLE_DAL_INIT - Full TABLE_DAL_INIT payload transferred from SMU to DRAM.
*/
#define TABLE_DAL_INIT 0xD
-#define MAX_PPCLK_COUNT 20
+#define MAX_PPCLK_COUNT 22
#define DPM_CLOCK_OFFSET(Ppclk) \
(sizeof(DalInitHeader_t) + (Ppclk) * sizeof(DpmClock_t))
#define UTM_TABLE_OFFSET \
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_clk_mgr.c
index 83989b4b1fdd..2b7740b82161 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_clk_mgr.c
@@ -479,6 +479,39 @@ static int dcn60_get_dtb_ref_freq_khz(struct clk_mgr *clk_mgr_base)
return dtb_ref_clk_khz;
}
+/**
+ * dcn60_override_dc_mode_limit - Override DC mode limits from the clock table.
+ * @dc_limit: output DC mode limit to populate
+ * @clk_table: clock table already populated (and possibly overridden)
+ *
+ * Sets the DC mode max frequency for each clock to the highest populated DPM
+ * level in the clock table. Deriving the limit from the clock table (rather
+ * than the raw DAL init table) ensures any overrides applied to the clock
+ * levels are respected.
+ */
+static void dcn60_override_dc_mode_limit(
+ struct clk_limit_table_entry *dc_limit,
+ const struct clk_limit_table *clk_table)
+{
+ const struct clk_limit_table_entry *entries = clk_table->entries;
+ const struct clk_limit_num_entries *num_entries = &clk_table->num_entries_per_clk;
+
+ dc_limit->dcfclk_mhz = num_entries->num_dcfclk_levels ?
+ entries[num_entries->num_dcfclk_levels - 1].dcfclk_mhz : 0;
+ dc_limit->socclk_mhz = num_entries->num_socclk_levels ?
+ entries[num_entries->num_socclk_levels - 1].socclk_mhz : 0;
+ dc_limit->dtbclk_mhz = num_entries->num_dtbclk_levels ?
+ entries[num_entries->num_dtbclk_levels - 1].dtbclk_mhz : 0;
+ dc_limit->dispclk_mhz = num_entries->num_dispclk_levels ?
+ entries[num_entries->num_dispclk_levels - 1].dispclk_mhz : 0;
+ dc_limit->dppclk_mhz = num_entries->num_dppclk_levels ?
+ entries[num_entries->num_dppclk_levels - 1].dppclk_mhz : 0;
+ dc_limit->memclk_mhz = num_entries->num_memclk_levels ?
+ entries[num_entries->num_memclk_levels - 1].memclk_mhz : 0;
+ dc_limit->fclk_mhz = num_entries->num_fclk_levels ?
+ entries[num_entries->num_fclk_levels - 1].fclk_mhz : 0;
+}
+
static unsigned int dcn60_get_dc_mode_limit_mhz(const DpmClock_t *dpm_clk)
{
if (dpm_clk->NumClocks
@@ -495,8 +528,10 @@ static unsigned int dcn60_get_dc_mode_limit_mhz(const DpmClock_t *dpm_clk)
*
* Sets the DC mode max frequency for each clock. If DcMaxClock equals the
* highest DPM level, the limit is set to 0 (no DC-specific cap).
+ *
+ * Temporarily unused.
*/
-static void dcn60_populate_dc_mode_limit(
+static void __maybe_unused dcn60_populate_dc_mode_limit(
struct clk_limit_table_entry *dc_limit,
const DalInitTable_t *init_table)
{
@@ -578,6 +613,20 @@ static void dcn60_populate_clk_table(struct clk_mgr_internal *clk_mgr,
clk_table->num_entries = 1;
}
+/**
+ * dcn60_override_clk_table - Override the clock table with hardcoded values.
+ * @clk_table: clock table to override
+ *
+ * Temporary debug/bring-up override that replaces the DPM clock levels
+ * populated from the DAL init table (see dcn60_populate_clk_table) with a
+ * fixed set of hardcoded values. Implement any override as needed.
+ */
+static void dcn60_override_clk_table(struct clk_limit_table *clk_table)
+{
+ /* Override as needed */
+ (void)clk_table;
+}
+
static void dcn60_override_bw_params(struct clk_mgr_internal *clk_mgr,
struct clk_bw_params *bw_params)
{
@@ -605,12 +654,17 @@ static void dcn60_override_bw_params(struct clk_mgr_internal *clk_mgr,
bw_params->dc_mode_softmax_memclk = bw_params->dc_mode_limit.memclk_mhz;
- /* The qos model stores dchub_v3 as a const view of a mutable table, so
- * cast away const to apply the override.
- */
- if (bw_params->utm_qos_model && bw_params->utm_qos_model->dchub_v3)
+ /* Override as needed - temporary for debug only. */
+ if (bw_params->utm_qos_model && bw_params->utm_qos_model->dchub_v3) {
+ dcn6_test_initialize_utm_qos_model_v3(
+ (struct utm_qos_model *)bw_params->utm_qos_model,
+ (struct utm_qos_model_dchub_v3 *)bw_params->utm_qos_model->dchub_v3);
+
+ // Override for lsdma here is redundant with the above call, but this may need to outlive
+ // the test_initialize call for debug purposes so keep it here for now.
dcn6_test_override_lsdma_bandwidth_v3(
(struct utm_qos_model_dchub_v3 *)bw_params->utm_qos_model->dchub_v3);
+ }
}
/**
@@ -685,7 +739,9 @@ static bool dcn60_fetch_dal_init_table(struct clk_mgr_internal *clk_mgr)
clk_mgr->smu_ver = init_table->Header.SmuVersion;
dcn60_populate_clk_table(clk_mgr, &bw_params->clk_table, init_table);
- dcn60_populate_dc_mode_limit(&bw_params->dc_mode_limit, init_table);
+ // Comment out for now - DC mode limit is not yet used in DCN6 and the current
+ // population from init table will cause undefined behaviors.
+ //dcn60_populate_dc_mode_limit(&bw_params->dc_mode_limit, init_table);
bw_params->num_channels = init_table->MemoryConfig.NumUmcChannels;
bw_params->dram_channel_width_bytes =
@@ -694,6 +750,8 @@ static bool dcn60_fetch_dal_init_table(struct clk_mgr_internal *clk_mgr)
dcn60_populate_utm_qos_model(clk_mgr, &bw_params->utm_qos_model, init_table);
dcn60_override_bw_params(clk_mgr, bw_params);
+ dcn60_override_clk_table(&bw_params->clk_table);
+ dcn60_override_dc_mode_limit(&bw_params->dc_mode_limit, &bw_params->clk_table);
return true;
}
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_smu_driver_if.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_smu_driver_if.h
index 3e101fa87cfd..ca23518d88b9 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_smu_driver_if.h
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_smu_driver_if.h
@@ -9,27 +9,29 @@
//Only Clks that have DPM descriptors are listed here
// This should be the same order as DPM_e
typedef enum {
- PPCLK_GFXCLK = 0,
- PPCLK_BTNCLK = 1,
- PPCLK_LCLK = 2,
- PPCLK_UCLK = 3,
- PPCLK_FCLK = 4,
- PPCLK_G7FCLK = 5,
- PPCLK_SOCCLK = 6,
- PPCLK_ACLK = 7,
- PPCLK_DCFCLK = 8,
- PPCLK_VPECLK = 9,
- PPCLK_DISPCLK = 10,
- PPCLK_DPPCLK = 11,
- PPCLK_DPREFCLK = 12,
- PPCLK_CFPUCLK = 13,
- PPCLK_LOGANCLK = 14,
- PPCLK_MSPCLK = 15,
- PPCLK_MOVADCLK = 16,
- PPCLK_DTBCLK = 17,
- PPCLK_DCLK_0 = 18,
- PPCLK_VCLK_0 = 19,
- PPCLK_COUNT = 20,
+ PPCLK_GFXCLK = 0,
+ PPCLK_NVECLK1,
+ PPCLK_NVECLK2,
+ PPCLK_NVECLK3,
+ PPCLK_LCLK,
+ PPCLK_UCLK,
+ PPCLK_FCLK,
+ PPCLK_G7FCLK,
+ PPCLK_SOCCLK,
+ PPCLK_ACLK,
+ PPCLK_DCFCLK,
+ PPCLK_VPECLK,
+ PPCLK_DISPCLK,
+ PPCLK_DPPCLK,
+ PPCLK_DPREFCLK,
+ PPCLK_CFPUCLK,
+ PPCLK_LOGANCLK,
+ PPCLK_MSPHCLK,
+ PPCLK_MSPLCLK,
+ PPCLK_MSPEDECLK,
+ PPCLK_MOVADCLK,
+ PPCLK_DTBCLK,
+ PPCLK_COUNT,
} PPCLK_e;
typedef struct {