diff options
| author | Ivan Lipski <ivan.lipski@amd.com> | 2026-05-14 18:53:50 +0300 |
|---|---|---|
| committer | Alex Deucher <alexander.deucher@amd.com> | 2026-05-27 17:35:16 +0300 |
| commit | 08236c3ef284cd2d110e5e3d51fc9615e551f9dc (patch) | |
| tree | a7c79ce8a7709ede7927923df227d488d70a0692 | |
| parent | 384dbef269d101e5b671fc7b942c56734cd1d186 (diff) | |
| download | linux-08236c3ef284cd2d110e5e3d51fc9615e551f9dc.tar.xz | |
drm/amd/display: Write REFCLK to 48MHz on DCN21
[Why&How]
dccg21_init() calls dccg2_init() which hardcodes 100MHz refclk values
for MICROSECOND_TIME_BASE_DIV and MILLISECOND_TIME_BASE_DIV. DCN21
uses 48MHz refclk, so the wrong values corrupt DCCG timing and cause eDP
link training failure on cold boot.
Write the correct 48MHz values directly instead of calling dccg2_init().
v2:
Fixed typo
Fixes: e6e2b956fc81 ("drm/amd/display: Add missing DCCG register entries for DCN20-DCN316")
Reported-by: Max Chernoff <git@maxchernoff.ca>
Tested-by: Max Chernoff <git@maxchernoff.ca>
Signed-off-by: Ivan Lipski <ivan.lipski@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
| -rw-r--r-- | drivers/gpu/drm/amd/display/dc/dccg/dcn21/dcn21_dccg.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn21/dcn21_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn21/dcn21_dccg.c index c4d4eea140f3..1f23dfccf07a 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn21/dcn21_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn21/dcn21_dccg.c @@ -105,15 +105,26 @@ static void dccg21_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppcl * dccg2_init() unconditionally overwrites MICROSECOND_TIME_BASE_DIV to * 0x00120264, destroying the marker before it can be read. * - * Guard the call: if the S0i3 marker is present, skip dccg2_init() so the + * Guard the call: if the S0i3 marker is present, skip init so the * WA can function correctly. bios_golden_init() will handle init in that case. + * + * DCN21 uses 48MHz refclk, not 100MHz, so we must explicitly set the correct + * values (48MHz is taken from rn_clk_mgr_construct()). */ static void dccg21_init(struct dccg *dccg) { + struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); + if (dccg2_is_s0i3_golden_init_wa_done(dccg)) return; - dccg2_init(dccg); + /* 48MHz refclk from rn_clk_mgr_construct() */ + REG_WRITE(MICROSECOND_TIME_BASE_DIV, 0x00120230); + REG_WRITE(MILLISECOND_TIME_BASE_DIV, 0x0010bb80); + REG_WRITE(DISPCLK_FREQ_CHANGE_CNTL, 0x0e01003c); + + if (REG(REFCLK_CNTL)) + REG_WRITE(REFCLK_CNTL, 0); } static const struct dccg_funcs dccg21_funcs = { |
