2020#include <linux/delay.h>
2121#include <linux/interrupt.h>
2222#include <linux/module.h>
23+ #include <linux/pm_opp.h>
2324#include <linux/regulator/consumer.h>
2425#include <linux/sched/clock.h>
2526#include <linux/iopoll.h>
@@ -274,7 +275,8 @@ static inline void ufshcd_add_delay_before_dme_cmd(struct ufs_hba *hba);
274275static int ufshcd_host_reset_and_restore (struct ufs_hba * hba );
275276static void ufshcd_resume_clkscaling (struct ufs_hba * hba );
276277static void ufshcd_suspend_clkscaling (struct ufs_hba * hba );
277- static int ufshcd_scale_clks (struct ufs_hba * hba , bool scale_up );
278+ static int ufshcd_scale_clks (struct ufs_hba * hba , unsigned long freq ,
279+ bool scale_up );
278280static irqreturn_t ufshcd_intr (int irq , void * __hba );
279281static int ufshcd_change_power_mode (struct ufs_hba * hba ,
280282 struct ufs_pa_layer_attr * pwr_mode );
@@ -1061,14 +1063,32 @@ static int ufshcd_set_clk_freq(struct ufs_hba *hba, bool scale_up)
10611063 return ret ;
10621064}
10631065
1066+ static int ufshcd_opp_set_rate (struct ufs_hba * hba , unsigned long freq )
1067+ {
1068+ struct dev_pm_opp * opp ;
1069+ int ret ;
1070+
1071+ opp = dev_pm_opp_find_freq_floor_indexed (hba -> dev ,
1072+ & freq , 0 );
1073+ if (IS_ERR (opp ))
1074+ return PTR_ERR (opp );
1075+
1076+ ret = dev_pm_opp_set_opp (hba -> dev , opp );
1077+ dev_pm_opp_put (opp );
1078+
1079+ return ret ;
1080+ }
1081+
10641082/**
10651083 * ufshcd_scale_clks - scale up or scale down UFS controller clocks
10661084 * @hba: per adapter instance
1085+ * @freq: frequency to scale
10671086 * @scale_up: True if scaling up and false if scaling down
10681087 *
10691088 * Return: 0 if successful; < 0 upon failure.
10701089 */
1071- static int ufshcd_scale_clks (struct ufs_hba * hba , bool scale_up )
1090+ static int ufshcd_scale_clks (struct ufs_hba * hba , unsigned long freq ,
1091+ bool scale_up )
10721092{
10731093 int ret = 0 ;
10741094 ktime_t start = ktime_get ();
@@ -1077,13 +1097,21 @@ static int ufshcd_scale_clks(struct ufs_hba *hba, bool scale_up)
10771097 if (ret )
10781098 goto out ;
10791099
1080- ret = ufshcd_set_clk_freq (hba , scale_up );
1100+ if (hba -> use_pm_opp )
1101+ ret = ufshcd_opp_set_rate (hba , freq );
1102+ else
1103+ ret = ufshcd_set_clk_freq (hba , scale_up );
10811104 if (ret )
10821105 goto out ;
10831106
10841107 ret = ufshcd_vops_clk_scale_notify (hba , scale_up , POST_CHANGE );
1085- if (ret )
1086- ufshcd_set_clk_freq (hba , !scale_up );
1108+ if (ret ) {
1109+ if (hba -> use_pm_opp )
1110+ ufshcd_opp_set_rate (hba ,
1111+ hba -> devfreq -> previous_freq );
1112+ else
1113+ ufshcd_set_clk_freq (hba , !scale_up );
1114+ }
10871115
10881116out :
10891117 trace_ufshcd_profile_clk_scaling (dev_name (hba -> dev ),
@@ -1095,19 +1123,23 @@ static int ufshcd_scale_clks(struct ufs_hba *hba, bool scale_up)
10951123/**
10961124 * ufshcd_is_devfreq_scaling_required - check if scaling is required or not
10971125 * @hba: per adapter instance
1126+ * @freq: frequency to scale
10981127 * @scale_up: True if scaling up and false if scaling down
10991128 *
11001129 * Return: true if scaling is required, false otherwise.
11011130 */
11021131static bool ufshcd_is_devfreq_scaling_required (struct ufs_hba * hba ,
1103- bool scale_up )
1132+ unsigned long freq , bool scale_up )
11041133{
11051134 struct ufs_clk_info * clki ;
11061135 struct list_head * head = & hba -> clk_list_head ;
11071136
11081137 if (list_empty (head ))
11091138 return false;
11101139
1140+ if (hba -> use_pm_opp )
1141+ return freq != hba -> clk_scaling .target_freq ;
1142+
11111143 list_for_each_entry (clki , head , list ) {
11121144 if (!IS_ERR_OR_NULL (clki -> clk )) {
11131145 if (scale_up && clki -> max_freq ) {
@@ -1303,12 +1335,14 @@ static void ufshcd_clock_scaling_unprepare(struct ufs_hba *hba, int err, bool sc
13031335/**
13041336 * ufshcd_devfreq_scale - scale up/down UFS clocks and gear
13051337 * @hba: per adapter instance
1338+ * @freq: frequency to scale
13061339 * @scale_up: True for scaling up and false for scalin down
13071340 *
13081341 * Return: 0 for success; -EBUSY if scaling can't happen at this time; non-zero
13091342 * for any other errors.
13101343 */
1311- static int ufshcd_devfreq_scale (struct ufs_hba * hba , bool scale_up )
1344+ static int ufshcd_devfreq_scale (struct ufs_hba * hba , unsigned long freq ,
1345+ bool scale_up )
13121346{
13131347 int ret = 0 ;
13141348
@@ -1323,7 +1357,7 @@ static int ufshcd_devfreq_scale(struct ufs_hba *hba, bool scale_up)
13231357 goto out_unprepare ;
13241358 }
13251359
1326- ret = ufshcd_scale_clks (hba , scale_up );
1360+ ret = ufshcd_scale_clks (hba , freq , scale_up );
13271361 if (ret ) {
13281362 if (!scale_up )
13291363 ufshcd_scale_gear (hba , true);
@@ -1334,7 +1368,8 @@ static int ufshcd_devfreq_scale(struct ufs_hba *hba, bool scale_up)
13341368 if (scale_up ) {
13351369 ret = ufshcd_scale_gear (hba , true);
13361370 if (ret ) {
1337- ufshcd_scale_clks (hba , false);
1371+ ufshcd_scale_clks (hba , hba -> devfreq -> previous_freq ,
1372+ false);
13381373 goto out_unprepare ;
13391374 }
13401375 }
@@ -1393,9 +1428,22 @@ static int ufshcd_devfreq_target(struct device *dev,
13931428 if (!ufshcd_is_clkscaling_supported (hba ))
13941429 return - EINVAL ;
13951430
1396- clki = list_first_entry (& hba -> clk_list_head , struct ufs_clk_info , list );
1397- /* Override with the closest supported frequency */
1398- * freq = (unsigned long ) clk_round_rate (clki -> clk , * freq );
1431+ if (hba -> use_pm_opp ) {
1432+ struct dev_pm_opp * opp ;
1433+
1434+ /* Get the recommended frequency from OPP framework */
1435+ opp = devfreq_recommended_opp (dev , freq , flags );
1436+ if (IS_ERR (opp ))
1437+ return PTR_ERR (opp );
1438+
1439+ dev_pm_opp_put (opp );
1440+ } else {
1441+ /* Override with the closest supported frequency */
1442+ clki = list_first_entry (& hba -> clk_list_head , struct ufs_clk_info ,
1443+ list );
1444+ * freq = (unsigned long ) clk_round_rate (clki -> clk , * freq );
1445+ }
1446+
13991447 spin_lock_irqsave (hba -> host -> host_lock , irq_flags );
14001448 if (ufshcd_eh_in_progress (hba )) {
14011449 spin_unlock_irqrestore (hba -> host -> host_lock , irq_flags );
@@ -1417,20 +1465,27 @@ static int ufshcd_devfreq_target(struct device *dev,
14171465 goto out ;
14181466 }
14191467
1420- /* Decide based on the rounded-off frequency and update */
1421- scale_up = * freq == clki -> max_freq ;
1422- if (!scale_up )
1468+ /* Decide based on the target or rounded-off frequency and update */
1469+ if (hba -> use_pm_opp )
1470+ scale_up = * freq > hba -> clk_scaling .target_freq ;
1471+ else
1472+ scale_up = * freq == clki -> max_freq ;
1473+
1474+ if (!hba -> use_pm_opp && !scale_up )
14231475 * freq = clki -> min_freq ;
1476+
14241477 /* Update the frequency */
1425- if (!ufshcd_is_devfreq_scaling_required (hba , scale_up )) {
1478+ if (!ufshcd_is_devfreq_scaling_required (hba , * freq , scale_up )) {
14261479 spin_unlock_irqrestore (hba -> host -> host_lock , irq_flags );
14271480 ret = 0 ;
14281481 goto out ; /* no state change required */
14291482 }
14301483 spin_unlock_irqrestore (hba -> host -> host_lock , irq_flags );
14311484
14321485 start = ktime_get ();
1433- ret = ufshcd_devfreq_scale (hba , scale_up );
1486+ ret = ufshcd_devfreq_scale (hba , * freq , scale_up );
1487+ if (!ret )
1488+ hba -> clk_scaling .target_freq = * freq ;
14341489
14351490 trace_ufshcd_profile_clk_scaling (dev_name (hba -> dev ),
14361491 (scale_up ? "up" : "down" ),
@@ -1450,8 +1505,6 @@ static int ufshcd_devfreq_get_dev_status(struct device *dev,
14501505 struct ufs_hba * hba = dev_get_drvdata (dev );
14511506 struct ufs_clk_scaling * scaling = & hba -> clk_scaling ;
14521507 unsigned long flags ;
1453- struct list_head * clk_list = & hba -> clk_list_head ;
1454- struct ufs_clk_info * clki ;
14551508 ktime_t curr_t ;
14561509
14571510 if (!ufshcd_is_clkscaling_supported (hba ))
@@ -1464,17 +1517,24 @@ static int ufshcd_devfreq_get_dev_status(struct device *dev,
14641517 if (!scaling -> window_start_t )
14651518 goto start_window ;
14661519
1467- clki = list_first_entry (clk_list , struct ufs_clk_info , list );
14681520 /*
14691521 * If current frequency is 0, then the ondemand governor considers
14701522 * there's no initial frequency set. And it always requests to set
14711523 * to max. frequency.
14721524 */
1473- stat -> current_frequency = clki -> curr_freq ;
1525+ if (hba -> use_pm_opp ) {
1526+ stat -> current_frequency = hba -> clk_scaling .target_freq ;
1527+ } else {
1528+ struct list_head * clk_list = & hba -> clk_list_head ;
1529+ struct ufs_clk_info * clki ;
1530+
1531+ clki = list_first_entry (clk_list , struct ufs_clk_info , list );
1532+ stat -> current_frequency = clki -> curr_freq ;
1533+ }
1534+
14741535 if (scaling -> is_busy_started )
14751536 scaling -> tot_busy_t += ktime_us_delta (curr_t ,
14761537 scaling -> busy_start_t );
1477-
14781538 stat -> total_time = ktime_us_delta (curr_t , scaling -> window_start_t );
14791539 stat -> busy_time = scaling -> tot_busy_t ;
14801540start_window :
@@ -1503,9 +1563,11 @@ static int ufshcd_devfreq_init(struct ufs_hba *hba)
15031563 if (list_empty (clk_list ))
15041564 return 0 ;
15051565
1506- clki = list_first_entry (clk_list , struct ufs_clk_info , list );
1507- dev_pm_opp_add (hba -> dev , clki -> min_freq , 0 );
1508- dev_pm_opp_add (hba -> dev , clki -> max_freq , 0 );
1566+ if (!hba -> use_pm_opp ) {
1567+ clki = list_first_entry (clk_list , struct ufs_clk_info , list );
1568+ dev_pm_opp_add (hba -> dev , clki -> min_freq , 0 );
1569+ dev_pm_opp_add (hba -> dev , clki -> max_freq , 0 );
1570+ }
15091571
15101572 ufshcd_vops_config_scaling_param (hba , & hba -> vps -> devfreq_profile ,
15111573 & hba -> vps -> ondemand_data );
@@ -1517,8 +1579,10 @@ static int ufshcd_devfreq_init(struct ufs_hba *hba)
15171579 ret = PTR_ERR (devfreq );
15181580 dev_err (hba -> dev , "Unable to register with devfreq %d\n" , ret );
15191581
1520- dev_pm_opp_remove (hba -> dev , clki -> min_freq );
1521- dev_pm_opp_remove (hba -> dev , clki -> max_freq );
1582+ if (!hba -> use_pm_opp ) {
1583+ dev_pm_opp_remove (hba -> dev , clki -> min_freq );
1584+ dev_pm_opp_remove (hba -> dev , clki -> max_freq );
1585+ }
15221586 return ret ;
15231587 }
15241588
@@ -1530,17 +1594,20 @@ static int ufshcd_devfreq_init(struct ufs_hba *hba)
15301594static void ufshcd_devfreq_remove (struct ufs_hba * hba )
15311595{
15321596 struct list_head * clk_list = & hba -> clk_list_head ;
1533- struct ufs_clk_info * clki ;
15341597
15351598 if (!hba -> devfreq )
15361599 return ;
15371600
15381601 devfreq_remove_device (hba -> devfreq );
15391602 hba -> devfreq = NULL ;
15401603
1541- clki = list_first_entry (clk_list , struct ufs_clk_info , list );
1542- dev_pm_opp_remove (hba -> dev , clki -> min_freq );
1543- dev_pm_opp_remove (hba -> dev , clki -> max_freq );
1604+ if (!hba -> use_pm_opp ) {
1605+ struct ufs_clk_info * clki ;
1606+
1607+ clki = list_first_entry (clk_list , struct ufs_clk_info , list );
1608+ dev_pm_opp_remove (hba -> dev , clki -> min_freq );
1609+ dev_pm_opp_remove (hba -> dev , clki -> max_freq );
1610+ }
15441611}
15451612
15461613static void ufshcd_suspend_clkscaling (struct ufs_hba * hba )
@@ -1616,7 +1683,7 @@ static ssize_t ufshcd_clkscale_enable_store(struct device *dev,
16161683 ufshcd_resume_clkscaling (hba );
16171684 } else {
16181685 ufshcd_suspend_clkscaling (hba );
1619- err = ufshcd_devfreq_scale (hba , true);
1686+ err = ufshcd_devfreq_scale (hba , ULONG_MAX , true);
16201687 if (err )
16211688 dev_err (hba -> dev , "%s: failed to scale clocks up %d\n" ,
16221689 __func__ , err );
@@ -7617,7 +7684,7 @@ static int ufshcd_host_reset_and_restore(struct ufs_hba *hba)
76177684 hba -> silence_err_logs = false;
76187685
76197686 /* scale up clocks to max frequency before full reinitialization */
7620- ufshcd_scale_clks (hba , true);
7687+ ufshcd_scale_clks (hba , ULONG_MAX , true);
76217688
76227689 err = ufshcd_hba_enable (hba );
76237690
@@ -9163,6 +9230,17 @@ static int ufshcd_init_clocks(struct ufs_hba *hba)
91639230 dev_dbg (dev , "%s: clk: %s, rate: %lu\n" , __func__ ,
91649231 clki -> name , clk_get_rate (clki -> clk ));
91659232 }
9233+
9234+ /* Set Max. frequency for all clocks */
9235+ if (hba -> use_pm_opp ) {
9236+ ret = ufshcd_opp_set_rate (hba , ULONG_MAX );
9237+ if (ret ) {
9238+ dev_err (hba -> dev , "%s: failed to set OPP: %d" , __func__ ,
9239+ ret );
9240+ goto out ;
9241+ }
9242+ }
9243+
91669244out :
91679245 return ret ;
91689246}
0 commit comments