Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/amd/display: Fix DP audio DTO1 clock source on DCE 6.

On DCE 6, DP audio was not working. However, it worked when an
HDMI monitor was also plugged in.

Looking at dce_aud_wall_dto_setup it seems that the main
difference is that we use DTO1 when only DP is plugged in.

When programming DTO1, it uses audio_dto_source_clock_in_khz
which is set from get_dp_ref_freq_khz

The dce60_get_dp_ref_freq_khz implementation looks incorrect,
because DENTIST_DISPCLK_CNTL seems to be always zero on DCE 6,
so it isn't usable.
I compared dce60_get_dp_ref_freq_khz to the legacy display code,
specifically dce_v6_0_audio_set_dto, and it turns out that in
case of DCE 6, it needs to use the display clock. With that,
DP audio started working on Pitcairn, Oland and Cape Verde.

However, it still didn't work on Tahiti. Despite having the
same DCE version, Tahiti seems to have a different audio device.
After some trial and error I realized that it works with the
default display clock as reported by the VBIOS, not the current
display clock.

The patch was tested on all four SI GPUs:

* Pitcairn (DCE 6.0)
* Oland (DCE 6.4)
* Cape Verde (DCE 6.0)
* Tahiti (DCE 6.0 but different)

The testing was done on Samsung Odyssey G7 LS28BG700EPXEN on
each of the above GPUs, at the following settings:

* 4K 60 Hz
* 1080p 60 Hz
* 1080p 144 Hz

Acked-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Rodrigo Siqueira <siqueira@igalia.com>
Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Timur Kristóf and committed by
Alex Deucher
645cc786 e3bd5365

+6 -15
+6 -15
drivers/gpu/drm/amd/display/dc/clk_mgr/dce60/dce60_clk_mgr.c
··· 83 83 static int dce60_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr_base) 84 84 { 85 85 struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); 86 - int dprefclk_wdivider; 87 - int dp_ref_clk_khz; 88 - int target_div; 86 + struct dc_context *ctx = clk_mgr_base->ctx; 87 + int dp_ref_clk_khz = 0; 89 88 90 - /* DCE6 has no DPREFCLK_CNTL to read DP Reference Clock source */ 91 - 92 - /* Read the mmDENTIST_DISPCLK_CNTL to get the currently 93 - * programmed DID DENTIST_DPREFCLK_WDIVIDER*/ 94 - REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DPREFCLK_WDIVIDER, &dprefclk_wdivider); 95 - 96 - /* Convert DENTIST_DPREFCLK_WDIVIDERto actual divider*/ 97 - target_div = dentist_get_divider_from_did(dprefclk_wdivider); 98 - 99 - /* Calculate the current DFS clock, in kHz.*/ 100 - dp_ref_clk_khz = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR 101 - * clk_mgr->base.dentist_vco_freq_khz) / target_div; 89 + if (ASIC_REV_IS_TAHITI_P(ctx->asic_id.hw_internal_rev)) 90 + dp_ref_clk_khz = ctx->dc_bios->fw_info.default_display_engine_pll_frequency; 91 + else 92 + dp_ref_clk_khz = clk_mgr_base->clks.dispclk_khz; 102 93 103 94 return dce_adjust_dp_ref_freq_for_ss(clk_mgr, dp_ref_clk_khz); 104 95 }