summaryrefslogtreecommitdiffstats
path: root/drivers/ufs/host
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 18:50:12 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 18:50:12 +0000
commit8665bd53f2f2e27e5511d90428cb3f60e6d0ce15 (patch)
tree8d58900dc0ebd4a3011f92c128d2fe45bc7c4bf2 /drivers/ufs/host
parentAdding debian version 6.7.12-1. (diff)
downloadlinux-8665bd53f2f2e27e5511d90428cb3f60e6d0ce15.tar.xz
linux-8665bd53f2f2e27e5511d90428cb3f60e6d0ce15.zip
Merging upstream version 6.8.9.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/ufs/host')
-rw-r--r--drivers/ufs/host/ufs-exynos.c7
-rw-r--r--drivers/ufs/host/ufs-hisi.c11
-rw-r--r--drivers/ufs/host/ufs-mediatek.c12
-rw-r--r--drivers/ufs/host/ufs-qcom.c494
-rw-r--r--drivers/ufs/host/ufs-qcom.h57
-rw-r--r--drivers/ufs/host/ufshcd-pltfrm.c69
-rw-r--r--drivers/ufs/host/ufshcd-pltfrm.h10
7 files changed, 210 insertions, 450 deletions
diff --git a/drivers/ufs/host/ufs-exynos.c b/drivers/ufs/host/ufs-exynos.c
index 71bd6dbc05..734d40f99e 100644
--- a/drivers/ufs/host/ufs-exynos.c
+++ b/drivers/ufs/host/ufs-exynos.c
@@ -765,7 +765,7 @@ static int exynos_ufs_pre_pwr_mode(struct ufs_hba *hba,
{
struct exynos_ufs *ufs = ufshcd_get_variant(hba);
struct phy *generic_phy = ufs->phy;
- struct ufs_dev_params ufs_exynos_cap;
+ struct ufs_host_params host_params;
int ret;
if (!dev_req_params) {
@@ -774,10 +774,9 @@ static int exynos_ufs_pre_pwr_mode(struct ufs_hba *hba,
goto out;
}
- ufshcd_init_pwr_dev_param(&ufs_exynos_cap);
+ ufshcd_init_host_params(&host_params);
- ret = ufshcd_get_pwr_dev_param(&ufs_exynos_cap,
- dev_max_params, dev_req_params);
+ ret = ufshcd_negotiate_pwr_params(&host_params, dev_max_params, dev_req_params);
if (ret) {
pr_err("%s: failed to determine capabilities\n", __func__);
goto out;
diff --git a/drivers/ufs/host/ufs-hisi.c b/drivers/ufs/host/ufs-hisi.c
index 0229ac0a8d..5ee73ff052 100644
--- a/drivers/ufs/host/ufs-hisi.c
+++ b/drivers/ufs/host/ufs-hisi.c
@@ -293,9 +293,9 @@ static int ufs_hisi_link_startup_notify(struct ufs_hba *hba,
return err;
}
-static void ufs_hisi_set_dev_cap(struct ufs_dev_params *hisi_param)
+static void ufs_hisi_set_dev_cap(struct ufs_host_params *host_params)
{
- ufshcd_init_pwr_dev_param(hisi_param);
+ ufshcd_init_host_params(host_params);
}
static void ufs_hisi_pwr_change_pre_change(struct ufs_hba *hba)
@@ -365,7 +365,7 @@ static int ufs_hisi_pwr_change_notify(struct ufs_hba *hba,
struct ufs_pa_layer_attr *dev_max_params,
struct ufs_pa_layer_attr *dev_req_params)
{
- struct ufs_dev_params ufs_hisi_cap;
+ struct ufs_host_params host_params;
int ret = 0;
if (!dev_req_params) {
@@ -377,9 +377,8 @@ static int ufs_hisi_pwr_change_notify(struct ufs_hba *hba,
switch (status) {
case PRE_CHANGE:
- ufs_hisi_set_dev_cap(&ufs_hisi_cap);
- ret = ufshcd_get_pwr_dev_param(&ufs_hisi_cap,
- dev_max_params, dev_req_params);
+ ufs_hisi_set_dev_cap(&host_params);
+ ret = ufshcd_negotiate_pwr_params(&host_params, dev_max_params, dev_req_params);
if (ret) {
dev_err(hba->dev,
"%s: failed to determine capabilities\n", __func__);
diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index fc61790d28..776bca4f70 100644
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -996,16 +996,14 @@ static int ufs_mtk_pre_pwr_change(struct ufs_hba *hba,
struct ufs_pa_layer_attr *dev_req_params)
{
struct ufs_mtk_host *host = ufshcd_get_variant(hba);
- struct ufs_dev_params host_cap;
+ struct ufs_host_params host_params;
int ret;
- ufshcd_init_pwr_dev_param(&host_cap);
- host_cap.hs_rx_gear = UFS_HS_G5;
- host_cap.hs_tx_gear = UFS_HS_G5;
+ ufshcd_init_host_params(&host_params);
+ host_params.hs_rx_gear = UFS_HS_G5;
+ host_params.hs_tx_gear = UFS_HS_G5;
- ret = ufshcd_get_pwr_dev_param(&host_cap,
- dev_max_params,
- dev_req_params);
+ ret = ufshcd_negotiate_pwr_params(&host_params, dev_max_params, dev_req_params);
if (ret) {
pr_info("%s: failed to determine capabilities\n",
__func__);
diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c
index 0d38864553..bcbcf75892 100644
--- a/drivers/ufs/host/ufs-qcom.c
+++ b/drivers/ufs/host/ufs-qcom.c
@@ -4,26 +4,26 @@
*/
#include <linux/acpi.h>
-#include <linux/time.h>
#include <linux/clk.h>
#include <linux/delay.h>
+#include <linux/devfreq.h>
+#include <linux/gpio/consumer.h>
#include <linux/interconnect.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/platform_device.h>
#include <linux/phy/phy.h>
-#include <linux/gpio/consumer.h>
+#include <linux/platform_device.h>
#include <linux/reset-controller.h>
-#include <linux/devfreq.h>
+#include <linux/time.h>
#include <soc/qcom/ice.h>
#include <ufs/ufshcd.h>
-#include "ufshcd-pltfrm.h"
-#include <ufs/unipro.h>
-#include "ufs-qcom.h"
#include <ufs/ufshci.h>
#include <ufs/ufs_quirks.h>
+#include <ufs/unipro.h>
+#include "ufshcd-pltfrm.h"
+#include "ufs-qcom.h"
#define MCQ_QCFGPTR_MASK GENMASK(7, 0)
#define MCQ_QCFGPTR_UNIT 0x200
@@ -47,7 +47,7 @@ enum {
TSTBUS_MAX,
};
-#define QCOM_UFS_MAX_GEAR 4
+#define QCOM_UFS_MAX_GEAR 5
#define QCOM_UFS_MAX_LANE 2
enum {
@@ -67,31 +67,35 @@ static const struct __ufs_qcom_bw_table {
[MODE_PWM][UFS_PWM_G2][UFS_LANE_1] = { 1844, 1000 },
[MODE_PWM][UFS_PWM_G3][UFS_LANE_1] = { 3688, 1000 },
[MODE_PWM][UFS_PWM_G4][UFS_LANE_1] = { 7376, 1000 },
+ [MODE_PWM][UFS_PWM_G5][UFS_LANE_1] = { 14752, 1000 },
[MODE_PWM][UFS_PWM_G1][UFS_LANE_2] = { 1844, 1000 },
[MODE_PWM][UFS_PWM_G2][UFS_LANE_2] = { 3688, 1000 },
[MODE_PWM][UFS_PWM_G3][UFS_LANE_2] = { 7376, 1000 },
[MODE_PWM][UFS_PWM_G4][UFS_LANE_2] = { 14752, 1000 },
+ [MODE_PWM][UFS_PWM_G5][UFS_LANE_2] = { 29504, 1000 },
[MODE_HS_RA][UFS_HS_G1][UFS_LANE_1] = { 127796, 1000 },
[MODE_HS_RA][UFS_HS_G2][UFS_LANE_1] = { 255591, 1000 },
[MODE_HS_RA][UFS_HS_G3][UFS_LANE_1] = { 1492582, 102400 },
[MODE_HS_RA][UFS_HS_G4][UFS_LANE_1] = { 2915200, 204800 },
+ [MODE_HS_RA][UFS_HS_G5][UFS_LANE_1] = { 5836800, 409600 },
[MODE_HS_RA][UFS_HS_G1][UFS_LANE_2] = { 255591, 1000 },
[MODE_HS_RA][UFS_HS_G2][UFS_LANE_2] = { 511181, 1000 },
[MODE_HS_RA][UFS_HS_G3][UFS_LANE_2] = { 1492582, 204800 },
[MODE_HS_RA][UFS_HS_G4][UFS_LANE_2] = { 2915200, 409600 },
+ [MODE_HS_RA][UFS_HS_G5][UFS_LANE_2] = { 5836800, 819200 },
[MODE_HS_RB][UFS_HS_G1][UFS_LANE_1] = { 149422, 1000 },
[MODE_HS_RB][UFS_HS_G2][UFS_LANE_1] = { 298189, 1000 },
[MODE_HS_RB][UFS_HS_G3][UFS_LANE_1] = { 1492582, 102400 },
[MODE_HS_RB][UFS_HS_G4][UFS_LANE_1] = { 2915200, 204800 },
+ [MODE_HS_RB][UFS_HS_G5][UFS_LANE_1] = { 5836800, 409600 },
[MODE_HS_RB][UFS_HS_G1][UFS_LANE_2] = { 298189, 1000 },
[MODE_HS_RB][UFS_HS_G2][UFS_LANE_2] = { 596378, 1000 },
[MODE_HS_RB][UFS_HS_G3][UFS_LANE_2] = { 1492582, 204800 },
[MODE_HS_RB][UFS_HS_G4][UFS_LANE_2] = { 2915200, 409600 },
+ [MODE_HS_RB][UFS_HS_G5][UFS_LANE_2] = { 5836800, 819200 },
[MODE_MAX][0][0] = { 7643136, 307200 },
};
-static struct ufs_qcom_host *ufs_qcom_hosts[MAX_UFS_QCOM_HOSTS];
-
static void ufs_qcom_get_default_testbus_cfg(struct ufs_qcom_host *host);
static int ufs_qcom_set_core_clk_ctrl(struct ufs_hba *hba, bool is_scale_up);
@@ -194,52 +198,12 @@ static inline int ufs_qcom_ice_suspend(struct ufs_qcom_host *host)
}
#endif
-static int ufs_qcom_host_clk_get(struct device *dev,
- const char *name, struct clk **clk_out, bool optional)
-{
- struct clk *clk;
- int err = 0;
-
- clk = devm_clk_get(dev, name);
- if (!IS_ERR(clk)) {
- *clk_out = clk;
- return 0;
- }
-
- err = PTR_ERR(clk);
-
- if (optional && err == -ENOENT) {
- *clk_out = NULL;
- return 0;
- }
-
- if (err != -EPROBE_DEFER)
- dev_err(dev, "failed to get %s err %d\n", name, err);
-
- return err;
-}
-
-static int ufs_qcom_host_clk_enable(struct device *dev,
- const char *name, struct clk *clk)
-{
- int err = 0;
-
- err = clk_prepare_enable(clk);
- if (err)
- dev_err(dev, "%s: %s enable failed %d\n", __func__, name, err);
-
- return err;
-}
-
static void ufs_qcom_disable_lane_clks(struct ufs_qcom_host *host)
{
if (!host->is_lane_clks_enabled)
return;
- clk_disable_unprepare(host->tx_l1_sync_clk);
- clk_disable_unprepare(host->tx_l0_sync_clk);
- clk_disable_unprepare(host->rx_l1_sync_clk);
- clk_disable_unprepare(host->rx_l0_sync_clk);
+ clk_bulk_disable_unprepare(host->num_clks, host->clks);
host->is_lane_clks_enabled = false;
}
@@ -247,73 +211,29 @@ static void ufs_qcom_disable_lane_clks(struct ufs_qcom_host *host)
static int ufs_qcom_enable_lane_clks(struct ufs_qcom_host *host)
{
int err;
- struct device *dev = host->hba->dev;
-
- if (host->is_lane_clks_enabled)
- return 0;
- err = ufs_qcom_host_clk_enable(dev, "rx_lane0_sync_clk",
- host->rx_l0_sync_clk);
+ err = clk_bulk_prepare_enable(host->num_clks, host->clks);
if (err)
return err;
- err = ufs_qcom_host_clk_enable(dev, "tx_lane0_sync_clk",
- host->tx_l0_sync_clk);
- if (err)
- goto disable_rx_l0;
-
- err = ufs_qcom_host_clk_enable(dev, "rx_lane1_sync_clk",
- host->rx_l1_sync_clk);
- if (err)
- goto disable_tx_l0;
-
- err = ufs_qcom_host_clk_enable(dev, "tx_lane1_sync_clk",
- host->tx_l1_sync_clk);
- if (err)
- goto disable_rx_l1;
-
host->is_lane_clks_enabled = true;
return 0;
-
-disable_rx_l1:
- clk_disable_unprepare(host->rx_l1_sync_clk);
-disable_tx_l0:
- clk_disable_unprepare(host->tx_l0_sync_clk);
-disable_rx_l0:
- clk_disable_unprepare(host->rx_l0_sync_clk);
-
- return err;
}
static int ufs_qcom_init_lane_clks(struct ufs_qcom_host *host)
{
- int err = 0;
+ int err;
struct device *dev = host->hba->dev;
if (has_acpi_companion(dev))
return 0;
- err = ufs_qcom_host_clk_get(dev, "rx_lane0_sync_clk",
- &host->rx_l0_sync_clk, false);
- if (err)
+ err = devm_clk_bulk_get_all(dev, &host->clks);
+ if (err <= 0)
return err;
- err = ufs_qcom_host_clk_get(dev, "tx_lane0_sync_clk",
- &host->tx_l0_sync_clk, false);
- if (err)
- return err;
-
- /* In case of single lane per direction, don't read lane1 clocks */
- if (host->hba->lanes_per_direction > 1) {
- err = ufs_qcom_host_clk_get(dev, "rx_lane1_sync_clk",
- &host->rx_l1_sync_clk, false);
- if (err)
- return err;
-
- err = ufs_qcom_host_clk_get(dev, "tx_lane1_sync_clk",
- &host->tx_l1_sync_clk, true);
- }
+ host->num_clks = err;
return 0;
}
@@ -321,7 +241,7 @@ static int ufs_qcom_init_lane_clks(struct ufs_qcom_host *host)
static int ufs_qcom_check_hibern8(struct ufs_hba *hba)
{
int err;
- u32 tx_fsm_val = 0;
+ u32 tx_fsm_val;
unsigned long timeout = jiffies + msecs_to_jiffies(HBRN8_POLL_TOUT_MS);
do {
@@ -360,9 +280,7 @@ static int ufs_qcom_check_hibern8(struct ufs_hba *hba)
static void ufs_qcom_select_unipro_mode(struct ufs_qcom_host *host)
{
- ufshcd_rmwl(host->hba, QUNIPRO_SEL,
- ufs_qcom_cap_qunipro(host) ? QUNIPRO_SEL : 0,
- REG_UFS_CFG1);
+ ufshcd_rmwl(host->hba, QUNIPRO_SEL, QUNIPRO_SEL, REG_UFS_CFG1);
if (host->hw_ver.major >= 0x05)
ufshcd_rmwl(host->hba, QUNIPRO_G4_SEL, 0, REG_UFS_CFG0);
@@ -376,18 +294,15 @@ static void ufs_qcom_select_unipro_mode(struct ufs_qcom_host *host)
*/
static int ufs_qcom_host_reset(struct ufs_hba *hba)
{
- int ret = 0;
+ int ret;
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
- bool reenable_intr = false;
+ bool reenable_intr;
- if (!host->core_reset) {
- dev_warn(hba->dev, "%s: reset control not set\n", __func__);
+ if (!host->core_reset)
return 0;
- }
reenable_intr = hba->is_irq_enabled;
- disable_irq(hba->irq);
- hba->is_irq_enabled = false;
+ ufshcd_disable_irq(hba);
ret = reset_control_assert(host->core_reset);
if (ret) {
@@ -404,16 +319,16 @@ static int ufs_qcom_host_reset(struct ufs_hba *hba)
usleep_range(200, 210);
ret = reset_control_deassert(host->core_reset);
- if (ret)
+ if (ret) {
dev_err(hba->dev, "%s: core_reset deassert failed, err = %d\n",
__func__, ret);
+ return ret;
+ }
usleep_range(1000, 1100);
- if (reenable_intr) {
- enable_irq(hba->irq);
- hba->is_irq_enabled = true;
- }
+ if (reenable_intr)
+ ufshcd_enable_irq(hba);
return 0;
}
@@ -422,18 +337,8 @@ static u32 ufs_qcom_get_hs_gear(struct ufs_hba *hba)
{
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
- if (host->hw_ver.major == 0x1) {
- /*
- * HS-G3 operations may not reliably work on legacy QCOM
- * UFS host controller hardware even though capability
- * exchange during link startup phase may end up
- * negotiating maximum supported gear as G3.
- * Hence downgrade the maximum supported gear to HS-G2.
- */
- return UFS_HS_G2;
- } else if (host->hw_ver.major >= 0x4) {
+ if (host->hw_ver.major >= 0x4)
return UFS_QCOM_MAX_GEAR(ufshcd_readl(hba, REG_UFS_PARAM0));
- }
/* Default is HS-G3 */
return UFS_HS_G3;
@@ -442,14 +347,29 @@ static u32 ufs_qcom_get_hs_gear(struct ufs_hba *hba)
static int ufs_qcom_power_up_sequence(struct ufs_hba *hba)
{
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
+ struct ufs_host_params *host_params = &host->host_params;
struct phy *phy = host->generic_phy;
+ enum phy_mode mode;
int ret;
+ /*
+ * HW ver 5 can only support up to HS-G5 Rate-A due to HW limitations.
+ * If the HS-G5 PHY gear is used, update host_params->hs_rate to Rate-A,
+ * so that the subsequent power mode change shall stick to Rate-A.
+ */
+ if (host->hw_ver.major == 0x5) {
+ if (host->phy_gear == UFS_HS_G5)
+ host_params->hs_rate = PA_HS_MODE_A;
+ else
+ host_params->hs_rate = PA_HS_MODE_B;
+ }
+
+ mode = host_params->hs_rate == PA_HS_MODE_B ? PHY_MODE_UFS_HS_B : PHY_MODE_UFS_HS_A;
+
/* Reset UFS Host Controller and PHY */
ret = ufs_qcom_host_reset(hba);
if (ret)
- dev_warn(hba->dev, "%s: host reset returned %d\n",
- __func__, ret);
+ return ret;
/* phy initialization - calibrate the phy */
ret = phy_init(phy);
@@ -459,7 +379,9 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba)
return ret;
}
- phy_set_mode_ext(phy, PHY_MODE_UFS_HS_B, host->phy_gear);
+ ret = phy_set_mode_ext(phy, mode, host->phy_gear);
+ if (ret)
+ goto out_disable_phy;
/* power on phy - start serdes and phy's power and clocks */
ret = phy_power_on(phy);
@@ -489,9 +411,8 @@ out_disable_phy:
*/
static void ufs_qcom_enable_hw_clk_gating(struct ufs_hba *hba)
{
- ufshcd_writel(hba,
- ufshcd_readl(hba, REG_UFS_CFG2) | REG_UFS_CFG2_CGC_EN_ALL,
- REG_UFS_CFG2);
+ ufshcd_rmwl(hba, REG_UFS_CFG2_CGC_EN_ALL, REG_UFS_CFG2_CGC_EN_ALL,
+ REG_UFS_CFG2);
/* Ensure that HW clock gating is enabled before next operations */
mb();
@@ -501,11 +422,14 @@ static int ufs_qcom_hce_enable_notify(struct ufs_hba *hba,
enum ufs_notify_change_status status)
{
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
- int err = 0;
+ int err;
switch (status) {
case PRE_CHANGE:
- ufs_qcom_power_up_sequence(hba);
+ err = ufs_qcom_power_up_sequence(hba);
+ if (err)
+ return err;
+
/*
* The PHY PLL output is the source of tx/rx lane symbol
* clocks, hence, enable the lane clocks only after PHY
@@ -544,41 +468,16 @@ static int ufs_qcom_cfg_timers(struct ufs_hba *hba, u32 gear,
{
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
struct ufs_clk_info *clki;
- u32 core_clk_period_in_ns;
- u32 tx_clk_cycles_per_us = 0;
unsigned long core_clk_rate = 0;
- u32 core_clk_cycles_per_us = 0;
-
- static u32 pwm_fr_table[][2] = {
- {UFS_PWM_G1, 0x1},
- {UFS_PWM_G2, 0x1},
- {UFS_PWM_G3, 0x1},
- {UFS_PWM_G4, 0x1},
- };
-
- static u32 hs_fr_table_rA[][2] = {
- {UFS_HS_G1, 0x1F},
- {UFS_HS_G2, 0x3e},
- {UFS_HS_G3, 0x7D},
- };
-
- static u32 hs_fr_table_rB[][2] = {
- {UFS_HS_G1, 0x24},
- {UFS_HS_G2, 0x49},
- {UFS_HS_G3, 0x92},
- };
+ u32 core_clk_cycles_per_us;
/*
- * The Qunipro controller does not use following registers:
- * SYS1CLK_1US_REG, TX_SYMBOL_CLK_1US_REG, CLK_NS_REG &
- * UFS_REG_PA_LINK_STARTUP_TIMER.
- * However UTP controller uses SYS1CLK_1US_REG register for Interrupt
+ * UTP controller uses SYS1CLK_1US_REG register for Interrupt
* Aggregation logic.
* It is mandatory to write SYS1CLK_1US_REG register on UFS host
* controller V4.0.0 onwards.
*/
- if (host->hw_ver.major < 4 && ufs_qcom_cap_qunipro(host) &&
- !ufshcd_is_intr_aggr_allowed(hba))
+ if (host->hw_ver.major < 4 && !ufshcd_is_intr_aggr_allowed(hba))
return 0;
if (gear == 0) {
@@ -611,79 +510,6 @@ static int ufs_qcom_cfg_timers(struct ufs_hba *hba, u32 gear,
mb();
}
- if (ufs_qcom_cap_qunipro(host))
- return 0;
-
- core_clk_period_in_ns = NSEC_PER_SEC / core_clk_rate;
- core_clk_period_in_ns <<= OFFSET_CLK_NS_REG;
- core_clk_period_in_ns &= MASK_CLK_NS_REG;
-
- switch (hs) {
- case FASTAUTO_MODE:
- case FAST_MODE:
- if (rate == PA_HS_MODE_A) {
- if (gear > ARRAY_SIZE(hs_fr_table_rA)) {
- dev_err(hba->dev,
- "%s: index %d exceeds table size %zu\n",
- __func__, gear,
- ARRAY_SIZE(hs_fr_table_rA));
- return -EINVAL;
- }
- tx_clk_cycles_per_us = hs_fr_table_rA[gear-1][1];
- } else if (rate == PA_HS_MODE_B) {
- if (gear > ARRAY_SIZE(hs_fr_table_rB)) {
- dev_err(hba->dev,
- "%s: index %d exceeds table size %zu\n",
- __func__, gear,
- ARRAY_SIZE(hs_fr_table_rB));
- return -EINVAL;
- }
- tx_clk_cycles_per_us = hs_fr_table_rB[gear-1][1];
- } else {
- dev_err(hba->dev, "%s: invalid rate = %d\n",
- __func__, rate);
- return -EINVAL;
- }
- break;
- case SLOWAUTO_MODE:
- case SLOW_MODE:
- if (gear > ARRAY_SIZE(pwm_fr_table)) {
- dev_err(hba->dev,
- "%s: index %d exceeds table size %zu\n",
- __func__, gear,
- ARRAY_SIZE(pwm_fr_table));
- return -EINVAL;
- }
- tx_clk_cycles_per_us = pwm_fr_table[gear-1][1];
- break;
- case UNCHANGED:
- default:
- dev_err(hba->dev, "%s: invalid mode = %d\n", __func__, hs);
- return -EINVAL;
- }
-
- if (ufshcd_readl(hba, REG_UFS_TX_SYMBOL_CLK_NS_US) !=
- (core_clk_period_in_ns | tx_clk_cycles_per_us)) {
- /* this register 2 fields shall be written at once */
- ufshcd_writel(hba, core_clk_period_in_ns | tx_clk_cycles_per_us,
- REG_UFS_TX_SYMBOL_CLK_NS_US);
- /*
- * make sure above write gets applied before we return from
- * this function.
- */
- mb();
- }
-
- if (update_link_startup_timer && host->hw_ver.major != 0x5) {
- ufshcd_writel(hba, ((core_clk_rate / MSEC_PER_SEC) * 100),
- REG_UFS_CFG0);
- /*
- * make sure that this configuration is applied before
- * we return
- */
- mb();
- }
-
return 0;
}
@@ -691,7 +517,6 @@ static int ufs_qcom_link_startup_notify(struct ufs_hba *hba,
enum ufs_notify_change_status status)
{
int err = 0;
- struct ufs_qcom_host *host = ufshcd_get_variant(hba);
switch (status) {
case PRE_CHANGE:
@@ -702,11 +527,9 @@ static int ufs_qcom_link_startup_notify(struct ufs_hba *hba,
return -EINVAL;
}
- if (ufs_qcom_cap_qunipro(host)) {
- err = ufs_qcom_set_core_clk_ctrl(hba, true);
- if (err)
- dev_err(hba->dev, "cfg core clk ctrl failed\n");
- }
+ err = ufs_qcom_set_core_clk_ctrl(hba, true);
+ if (err)
+ dev_err(hba->dev, "cfg core clk ctrl failed\n");
/*
* Some UFS devices (and may be host) have issues if LCC is
* enabled. So we are setting PA_Local_TX_LCC_Enable to 0
@@ -898,7 +721,7 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
struct ufs_pa_layer_attr *dev_req_params)
{
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
- struct ufs_dev_params ufs_qcom_cap;
+ struct ufs_host_params *host_params = &host->host_params;
int ret = 0;
if (!dev_req_params) {
@@ -908,15 +731,7 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
switch (status) {
case PRE_CHANGE:
- ufshcd_init_pwr_dev_param(&ufs_qcom_cap);
- ufs_qcom_cap.hs_rate = UFS_QCOM_LIMIT_HS_RATE;
-
- /* This driver only supports symmetic gear setting i.e., hs_tx_gear == hs_rx_gear */
- ufs_qcom_cap.hs_tx_gear = ufs_qcom_cap.hs_rx_gear = ufs_qcom_get_hs_gear(hba);
-
- ret = ufshcd_get_pwr_dev_param(&ufs_qcom_cap,
- dev_max_params,
- dev_req_params);
+ ret = ufshcd_negotiate_pwr_params(host_params, dev_max_params, dev_req_params);
if (ret) {
dev_err(hba->dev, "%s: failed to determine capabilities\n",
__func__);
@@ -924,12 +739,22 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
}
/*
- * Update phy_gear only when the gears are scaled to a higher value. This is
- * because, the PHY gear settings are backwards compatible and we only need to
- * change the PHY gear settings while scaling to higher gears.
+ * During UFS driver probe, always update the PHY gear to match the negotiated
+ * gear, so that, if quirk UFSHCD_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH is enabled,
+ * the second init can program the optimal PHY settings. This allows one to start
+ * the first init with either the minimum or the maximum support gear.
*/
- if (dev_req_params->gear_tx > host->phy_gear)
- host->phy_gear = dev_req_params->gear_tx;
+ if (hba->ufshcd_state == UFSHCD_STATE_RESET) {
+ /*
+ * Skip REINIT if the negotiated gear matches with the
+ * initial phy_gear. Otherwise, update the phy_gear to
+ * program the optimal gear setting during REINIT.
+ */
+ if (host->phy_gear == dev_req_params->gear_tx)
+ hba->quirks &= ~UFSHCD_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH;
+ else
+ host->phy_gear = dev_req_params->gear_tx;
+ }
/* enable the device ref clock before changing to HS mode */
if (!ufshcd_is_hs_mode(&hba->pwr_info) &&
@@ -1005,12 +830,7 @@ static int ufs_qcom_apply_dev_quirks(struct ufs_hba *hba)
static u32 ufs_qcom_get_ufs_hci_version(struct ufs_hba *hba)
{
- struct ufs_qcom_host *host = ufshcd_get_variant(hba);
-
- if (host->hw_ver.major == 0x1)
- return ufshci_version(1, 1);
- else
- return ufshci_version(2, 0);
+ return ufshci_version(2, 0);
}
/**
@@ -1026,46 +846,69 @@ static void ufs_qcom_advertise_quirks(struct ufs_hba *hba)
{
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
- if (host->hw_ver.major == 0x01) {
- hba->quirks |= UFSHCD_QUIRK_DELAY_BEFORE_DME_CMDS
- | UFSHCD_QUIRK_BROKEN_PA_RXHSUNTERMCAP
- | UFSHCD_QUIRK_DME_PEER_ACCESS_AUTO_MODE;
+ if (host->hw_ver.major == 0x2)
+ hba->quirks |= UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION;
- if (host->hw_ver.minor == 0x0001 && host->hw_ver.step == 0x0001)
- hba->quirks |= UFSHCD_QUIRK_BROKEN_INTR_AGGR;
+ if (host->hw_ver.major > 0x3)
+ hba->quirks |= UFSHCD_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH;
+}
- hba->quirks |= UFSHCD_QUIRK_BROKEN_LCC;
- }
+static void ufs_qcom_set_phy_gear(struct ufs_qcom_host *host)
+{
+ struct ufs_host_params *host_params = &host->host_params;
+ u32 val, dev_major;
- if (host->hw_ver.major == 0x2) {
- hba->quirks |= UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION;
+ host->phy_gear = host_params->hs_tx_gear;
- if (!ufs_qcom_cap_qunipro(host))
- /* Legacy UniPro mode still need following quirks */
- hba->quirks |= (UFSHCD_QUIRK_DELAY_BEFORE_DME_CMDS
- | UFSHCD_QUIRK_DME_PEER_ACCESS_AUTO_MODE
- | UFSHCD_QUIRK_BROKEN_PA_RXHSUNTERMCAP);
- }
+ if (host->hw_ver.major < 0x4) {
+ /*
+ * For controllers whose major HW version is < 4, power up the
+ * PHY using minimum supported gear (UFS_HS_G2). Switching to
+ * max gear will be performed during reinit if supported.
+ * For newer controllers, whose major HW version is >= 4, power
+ * up the PHY using max supported gear.
+ */
+ host->phy_gear = UFS_HS_G2;
+ } else if (host->hw_ver.major >= 0x5) {
+ val = ufshcd_readl(host->hba, REG_UFS_DEBUG_SPARE_CFG);
+ dev_major = FIELD_GET(UFS_DEV_VER_MAJOR_MASK, val);
- if (host->hw_ver.major > 0x3)
- hba->quirks |= UFSHCD_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH;
+ /*
+ * Since the UFS device version is populated, let's remove the
+ * REINIT quirk as the negotiated gear won't change during boot.
+ * So there is no need to do reinit.
+ */
+ if (dev_major != 0x0)
+ host->hba->quirks &= ~UFSHCD_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH;
+
+ /*
+ * For UFS 3.1 device and older, power up the PHY using HS-G4
+ * PHY gear to save power.
+ */
+ if (dev_major > 0x0 && dev_major < 0x4)
+ host->phy_gear = UFS_HS_G4;
+ }
}
-static void ufs_qcom_set_caps(struct ufs_hba *hba)
+static void ufs_qcom_set_host_params(struct ufs_hba *hba)
{
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
+ struct ufs_host_params *host_params = &host->host_params;
+
+ ufshcd_init_host_params(host_params);
+
+ /* This driver only supports symmetic gear setting i.e., hs_tx_gear == hs_rx_gear */
+ host_params->hs_tx_gear = host_params->hs_rx_gear = ufs_qcom_get_hs_gear(hba);
+}
+static void ufs_qcom_set_caps(struct ufs_hba *hba)
+{
hba->caps |= UFSHCD_CAP_CLK_GATING | UFSHCD_CAP_HIBERN8_WITH_CLK_GATING;
hba->caps |= UFSHCD_CAP_CLK_SCALING | UFSHCD_CAP_WB_WITH_CLK_SCALING;
hba->caps |= UFSHCD_CAP_AUTO_BKOPS_SUSPEND;
hba->caps |= UFSHCD_CAP_WB_EN;
hba->caps |= UFSHCD_CAP_AGGR_POWER_COLLAPSE;
hba->caps |= UFSHCD_CAP_RPM_AUTOSUSPEND;
-
- if (host->hw_ver.major >= 0x2) {
- host->caps = UFS_QCOM_CAP_QUNIPRO |
- UFS_QCOM_CAP_RETAIN_SEC_CFG_AFTER_PWR_COLLAPSE;
- }
}
/**
@@ -1188,16 +1031,12 @@ static int ufs_qcom_init(struct ufs_hba *hba)
{
int err;
struct device *dev = hba->dev;
- struct platform_device *pdev = to_platform_device(dev);
struct ufs_qcom_host *host;
- struct resource *res;
struct ufs_clk_info *clki;
host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
- if (!host) {
- dev_err(dev, "%s: no memory for qcom ufs host\n", __func__);
+ if (!host)
return -ENOMEM;
- }
/* Make a two way bind between the qcom host and the hba */
host->hba = hba;
@@ -1235,34 +1074,16 @@ static int ufs_qcom_init(struct ufs_hba *hba)
host->device_reset = devm_gpiod_get_optional(dev, "reset",
GPIOD_OUT_HIGH);
if (IS_ERR(host->device_reset)) {
- err = PTR_ERR(host->device_reset);
- if (err != -EPROBE_DEFER)
- dev_err(dev, "failed to acquire reset gpio: %d\n", err);
+ err = dev_err_probe(dev, PTR_ERR(host->device_reset),
+ "Failed to acquire device reset gpio\n");
goto out_variant_clear;
}
ufs_qcom_get_controller_revision(hba, &host->hw_ver.major,
&host->hw_ver.minor, &host->hw_ver.step);
- /*
- * for newer controllers, device reference clock control bit has
- * moved inside UFS controller register address space itself.
- */
- if (host->hw_ver.major >= 0x02) {
- host->dev_ref_clk_ctrl_mmio = hba->mmio_base + REG_UFS_CFG1;
- host->dev_ref_clk_en_mask = BIT(26);
- } else {
- /* "dev_ref_clk_ctrl_mem" is optional resource */
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
- "dev_ref_clk_ctrl_mem");
- if (res) {
- host->dev_ref_clk_ctrl_mmio =
- devm_ioremap_resource(dev, res);
- if (IS_ERR(host->dev_ref_clk_ctrl_mmio))
- host->dev_ref_clk_ctrl_mmio = NULL;
- host->dev_ref_clk_en_mask = BIT(5);
- }
- }
+ host->dev_ref_clk_ctrl_mmio = hba->mmio_base + REG_UFS_CFG1;
+ host->dev_ref_clk_en_mask = BIT(26);
list_for_each_entry(clki, &hba->clk_list_head, list) {
if (!strcmp(clki->name, "core_clk_unipro"))
@@ -1275,6 +1096,8 @@ static int ufs_qcom_init(struct ufs_hba *hba)
ufs_qcom_set_caps(hba);
ufs_qcom_advertise_quirks(hba);
+ ufs_qcom_set_host_params(hba);
+ ufs_qcom_set_phy_gear(host);
err = ufs_qcom_ice_init(host);
if (err)
@@ -1282,9 +1105,6 @@ static int ufs_qcom_init(struct ufs_hba *hba)
ufs_qcom_setup_clocks(hba, true, POST_CHANGE);
- if (hba->dev->id < MAX_UFS_QCOM_HOSTS)
- ufs_qcom_hosts[hba->dev->id] = host;
-
ufs_qcom_get_default_testbus_cfg(host);
err = ufs_qcom_testbus_config(host);
if (err)
@@ -1292,12 +1112,6 @@ static int ufs_qcom_init(struct ufs_hba *hba)
dev_warn(dev, "%s: failed to configure the testbus %d\n",
__func__, err);
- /*
- * Power up the PHY using the minimum supported gear (UFS_HS_G2).
- * Switching to max gear will be performed during reinit if supported.
- */
- host->phy_gear = UFS_HS_G2;
-
return 0;
out_variant_clear:
@@ -1391,7 +1205,7 @@ static int ufs_qcom_set_core_clk_ctrl(struct ufs_hba *hba, bool is_scale_up)
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
struct list_head *head = &hba->clk_list_head;
struct ufs_clk_info *clki;
- u32 cycles_in_1us;
+ u32 cycles_in_1us = 0;
u32 core_clk_ctrl_reg;
int err;
@@ -1446,9 +1260,6 @@ static int ufs_qcom_clk_scale_up_pre_change(struct ufs_hba *hba)
struct ufs_pa_layer_attr *attr = &host->dev_req_params;
int ret;
- if (!ufs_qcom_cap_qunipro(host))
- return 0;
-
ret = ufs_qcom_cfg_timers(hba, attr->gear_rx, attr->pwr_rx,
attr->hs_rate, false, true);
if (ret) {
@@ -1466,13 +1277,9 @@ static int ufs_qcom_clk_scale_up_post_change(struct ufs_hba *hba)
static int ufs_qcom_clk_scale_down_pre_change(struct ufs_hba *hba)
{
- struct ufs_qcom_host *host = ufshcd_get_variant(hba);
int err;
u32 core_clk_ctrl_reg;
- if (!ufs_qcom_cap_qunipro(host))
- return 0;
-
err = ufshcd_dme_get(hba,
UIC_ARG_MIB(DME_VS_CORE_CLK_CTRL),
&core_clk_ctrl_reg);
@@ -1491,11 +1298,6 @@ static int ufs_qcom_clk_scale_down_pre_change(struct ufs_hba *hba)
static int ufs_qcom_clk_scale_down_post_change(struct ufs_hba *hba)
{
- struct ufs_qcom_host *host = ufshcd_get_variant(hba);
-
- if (!ufs_qcom_cap_qunipro(host))
- return 0;
-
/* set unipro core clock attributes and clear clock divider */
return ufs_qcom_set_core_clk_ctrl(hba, false);
}
@@ -1504,7 +1306,7 @@ static int ufs_qcom_clk_scale_notify(struct ufs_hba *hba,
bool scale_up, enum ufs_notify_change_status status)
{
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
- int err = 0;
+ int err;
/* check the host controller state before sending hibern8 cmd */
if (!ufshcd_is_hba_active(hba))
@@ -1777,7 +1579,7 @@ static int ufs_qcom_mcq_config_resource(struct ufs_hba *hba)
struct platform_device *pdev = to_platform_device(hba->dev);
struct ufshcd_res_info *res;
struct resource *res_mem, *res_mcq;
- int i, ret = 0;
+ int i, ret;
memcpy(hba->res, ufs_res_info, sizeof(ufs_res_info));
@@ -1931,7 +1733,7 @@ static int ufs_qcom_config_esi(struct ufs_hba *hba)
ufs_qcom_write_msi_msg);
if (ret) {
dev_err(hba->dev, "Failed to request Platform MSI %d\n", ret);
- goto out;
+ return ret;
}
msi_lock_descs(hba->dev);
@@ -1960,17 +1762,13 @@ static int ufs_qcom_config_esi(struct ufs_hba *hba)
platform_msi_domain_free_irqs(hba->dev);
} else {
if (host->hw_ver.major == 6 && host->hw_ver.minor == 0 &&
- host->hw_ver.step == 0) {
- ufshcd_writel(hba,
- ufshcd_readl(hba, REG_UFS_CFG3) | 0x1F000,
- REG_UFS_CFG3);
- }
+ host->hw_ver.step == 0)
+ ufshcd_rmwl(hba, ESI_VEC_MASK,
+ FIELD_PREP(ESI_VEC_MASK, MAX_ESI_VEC - 1),
+ REG_UFS_CFG3);
ufshcd_mcq_enable_esi(hba);
- }
-
-out:
- if (!ret)
host->esi_enabled = true;
+ }
return ret;
}
diff --git a/drivers/ufs/host/ufs-qcom.h b/drivers/ufs/host/ufs-qcom.h
index 9950a00894..9dd9a391eb 100644
--- a/drivers/ufs/host/ufs-qcom.h
+++ b/drivers/ufs/host/ufs-qcom.h
@@ -10,22 +10,17 @@
#include <soc/qcom/ice.h>
#include <ufs/ufshcd.h>
-#define MAX_UFS_QCOM_HOSTS 1
-#define MAX_U32 (~(u32)0)
#define MPHY_TX_FSM_STATE 0x41
#define TX_FSM_HIBERN8 0x1
#define HBRN8_POLL_TOUT_MS 100
#define DEFAULT_CLK_RATE_HZ 1000000
-#define BUS_VECTOR_NAME_LEN 32
#define MAX_SUPP_MAC 64
+#define MAX_ESI_VEC 32
#define UFS_HW_VER_MAJOR_MASK GENMASK(31, 28)
#define UFS_HW_VER_MINOR_MASK GENMASK(27, 16)
#define UFS_HW_VER_STEP_MASK GENMASK(15, 0)
-
-/* vendor specific pre-defined parameters */
-#define SLOW 1
-#define FAST 2
+#define UFS_DEV_VER_MAJOR_MASK GENMASK(7, 4)
#define UFS_QCOM_LIMIT_HS_RATE PA_HS_MODE_B
@@ -56,6 +51,8 @@ enum {
UFS_AH8_CFG = 0xFC,
REG_UFS_CFG3 = 0x271C,
+
+ REG_UFS_DEBUG_SPARE_CFG = 0x284C,
};
/* QCOM UFS host controller vendor specific debug registers */
@@ -93,9 +90,6 @@ enum {
#define TEST_BUS_SEL GENMASK(22, 19)
#define UFS_REG_TEST_BUS_EN BIT(30)
-#define UFS_PHY_RESET_ENABLE 1
-#define UFS_PHY_RESET_DISABLE 0
-
/* bit definitions for REG_UFS_CFG2 register */
#define UAWM_HW_CGC_EN BIT(0)
#define UARM_HW_CGC_EN BIT(1)
@@ -106,6 +100,9 @@ enum {
#define TMRLUT_HW_CGC_EN BIT(6)
#define OCSC_HW_CGC_EN BIT(7)
+/* bit definitions for REG_UFS_CFG3 register */
+#define ESI_VEC_MASK GENMASK(22, 12)
+
/* bit definitions for REG_UFS_PARAM0 */
#define MAX_HS_GEAR_MASK GENMASK(6, 4)
#define UFS_QCOM_MAX_GEAR(x) FIELD_GET(MAX_HS_GEAR_MASK, (x))
@@ -118,13 +115,6 @@ enum {
DFC_HW_CGC_EN | TRLUT_HW_CGC_EN |\
TMRLUT_HW_CGC_EN | OCSC_HW_CGC_EN)
-/* bit offset */
-#define OFFSET_CLK_NS_REG 0xa
-
-/* bit masks */
-#define MASK_TX_SYMBOL_CLK_1US_REG GENMASK(9, 0)
-#define MASK_CLK_NS_REG GENMASK(23, 10)
-
/* QUniPro Vendor specific attributes */
#define PA_VS_CONFIG_REG1 0x9000
#define DME_VS_CORE_CLK_CTRL 0xD002
@@ -158,8 +148,7 @@ ufs_qcom_get_controller_revision(struct ufs_hba *hba,
static inline void ufs_qcom_assert_reset(struct ufs_hba *hba)
{
- ufshcd_rmwl(hba, UFS_PHY_SOFT_RESET, FIELD_PREP(UFS_PHY_SOFT_RESET, UFS_PHY_RESET_ENABLE),
- REG_UFS_CFG1);
+ ufshcd_rmwl(hba, UFS_PHY_SOFT_RESET, UFS_PHY_SOFT_RESET, REG_UFS_CFG1);
/*
* Make sure assertion of ufs phy reset is written to
@@ -170,8 +159,7 @@ static inline void ufs_qcom_assert_reset(struct ufs_hba *hba)
static inline void ufs_qcom_deassert_reset(struct ufs_hba *hba)
{
- ufshcd_rmwl(hba, UFS_PHY_SOFT_RESET, FIELD_PREP(UFS_PHY_SOFT_RESET, UFS_PHY_RESET_DISABLE),
- REG_UFS_CFG1);
+ ufshcd_rmwl(hba, UFS_PHY_SOFT_RESET, 0, REG_UFS_CFG1);
/*
* Make sure de-assertion of ufs phy reset is written to
@@ -195,28 +183,11 @@ struct ufs_qcom_testbus {
struct gpio_desc;
struct ufs_qcom_host {
- /*
- * Set this capability if host controller supports the QUniPro mode
- * and if driver wants the Host controller to operate in QUniPro mode.
- * Note: By default this capability will be kept enabled if host
- * controller supports the QUniPro mode.
- */
- #define UFS_QCOM_CAP_QUNIPRO 0x1
-
- /*
- * Set this capability if host controller can retain the secure
- * configuration even after UFS controller core power collapse.
- */
- #define UFS_QCOM_CAP_RETAIN_SEC_CFG_AFTER_PWR_COLLAPSE 0x2
- u32 caps;
-
struct phy *generic_phy;
struct ufs_hba *hba;
struct ufs_pa_layer_attr dev_req_params;
- struct clk *rx_l0_sync_clk;
- struct clk *tx_l0_sync_clk;
- struct clk *rx_l1_sync_clk;
- struct clk *tx_l1_sync_clk;
+ struct clk_bulk_data *clks;
+ u32 num_clks;
bool is_lane_clks_enabled;
struct icc_path *icc_ddr;
@@ -240,6 +211,7 @@ struct ufs_qcom_host {
struct gpio_desc *device_reset;
+ struct ufs_host_params host_params;
u32 phy_gear;
bool esi_enabled;
@@ -261,9 +233,4 @@ ufs_qcom_get_debug_reg_offset(struct ufs_qcom_host *host, u32 reg)
int ufs_qcom_testbus_config(struct ufs_qcom_host *host);
-static inline bool ufs_qcom_cap_qunipro(struct ufs_qcom_host *host)
-{
- return host->caps & UFS_QCOM_CAP_QUNIPRO;
-}
-
#endif /* UFS_QCOM_H_ */
diff --git a/drivers/ufs/host/ufshcd-pltfrm.c b/drivers/ufs/host/ufshcd-pltfrm.c
index db9d9365ff..a3e69ecafd 100644
--- a/drivers/ufs/host/ufshcd-pltfrm.c
+++ b/drivers/ufs/host/ufshcd-pltfrm.c
@@ -339,61 +339,60 @@ static int ufshcd_parse_operating_points(struct ufs_hba *hba)
}
/**
- * ufshcd_get_pwr_dev_param - get finally agreed attributes for
- * power mode change
- * @pltfrm_param: pointer to platform parameters
+ * ufshcd_negotiate_pwr_params - find power mode settings that are supported by
+ * both the controller and the device
+ * @host_params: pointer to host parameters
* @dev_max: pointer to device attributes
* @agreed_pwr: returned agreed attributes
*
* Return: 0 on success, non-zero value on failure.
*/
-int ufshcd_get_pwr_dev_param(const struct ufs_dev_params *pltfrm_param,
- const struct ufs_pa_layer_attr *dev_max,
- struct ufs_pa_layer_attr *agreed_pwr)
+int ufshcd_negotiate_pwr_params(const struct ufs_host_params *host_params,
+ const struct ufs_pa_layer_attr *dev_max,
+ struct ufs_pa_layer_attr *agreed_pwr)
{
- int min_pltfrm_gear;
+ int min_host_gear;
int min_dev_gear;
bool is_dev_sup_hs = false;
- bool is_pltfrm_max_hs = false;
+ bool is_host_max_hs = false;
if (dev_max->pwr_rx == FAST_MODE)
is_dev_sup_hs = true;
- if (pltfrm_param->desired_working_mode == UFS_HS_MODE) {
- is_pltfrm_max_hs = true;
- min_pltfrm_gear = min_t(u32, pltfrm_param->hs_rx_gear,
- pltfrm_param->hs_tx_gear);
+ if (host_params->desired_working_mode == UFS_HS_MODE) {
+ is_host_max_hs = true;
+ min_host_gear = min_t(u32, host_params->hs_rx_gear,
+ host_params->hs_tx_gear);
} else {
- min_pltfrm_gear = min_t(u32, pltfrm_param->pwm_rx_gear,
- pltfrm_param->pwm_tx_gear);
+ min_host_gear = min_t(u32, host_params->pwm_rx_gear,
+ host_params->pwm_tx_gear);
}
/*
- * device doesn't support HS but
- * pltfrm_param->desired_working_mode is HS,
- * thus device and pltfrm_param don't agree
+ * device doesn't support HS but host_params->desired_working_mode is HS,
+ * thus device and host_params don't agree
*/
- if (!is_dev_sup_hs && is_pltfrm_max_hs) {
+ if (!is_dev_sup_hs && is_host_max_hs) {
pr_info("%s: device doesn't support HS\n",
__func__);
return -ENOTSUPP;
- } else if (is_dev_sup_hs && is_pltfrm_max_hs) {
+ } else if (is_dev_sup_hs && is_host_max_hs) {
/*
* since device supports HS, it supports FAST_MODE.
- * since pltfrm_param->desired_working_mode is also HS
+ * since host_params->desired_working_mode is also HS
* then final decision (FAST/FASTAUTO) is done according
* to pltfrm_params as it is the restricting factor
*/
- agreed_pwr->pwr_rx = pltfrm_param->rx_pwr_hs;
+ agreed_pwr->pwr_rx = host_params->rx_pwr_hs;
agreed_pwr->pwr_tx = agreed_pwr->pwr_rx;
} else {
/*
- * here pltfrm_param->desired_working_mode is PWM.
+ * here host_params->desired_working_mode is PWM.
* it doesn't matter whether device supports HS or PWM,
- * in both cases pltfrm_param->desired_working_mode will
+ * in both cases host_params->desired_working_mode will
* determine the mode
*/
- agreed_pwr->pwr_rx = pltfrm_param->rx_pwr_pwm;
+ agreed_pwr->pwr_rx = host_params->rx_pwr_pwm;
agreed_pwr->pwr_tx = agreed_pwr->pwr_rx;
}
@@ -403,9 +402,9 @@ int ufshcd_get_pwr_dev_param(const struct ufs_dev_params *pltfrm_param,
* the same decision will be made for rx
*/
agreed_pwr->lane_tx = min_t(u32, dev_max->lane_tx,
- pltfrm_param->tx_lanes);
+ host_params->tx_lanes);
agreed_pwr->lane_rx = min_t(u32, dev_max->lane_rx,
- pltfrm_param->rx_lanes);
+ host_params->rx_lanes);
/* device maximum gear is the minimum between device rx and tx gears */
min_dev_gear = min_t(u32, dev_max->gear_rx, dev_max->gear_tx);
@@ -418,26 +417,26 @@ int ufshcd_get_pwr_dev_param(const struct ufs_dev_params *pltfrm_param,
* what is the gear, as it is the one that also decided previously what
* pwr the device will be configured to.
*/
- if ((is_dev_sup_hs && is_pltfrm_max_hs) ||
- (!is_dev_sup_hs && !is_pltfrm_max_hs)) {
+ if ((is_dev_sup_hs && is_host_max_hs) ||
+ (!is_dev_sup_hs && !is_host_max_hs)) {
agreed_pwr->gear_rx =
- min_t(u32, min_dev_gear, min_pltfrm_gear);
+ min_t(u32, min_dev_gear, min_host_gear);
} else if (!is_dev_sup_hs) {
agreed_pwr->gear_rx = min_dev_gear;
} else {
- agreed_pwr->gear_rx = min_pltfrm_gear;
+ agreed_pwr->gear_rx = min_host_gear;
}
agreed_pwr->gear_tx = agreed_pwr->gear_rx;
- agreed_pwr->hs_rate = pltfrm_param->hs_rate;
+ agreed_pwr->hs_rate = host_params->hs_rate;
return 0;
}
-EXPORT_SYMBOL_GPL(ufshcd_get_pwr_dev_param);
+EXPORT_SYMBOL_GPL(ufshcd_negotiate_pwr_params);
-void ufshcd_init_pwr_dev_param(struct ufs_dev_params *dev_param)
+void ufshcd_init_host_params(struct ufs_host_params *host_params)
{
- *dev_param = (struct ufs_dev_params){
+ *host_params = (struct ufs_host_params){
.tx_lanes = UFS_LANE_2,
.rx_lanes = UFS_LANE_2,
.hs_rx_gear = UFS_HS_G3,
@@ -452,7 +451,7 @@ void ufshcd_init_pwr_dev_param(struct ufs_dev_params *dev_param)
.desired_working_mode = UFS_HS_MODE,
};
}
-EXPORT_SYMBOL_GPL(ufshcd_init_pwr_dev_param);
+EXPORT_SYMBOL_GPL(ufshcd_init_host_params);
/**
* ufshcd_pltfrm_init - probe routine of the driver
diff --git a/drivers/ufs/host/ufshcd-pltfrm.h b/drivers/ufs/host/ufshcd-pltfrm.h
index a86a3ada4b..df387be521 100644
--- a/drivers/ufs/host/ufshcd-pltfrm.h
+++ b/drivers/ufs/host/ufshcd-pltfrm.h
@@ -10,7 +10,7 @@
#define UFS_PWM_MODE 1
#define UFS_HS_MODE 2
-struct ufs_dev_params {
+struct ufs_host_params {
u32 pwm_rx_gear; /* pwm rx gear to work in */
u32 pwm_tx_gear; /* pwm tx gear to work in */
u32 hs_rx_gear; /* hs rx gear to work in */
@@ -25,10 +25,10 @@ struct ufs_dev_params {
u32 desired_working_mode;
};
-int ufshcd_get_pwr_dev_param(const struct ufs_dev_params *dev_param,
- const struct ufs_pa_layer_attr *dev_max,
- struct ufs_pa_layer_attr *agreed_pwr);
-void ufshcd_init_pwr_dev_param(struct ufs_dev_params *dev_param);
+int ufshcd_negotiate_pwr_params(const struct ufs_host_params *host_params,
+ const struct ufs_pa_layer_attr *dev_max,
+ struct ufs_pa_layer_attr *agreed_pwr);
+void ufshcd_init_host_params(struct ufs_host_params *host_params);
int ufshcd_pltfrm_init(struct platform_device *pdev,
const struct ufs_hba_variant_ops *vops);
int ufshcd_populate_vreg(struct device *dev, const char *name,