summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/dc/clk_mgr
diff options
context:
space:
mode:
authorChris Park <chris.park@amd.com>2024-06-04 14:25:14 -0400
committerAlex Deucher <alexander.deucher@amd.com>2024-06-14 16:18:55 -0400
commit3838c6736524c903a95cd1d46fcbbcb6cae8e42f (patch)
tree31d10f8e4e291fc86cd719b56297bc3fe4c2fb6a /drivers/gpu/drm/amd/display/dc/clk_mgr
parent3a69c1702fdff79f631525ac6dc4487de050865a (diff)
downloadlinux-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.c17
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(