@@ -64,12 +64,6 @@ enum mtk_dvfsrc_bw_type {
6464 DVFSRC_BW_MAX ,
6565};
6666
67- struct dvfsrc_bw_constraints {
68- u16 max_dram_nom_bw ;
69- u16 max_dram_peak_bw ;
70- u16 max_dram_hrt_bw ;
71- };
72-
7367struct dvfsrc_opp {
7468 u32 vcore_opp ;
7569 u32 dram_opp ;
@@ -98,7 +92,7 @@ struct dvfsrc_soc_data {
9892 const u8 * bw_units ;
9993 const bool has_emi_ddr ;
10094 const struct dvfsrc_opp_desc * opps_desc ;
101- u32 (* calc_dram_bw )(struct mtk_dvfsrc * dvfsrc , int type , u64 bw );
95+ u32 (* calc_dram_bw )(struct mtk_dvfsrc * dvfsrc , enum mtk_dvfsrc_bw_type type , u64 bw );
10296 u32 (* get_target_level )(struct mtk_dvfsrc * dvfsrc );
10397 u32 (* get_current_level )(struct mtk_dvfsrc * dvfsrc );
10498 u32 (* get_vcore_level )(struct mtk_dvfsrc * dvfsrc );
@@ -113,7 +107,22 @@ struct dvfsrc_soc_data {
113107 void (* set_vscp_level )(struct mtk_dvfsrc * dvfsrc , u32 level );
114108 int (* wait_for_opp_level )(struct mtk_dvfsrc * dvfsrc , u32 level );
115109 int (* wait_for_vcore_level )(struct mtk_dvfsrc * dvfsrc , u32 level );
116- const struct dvfsrc_bw_constraints * bw_constraints ;
110+
111+ /**
112+ * @bw_max_constraints - array of maximum bandwidth for this hardware
113+ *
114+ * indexed by &enum mtk_dvfsrc_bw_type, storing the maximum permissible
115+ * hardware value for each bandwidth type.
116+ */
117+ const u32 * const bw_max_constraints ;
118+
119+ /**
120+ * @bw_min_constraints - array of minimum bandwidth for this hardware
121+ *
122+ * indexed by &enum mtk_dvfsrc_bw_type, storing the minimum permissible
123+ * hardware value for each bandwidth type.
124+ */
125+ const u32 * const bw_min_constraints ;
117126};
118127
119128static u32 dvfsrc_readl (struct mtk_dvfsrc * dvfs , u32 offset )
@@ -383,59 +392,62 @@ static u32 dvfsrc_get_opp_count_v4(struct mtk_dvfsrc *dvfsrc)
383392 return FIELD_GET (DVFSRC_V4_BASIC_CTRL_OPP_COUNT , val ) + 1 ;
384393}
385394
386- static u32 dvfsrc_calc_dram_bw_v1 (struct mtk_dvfsrc * dvfsrc , int type , u64 bw )
395+ static u32
396+ dvfsrc_calc_dram_bw_v1 (struct mtk_dvfsrc * dvfsrc , enum mtk_dvfsrc_bw_type type , u64 bw )
387397{
388- return (u32 )div_u64 (bw , 100 * 1000 );
398+ return clamp_val (div_u64 (bw , 100 * 1000 ), dvfsrc -> dvd -> bw_min_constraints [type ],
399+ dvfsrc -> dvd -> bw_max_constraints [type ]);
389400}
390401
391- static u32 dvfsrc_calc_dram_bw_v4 (struct mtk_dvfsrc * dvfsrc , int type , u64 bw )
402+ /**
403+ * dvfsrc_calc_dram_bw_v4 - convert kbps to hardware register bandwidth value
404+ * @dvfsrc: pointer to the &struct mtk_dvfsrc of this driver instance
405+ * @type: one of %DVFSRC_BW_AVG, %DVFSRC_BW_PEAK, or %DVFSRC_BW_HRT
406+ * @bw: the bandwidth in kilobits per second
407+ *
408+ * Returns the hardware register value appropriate for expressing @bw, clamped
409+ * to hardware limits.
410+ */
411+ static u32
412+ dvfsrc_calc_dram_bw_v4 (struct mtk_dvfsrc * dvfsrc , enum mtk_dvfsrc_bw_type type , u64 bw )
392413{
393414 u8 bw_unit = dvfsrc -> dvd -> bw_units [type ];
394415 u64 bw_mbps ;
416+ u32 bw_hw ;
395417
396418 if (type < DVFSRC_BW_AVG || type >= DVFSRC_BW_MAX )
397419 return 0 ;
398420
399421 bw_mbps = div_u64 (bw , 1000 );
400- return (u32 )div_u64 ((bw_mbps + bw_unit - 1 ), bw_unit );
422+ bw_hw = div_u64 ((bw_mbps + bw_unit - 1 ), bw_unit );
423+ return clamp_val (bw_hw , dvfsrc -> dvd -> bw_min_constraints [type ],
424+ dvfsrc -> dvd -> bw_max_constraints [type ]);
401425}
402426
403427static void __dvfsrc_set_dram_bw_v1 (struct mtk_dvfsrc * dvfsrc , u32 reg ,
404- int type , u16 max_bw , u16 min_bw , u64 bw )
428+ enum mtk_dvfsrc_bw_type type , u64 bw )
405429{
406- u32 new_bw = dvfsrc -> dvd -> calc_dram_bw (dvfsrc , type , bw );
407-
408- /* If bw constraints (in mbps) are defined make sure to respect them */
409- if (max_bw )
410- new_bw = min (new_bw , max_bw );
411- if (min_bw && new_bw > 0 )
412- new_bw = max (new_bw , min_bw );
430+ u32 bw_hw = dvfsrc -> dvd -> calc_dram_bw (dvfsrc , type , bw );
413431
414- dvfsrc_writel (dvfsrc , reg , new_bw );
432+ dvfsrc_writel (dvfsrc , reg , bw_hw );
415433
416434 if (type == DVFSRC_BW_AVG && dvfsrc -> dvd -> has_emi_ddr )
417- dvfsrc_writel (dvfsrc , DVFSRC_SW_EMI_BW , bw );
435+ dvfsrc_writel (dvfsrc , DVFSRC_SW_EMI_BW , bw_hw );
418436}
419437
420438static void dvfsrc_set_dram_bw_v1 (struct mtk_dvfsrc * dvfsrc , u64 bw )
421439{
422- u64 max_bw = dvfsrc -> dvd -> bw_constraints -> max_dram_nom_bw ;
423-
424- __dvfsrc_set_dram_bw_v1 (dvfsrc , DVFSRC_SW_BW , DVFSRC_BW_AVG , max_bw , 0 , bw );
440+ __dvfsrc_set_dram_bw_v1 (dvfsrc , DVFSRC_SW_BW , DVFSRC_BW_AVG , bw );
425441};
426442
427443static void dvfsrc_set_dram_peak_bw_v1 (struct mtk_dvfsrc * dvfsrc , u64 bw )
428444{
429- u64 max_bw = dvfsrc -> dvd -> bw_constraints -> max_dram_peak_bw ;
430-
431- __dvfsrc_set_dram_bw_v1 (dvfsrc , DVFSRC_SW_PEAK_BW , DVFSRC_BW_PEAK , max_bw , 0 , bw );
445+ __dvfsrc_set_dram_bw_v1 (dvfsrc , DVFSRC_SW_PEAK_BW , DVFSRC_BW_PEAK , bw );
432446}
433447
434448static void dvfsrc_set_dram_hrt_bw_v1 (struct mtk_dvfsrc * dvfsrc , u64 bw )
435449{
436- u64 max_bw = dvfsrc -> dvd -> bw_constraints -> max_dram_hrt_bw ;
437-
438- __dvfsrc_set_dram_bw_v1 (dvfsrc , DVFSRC_SW_HRT_BW , DVFSRC_BW_HRT , max_bw , 0 , bw );
450+ __dvfsrc_set_dram_bw_v1 (dvfsrc , DVFSRC_SW_HRT_BW , DVFSRC_BW_HRT , bw );
439451}
440452
441453static void dvfsrc_set_opp_level_v1 (struct mtk_dvfsrc * dvfsrc , u32 level )
@@ -688,11 +700,22 @@ static int mtk_dvfsrc_probe(struct platform_device *pdev)
688700 return 0 ;
689701}
690702
691- static const struct dvfsrc_bw_constraints dvfsrc_bw_constr_v1 = { 0 , 0 , 0 };
692- static const struct dvfsrc_bw_constraints dvfsrc_bw_constr_v2 = {
693- .max_dram_nom_bw = 255 ,
694- .max_dram_peak_bw = 255 ,
695- .max_dram_hrt_bw = 1023 ,
703+ static const u32 dvfsrc_bw_min_constr_none [DVFSRC_BW_MAX ] = {
704+ [DVFSRC_BW_AVG ] = 0 ,
705+ [DVFSRC_BW_PEAK ] = 0 ,
706+ [DVFSRC_BW_HRT ] = 0 ,
707+ };
708+
709+ static const u32 dvfsrc_bw_max_constr_v1 [DVFSRC_BW_MAX ] = {
710+ [DVFSRC_BW_AVG ] = U32_MAX ,
711+ [DVFSRC_BW_PEAK ] = U32_MAX ,
712+ [DVFSRC_BW_HRT ] = U32_MAX ,
713+ };
714+
715+ static const u32 dvfsrc_bw_max_constr_v2 [DVFSRC_BW_MAX ] = {
716+ [DVFSRC_BW_AVG ] = 65535 ,
717+ [DVFSRC_BW_PEAK ] = 65535 ,
718+ [DVFSRC_BW_HRT ] = 1023 ,
696719};
697720
698721static const struct dvfsrc_opp dvfsrc_opp_mt6893_lp4 [] = {
@@ -725,7 +748,8 @@ static const struct dvfsrc_soc_data mt6893_data = {
725748 .set_vscp_level = dvfsrc_set_vscp_level_v2 ,
726749 .wait_for_opp_level = dvfsrc_wait_for_opp_level_v2 ,
727750 .wait_for_vcore_level = dvfsrc_wait_for_vcore_level_v1 ,
728- .bw_constraints = & dvfsrc_bw_constr_v2 ,
751+ .bw_max_constraints = dvfsrc_bw_max_constr_v2 ,
752+ .bw_min_constraints = dvfsrc_bw_min_constr_none ,
729753};
730754
731755static const struct dvfsrc_opp dvfsrc_opp_mt8183_lp4 [] = {
@@ -763,7 +787,8 @@ static const struct dvfsrc_soc_data mt8183_data = {
763787 .set_vcore_level = dvfsrc_set_vcore_level_v1 ,
764788 .wait_for_opp_level = dvfsrc_wait_for_opp_level_v1 ,
765789 .wait_for_vcore_level = dvfsrc_wait_for_vcore_level_v1 ,
766- .bw_constraints = & dvfsrc_bw_constr_v1 ,
790+ .bw_max_constraints = dvfsrc_bw_max_constr_v1 ,
791+ .bw_min_constraints = dvfsrc_bw_min_constr_none ,
767792};
768793
769794static const struct dvfsrc_opp dvfsrc_opp_mt8195_lp4 [] = {
@@ -797,7 +822,8 @@ static const struct dvfsrc_soc_data mt8195_data = {
797822 .set_vscp_level = dvfsrc_set_vscp_level_v2 ,
798823 .wait_for_opp_level = dvfsrc_wait_for_opp_level_v2 ,
799824 .wait_for_vcore_level = dvfsrc_wait_for_vcore_level_v1 ,
800- .bw_constraints = & dvfsrc_bw_constr_v2 ,
825+ .bw_max_constraints = dvfsrc_bw_max_constr_v2 ,
826+ .bw_min_constraints = dvfsrc_bw_min_constr_none ,
801827};
802828
803829static const u8 mt8196_bw_units [] = {
@@ -825,7 +851,8 @@ static const struct dvfsrc_soc_data mt8196_data = {
825851 .set_vscp_level = dvfsrc_set_vscp_level_v2 ,
826852 .wait_for_opp_level = dvfsrc_wait_for_opp_level_v4 ,
827853 .wait_for_vcore_level = dvfsrc_wait_for_vcore_level_v4 ,
828- .bw_constraints = & dvfsrc_bw_constr_v1 ,
854+ .bw_max_constraints = dvfsrc_bw_max_constr_v2 ,
855+ .bw_min_constraints = dvfsrc_bw_min_constr_none ,
829856};
830857
831858static const struct of_device_id mtk_dvfsrc_of_match [] = {
0 commit comments