[PATCH 08/36] drm/amd/display: On clock init, maintain DISPCLK freq
Hamza Mahfooz
hamza.mahfooz at amd.com
Tue Jun 11 16:51:11 UTC 2024
From: Chris Park <chris.park at amd.com>
[Why]
On init if a display is connected, we need to maintain the DISPCLK
frequency Even though DPG_EN=1, the display still requires the correct
timing or it could cause audio corruption (if DISPCLK freq is reduced).
[How]
Read the current DISPCLK freq and request the same value to ensure the
timing is valid and unchanged.
Reviewed-by: Alvin Lee <alvin.lee2 at amd.com>
Acked-by: Hamza Mahfooz <hamza.mahfooz at amd.com>
Signed-off-by: Chris Park <chris.park at amd.com>
---
.../display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c | 17 +++++++++++++++++
.../amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 11 ++++++++++-
2 files changed, 27 insertions(+), 1 deletion(-)
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 cd1c30fa783a..70f06a7c882e 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
@@ -1459,6 +1459,22 @@ static int dcn401_get_dtb_ref_freq_khz(struct clk_mgr *clk_mgr_base)
return dtb_ref_clk_khz;
}
+static int dcn401_get_dispclk_from_dentist(struct clk_mgr *clk_mgr_base)
+{
+ struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
+ uint32_t dispclk_wdivider;
+ int disp_divider;
+
+ REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, &dispclk_wdivider);
+ disp_divider = dentist_get_divider_from_did(dispclk_wdivider);
+
+ /* Return DISPCLK freq in Khz */
+ if (disp_divider)
+ return (DENTIST_DIVIDER_RANGE_SCALE_FACTOR * clk_mgr->base.dentist_vco_freq_khz) / disp_divider;
+
+ return 0;
+}
+
static struct clk_mgr_funcs dcn401_funcs = {
.get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
.get_dtb_ref_clk_frequency = dcn401_get_dtb_ref_freq_khz,
@@ -1472,6 +1488,7 @@ static struct clk_mgr_funcs dcn401_funcs = {
.are_clock_states_equal = dcn401_are_clock_states_equal,
.enable_pme_wa = dcn401_enable_pme_wa,
.is_smu_present = dcn401_is_smu_present,
+ .get_dispclk_from_dentist = dcn401_get_dispclk_from_dentist,
};
struct clk_mgr_internal *dcn401_clk_mgr_construct(
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
index 4d0c01e866be..e7d6d987e3d3 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
@@ -57,7 +57,16 @@ static void dcn401_initialize_min_clocks(struct dc *dc)
clocks->socclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].socclk_mhz * 1000;
clocks->dramclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].memclk_mhz * 1000;
clocks->dppclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].dppclk_mhz * 1000;
- clocks->dispclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].dispclk_mhz * 1000;
+ if (dc->debug.disable_boot_optimizations) {
+ clocks->dispclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].dispclk_mhz * 1000;
+ } else {
+ /* Even though DPG_EN = 1 for the connected display, it still requires the
+ * correct timing so we cannot set DISPCLK to min freq or it could cause
+ * audio corruption. Read current DISPCLK from DENTIST and request the same
+ * freq to ensure that the timing is valid and unchanged.
+ */
+ clocks->dispclk_khz = dc->clk_mgr->funcs->get_dispclk_from_dentist(dc->clk_mgr);
+ }
clocks->ref_dtbclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].dtbclk_mhz * 1000;
clocks->fclk_p_state_change_support = true;
clocks->p_state_change_support = true;
--
2.45.1
More information about the amd-gfx
mailing list