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: eliminate clock manager code duplication

[Why]
Clock manager contained significant duplicate code between
variants with identical logic for functions using only SMU
calls or shared registers. This increases maintenance overhead
and potential for bugs.

[How]
Expose clock constants and internal functions in header for
sharing. Remove duplicate implementations and update function
pointers to use shared functions. Refactor remaining
variant-specific functions to use shared constants and helper
functions. Add compatibility comments for hardware differences.

Reviewed-by: Dmytro Laktyushkin <dmytro.laktyushkin@amd.com>
Signed-off-by: Gabe Teeger <gabe.teeger@amd.com>
Signed-off-by: Chuanyu Tseng <chuanyu.tseng@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Gabe Teeger and committed by
Alex Deucher
8424ee7d d77ff733

+21 -13
+14 -12
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.c
··· 43 43 #define DC_LOGGER_INIT(logger) \ 44 44 struct dal_logger *dc_logger = logger 45 45 46 - #define DCN42_CLKIP_REFCLK 48000 47 - 48 46 #undef FN 49 47 #define FN(reg_name, field_name) \ 50 48 clk_mgr->clk_mgr_shift->field_name, clk_mgr->clk_mgr_mask->field_name ··· 253 255 dcn42_smu_set_zstate_support(clk_mgr, DCN_ZSTATE_SUPPORT_DISALLOW); 254 256 clk_mgr_base->clks.zstate_support = new_clocks->zstate_support; 255 257 } 258 + /* Only attempt to enable dtbclk if currently disabled AND new state requests it. 259 + * For dcn42b (no dtbclk hardware), init_clk_states sets dtbclk_en=false and 260 + * new_clocks->dtbclk_en should always be false, so this block never executes. 261 + */ 256 262 if (!clk_mgr_base->clks.dtbclk_en && new_clocks->dtbclk_en) { 257 263 int actual_dtbclk = 0; 258 264 ··· 328 326 } 329 327 330 328 /* clock limits are received with MHz precision, divide by 1000 to prevent setting clocks at every call */ 331 - if (!dc->debug.disable_dtb_ref_clk_switch && 329 + if (!dc->debug.disable_dtb_ref_clk_switch && new_clocks->dtbclk_en && 332 330 should_set_clock(safe_to_lower, new_clocks->ref_dtbclk_khz / 1000, 333 331 clk_mgr_base->clks.ref_dtbclk_khz / 1000)) { 334 332 dcn42_update_clocks_update_dtb_dto(clk_mgr, context, new_clocks->ref_dtbclk_khz); ··· 521 519 clk_mgr->clks.zstate_support = DCN_ZSTATE_SUPPORT_UNKNOWN; 522 520 } 523 521 524 - static void dcn42_get_dpm_table_from_smu(struct clk_mgr_internal *clk_mgr, 522 + void dcn42_get_dpm_table_from_smu(struct clk_mgr_internal *clk_mgr, 525 523 struct dcn42_smu_dpm_clks *smu_dpm_clks) 526 524 { 527 525 DpmClocks_t_dcn42 *table = smu_dpm_clks->dpm_clks; ··· 844 842 845 843 } 846 844 847 - static void dcn42_update_clocks_fpga(struct clk_mgr *clk_mgr, 845 + void dcn42_update_clocks_fpga(struct clk_mgr *clk_mgr, 848 846 struct dc_state *context, 849 847 bool safe_to_lower) 850 848 { ··· 897 895 // Both fclk and ref_dppclk run on the same scemi clock. 898 896 clk_mgr_int->dccg->ref_dppclk = clk_mgr->clks.fclk_khz; 899 897 900 - /* TODO: set dtbclk in correct place */ 901 - clk_mgr->clks.dtbclk_en = true; 902 - 903 898 dm_set_dcn_clocks(clk_mgr->ctx, &clk_mgr->clks); 899 + if (clk_mgr->clks.dtbclk_en) { 900 + dcn42_update_clocks_update_dtb_dto(clk_mgr_int, context, clk_mgr->clks.ref_dtbclk_khz); 901 + } else { 902 + clk_mgr->clks.ref_dtbclk_khz = 0; 903 + } 904 904 dcn42_update_clocks_update_dpp_dto(clk_mgr_int, context, safe_to_lower); 905 - 906 - dcn42_update_clocks_update_dtb_dto(clk_mgr_int, context, clk_mgr->clks.ref_dtbclk_khz); 907 905 } 908 906 909 907 unsigned int dcn42_get_max_clock_khz(struct clk_mgr *clk_mgr_base, enum clk_type clk_type) ··· 935 933 return 0; 936 934 } 937 935 938 - static int dcn42_get_dispclk_from_dentist(struct clk_mgr *clk_mgr_base) 936 + int dcn42_get_dispclk_from_dentist(struct clk_mgr *clk_mgr_base) 939 937 { 940 938 struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); 941 939 uint32_t dispclk_wdivider; ··· 956 954 return clk_mgr->smu_present; 957 955 } 958 956 959 - static void dcn42_get_smu_clocks(struct clk_mgr_internal *clk_mgr_int) 957 + void dcn42_get_smu_clocks(struct clk_mgr_internal *clk_mgr_int) 960 958 { 961 959 struct clk_mgr *clk_mgr_base = &clk_mgr_int->base; 962 960 struct dcn42_smu_dpm_clks smu_dpm_clks = { 0 };
+7 -1
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.h
··· 27 27 #include "clk_mgr_internal.h" 28 28 29 29 #define NUM_CLOCK_SOURCES 5 30 + #define DCN42_CLKIP_REFCLK 48000 30 31 31 32 struct dcn42_watermarks; 32 33 ··· 72 71 void dcn42_exit_low_power_state(struct clk_mgr *clk_mgr_base); 73 72 unsigned int dcn42_get_max_clock_khz(struct clk_mgr *clk_mgr_base, enum clk_type clk_type); 74 73 bool dcn42_is_smu_present(struct clk_mgr *clk_mgr_base); 74 + bool dcn42_has_active_display(struct dc *dc, const struct dc_state *context); 75 75 int dcn42_get_active_display_cnt_wa(struct dc *dc, struct dc_state *context, int *all_active_disps); 76 76 void dcn42_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr, struct dc_state *context, bool safe_to_lower); 77 77 void dcn42_update_clocks_update_dtb_dto(struct clk_mgr_internal *clk_mgr, struct dc_state *context, int ref_dtbclk_khz); 78 78 bool dcn42_is_spll_ssc_enabled(struct clk_mgr *clk_mgr_base); 79 - bool dcn42_has_active_display(struct dc *dc, const struct dc_state *context); 79 + struct dcn42_smu_dpm_clks; /* Forward declaration for pointer parameter below */ 80 + void dcn42_get_dpm_table_from_smu(struct clk_mgr_internal *clk_mgr, struct dcn42_smu_dpm_clks *smu_dpm_clks); 81 + void dcn42_get_smu_clocks(struct clk_mgr_internal *clk_mgr_int); 82 + void dcn42_update_clocks_fpga(struct clk_mgr *clk_mgr, struct dc_state *context, bool safe_to_lower); 83 + int dcn42_get_dispclk_from_dentist(struct clk_mgr *clk_mgr_base); 80 84 #endif //__DCN42_CLK_MGR_H__