@@ -648,27 +648,47 @@ static unsigned int convert_wck_ratio(uint8_t wck_ratio)
648
648
return 1 ;
649
649
}
650
650
651
+ static inline uint32_t calc_dram_speed_mts (const MemPstateTable_t * entry )
652
+ {
653
+ return entry -> UClk * convert_wck_ratio (entry -> WckRatio ) * 2 ;
654
+ }
655
+
651
656
static void dcn35_clk_mgr_helper_populate_bw_params (struct clk_mgr_internal * clk_mgr ,
652
657
struct integrated_info * bios_info ,
653
658
DpmClocks_t_dcn35 * clock_table )
654
659
{
655
660
struct clk_bw_params * bw_params = clk_mgr -> base .bw_params ;
656
661
struct clk_limit_table_entry def_max = bw_params -> clk_table .entries [bw_params -> clk_table .num_entries - 1 ];
657
- uint32_t max_pstate = 0 , max_uclk = 0 , max_fclk = 0 ;
658
- uint32_t min_pstate = 0 , max_dispclk = 0 , max_dppclk = 0 ;
662
+ uint32_t max_fclk = 0 , min_pstate = 0 , max_dispclk = 0 , max_dppclk = 0 ;
663
+ uint32_t max_pstate = 0 , max_dram_speed_mts = 0 , min_dram_speed_mts = 0 ;
659
664
int i ;
660
665
666
+ /* Determine min/max p-state values. */
661
667
for (i = 0 ; i < clock_table -> NumMemPstatesEnabled ; i ++ ) {
662
- if (is_valid_clock_value (clock_table -> MemPstateTable [i ].UClk ) &&
663
- clock_table -> MemPstateTable [i ].UClk > max_uclk ) {
664
- max_uclk = clock_table -> MemPstateTable [i ].UClk ;
668
+ uint32_t dram_speed_mts = calc_dram_speed_mts (& clock_table -> MemPstateTable [i ]);
669
+
670
+ if (is_valid_clock_value (dram_speed_mts ) && dram_speed_mts > max_dram_speed_mts ) {
671
+ max_dram_speed_mts = dram_speed_mts ;
665
672
max_pstate = i ;
666
673
}
667
674
}
668
675
669
- /* We expect the table to contain at least one valid Uclk entry. */
670
- ASSERT ( is_valid_clock_value ( max_uclk )) ;
676
+ min_dram_speed_mts = max_dram_speed_mts ;
677
+ min_pstate = max_pstate ;
671
678
679
+ for (i = 0 ; i < clock_table -> NumMemPstatesEnabled ; i ++ ) {
680
+ uint32_t dram_speed_mts = calc_dram_speed_mts (& clock_table -> MemPstateTable [i ]);
681
+
682
+ if (is_valid_clock_value (dram_speed_mts ) && dram_speed_mts < min_dram_speed_mts ) {
683
+ min_dram_speed_mts = dram_speed_mts ;
684
+ min_pstate = i ;
685
+ }
686
+ }
687
+
688
+ /* We expect the table to contain at least one valid P-state entry. */
689
+ ASSERT (clock_table -> NumMemPstatesEnabled &&
690
+ is_valid_clock_value (max_dram_speed_mts ) &&
691
+ is_valid_clock_value (min_dram_speed_mts ));
672
692
673
693
/* dispclk and dppclk can be max at any voltage, same number of levels for both */
674
694
if (clock_table -> NumDispClkLevelsEnabled <= NUM_DISPCLK_DPM_LEVELS &&
@@ -678,47 +698,46 @@ static void dcn35_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *clk
678
698
max_dppclk = find_max_clk_value (clock_table -> DppClocks ,
679
699
clock_table -> NumDispClkLevelsEnabled );
680
700
} else {
701
+ /* Invalid number of entries in the table from PMFW. */
681
702
ASSERT (0 );
682
703
}
683
- if (clock_table -> NumFclkLevelsEnabled <= NUM_FCLK_DPM_LEVELS )
684
- max_fclk = find_max_clk_value (clock_table -> FclkClocks_Freq ,
685
- clock_table -> NumFclkLevelsEnabled );
686
704
687
- for (i = 0 ; i < clock_table -> NumMemPstatesEnabled ; i ++ ) {
688
- uint32_t min_uclk = clock_table -> MemPstateTable [0 ].UClk ;
689
- int j ;
705
+ /* Base the clock table on dcfclk, need at least one entry regardless of pmfw table */
706
+ ASSERT (clock_table -> NumDcfClkLevelsEnabled > 0 );
690
707
691
- for (j = 1 ; j < clock_table -> NumMemPstatesEnabled ; j ++ ) {
692
- if (is_valid_clock_value (clock_table -> MemPstateTable [j ].UClk ) &&
693
- clock_table -> MemPstateTable [j ].UClk < min_uclk &&
694
- clock_table -> MemPstateTable [j ].Voltage <= clock_table -> SocVoltage [i ]) {
695
- min_uclk = clock_table -> MemPstateTable [j ].UClk ;
696
- min_pstate = j ;
697
- }
698
- }
708
+ max_fclk = find_max_clk_value (clock_table -> FclkClocks_Freq , clock_table -> NumFclkLevelsEnabled );
699
709
710
+ for (i = 0 ; i < clock_table -> NumDcfClkLevelsEnabled ; i ++ ) {
711
+ int j ;
712
+
713
+ /* First search defaults for the clocks we don't read using closest lower or equal default dcfclk */
700
714
for (j = bw_params -> clk_table .num_entries - 1 ; j > 0 ; j -- )
701
715
if (bw_params -> clk_table .entries [j ].dcfclk_mhz <= clock_table -> DcfClocks [i ])
702
- break ;
716
+ break ;
703
717
704
718
bw_params -> clk_table .entries [i ].phyclk_mhz = bw_params -> clk_table .entries [j ].phyclk_mhz ;
705
719
bw_params -> clk_table .entries [i ].phyclk_d18_mhz = bw_params -> clk_table .entries [j ].phyclk_d18_mhz ;
706
720
bw_params -> clk_table .entries [i ].dtbclk_mhz = bw_params -> clk_table .entries [j ].dtbclk_mhz ;
707
- bw_params -> clk_table .entries [i ].fclk_mhz = max_fclk ;
721
+
722
+ /* Now update clocks we do read */
708
723
bw_params -> clk_table .entries [i ].memclk_mhz = clock_table -> MemPstateTable [min_pstate ].MemClk ;
709
724
bw_params -> clk_table .entries [i ].voltage = clock_table -> MemPstateTable [min_pstate ].Voltage ;
710
725
bw_params -> clk_table .entries [i ].dcfclk_mhz = clock_table -> DcfClocks [i ];
711
726
bw_params -> clk_table .entries [i ].socclk_mhz = clock_table -> SocClocks [i ];
712
727
bw_params -> clk_table .entries [i ].dispclk_mhz = max_dispclk ;
713
728
bw_params -> clk_table .entries [i ].dppclk_mhz = max_dppclk ;
714
- bw_params -> clk_table .entries [i ].wck_ratio = convert_wck_ratio (
715
- clock_table -> MemPstateTable [min_pstate ].WckRatio );
716
- }
729
+ bw_params -> clk_table .entries [i ].wck_ratio =
730
+ convert_wck_ratio (clock_table -> MemPstateTable [min_pstate ].WckRatio );
731
+
732
+ /* Dcfclk and Fclk are tied, but at a different ratio */
733
+ bw_params -> clk_table .entries [i ].fclk_mhz = min (max_fclk , 2 * clock_table -> DcfClocks [i ]);
734
+ }
717
735
718
736
/* Make sure to include at least one entry at highest pstate */
719
737
if (max_pstate != min_pstate || i == 0 ) {
720
738
if (i > MAX_NUM_DPM_LVL - 1 )
721
739
i = MAX_NUM_DPM_LVL - 1 ;
740
+
722
741
bw_params -> clk_table .entries [i ].fclk_mhz = max_fclk ;
723
742
bw_params -> clk_table .entries [i ].memclk_mhz = clock_table -> MemPstateTable [max_pstate ].MemClk ;
724
743
bw_params -> clk_table .entries [i ].voltage = clock_table -> MemPstateTable [max_pstate ].Voltage ;
@@ -734,6 +753,7 @@ static void dcn35_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *clk
734
753
}
735
754
bw_params -> clk_table .num_entries = i -- ;
736
755
756
+ /* Make sure all highest clocks are included*/
737
757
bw_params -> clk_table .entries [i ].socclk_mhz =
738
758
find_max_clk_value (clock_table -> SocClocks , NUM_SOCCLK_DPM_LEVELS );
739
759
bw_params -> clk_table .entries [i ].dispclk_mhz =
@@ -752,6 +772,11 @@ static void dcn35_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *clk
752
772
bw_params -> clk_table .num_entries_per_clk .num_fclk_levels = clock_table -> NumFclkLevelsEnabled ;
753
773
bw_params -> clk_table .num_entries_per_clk .num_memclk_levels = clock_table -> NumMemPstatesEnabled ;
754
774
bw_params -> clk_table .num_entries_per_clk .num_socclk_levels = clock_table -> NumSocClkLevelsEnabled ;
775
+
776
+ /*
777
+ * Set any 0 clocks to max default setting. Not an issue for
778
+ * power since we aren't doing switching in such case anyway
779
+ */
755
780
for (i = 0 ; i < bw_params -> clk_table .num_entries ; i ++ ) {
756
781
if (!bw_params -> clk_table .entries [i ].fclk_mhz ) {
757
782
bw_params -> clk_table .entries [i ].fclk_mhz = def_max .fclk_mhz ;
0 commit comments