@@ -122,7 +122,9 @@ static const struct {
122122};
123123
124124static void ufs_qcom_get_default_testbus_cfg (struct ufs_qcom_host * host );
125- static int ufs_qcom_set_core_clk_ctrl (struct ufs_hba * hba , unsigned long freq );
125+ static unsigned long ufs_qcom_opp_freq_to_clk_freq (struct ufs_hba * hba ,
126+ unsigned long freq , char * name );
127+ static int ufs_qcom_set_core_clk_ctrl (struct ufs_hba * hba , bool is_scale_up , unsigned long freq );
126128
127129static struct ufs_qcom_host * rcdev_to_ufs_host (struct reset_controller_dev * rcd )
128130{
@@ -656,7 +658,7 @@ static int ufs_qcom_link_startup_notify(struct ufs_hba *hba,
656658 return - EINVAL ;
657659 }
658660
659- err = ufs_qcom_set_core_clk_ctrl (hba , ULONG_MAX );
661+ err = ufs_qcom_set_core_clk_ctrl (hba , true, ULONG_MAX );
660662 if (err )
661663 dev_err (hba -> dev , "cfg core clk ctrl failed\n" );
662664 /*
@@ -1414,29 +1416,46 @@ static int ufs_qcom_set_clk_40ns_cycles(struct ufs_hba *hba,
14141416 return ufshcd_dme_set (hba , UIC_ARG_MIB (PA_VS_CORE_CLK_40NS_CYCLES ), reg );
14151417}
14161418
1417- static int ufs_qcom_set_core_clk_ctrl (struct ufs_hba * hba , unsigned long freq )
1419+ static int ufs_qcom_set_core_clk_ctrl (struct ufs_hba * hba , bool is_scale_up , unsigned long freq )
14181420{
14191421 struct ufs_qcom_host * host = ufshcd_get_variant (hba );
14201422 struct list_head * head = & hba -> clk_list_head ;
14211423 struct ufs_clk_info * clki ;
14221424 u32 cycles_in_1us = 0 ;
14231425 u32 core_clk_ctrl_reg ;
1426+ unsigned long clk_freq ;
14241427 int err ;
14251428
1429+ if (hba -> use_pm_opp && freq != ULONG_MAX ) {
1430+ clk_freq = ufs_qcom_opp_freq_to_clk_freq (hba , freq , "core_clk_unipro" );
1431+ if (clk_freq ) {
1432+ cycles_in_1us = ceil (clk_freq , HZ_PER_MHZ );
1433+ goto set_core_clk_ctrl ;
1434+ }
1435+ }
1436+
14261437 list_for_each_entry (clki , head , list ) {
14271438 if (!IS_ERR_OR_NULL (clki -> clk ) &&
14281439 !strcmp (clki -> name , "core_clk_unipro" )) {
1429- if (!clki -> max_freq )
1440+ if (!clki -> max_freq ) {
14301441 cycles_in_1us = 150 ; /* default for backwards compatibility */
1431- else if (freq == ULONG_MAX )
1442+ break ;
1443+ }
1444+
1445+ if (freq == ULONG_MAX ) {
14321446 cycles_in_1us = ceil (clki -> max_freq , HZ_PER_MHZ );
1433- else
1434- cycles_in_1us = ceil ( freq , HZ_PER_MHZ );
1447+ break ;
1448+ }
14351449
1450+ if (is_scale_up )
1451+ cycles_in_1us = ceil (clki -> max_freq , HZ_PER_MHZ );
1452+ else
1453+ cycles_in_1us = ceil (clk_get_rate (clki -> clk ), HZ_PER_MHZ );
14361454 break ;
14371455 }
14381456 }
14391457
1458+ set_core_clk_ctrl :
14401459 err = ufshcd_dme_get (hba ,
14411460 UIC_ARG_MIB (DME_VS_CORE_CLK_CTRL ),
14421461 & core_clk_ctrl_reg );
@@ -1479,7 +1498,7 @@ static int ufs_qcom_clk_scale_up_pre_change(struct ufs_hba *hba, unsigned long f
14791498 return ret ;
14801499 }
14811500 /* set unipro core clock attributes and clear clock divider */
1482- return ufs_qcom_set_core_clk_ctrl (hba , freq );
1501+ return ufs_qcom_set_core_clk_ctrl (hba , true, freq );
14831502}
14841503
14851504static int ufs_qcom_clk_scale_up_post_change (struct ufs_hba * hba )
@@ -1511,7 +1530,7 @@ static int ufs_qcom_clk_scale_down_pre_change(struct ufs_hba *hba)
15111530static int ufs_qcom_clk_scale_down_post_change (struct ufs_hba * hba , unsigned long freq )
15121531{
15131532 /* set unipro core clock attributes and clear clock divider */
1514- return ufs_qcom_set_core_clk_ctrl (hba , freq );
1533+ return ufs_qcom_set_core_clk_ctrl (hba , false, freq );
15151534}
15161535
15171536static int ufs_qcom_clk_scale_notify (struct ufs_hba * hba , bool scale_up ,
@@ -2081,11 +2100,53 @@ static int ufs_qcom_config_esi(struct ufs_hba *hba)
20812100 return ret ;
20822101}
20832102
2103+ static unsigned long ufs_qcom_opp_freq_to_clk_freq (struct ufs_hba * hba ,
2104+ unsigned long freq , char * name )
2105+ {
2106+ struct ufs_clk_info * clki ;
2107+ struct dev_pm_opp * opp ;
2108+ unsigned long clk_freq ;
2109+ int idx = 0 ;
2110+ bool found = false;
2111+
2112+ opp = dev_pm_opp_find_freq_exact_indexed (hba -> dev , freq , 0 , true);
2113+ if (IS_ERR (opp )) {
2114+ dev_err (hba -> dev , "Failed to find OPP for exact frequency %lu\n" , freq );
2115+ return 0 ;
2116+ }
2117+
2118+ list_for_each_entry (clki , & hba -> clk_list_head , list ) {
2119+ if (!strcmp (clki -> name , name )) {
2120+ found = true;
2121+ break ;
2122+ }
2123+
2124+ idx ++ ;
2125+ }
2126+
2127+ if (!found ) {
2128+ dev_err (hba -> dev , "Failed to find clock '%s' in clk list\n" , name );
2129+ dev_pm_opp_put (opp );
2130+ return 0 ;
2131+ }
2132+
2133+ clk_freq = dev_pm_opp_get_freq_indexed (opp , idx );
2134+
2135+ dev_pm_opp_put (opp );
2136+
2137+ return clk_freq ;
2138+ }
2139+
20842140static u32 ufs_qcom_freq_to_gear_speed (struct ufs_hba * hba , unsigned long freq )
20852141{
20862142 u32 gear = UFS_HS_DONT_CHANGE ;
2143+ unsigned long unipro_freq ;
2144+
2145+ if (!hba -> use_pm_opp )
2146+ return gear ;
20872147
2088- switch (freq ) {
2148+ unipro_freq = ufs_qcom_opp_freq_to_clk_freq (hba , freq , "core_clk_unipro" );
2149+ switch (unipro_freq ) {
20892150 case 403000000 :
20902151 gear = UFS_HS_G5 ;
20912152 break ;
0 commit comments