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

drm/amd/display: Fix null-deref on vega20 with xgmi

[Why]
After clkmgr rework it gets initialized after resource pool.
The clkmgr is used in resource pool init for xgmi path.
That causes driver crash on Vega20 with xgmi due to NULL deref.

[How]
Move xgmi compensation code to dce121_clk_mgr_construct()
That also allows to make dce121_clock_patch_xgmi_ss_info()
internal static function.

Signed-off-by: Roman Li <Roman.Li@amd.com>
Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Roman Li and committed by
Alex Deucher
496091fa de9f26bb

+11 -15
+11 -3
drivers/gpu/drm/amd/display/dc/clk_mgr/dce120/dce120_clk_mgr.c
··· 30 30 #include "dce110/dce110_clk_mgr.h" 31 31 #include "dce120_clk_mgr.h" 32 32 #include "dce100/dce_clk_mgr.h" 33 + #include "dce120/dce120_hw_sequencer.h" 33 34 34 35 static const struct state_dependent_clocks dce120_max_clks_by_state[] = { 35 36 /*ClocksStateInvalid - should not be used*/ ··· 46 45 47 46 /** 48 47 * dce121_clock_patch_xgmi_ss_info() - Save XGMI spread spectrum info 49 - * @clk_mgr: clock manager base structure 48 + * @clk_mgr_dce: clock manager internal structure 50 49 * 51 50 * Reads from VBIOS the XGMI spread spectrum info and saves it within 52 51 * the dce clock manager. This operation will overwrite the existing dprefclk 53 52 * SS values if the vBIOS query succeeds. Otherwise, it does nothing. It also 54 53 * sets the ->xgmi_enabled flag. 55 54 */ 56 - void dce121_clock_patch_xgmi_ss_info(struct clk_mgr *clk_mgr_base) 55 + static void dce121_clock_patch_xgmi_ss_info(struct clk_mgr_internal *clk_mgr_dce) 57 56 { 58 - struct clk_mgr_internal *clk_mgr_dce = TO_CLK_MGR_INTERNAL(clk_mgr_base); 59 57 enum bp_result result; 60 58 struct spread_spectrum_info info = { { 0 } }; 61 59 struct dc_bios *bp = clk_mgr_dce->base.ctx->dc_bios; ··· 141 141 { 142 142 dce120_clk_mgr_construct(ctx, clk_mgr); 143 143 clk_mgr->base.dprefclk_khz = 625000; 144 + 145 + /* 146 + * The xGMI enabled info is used to determine if audio and display 147 + * clocks need to be adjusted with the WAFL link's SS info. 148 + */ 149 + if (dce121_xgmi_enabled(ctx->dc->hwseq)) 150 + dce121_clock_patch_xgmi_ss_info(clk_mgr); 151 + 144 152 } 145 153
-10
drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
··· 1163 1163 if (!resource_construct(num_virtual_links, dc, &pool->base, res_funcs)) 1164 1164 goto res_create_fail; 1165 1165 1166 - /* 1167 - * This is a bit of a hack. The xGMI enabled info is used to determine 1168 - * if audio and display clocks need to be adjusted with the WAFL link's 1169 - * SS info. This is a responsiblity of the clk_mgr. But since MMHUB is 1170 - * under hwseq, and the relevant register is in MMHUB, we have to do it 1171 - * here. 1172 - */ 1173 - if (is_vg20 && dce121_xgmi_enabled(dc->hwseq)) 1174 - dce121_clock_patch_xgmi_ss_info(dc->clk_mgr); 1175 - 1176 1166 /* Create hardware sequencer */ 1177 1167 if (!dce120_hw_sequencer_create(dc)) 1178 1168 goto controller_create_fail;
-2
drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
··· 53 53 void (*enable_pme_wa) (struct clk_mgr *clk_mgr); 54 54 }; 55 55 56 - void dce121_clock_patch_xgmi_ss_info(struct clk_mgr *clk_mgr_base); 57 - 58 56 struct clk_mgr { 59 57 struct dc_context *ctx; 60 58 struct clk_mgr_funcs *funcs;