Skip to content

Commit c77b37d

Browse files
quic-cangmartinkpetersen
authored andcommitted
scsi: ufs: qcom: Call ufs_qcom_cfg_timers() in clock scaling path
ufs_qcom_cfg_timers() is clock freq dependent like ufs_qcom_set_core_clk_ctrl(), hence move ufs_qcom_cfg_timers() call to clock scaling path. In addition, do not assume the devfreq OPP freq is always the 'core_clock' freq although 'core_clock' is the first clock phandle in device tree, use ufs_qcom_opp_freq_to_clk_freq() to find the core clk freq. Signed-off-by: Can Guo <[email protected]> Co-developed-by: Ziqi Chen <[email protected]> Signed-off-by: Ziqi Chen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reported-by: Luca Weiss <[email protected]> Closes: https://lore.kernel.org/linux-arm-msm/[email protected]/ Tested-by: Luca Weiss <[email protected]> Reviewed-by: Bean Huo <[email protected]> Tested-by: Loïc Minier <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 8c5bcb3 commit c77b37d

File tree

1 file changed

+29
-20
lines changed

1 file changed

+29
-20
lines changed

drivers/ufs/host/ufs-qcom.c

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -599,13 +599,14 @@ static int ufs_qcom_hce_enable_notify(struct ufs_hba *hba,
599599
*
600600
* @hba: host controller instance
601601
* @is_pre_scale_up: flag to check if pre scale up condition.
602+
* @freq: target opp freq
602603
* Return: zero for success and non-zero in case of a failure.
603604
*/
604-
static int ufs_qcom_cfg_timers(struct ufs_hba *hba, bool is_pre_scale_up)
605+
static int ufs_qcom_cfg_timers(struct ufs_hba *hba, bool is_pre_scale_up, unsigned long freq)
605606
{
606607
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
607608
struct ufs_clk_info *clki;
608-
unsigned long core_clk_rate = 0;
609+
unsigned long clk_freq = 0;
609610
u32 core_clk_cycles_per_us;
610611

611612
/*
@@ -617,22 +618,34 @@ static int ufs_qcom_cfg_timers(struct ufs_hba *hba, bool is_pre_scale_up)
617618
if (host->hw_ver.major < 4 && !ufshcd_is_intr_aggr_allowed(hba))
618619
return 0;
619620

621+
if (hba->use_pm_opp && freq != ULONG_MAX) {
622+
clk_freq = ufs_qcom_opp_freq_to_clk_freq(hba, freq, "core_clk");
623+
if (clk_freq)
624+
goto cfg_timers;
625+
}
626+
620627
list_for_each_entry(clki, &hba->clk_list_head, list) {
621628
if (!strcmp(clki->name, "core_clk")) {
629+
if (freq == ULONG_MAX) {
630+
clk_freq = clki->max_freq;
631+
break;
632+
}
633+
622634
if (is_pre_scale_up)
623-
core_clk_rate = clki->max_freq;
635+
clk_freq = clki->max_freq;
624636
else
625-
core_clk_rate = clk_get_rate(clki->clk);
637+
clk_freq = clk_get_rate(clki->clk);
626638
break;
627639
}
628640

629641
}
630642

643+
cfg_timers:
631644
/* If frequency is smaller than 1MHz, set to 1MHz */
632-
if (core_clk_rate < DEFAULT_CLK_RATE_HZ)
633-
core_clk_rate = DEFAULT_CLK_RATE_HZ;
645+
if (clk_freq < DEFAULT_CLK_RATE_HZ)
646+
clk_freq = DEFAULT_CLK_RATE_HZ;
634647

635-
core_clk_cycles_per_us = core_clk_rate / USEC_PER_SEC;
648+
core_clk_cycles_per_us = clk_freq / USEC_PER_SEC;
636649
if (ufshcd_readl(hba, REG_UFS_SYS1CLK_1US) != core_clk_cycles_per_us) {
637650
ufshcd_writel(hba, core_clk_cycles_per_us, REG_UFS_SYS1CLK_1US);
638651
/*
@@ -652,7 +665,7 @@ static int ufs_qcom_link_startup_notify(struct ufs_hba *hba,
652665

653666
switch (status) {
654667
case PRE_CHANGE:
655-
if (ufs_qcom_cfg_timers(hba, false)) {
668+
if (ufs_qcom_cfg_timers(hba, false, ULONG_MAX)) {
656669
dev_err(hba->dev, "%s: ufs_qcom_cfg_timers() failed\n",
657670
__func__);
658671
return -EINVAL;
@@ -930,17 +943,6 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
930943

931944
break;
932945
case POST_CHANGE:
933-
if (ufs_qcom_cfg_timers(hba, false)) {
934-
dev_err(hba->dev, "%s: ufs_qcom_cfg_timers() failed\n",
935-
__func__);
936-
/*
937-
* we return error code at the end of the routine,
938-
* but continue to configure UFS_PHY_TX_LANE_ENABLE
939-
* and bus voting as usual
940-
*/
941-
ret = -EINVAL;
942-
}
943-
944946
/* cache the power mode parameters to use internally */
945947
memcpy(&host->dev_req_params,
946948
dev_req_params, sizeof(*dev_req_params));
@@ -1492,7 +1494,7 @@ static int ufs_qcom_clk_scale_up_pre_change(struct ufs_hba *hba, unsigned long f
14921494
{
14931495
int ret;
14941496

1495-
ret = ufs_qcom_cfg_timers(hba, true);
1497+
ret = ufs_qcom_cfg_timers(hba, true, freq);
14961498
if (ret) {
14971499
dev_err(hba->dev, "%s ufs cfg timer failed\n", __func__);
14981500
return ret;
@@ -1529,6 +1531,13 @@ static int ufs_qcom_clk_scale_down_pre_change(struct ufs_hba *hba)
15291531

15301532
static int ufs_qcom_clk_scale_down_post_change(struct ufs_hba *hba, unsigned long freq)
15311533
{
1534+
int ret;
1535+
1536+
ret = ufs_qcom_cfg_timers(hba, false, freq);
1537+
if (ret) {
1538+
dev_err(hba->dev, "%s: ufs_qcom_cfg_timers() failed\n", __func__);
1539+
return ret;
1540+
}
15321541
/* set unipro core clock attributes and clear clock divider */
15331542
return ufs_qcom_set_core_clk_ctrl(hba, false, freq);
15341543
}

0 commit comments

Comments
 (0)