diff options
author | Joshua Aberback <joshua.aberback@amd.com> | 2024-03-28 13:43:36 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2024-05-13 15:45:55 -0400 |
commit | 7662bc61c030edae9346dc56daa6109ce353f5b4 (patch) | |
tree | 21cdae99f52796101499cabce4c4e97620fa8c53 /drivers/gpu/drm/amd/display/dc/clk_mgr | |
parent | 78d18b6655fea3d9d8b30fd2b78b11749b4b981f (diff) |
drm/amd/display: Disable AC/DC codepath when unnecessary
[WHY]
If there are no DC clock limits present, or if the DC limits are the same
as the AC limits, we can disable the AC/DC codepath as there won't be any
validation differences between the two modes.
[HOW]
When all DC power mode clock limits are the same as the max clock
values, there won't be any difference between AC mode and DC mode. Zero
out DC limits that equal max and provide a new cap to indicate the
presence of any non-zero DC mode limit. In summary:
- zero out DC limits that are the same as max clock value
- new dc cap to indicate the presence of DC mode limits
- set limits present if any clock has distinct AC and DC values from SMU
Acked-by: Alex Hung <alex.hung@amd.com>
Reviewed-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Joshua Aberback <joshua.aberback@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/clk_mgr')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c index 1cf750cfed66..bd74ff47fb37 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c @@ -180,7 +180,6 @@ static void dcn401_build_wm_range_table(struct clk_mgr *clk_mgr) void dcn401_init_clocks(struct clk_mgr *clk_mgr_base) { struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); - unsigned int num_levels; struct clk_limit_num_entries *num_entries_per_clk = &clk_mgr_base->bw_params->clk_table.num_entries_per_clk; unsigned int i; @@ -208,34 +207,43 @@ void dcn401_init_clocks(struct clk_mgr *clk_mgr_base) &clk_mgr_base->bw_params->clk_table.entries[0].dcfclk_mhz, &num_entries_per_clk->num_dcfclk_levels); clk_mgr_base->bw_params->dc_mode_limit.dcfclk_mhz = dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, PPCLK_DCFCLK); + if (num_entries_per_clk->num_dcfclk_levels && clk_mgr_base->bw_params->dc_mode_limit.dcfclk_mhz == + clk_mgr_base->bw_params->clk_table.entries[num_entries_per_clk->num_dcfclk_levels - 1].dcfclk_mhz) + clk_mgr_base->bw_params->dc_mode_limit.dcfclk_mhz = 0; /* SOCCLK */ dcn401_init_single_clock(clk_mgr, PPCLK_SOCCLK, &clk_mgr_base->bw_params->clk_table.entries[0].socclk_mhz, &num_entries_per_clk->num_socclk_levels); clk_mgr_base->bw_params->dc_mode_limit.socclk_mhz = dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, PPCLK_SOCCLK); + if (num_entries_per_clk->num_socclk_levels && clk_mgr_base->bw_params->dc_mode_limit.socclk_mhz == + clk_mgr_base->bw_params->clk_table.entries[num_entries_per_clk->num_socclk_levels - 1].socclk_mhz) + clk_mgr_base->bw_params->dc_mode_limit.socclk_mhz = 0; /* DTBCLK */ if (!clk_mgr->base.ctx->dc->debug.disable_dtb_ref_clk_switch) { dcn401_init_single_clock(clk_mgr, PPCLK_DTBCLK, &clk_mgr_base->bw_params->clk_table.entries[0].dtbclk_mhz, &num_entries_per_clk->num_dtbclk_levels); - clk_mgr_base->bw_params->dc_mode_limit.dtbclk_mhz = - dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, PPCLK_DTBCLK); + clk_mgr_base->bw_params->dc_mode_limit.dtbclk_mhz = dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, PPCLK_DTBCLK); + if (num_entries_per_clk->num_dtbclk_levels && clk_mgr_base->bw_params->dc_mode_limit.dtbclk_mhz == + clk_mgr_base->bw_params->clk_table.entries[num_entries_per_clk->num_dtbclk_levels - 1].dtbclk_mhz) + clk_mgr_base->bw_params->dc_mode_limit.dtbclk_mhz = 0; } /* DISPCLK */ dcn401_init_single_clock(clk_mgr, PPCLK_DISPCLK, &clk_mgr_base->bw_params->clk_table.entries[0].dispclk_mhz, &num_entries_per_clk->num_dispclk_levels); - num_levels = num_entries_per_clk->num_dispclk_levels; clk_mgr_base->bw_params->dc_mode_limit.dispclk_mhz = dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, PPCLK_DISPCLK); + if (num_entries_per_clk->num_dispclk_levels && clk_mgr_base->bw_params->dc_mode_limit.dispclk_mhz == + clk_mgr_base->bw_params->clk_table.entries[num_entries_per_clk->num_dispclk_levels - 1].dispclk_mhz) + clk_mgr_base->bw_params->dc_mode_limit.dispclk_mhz = 0; /* DPPCLK */ dcn401_init_single_clock(clk_mgr, PPCLK_DPPCLK, &clk_mgr_base->bw_params->clk_table.entries[0].dppclk_mhz, &num_entries_per_clk->num_dppclk_levels); - num_levels = num_entries_per_clk->num_dppclk_levels; if (num_entries_per_clk->num_dcfclk_levels && num_entries_per_clk->num_dtbclk_levels && @@ -243,7 +251,7 @@ void dcn401_init_clocks(struct clk_mgr *clk_mgr_base) clk_mgr->dpm_present = true; if (clk_mgr_base->ctx->dc->debug.min_disp_clk_khz) { - for (i = 0; i < num_levels; i++) + for (i = 0; i < num_entries_per_clk->num_dispclk_levels; i++) if (clk_mgr_base->bw_params->clk_table.entries[i].dispclk_mhz < khz_to_mhz_ceil(clk_mgr_base->ctx->dc->debug.min_disp_clk_khz)) clk_mgr_base->bw_params->clk_table.entries[i].dispclk_mhz @@ -251,7 +259,7 @@ void dcn401_init_clocks(struct clk_mgr *clk_mgr_base) } if (clk_mgr_base->ctx->dc->debug.min_dpp_clk_khz) { - for (i = 0; i < num_levels; i++) + for (i = 0; i < num_entries_per_clk->num_dppclk_levels; i++) if (clk_mgr_base->bw_params->clk_table.entries[i].dppclk_mhz < khz_to_mhz_ceil(clk_mgr_base->ctx->dc->debug.min_dpp_clk_khz)) clk_mgr_base->bw_params->clk_table.entries[i].dppclk_mhz @@ -842,12 +850,18 @@ static void dcn401_get_memclk_states_from_smu(struct clk_mgr *clk_mgr_base) } clk_mgr_base->bw_params->dc_mode_limit.memclk_mhz = dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, PPCLK_UCLK); + if (num_entries_per_clk->num_memclk_levels && clk_mgr_base->bw_params->dc_mode_limit.memclk_mhz == + clk_mgr_base->bw_params->clk_table.entries[num_entries_per_clk->num_memclk_levels - 1].memclk_mhz) + clk_mgr_base->bw_params->dc_mode_limit.memclk_mhz = 0; clk_mgr_base->bw_params->dc_mode_softmax_memclk = clk_mgr_base->bw_params->dc_mode_limit.memclk_mhz; dcn401_init_single_clock(clk_mgr, PPCLK_FCLK, &clk_mgr_base->bw_params->clk_table.entries[0].fclk_mhz, &num_entries_per_clk->num_fclk_levels); clk_mgr_base->bw_params->dc_mode_limit.fclk_mhz = dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, PPCLK_FCLK); + if (num_entries_per_clk->num_fclk_levels && clk_mgr_base->bw_params->dc_mode_limit.fclk_mhz == + clk_mgr_base->bw_params->clk_table.entries[num_entries_per_clk->num_fclk_levels - 1].fclk_mhz) + clk_mgr_base->bw_params->dc_mode_limit.fclk_mhz = 0; if (num_entries_per_clk->num_memclk_levels >= num_entries_per_clk->num_fclk_levels) { num_levels = num_entries_per_clk->num_memclk_levels; |