7373#define CLK1_CLK2_BYPASS_CNTL__CLK2_BYPASS_SEL_MASK 0x00000007L
7474#define CLK1_CLK2_BYPASS_CNTL__CLK2_BYPASS_DIV_MASK 0x000F0000L
7575
76+ #define regCLK5_0_CLK5_spll_field_8 0x464b
77+ #define regCLK5_0_CLK5_spll_field_8_BASE_IDX 0
78+
79+ #define CLK5_0_CLK5_spll_field_8__spll_ssc_en__SHIFT 0xd
80+ #define CLK5_0_CLK5_spll_field_8__spll_ssc_en_MASK 0x00002000L
81+
7682#define SMU_VER_THRESHOLD 0x5D4A00 //93.74.0
7783
7884#define REG (reg_name ) \
@@ -411,6 +417,17 @@ static void dcn35_dump_clk_registers(struct clk_state_registers_and_bypass *regs
411417{
412418}
413419
420+ static bool dcn35_is_spll_ssc_enabled (struct clk_mgr * clk_mgr_base )
421+ {
422+ struct clk_mgr_internal * clk_mgr = TO_CLK_MGR_INTERNAL (clk_mgr_base );
423+ struct dc_context * ctx = clk_mgr -> base .ctx ;
424+ uint32_t ssc_enable ;
425+
426+ REG_GET (CLK5_0_CLK5_spll_field_8 , spll_ssc_en , & ssc_enable );
427+
428+ return ssc_enable == 1 ;
429+ }
430+
414431static void init_clk_states (struct clk_mgr * clk_mgr )
415432{
416433 struct clk_mgr_internal * clk_mgr_int = TO_CLK_MGR_INTERNAL (clk_mgr );
@@ -428,7 +445,16 @@ static void init_clk_states(struct clk_mgr *clk_mgr)
428445
429446void dcn35_init_clocks (struct clk_mgr * clk_mgr )
430447{
448+ struct clk_mgr_internal * clk_mgr_int = TO_CLK_MGR_INTERNAL (clk_mgr );
431449 init_clk_states (clk_mgr );
450+
451+ // to adjust dp_dto reference clock if ssc is enable otherwise to apply dprefclk
452+ if (dcn35_is_spll_ssc_enabled (clk_mgr ))
453+ clk_mgr -> dp_dto_source_clock_in_khz =
454+ dce_adjust_dp_ref_freq_for_ss (clk_mgr_int , clk_mgr -> dprefclk_khz );
455+ else
456+ clk_mgr -> dp_dto_source_clock_in_khz = clk_mgr -> dprefclk_khz ;
457+
432458}
433459static struct clk_bw_params dcn35_bw_params = {
434460 .vram_type = Ddr4MemType ,
@@ -517,6 +543,28 @@ static DpmClocks_t_dcn35 dummy_clocks;
517543
518544static struct dcn35_watermarks dummy_wms = { 0 };
519545
546+ static struct dcn35_ss_info_table ss_info_table = {
547+ .ss_divider = 1000 ,
548+ .ss_percentage = {0 , 0 , 375 , 375 , 375 }
549+ };
550+
551+ static void dcn35_read_ss_info_from_lut (struct clk_mgr_internal * clk_mgr )
552+ {
553+ struct dc_context * ctx = clk_mgr -> base .ctx ;
554+ uint32_t clock_source ;
555+
556+ REG_GET (CLK1_CLK2_BYPASS_CNTL , CLK2_BYPASS_SEL , & clock_source );
557+ // If it's DFS mode, clock_source is 0.
558+ if (dcn35_is_spll_ssc_enabled (& clk_mgr -> base ) && (clock_source < ARRAY_SIZE (ss_info_table .ss_percentage ))) {
559+ clk_mgr -> dprefclk_ss_percentage = ss_info_table .ss_percentage [clock_source ];
560+
561+ if (clk_mgr -> dprefclk_ss_percentage != 0 ) {
562+ clk_mgr -> ss_on_dprefclk = true;
563+ clk_mgr -> dprefclk_ss_divider = ss_info_table .ss_divider ;
564+ }
565+ }
566+ }
567+
520568static void dcn35_build_watermark_ranges (struct clk_bw_params * bw_params , struct dcn35_watermarks * table )
521569{
522570 int i , num_valid_sets ;
@@ -1061,6 +1109,8 @@ void dcn35_clk_mgr_construct(
10611109 dce_clock_read_ss_info (& clk_mgr -> base );
10621110 /*when clk src is from FCH, it could have ss, same clock src as DPREF clk*/
10631111
1112+ dcn35_read_ss_info_from_lut (& clk_mgr -> base );
1113+
10641114 clk_mgr -> base .base .bw_params = & dcn35_bw_params ;
10651115
10661116 if (clk_mgr -> base .base .ctx -> dc -> debug .pstate_enabled ) {
0 commit comments