Skip to content

Commit b4e13e1

Browse files
Nitin Rawatmartinkpetersen
authored andcommitted
scsi: ufs: qcom: Add multiple frequency support for MAX_CORE_CLK_1US_CYCLES
Qualcomm UFS Controller V4 and above supports multiple unipro frequencies like 403MHz, 300MHz, 202MHz, 150 MHz, 75Mhz, 37.5 MHz. Current code supports only 150MHz and 75MHz which have performance impact due to low UFS controller frequencies. For targets which supports frequencies other than 150 MHz and 75 Mhz, needs an update of MAX_CORE_CLK_1US_CYCLES to match the configured frequency to avoid functionality issues. Add multiple frequency support for MAX_CORE_CLK_1US_CYCLES based on the frequency configured. Co-developed-by: Naveen Kumar Goud Arepalli <[email protected]> Signed-off-by: Naveen Kumar Goud Arepalli <[email protected]> Signed-off-by: Nitin Rawat <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Can Guo <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 07d2290 commit b4e13e1

File tree

2 files changed

+31
-21
lines changed

2 files changed

+31
-21
lines changed

drivers/ufs/host/ufs-qcom.c

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,7 @@ static const struct __ufs_qcom_bw_table {
9393
static struct ufs_qcom_host *ufs_qcom_hosts[MAX_UFS_QCOM_HOSTS];
9494

9595
static void ufs_qcom_get_default_testbus_cfg(struct ufs_qcom_host *host);
96-
static int ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(struct ufs_hba *hba,
97-
u32 clk_cycles);
96+
static int ufs_qcom_set_core_clk_ctrl(struct ufs_hba *hba, bool is_scale_up);
9897

9998
static struct ufs_qcom_host *rcdev_to_ufs_host(struct reset_controller_dev *rcd)
10099
{
@@ -685,14 +684,11 @@ static int ufs_qcom_link_startup_notify(struct ufs_hba *hba,
685684
return -EINVAL;
686685
}
687686

688-
if (ufs_qcom_cap_qunipro(host))
689-
/*
690-
* set unipro core clock cycles to 150 & clear clock
691-
* divider
692-
*/
693-
err = ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(hba,
694-
150);
695-
687+
if (ufs_qcom_cap_qunipro(host)) {
688+
err = ufs_qcom_set_core_clk_ctrl(hba, true);
689+
if (err)
690+
dev_err(hba->dev, "cfg core clk ctrl failed\n");
691+
}
696692
/*
697693
* Some UFS devices (and may be host) have issues if LCC is
698694
* enabled. So we are setting PA_Local_TX_LCC_Enable to 0
@@ -1296,12 +1292,25 @@ static void ufs_qcom_exit(struct ufs_hba *hba)
12961292
phy_exit(host->generic_phy);
12971293
}
12981294

1299-
static int ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(struct ufs_hba *hba,
1300-
u32 clk_cycles)
1295+
static int ufs_qcom_set_core_clk_ctrl(struct ufs_hba *hba, bool is_scale_up)
13011296
{
13021297
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
1303-
int err;
1298+
struct list_head *head = &hba->clk_list_head;
1299+
struct ufs_clk_info *clki;
1300+
u32 cycles_in_1us;
13041301
u32 core_clk_ctrl_reg;
1302+
int err;
1303+
1304+
list_for_each_entry(clki, head, list) {
1305+
if (!IS_ERR_OR_NULL(clki->clk) &&
1306+
!strcmp(clki->name, "core_clk_unipro")) {
1307+
if (is_scale_up)
1308+
cycles_in_1us = ceil(clki->max_freq, (1000 * 1000));
1309+
else
1310+
cycles_in_1us = ceil(clk_get_rate(clki->clk), (1000 * 1000));
1311+
break;
1312+
}
1313+
}
13051314

13061315
err = ufshcd_dme_get(hba,
13071316
UIC_ARG_MIB(DME_VS_CORE_CLK_CTRL),
@@ -1311,15 +1320,15 @@ static int ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(struct ufs_hba *hba,
13111320

13121321
/* Bit mask is different for UFS host controller V4.0.0 onwards */
13131322
if (host->hw_ver.major >= 4) {
1314-
if (!FIELD_FIT(CLK_1US_CYCLES_MASK_V4, clk_cycles))
1323+
if (!FIELD_FIT(CLK_1US_CYCLES_MASK_V4, cycles_in_1us))
13151324
return -ERANGE;
13161325
core_clk_ctrl_reg &= ~CLK_1US_CYCLES_MASK_V4;
1317-
core_clk_ctrl_reg |= FIELD_PREP(CLK_1US_CYCLES_MASK_V4, clk_cycles);
1326+
core_clk_ctrl_reg |= FIELD_PREP(CLK_1US_CYCLES_MASK_V4, cycles_in_1us);
13181327
} else {
1319-
if (!FIELD_FIT(CLK_1US_CYCLES_MASK, clk_cycles))
1328+
if (!FIELD_FIT(CLK_1US_CYCLES_MASK, cycles_in_1us))
13201329
return -ERANGE;
13211330
core_clk_ctrl_reg &= ~CLK_1US_CYCLES_MASK;
1322-
core_clk_ctrl_reg |= FIELD_PREP(CLK_1US_CYCLES_MASK, clk_cycles);
1331+
core_clk_ctrl_reg |= FIELD_PREP(CLK_1US_CYCLES_MASK, cycles_in_1us);
13231332
}
13241333

13251334
/* Clear CORE_CLK_DIV_EN */
@@ -1343,8 +1352,8 @@ static int ufs_qcom_clk_scale_up_post_change(struct ufs_hba *hba)
13431352
if (!ufs_qcom_cap_qunipro(host))
13441353
return 0;
13451354

1346-
/* set unipro core clock cycles to 150 and clear clock divider */
1347-
return ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(hba, 150);
1355+
/* set unipro core clock attributes and clear clock divider */
1356+
return ufs_qcom_set_core_clk_ctrl(hba, true);
13481357
}
13491358

13501359
static int ufs_qcom_clk_scale_down_pre_change(struct ufs_hba *hba)
@@ -1379,8 +1388,8 @@ static int ufs_qcom_clk_scale_down_post_change(struct ufs_hba *hba)
13791388
if (!ufs_qcom_cap_qunipro(host))
13801389
return 0;
13811390

1382-
/* set unipro core clock cycles to 75 and clear clock divider */
1383-
return ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(hba, 75);
1391+
/* set unipro core clock attributes and clear clock divider */
1392+
return ufs_qcom_set_core_clk_ctrl(hba, false);
13841393
}
13851394

13861395
static int ufs_qcom_clk_scale_notify(struct ufs_hba *hba,

drivers/ufs/host/ufs-qcom.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ ufs_qcom_get_debug_reg_offset(struct ufs_qcom_host *host, u32 reg)
245245
#define ufs_qcom_is_link_off(hba) ufshcd_is_link_off(hba)
246246
#define ufs_qcom_is_link_active(hba) ufshcd_is_link_active(hba)
247247
#define ufs_qcom_is_link_hibern8(hba) ufshcd_is_link_hibern8(hba)
248+
#define ceil(freq, div) ((freq) % (div) == 0 ? ((freq)/(div)) : ((freq)/(div) + 1))
248249

249250
int ufs_qcom_testbus_config(struct ufs_qcom_host *host);
250251

0 commit comments

Comments
 (0)