From: Chris Park <chris.p...@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.l...@amd.com>
Acked-by: Hamza Mahfooz <hamza.mahf...@amd.com>
Signed-off-by: Chris Park <chris.p...@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

Reply via email to