2020-10-29 11:59:58

by Stanley Chu

[permalink] [raw]
Subject: [PATCH v1 0/6] scsi: ufs: Add some proprietary features in MediaTek UFS platforms

Hi,

This patch series provides some features and fixes in MediaTek UFS platforms,

1. Support VA09 regulator operations
2. Support option to disable auto-hibern8
3. Support HS-G4
4. Decouple features from platform bindings
5. Misc fixes

Stanley Chu (6):
scsi: ufs-mediatek: Assign arguments with correct type
scsi: ufs-mediatek: Support VA09 regulator operations
scsi: ufs-mediatek: Decouple features from platform bindings
scsi: ufs-mediatek: Support option to disable auto-hibern8
scsi: ufs: Add enums for UniPro version higher than 1.6
scsi: ufs-mediatek: Add HS-G4 support

drivers/scsi/ufs/ufs-mediatek.c | 218 +++++++++++++++++++++++---------
drivers/scsi/ufs/ufs-mediatek.h | 22 ++--
drivers/scsi/ufs/unipro.h | 6 +-
3 files changed, 179 insertions(+), 67 deletions(-)

--
2.18.0


2020-10-29 12:00:06

by Stanley Chu

[permalink] [raw]
Subject: [PATCH v1 4/6] scsi: ufs-mediatek: Support option to disable auto-hibern8

Support an option to allow users to disable auto-hibern8 feature.

Instead, enable hibern8-during-clk-gating feature to keep similar
power consumption.

Signed-off-by: Stanley Chu <[email protected]>
---
drivers/scsi/ufs/ufs-mediatek.c | 18 ++++++++++++++++++
drivers/scsi/ufs/ufs-mediatek.h | 1 +
2 files changed, 19 insertions(+)

diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c
index fa7d0e4eeb0d..dda028ec30dc 100644
--- a/drivers/scsi/ufs/ufs-mediatek.c
+++ b/drivers/scsi/ufs/ufs-mediatek.c
@@ -158,6 +158,7 @@ static int ufs_mtk_hce_enable_notify(struct ufs_hba *hba,
enum ufs_notify_change_status status)
{
struct ufs_mtk_host *host = ufshcd_get_variant(hba);
+ unsigned long flags;

if (status == PRE_CHANGE) {
if (host->unipro_lpm) {
@@ -169,6 +170,17 @@ static int ufs_mtk_hce_enable_notify(struct ufs_hba *hba,

if (hba->caps & UFSHCD_CAP_CRYPTO)
ufs_mtk_crypto_enable(hba);
+
+ if (host->caps & UFS_MTK_CAP_DISABLE_AH8) {
+ spin_lock_irqsave(hba->host->host_lock, flags);
+ ufshcd_writel(hba, 0,
+ REG_AUTO_HIBERNATE_IDLE_TIMER);
+ spin_unlock_irqrestore(hba->host->host_lock,
+ flags);
+
+ hba->capabilities &= ~MASK_AUTO_HIBERN8_SUPPORT;
+ hba->ahit = 0;
+ }
}

return 0;
@@ -496,6 +508,9 @@ static void ufs_mtk_init_host_caps(struct ufs_hba *hba)
if (of_property_read_bool(np, "mediatek,ufs-support-va09"))
ufs_mtk_init_va09_pwr_ctrl(hba);

+ if (of_property_read_bool(np, "mediatek,ufs-disable-ah8"))
+ host->caps |= UFS_MTK_CAP_DISABLE_AH8;
+
dev_info(hba->dev, "caps: 0x%x", host->caps);
}

@@ -609,6 +624,9 @@ static int ufs_mtk_init(struct ufs_hba *hba)
hba->caps |= UFSHCD_CAP_WB_EN;
hba->vps->wb_flush_threshold = UFS_WB_BUF_REMAIN_PERCENT(80);

+ if (host->caps & UFS_MTK_CAP_DISABLE_AH8)
+ hba->caps |= UFSHCD_CAP_HIBERN8_WITH_CLK_GATING;
+
/*
* ufshcd_vops_init() is invoked after
* ufshcd_setup_clock(true) in ufshcd_hba_init() thus
diff --git a/drivers/scsi/ufs/ufs-mediatek.h b/drivers/scsi/ufs/ufs-mediatek.h
index 0e76429f69d6..30f45dfce04c 100644
--- a/drivers/scsi/ufs/ufs-mediatek.h
+++ b/drivers/scsi/ufs/ufs-mediatek.h
@@ -96,6 +96,7 @@ enum {
enum ufs_mtk_host_caps {
UFS_MTK_CAP_BOOST_CRYPT_ENGINE = 1 << 0,
UFS_MTK_CAP_VA09_PWR_CTRL = 1 << 1,
+ UFS_MTK_CAP_DISABLE_AH8 = 1 << 2,
};

struct ufs_mtk_crypt_cfg {
--
2.18.0

2020-10-29 12:00:22

by Stanley Chu

[permalink] [raw]
Subject: [PATCH v1 6/6] scsi: ufs-mediatek: Add HS-G4 support

Provide HS-G4 support in MediaTek UFS platforms.

To support HS-G4, introduce mechanism to get the
MediaTek UFS controller version. With such information,
driver can make right decision to apply different
configurations in different controllers.

Signed-off-by: Stanley Chu <[email protected]>
---
drivers/scsi/ufs/ufs-mediatek.c | 32 ++++++++++++++++++++++++++++++++
drivers/scsi/ufs/ufs-mediatek.h | 11 +++++++++--
2 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c
index dda028ec30dc..1a355f519556 100644
--- a/drivers/scsi/ufs/ufs-mediatek.c
+++ b/drivers/scsi/ufs/ufs-mediatek.c
@@ -569,6 +569,24 @@ static int ufs_mtk_setup_clocks(struct ufs_hba *hba, bool on,
return ret;
}

+static void ufs_mtk_get_controller_version(struct ufs_hba *hba)
+{
+ struct ufs_mtk_host *host = ufshcd_get_variant(hba);
+ int ret, ver = 0;
+
+ if (host->hw_ver.major)
+ return;
+
+ /* Set default (minimum) version anyway */
+ host->hw_ver.major = 2;
+
+ ret = ufshcd_dme_get(hba, UIC_ARG_MIB(PA_LOCALVERINFO), &ver);
+ if (!ret) {
+ if (ver >= UFS_UNIPRO_VER_1_8)
+ host->hw_ver.major = 3;
+ }
+}
+
/**
* ufs_mtk_init - find other essential mmio bases
* @hba: host controller instance
@@ -649,7 +667,9 @@ static int ufs_mtk_pre_pwr_change(struct ufs_hba *hba,
struct ufs_pa_layer_attr *dev_max_params,
struct ufs_pa_layer_attr *dev_req_params)
{
+ struct ufs_mtk_host *host = ufshcd_get_variant(hba);
struct ufs_dev_params host_cap;
+ u32 adapt_val;
int ret;

host_cap.tx_lanes = UFS_MTK_LIMIT_NUM_LANES_TX;
@@ -674,6 +694,16 @@ static int ufs_mtk_pre_pwr_change(struct ufs_hba *hba,
__func__);
}

+ if (host->hw_ver.major >= 3) {
+ if (dev_req_params->gear_tx == UFS_HS_G4)
+ adapt_val = PA_INITIAL_ADAPT;
+ else
+ adapt_val = PA_NO_ADAPT;
+ ufshcd_dme_set(hba,
+ UIC_ARG_MIB(PA_TXHSADAPTTYPE),
+ adapt_val);
+ }
+
return ret;
}

@@ -724,6 +754,8 @@ static int ufs_mtk_pre_link(struct ufs_hba *hba)
int ret;
u32 tmp;

+ ufs_mtk_get_controller_version(hba);
+
ret = ufs_mtk_unipro_set_lpm(hba, false);
if (ret)
return ret;
diff --git a/drivers/scsi/ufs/ufs-mediatek.h b/drivers/scsi/ufs/ufs-mediatek.h
index 30f45dfce04c..ac37b11803fb 100644
--- a/drivers/scsi/ufs/ufs-mediatek.h
+++ b/drivers/scsi/ufs/ufs-mediatek.h
@@ -35,8 +35,8 @@
*/
#define UFS_MTK_LIMIT_NUM_LANES_RX 2
#define UFS_MTK_LIMIT_NUM_LANES_TX 2
-#define UFS_MTK_LIMIT_HSGEAR_RX UFS_HS_G3
-#define UFS_MTK_LIMIT_HSGEAR_TX UFS_HS_G3
+#define UFS_MTK_LIMIT_HSGEAR_RX UFS_HS_G4
+#define UFS_MTK_LIMIT_HSGEAR_TX UFS_HS_G4
#define UFS_MTK_LIMIT_PWMGEAR_RX UFS_PWM_G4
#define UFS_MTK_LIMIT_PWMGEAR_TX UFS_PWM_G4
#define UFS_MTK_LIMIT_RX_PWR_PWM SLOW_MODE
@@ -107,6 +107,12 @@ struct ufs_mtk_crypt_cfg {
int vcore_volt;
};

+struct ufs_mtk_hw_ver {
+ u8 step;
+ u8 minor;
+ u8 major;
+};
+
struct ufs_mtk_host {
struct phy *mphy;
struct regulator *reg_va09;
@@ -115,6 +121,7 @@ struct ufs_mtk_host {
struct reset_control *crypto_reset;
struct ufs_hba *hba;
struct ufs_mtk_crypt_cfg *crypt;
+ struct ufs_mtk_hw_ver hw_ver;
enum ufs_mtk_host_caps caps;
bool mphy_powered_on;
bool unipro_lpm;
--
2.18.0

2020-10-29 12:00:28

by Stanley Chu

[permalink] [raw]
Subject: [PATCH v1 3/6] scsi: ufs-mediatek: Decouple features from platform bindings

UFS proprietary features (including features introduced later) in
MediaTek UFS platforms have complicated combinations among different
platforms.

To ease code readability and maintenance, decouple all proprietary
features from platform bindings. Each feature would be enabled only
if specific property string is defined in device tree node.

Signed-off-by: Stanley Chu <[email protected]>
---
drivers/scsi/ufs/ufs-mediatek.c | 49 ++++++++++-----------------------
drivers/scsi/ufs/ufs-mediatek.h | 11 ++------
2 files changed, 18 insertions(+), 42 deletions(-)

diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c
index 795fc2961f77..fa7d0e4eeb0d 100644
--- a/drivers/scsi/ufs/ufs-mediatek.c
+++ b/drivers/scsi/ufs/ufs-mediatek.c
@@ -48,23 +48,8 @@ static struct ufs_dev_fix ufs_mtk_dev_fixups[] = {
END_FIX
};

-static const struct ufs_mtk_host_cfg ufs_mtk_mt8183_cfg = {
- .caps = UFS_MTK_CAP_VA09_PWR_CTRL,
-};
-
-static const struct ufs_mtk_host_cfg ufs_mtk_mt8192_cfg = {
- .caps = UFS_MTK_CAP_BOOST_CRYPT_ENGINE,
-};
-
static const struct of_device_id ufs_mtk_of_match[] = {
- {
- .compatible = "mediatek,mt8183-ufshci",
- .data = &ufs_mtk_mt8183_cfg
- },
- {
- .compatible = "mediatek,mt8192-ufshci",
- .data = &ufs_mtk_mt8192_cfg
- },
+ { .compatible = "mediatek,mt8183-ufshci" },
{},
};

@@ -72,14 +57,14 @@ static bool ufs_mtk_is_boost_crypt_enabled(struct ufs_hba *hba)
{
struct ufs_mtk_host *host = ufshcd_get_variant(hba);

- return (host->caps & UFS_MTK_CAP_BOOST_CRYPT_ENGINE);
+ return !!(host->caps & UFS_MTK_CAP_BOOST_CRYPT_ENGINE);
}

static bool ufs_mtk_is_va09_supported(struct ufs_hba *hba)
{
struct ufs_mtk_host *host = ufshcd_get_variant(hba);

- return (host->caps & UFS_MTK_CAP_VA09_PWR_CTRL);
+ return !!(host->caps & UFS_MTK_CAP_VA09_PWR_CTRL);
}

static void ufs_mtk_cfg_unipro_cg(struct ufs_hba *hba, bool enable)
@@ -326,7 +311,7 @@ static int ufs_mtk_mphy_power_on(struct ufs_hba *hba, bool on)
return 0;

if (on) {
- if (host->reg_va09) {
+ if (ufs_mtk_is_va09_supported(hba)) {
ret = regulator_enable(host->reg_va09);
if (ret < 0)
goto out;
@@ -337,7 +322,7 @@ static int ufs_mtk_mphy_power_on(struct ufs_hba *hba, bool on)
phy_power_on(mphy);
} else {
phy_power_off(mphy);
- if (host->reg_va09) {
+ if (ufs_mtk_is_va09_supported(hba)) {
ufs_mtk_va09_pwr_ctrl(res, 0);
ret = regulator_disable(host->reg_va09);
if (ret < 0)
@@ -483,10 +468,10 @@ static void ufs_mtk_init_boost_crypt(struct ufs_hba *hba)

cfg->reg_vcore = reg;
cfg->vcore_volt = volt;
- return;
+ host->caps |= UFS_MTK_CAP_BOOST_CRYPT_ENGINE;

disable_caps:
- host->caps &= ~UFS_MTK_CAP_BOOST_CRYPT_ENGINE;
+ return;
}

static void ufs_mtk_init_va09_pwr_ctrl(struct ufs_hba *hba)
@@ -494,22 +479,21 @@ static void ufs_mtk_init_va09_pwr_ctrl(struct ufs_hba *hba)
struct ufs_mtk_host *host = ufshcd_get_variant(hba);

host->reg_va09 = regulator_get(hba->dev, "va09");
- if (!host->reg_va09) {
+ if (!host->reg_va09)
dev_info(hba->dev, "failed to get va09");
- host->caps &= ~UFS_MTK_CAP_VA09_PWR_CTRL;
- }
+ else
+ host->caps |= UFS_MTK_CAP_VA09_PWR_CTRL;
}

static void ufs_mtk_init_host_caps(struct ufs_hba *hba)
{
struct ufs_mtk_host *host = ufshcd_get_variant(hba);
+ struct device_node *np = hba->dev->of_node;

- host->caps = host->cfg->caps;
-
- if (ufs_mtk_is_boost_crypt_enabled(hba))
+ if (of_property_read_bool(np, "mediatek,ufs-boost-crypt"))
ufs_mtk_init_boost_crypt(hba);

- if (ufs_mtk_is_va09_supported(hba))
+ if (of_property_read_bool(np, "mediatek,ufs-support-va09"))
ufs_mtk_init_va09_pwr_ctrl(hba);

dev_info(hba->dev, "caps: 0x%x", host->caps);
@@ -597,17 +581,14 @@ static int ufs_mtk_init(struct ufs_hba *hba)
host->hba = hba;
ufshcd_set_variant(hba, host);

- /* Get host capability and platform data */
id = of_match_device(ufs_mtk_of_match, dev);
if (!id) {
err = -EINVAL;
goto out;
}

- if (id->data) {
- host->cfg = (struct ufs_mtk_host_cfg *)id->data;
- ufs_mtk_init_host_caps(hba);
- }
+ /* Initialize host capability */
+ ufs_mtk_init_host_caps(hba);

err = ufs_mtk_bind_mphy(hba);
if (err)
diff --git a/drivers/scsi/ufs/ufs-mediatek.h b/drivers/scsi/ufs/ufs-mediatek.h
index f668241d37f8..0e76429f69d6 100644
--- a/drivers/scsi/ufs/ufs-mediatek.h
+++ b/drivers/scsi/ufs/ufs-mediatek.h
@@ -106,20 +106,15 @@ struct ufs_mtk_crypt_cfg {
int vcore_volt;
};

-struct ufs_mtk_host_cfg {
- enum ufs_mtk_host_caps caps;
-};
-
struct ufs_mtk_host {
- struct ufs_hba *hba;
struct phy *mphy;
- struct ufs_mtk_host_cfg *cfg;
- struct ufs_mtk_crypt_cfg *crypt;
struct regulator *reg_va09;
- enum ufs_mtk_host_caps caps;
struct reset_control *hci_reset;
struct reset_control *unipro_reset;
struct reset_control *crypto_reset;
+ struct ufs_hba *hba;
+ struct ufs_mtk_crypt_cfg *crypt;
+ enum ufs_mtk_host_caps caps;
bool mphy_powered_on;
bool unipro_lpm;
bool ref_clk_enabled;
--
2.18.0

2020-10-29 12:01:08

by Stanley Chu

[permalink] [raw]
Subject: [PATCH v1 5/6] scsi: ufs: Add enums for UniPro version higher than 1.6

Some vendors need newer UniPro version to decide if some features
can be enabled or not.

Simply add missing enums for the latest UniPro versions.

Signed-off-by: Stanley Chu <[email protected]>
---
drivers/scsi/ufs/unipro.h | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/ufs/unipro.h b/drivers/scsi/ufs/unipro.h
index f6b52ce36de6..8e9e486a4f7b 100644
--- a/drivers/scsi/ufs/unipro.h
+++ b/drivers/scsi/ufs/unipro.h
@@ -237,8 +237,10 @@ enum ufs_unipro_ver {
UFS_UNIPRO_VER_RESERVED = 0,
UFS_UNIPRO_VER_1_40 = 1, /* UniPro version 1.40 */
UFS_UNIPRO_VER_1_41 = 2, /* UniPro version 1.41 */
- UFS_UNIPRO_VER_1_6 = 3, /* UniPro version 1.6 */
- UFS_UNIPRO_VER_MAX = 4, /* UniPro unsupported version */
+ UFS_UNIPRO_VER_1_6 = 3, /* UniPro version 1.6 */
+ UFS_UNIPRO_VER_1_61 = 4, /* UniPro version 1.61 */
+ UFS_UNIPRO_VER_1_8 = 5, /* UniPro version 1.8 */
+ UFS_UNIPRO_VER_MAX = 6, /* UniPro unsupported version */
/* UniPro version field mask in PA_LOCALVERINFO */
UFS_UNIPRO_VER_MASK = 0xF,
};
--
2.18.0

2020-10-29 12:01:12

by Stanley Chu

[permalink] [raw]
Subject: [PATCH v1 2/6] scsi: ufs-mediatek: Support VA09 regulator operations

Some MediaTek UFS platforms need to control VA09 power
specifically. Provide such control according to the device
tree binding.

Signed-off-by: Stanley Chu <[email protected]>
---
drivers/scsi/ufs/ufs-mediatek.c | 137 ++++++++++++++++++++++++--------
drivers/scsi/ufs/ufs-mediatek.h | 3 +
2 files changed, 108 insertions(+), 32 deletions(-)

diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c
index 0196a89055b5..795fc2961f77 100644
--- a/drivers/scsi/ufs/ufs-mediatek.c
+++ b/drivers/scsi/ufs/ufs-mediatek.c
@@ -28,6 +28,9 @@
arm_smccc_smc(MTK_SIP_UFS_CONTROL, \
cmd, val, 0, 0, 0, 0, 0, &(res))

+#define ufs_mtk_va09_pwr_ctrl(res, on) \
+ ufs_mtk_smc(UFS_MTK_SIP_VA09_PWR_CTRL, on, res)
+
#define ufs_mtk_crypto_ctrl(res, enable) \
ufs_mtk_smc(UFS_MTK_SIP_CRYPTO_CTRL, enable, res)

@@ -45,6 +48,10 @@ static struct ufs_dev_fix ufs_mtk_dev_fixups[] = {
END_FIX
};

+static const struct ufs_mtk_host_cfg ufs_mtk_mt8183_cfg = {
+ .caps = UFS_MTK_CAP_VA09_PWR_CTRL,
+};
+
static const struct ufs_mtk_host_cfg ufs_mtk_mt8192_cfg = {
.caps = UFS_MTK_CAP_BOOST_CRYPT_ENGINE,
};
@@ -52,6 +59,7 @@ static const struct ufs_mtk_host_cfg ufs_mtk_mt8192_cfg = {
static const struct of_device_id ufs_mtk_of_match[] = {
{
.compatible = "mediatek,mt8183-ufshci",
+ .data = &ufs_mtk_mt8183_cfg
},
{
.compatible = "mediatek,mt8192-ufshci",
@@ -67,6 +75,13 @@ static bool ufs_mtk_is_boost_crypt_enabled(struct ufs_hba *hba)
return (host->caps & UFS_MTK_CAP_BOOST_CRYPT_ENGINE);
}

+static bool ufs_mtk_is_va09_supported(struct ufs_hba *hba)
+{
+ struct ufs_mtk_host *host = ufshcd_get_variant(hba);
+
+ return (host->caps & UFS_MTK_CAP_VA09_PWR_CTRL);
+}
+
static void ufs_mtk_cfg_unipro_cg(struct ufs_hba *hba, bool enable)
{
u32 tmp;
@@ -300,21 +315,46 @@ static int ufs_mtk_wait_link_state(struct ufs_hba *hba, u32 state,
return -ETIMEDOUT;
}

-static void ufs_mtk_mphy_power_on(struct ufs_hba *hba, bool on)
+static int ufs_mtk_mphy_power_on(struct ufs_hba *hba, bool on)
{
struct ufs_mtk_host *host = ufshcd_get_variant(hba);
struct phy *mphy = host->mphy;
+ struct arm_smccc_res res;
+ int ret = 0;

- if (!mphy)
- return;
+ if (!mphy || !(on ^ host->mphy_powered_on))
+ return 0;

- if (on && !host->mphy_powered_on)
+ if (on) {
+ if (host->reg_va09) {
+ ret = regulator_enable(host->reg_va09);
+ if (ret < 0)
+ goto out;
+ /* wait 200 us to stablize VA09 */
+ usleep_range(200, 210);
+ ufs_mtk_va09_pwr_ctrl(res, 1);
+ }
phy_power_on(mphy);
- else if (!on && host->mphy_powered_on)
+ } else {
phy_power_off(mphy);
- else
- return;
- host->mphy_powered_on = on;
+ if (host->reg_va09) {
+ ufs_mtk_va09_pwr_ctrl(res, 0);
+ ret = regulator_disable(host->reg_va09);
+ if (ret < 0)
+ goto out;
+ }
+ }
+out:
+ if (ret) {
+ dev_info(hba->dev,
+ "failed to %s va09: %d\n",
+ on ? "enable" : "disable",
+ ret);
+ } else {
+ host->mphy_powered_on = on;
+ }
+
+ return ret;
}

static int ufs_mtk_get_host_clk(struct device *dev, const char *name,
@@ -402,7 +442,7 @@ static int ufs_mtk_init_host_clk(struct ufs_hba *hba, const char *name,
return ret;
}

-static void ufs_mtk_init_host_caps(struct ufs_hba *hba)
+static void ufs_mtk_init_boost_crypt(struct ufs_hba *hba)
{
struct ufs_mtk_host *host = ufshcd_get_variant(hba);
struct ufs_mtk_crypt_cfg *cfg;
@@ -410,11 +450,6 @@ static void ufs_mtk_init_host_caps(struct ufs_hba *hba)
struct regulator *reg;
u32 volt;

- host->caps = host->cfg->caps;
-
- if (!ufs_mtk_is_boost_crypt_enabled(hba))
- return;
-
host->crypt = devm_kzalloc(dev, sizeof(*(host->crypt)),
GFP_KERNEL);
if (!host->crypt)
@@ -448,13 +483,38 @@ static void ufs_mtk_init_host_caps(struct ufs_hba *hba)

cfg->reg_vcore = reg;
cfg->vcore_volt = volt;
- dev_info(dev, "caps: boost-crypt");
return;

disable_caps:
host->caps &= ~UFS_MTK_CAP_BOOST_CRYPT_ENGINE;
}

+static void ufs_mtk_init_va09_pwr_ctrl(struct ufs_hba *hba)
+{
+ struct ufs_mtk_host *host = ufshcd_get_variant(hba);
+
+ host->reg_va09 = regulator_get(hba->dev, "va09");
+ if (!host->reg_va09) {
+ dev_info(hba->dev, "failed to get va09");
+ host->caps &= ~UFS_MTK_CAP_VA09_PWR_CTRL;
+ }
+}
+
+static void ufs_mtk_init_host_caps(struct ufs_hba *hba)
+{
+ struct ufs_mtk_host *host = ufshcd_get_variant(hba);
+
+ host->caps = host->cfg->caps;
+
+ if (ufs_mtk_is_boost_crypt_enabled(hba))
+ ufs_mtk_init_boost_crypt(hba);
+
+ if (ufs_mtk_is_va09_supported(hba))
+ ufs_mtk_init_va09_pwr_ctrl(hba);
+
+ dev_info(hba->dev, "caps: 0x%x", host->caps);
+}
+
/**
* ufs_mtk_setup_clocks - enables/disable clocks
* @hba: host controller instance
@@ -467,8 +527,8 @@ static int ufs_mtk_setup_clocks(struct ufs_hba *hba, bool on,
enum ufs_notify_change_status status)
{
struct ufs_mtk_host *host = ufshcd_get_variant(hba);
- int ret = 0;
bool clk_pwr_off = false;
+ int ret = 0;

/*
* In case ufs_mtk_init() is not yet done, simply ignore.
@@ -499,10 +559,10 @@ static int ufs_mtk_setup_clocks(struct ufs_hba *hba, bool on,
if (clk_pwr_off) {
ufs_mtk_boost_crypt(hba, on);
ufs_mtk_setup_ref_clk(hba, on);
- ufs_mtk_mphy_power_on(hba, on);
+ phy_power_off(host->mphy);
}
} else if (on && status == POST_CHANGE) {
- ufs_mtk_mphy_power_on(hba, on);
+ phy_power_on(host->mphy);
ufs_mtk_setup_ref_clk(hba, on);
ufs_mtk_boost_crypt(hba, on);
}
@@ -575,6 +635,7 @@ static int ufs_mtk_init(struct ufs_hba *hba)
*
* Enable phy clocks specifically here.
*/
+ ufs_mtk_mphy_power_on(hba, true);
ufs_mtk_setup_clocks(hba, true, POST_CHANGE);

goto out;
@@ -824,40 +885,52 @@ static int ufs_mtk_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)

if (ufshcd_is_link_hibern8(hba)) {
err = ufs_mtk_link_set_lpm(hba);
- if (err) {
- /*
- * Set link as off state enforcedly to trigger
- * ufshcd_host_reset_and_restore() in ufshcd_suspend()
- * for completed host reset.
- */
- ufshcd_set_link_off(hba);
- return -EAGAIN;
- }
+ if (err)
+ goto fail;
+ }
+
+ if (!ufshcd_is_link_active(hba)) {
/*
* Make sure no error will be returned to prevent
* ufshcd_suspend() re-enabling regulators while vreg is still
* in low-power mode.
*/
ufs_mtk_vreg_set_lpm(hba, true);
+ err = ufs_mtk_mphy_power_on(hba, false);
+ if (err)
+ goto fail;
}

return 0;
+fail:
+ /*
+ * Set link as off state enforcedly to trigger
+ * ufshcd_host_reset_and_restore() in ufshcd_suspend()
+ * for completed host reset.
+ */
+ ufshcd_set_link_off(hba);
+ return -EAGAIN;
}

static int ufs_mtk_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
{
int err;

+ err = ufs_mtk_mphy_power_on(hba, true);
+ if (err)
+ goto fail;
+
+ ufs_mtk_vreg_set_lpm(hba, false);
+
if (ufshcd_is_link_hibern8(hba)) {
- ufs_mtk_vreg_set_lpm(hba, false);
err = ufs_mtk_link_set_hpm(hba);
- if (err) {
- err = ufshcd_link_recovery(hba);
- return err;
- }
+ if (err)
+ goto fail;
}

return 0;
+fail:
+ return ufshcd_link_recovery(hba);
}

static void ufs_mtk_dbg_register_dump(struct ufs_hba *hba)
diff --git a/drivers/scsi/ufs/ufs-mediatek.h b/drivers/scsi/ufs/ufs-mediatek.h
index 2b6a1312c9bc..f668241d37f8 100644
--- a/drivers/scsi/ufs/ufs-mediatek.h
+++ b/drivers/scsi/ufs/ufs-mediatek.h
@@ -69,6 +69,7 @@ enum {
* SiP commands
*/
#define MTK_SIP_UFS_CONTROL MTK_SIP_SMC_CMD(0x276)
+#define UFS_MTK_SIP_VA09_PWR_CTRL BIT(0)
#define UFS_MTK_SIP_DEVICE_RESET BIT(1)
#define UFS_MTK_SIP_CRYPTO_CTRL BIT(2)
#define UFS_MTK_SIP_REF_CLK_NOTIFICATION BIT(3)
@@ -94,6 +95,7 @@ enum {
*/
enum ufs_mtk_host_caps {
UFS_MTK_CAP_BOOST_CRYPT_ENGINE = 1 << 0,
+ UFS_MTK_CAP_VA09_PWR_CTRL = 1 << 1,
};

struct ufs_mtk_crypt_cfg {
@@ -113,6 +115,7 @@ struct ufs_mtk_host {
struct phy *mphy;
struct ufs_mtk_host_cfg *cfg;
struct ufs_mtk_crypt_cfg *crypt;
+ struct regulator *reg_va09;
enum ufs_mtk_host_caps caps;
struct reset_control *hci_reset;
struct reset_control *unipro_reset;
--
2.18.0

2020-11-06 06:15:27

by Stanley Chu

[permalink] [raw]
Subject: Re: [PATCH v1 0/6] scsi: ufs: Add some proprietary features in MediaTek UFS platforms

Hi Martin, Avri,

On Thu, 2020-10-29 at 19:57 +0800, Stanley Chu wrote:
> Hi,
>
> This patch series provides some features and fixes in MediaTek UFS platforms,

Sorry for the gentle ping. Just please consider this patch series for
merging to kernel version 5.11.

Thanks,
Stanley Chu.

>
> 1. Support VA09 regulator operations
> 2. Support option to disable auto-hibern8
> 3. Support HS-G4
> 4. Decouple features from platform bindings
> 5. Misc fixes
>
> Stanley Chu (6):
> scsi: ufs-mediatek: Assign arguments with correct type
> scsi: ufs-mediatek: Support VA09 regulator operations
> scsi: ufs-mediatek: Decouple features from platform bindings
> scsi: ufs-mediatek: Support option to disable auto-hibern8
> scsi: ufs: Add enums for UniPro version higher than 1.6
> scsi: ufs-mediatek: Add HS-G4 support
>
> drivers/scsi/ufs/ufs-mediatek.c | 218 +++++++++++++++++++++++---------
> drivers/scsi/ufs/ufs-mediatek.h | 22 ++--
> drivers/scsi/ufs/unipro.h | 6 +-
> 3 files changed, 179 insertions(+), 67 deletions(-)
>

2020-11-11 04:07:22

by Martin K. Petersen

[permalink] [raw]
Subject: Re: [PATCH v1 0/6] scsi: ufs: Add some proprietary features in MediaTek UFS platforms


Stanley,

> This patch series provides some features and fixes in MediaTek UFS
> platforms,

Applied to 5.11/scsi-staging, thanks!

--
Martin K. Petersen Oracle Linux Engineering