diff options
author | Chris Park <chris.park@amd.com> | 2024-06-04 14:25:14 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2024-06-14 16:18:55 -0400 |
commit | 3838c6736524c903a95cd1d46fcbbcb6cae8e42f (patch) | |
tree | 31d10f8e4e291fc86cd719b56297bc3fe4c2fb6a /drivers/gpu/drm/amd/display/dc/clk_mgr | |
parent | 3a69c1702fdff79f631525ac6dc4487de050865a (diff) | |
download | linux-3838c6736524c903a95cd1d46fcbbcb6cae8e42f.tar.gz linux-3838c6736524c903a95cd1d46fcbbcb6cae8e42f.tar.bz2 linux-3838c6736524c903a95cd1d46fcbbcb6cae8e42f.zip |
drm/amd/display: On clock init, maintain DISPCLK freq
[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@amd.com>
Acked-by: Hamza Mahfooz <hamza.mahfooz@amd.com>
Signed-off-by: Chris Park <chris.park@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 | 17 |
1 files changed, 17 insertions, 0 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 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( |