linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 00/10] csi: ufs: Fix PMC and low-power mode on MediaTek UFS platforms
@ 2022-06-15  3:51 Stanley Chu
  2022-06-15  3:51 ` [PATCH v4 01/10] scsi: ufs: Export ufshcd_uic_change_pwr_mode() Stanley Chu
                   ` (9 more replies)
  0 siblings, 10 replies; 13+ messages in thread
From: Stanley Chu @ 2022-06-15  3:51 UTC (permalink / raw)
  To: linux-scsi, linux-kernel, martin.petersen, avri.altman,
	alim.akhtar, jejb, bvanassche
  Cc: peter.wang, chun-hung.wu, alice.chao, powen.kao, mason.zhang,
	qilin.tan, lin.gui, eddie.huang, tun-yu.yu, cc.chou,
	chaotian.jing, jiajie.hao, stanley.chu

Hi Martin,

This series provides some fixes on MediaTek UFS platforms, please consider this patch series for kernel v5.20.

- Provide workaround for power mode change for HS-G5
- Fix and provide regulator features

Changes compared to v3:
- Rewrite and simplify SMC call wrappers
- Fix coding styles

Changes compared to v2:
- Add patches to support multiple VCC sources

Changes compared to v1:
- Add patches to fix and provide VCCQx low-power support


CC Chou (1):
  scsi: ufs-mediatek: Introduce workaround for power mode change

Peter Wang (1):
  scsi: ufs-mediatek: Support low-power mode for VCCQ

Po-Wen Kao (2):
  scsi: ufs-mediatek: Fix the timing of configuring device regulators
  scsi: ufs-mediatek: Prevent device regulators setting as LPM
    incorrectly

Stanley Chu (6):
  scsi: ufs: Export ufshcd_uic_change_pwr_mode()
  scsi: ufs: Fix ADAPT logic for HS-G5
  scsi: ufs-mediatek: Support flexible parameters for smc calls
  scsi: ufs-mediatek: Support low-power mode for parents of VCCQx
  scsi: ufs: Export regulator functions
  scsi: ufs-mediatek: Support multiple VCC sources

 drivers/ufs/core/ufshcd.c        |   8 +-
 drivers/ufs/host/ufs-mediatek.c  | 231 ++++++++++++++++++++++++++-----
 drivers/ufs/host/ufs-mediatek.h  |  58 ++++++++
 drivers/ufs/host/ufshcd-pltfrm.c |   5 +-
 drivers/ufs/host/ufshcd-pltfrm.h |   2 +
 include/ufs/ufshcd.h             |   3 +
 include/ufs/unipro.h             |   1 +
 7 files changed, 272 insertions(+), 36 deletions(-)

-- 
2.18.0


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v4 01/10] scsi: ufs: Export ufshcd_uic_change_pwr_mode()
  2022-06-15  3:51 [PATCH v4 00/10] csi: ufs: Fix PMC and low-power mode on MediaTek UFS platforms Stanley Chu
@ 2022-06-15  3:51 ` Stanley Chu
  2022-06-15 16:44   ` Bart Van Assche
  2022-06-15  3:51 ` [PATCH v4 02/10] scsi: ufs: Fix ADAPT logic for HS-G5 Stanley Chu
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 13+ messages in thread
From: Stanley Chu @ 2022-06-15  3:51 UTC (permalink / raw)
  To: linux-scsi, linux-kernel, martin.petersen, avri.altman,
	alim.akhtar, jejb, bvanassche
  Cc: peter.wang, chun-hung.wu, alice.chao, powen.kao, mason.zhang,
	qilin.tan, lin.gui, eddie.huang, tun-yu.yu, cc.chou,
	chaotian.jing, jiajie.hao, stanley.chu

Export ufshcd_uic_change_pwr_mode() to allow vendors to
use it for SoC-specific power mode change design limitation.

Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
---
 drivers/ufs/core/ufshcd.c | 3 ++-
 include/ufs/ufshcd.h      | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 936a6d5467c9..19e17c898319 100755
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -4091,7 +4091,7 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd)
  *
  * Returns 0 on success, non-zero value on failure
  */
-static int ufshcd_uic_change_pwr_mode(struct ufs_hba *hba, u8 mode)
+int ufshcd_uic_change_pwr_mode(struct ufs_hba *hba, u8 mode)
 {
 	struct uic_command uic_cmd = {0};
 	int ret;
@@ -4116,6 +4116,7 @@ static int ufshcd_uic_change_pwr_mode(struct ufs_hba *hba, u8 mode)
 out:
 	return ret;
 }
+EXPORT_SYMBOL_GPL(ufshcd_uic_change_pwr_mode);
 
 int ufshcd_link_recovery(struct ufs_hba *hba)
 {
diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h
index a92271421718..aa778418703f 100755
--- a/include/ufs/ufshcd.h
+++ b/include/ufs/ufshcd.h
@@ -1087,6 +1087,7 @@ extern int ufshcd_dme_get_attr(struct ufs_hba *hba, u32 attr_sel,
 			       u32 *mib_val, u8 peer);
 extern int ufshcd_config_pwr_mode(struct ufs_hba *hba,
 			struct ufs_pa_layer_attr *desired_pwr_mode);
+extern int ufshcd_uic_change_pwr_mode(struct ufs_hba *hba, u8 mode);
 
 /* UIC command interfaces for DME primitives */
 #define DME_LOCAL	0
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 02/10] scsi: ufs: Fix ADAPT logic for HS-G5
  2022-06-15  3:51 [PATCH v4 00/10] csi: ufs: Fix PMC and low-power mode on MediaTek UFS platforms Stanley Chu
  2022-06-15  3:51 ` [PATCH v4 01/10] scsi: ufs: Export ufshcd_uic_change_pwr_mode() Stanley Chu
@ 2022-06-15  3:51 ` Stanley Chu
  2022-06-15 16:44   ` Bart Van Assche
  2022-06-15  3:51 ` [PATCH v4 03/10] scsi: ufs-mediatek: Introduce workaround for power mode change Stanley Chu
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 13+ messages in thread
From: Stanley Chu @ 2022-06-15  3:51 UTC (permalink / raw)
  To: linux-scsi, linux-kernel, martin.petersen, avri.altman,
	alim.akhtar, jejb, bvanassche
  Cc: peter.wang, chun-hung.wu, alice.chao, powen.kao, mason.zhang,
	qilin.tan, lin.gui, eddie.huang, tun-yu.yu, cc.chou,
	chaotian.jing, jiajie.hao, stanley.chu

ADAPT now is added not only for HS Gear4 mode but also higher gears.
Fix the logic for higher gears.

Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
---
 drivers/ufs/core/ufshcd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 19e17c898319..0d16739c67bb 100755
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -3802,7 +3802,7 @@ int ufshcd_dme_configure_adapt(struct ufs_hba *hba,
 {
 	int ret;
 
-	if (agreed_gear != UFS_HS_G4)
+	if (agreed_gear < UFS_HS_G4)
 		adapt_val = PA_NO_ADAPT;
 
 	ret = ufshcd_dme_set(hba,
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 03/10] scsi: ufs-mediatek: Introduce workaround for power mode change
  2022-06-15  3:51 [PATCH v4 00/10] csi: ufs: Fix PMC and low-power mode on MediaTek UFS platforms Stanley Chu
  2022-06-15  3:51 ` [PATCH v4 01/10] scsi: ufs: Export ufshcd_uic_change_pwr_mode() Stanley Chu
  2022-06-15  3:51 ` [PATCH v4 02/10] scsi: ufs: Fix ADAPT logic for HS-G5 Stanley Chu
@ 2022-06-15  3:51 ` Stanley Chu
  2022-06-15  3:51 ` [PATCH v4 04/10] scsi: ufs-mediatek: Fix the timing of configuring device regulators Stanley Chu
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Stanley Chu @ 2022-06-15  3:51 UTC (permalink / raw)
  To: linux-scsi, linux-kernel, martin.petersen, avri.altman,
	alim.akhtar, jejb, bvanassche
  Cc: peter.wang, chun-hung.wu, alice.chao, powen.kao, mason.zhang,
	qilin.tan, lin.gui, eddie.huang, tun-yu.yu, cc.chou,
	chaotian.jing, jiajie.hao, stanley.chu, Peter Wang

From: CC Chou <cc.chou@mediatek.com>

Some MediaTek SoC chips need special flow for power mode change,
especially for chips supporting HS-G5.

Enable the workaround by setting the host-specific capability.

Reviewed-by: Stanley Chu <stanley.chu@mediatek.com>
Signed-off-by: CC Chou <cc.chou@mediatek.com>
Signed-off-by: Eddie Huang <eddie.huang@mediatek.com>
Signed-off-by: Dennis Yu <tun-yu.yu@mediatek.com>
Signed-off-by: Peter Wang <peter.want@medaitek.com>
Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
---
 drivers/ufs/host/ufs-mediatek.c | 60 +++++++++++++++++++++++++++++++--
 drivers/ufs/host/ufs-mediatek.h |  1 +
 include/ufs/unipro.h            |  1 +
 3 files changed, 60 insertions(+), 2 deletions(-)

diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index beabc3ccd30b..2931fd21e38a 100755
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -82,6 +82,13 @@ static bool ufs_mtk_is_broken_vcc(struct ufs_hba *hba)
 	return !!(host->caps & UFS_MTK_CAP_BROKEN_VCC);
 }
 
+static bool ufs_mtk_is_pmc_via_fastauto(struct ufs_hba *hba)
+{
+	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
+
+	return (host->caps & UFS_MTK_CAP_PMC_VIA_FASTAUTO);
+}
+
 static void ufs_mtk_cfg_unipro_cg(struct ufs_hba *hba, bool enable)
 {
 	u32 tmp;
@@ -579,6 +586,9 @@ static void ufs_mtk_init_host_caps(struct ufs_hba *hba)
 	if (of_property_read_bool(np, "mediatek,ufs-broken-vcc"))
 		host->caps |= UFS_MTK_CAP_BROKEN_VCC;
 
+	if (of_property_read_bool(np, "mediatek,ufs-pmc-via-fastauto"))
+		host->caps |= UFS_MTK_CAP_PMC_VIA_FASTAUTO;
+
 	dev_info(hba->dev, "caps: 0x%x", host->caps);
 }
 
@@ -754,6 +764,26 @@ static int ufs_mtk_init(struct ufs_hba *hba)
 	return err;
 }
 
+static bool ufs_mtk_pmc_via_fastauto(struct ufs_hba *hba,
+				     struct ufs_pa_layer_attr *dev_req_params)
+{
+	if (!ufs_mtk_is_pmc_via_fastauto(hba))
+		return false;
+
+	if (dev_req_params->hs_rate == hba->pwr_info.hs_rate)
+		return false;
+
+	if (dev_req_params->pwr_tx != FAST_MODE &&
+	    dev_req_params->gear_tx < UFS_HS_G4)
+		return false;
+
+	if (dev_req_params->pwr_rx != FAST_MODE &&
+	    dev_req_params->gear_rx < UFS_HS_G4)
+		return false;
+
+	return true;
+}
+
 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)
@@ -763,8 +793,8 @@ static int ufs_mtk_pre_pwr_change(struct ufs_hba *hba,
 	int ret;
 
 	ufshcd_init_pwr_dev_param(&host_cap);
-	host_cap.hs_rx_gear = UFS_HS_G4;
-	host_cap.hs_tx_gear = UFS_HS_G4;
+	host_cap.hs_rx_gear = UFS_HS_G5;
+	host_cap.hs_tx_gear = UFS_HS_G5;
 
 	ret = ufshcd_get_pwr_dev_param(&host_cap,
 				       dev_max_params,
@@ -774,6 +804,32 @@ static int ufs_mtk_pre_pwr_change(struct ufs_hba *hba,
 			__func__);
 	}
 
+	if (ufs_mtk_pmc_via_fastauto(hba, dev_req_params)) {
+		ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TXTERMINATION), true);
+		ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TXGEAR), UFS_HS_G1);
+
+		ufshcd_dme_set(hba, UIC_ARG_MIB(PA_RXTERMINATION), true);
+		ufshcd_dme_set(hba, UIC_ARG_MIB(PA_RXGEAR), UFS_HS_G1);
+
+		ufshcd_dme_set(hba, UIC_ARG_MIB(PA_ACTIVETXDATALANES),
+			       dev_req_params->lane_tx);
+		ufshcd_dme_set(hba, UIC_ARG_MIB(PA_ACTIVERXDATALANES),
+			       dev_req_params->lane_rx);
+		ufshcd_dme_set(hba, UIC_ARG_MIB(PA_HSSERIES),
+			       dev_req_params->hs_rate);
+
+		ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TXHSADAPTTYPE),
+			       PA_NO_ADAPT);
+
+		ret = ufshcd_uic_change_pwr_mode(hba,
+					FASTAUTO_MODE << 4 | FASTAUTO_MODE);
+
+		if (ret) {
+			dev_err(hba->dev, "%s: HSG1B FASTAUTO failed ret=%d\n",
+				__func__, ret);
+		}
+	}
+
 	if (host->hw_ver.major >= 3) {
 		ret = ufshcd_dme_configure_adapt(hba,
 					   dev_req_params->gear_tx,
diff --git a/drivers/ufs/host/ufs-mediatek.h b/drivers/ufs/host/ufs-mediatek.h
index 414dca86c09f..7e1913769671 100755
--- a/drivers/ufs/host/ufs-mediatek.h
+++ b/drivers/ufs/host/ufs-mediatek.h
@@ -108,6 +108,7 @@ enum ufs_mtk_host_caps {
 	UFS_MTK_CAP_VA09_PWR_CTRL              = 1 << 1,
 	UFS_MTK_CAP_DISABLE_AH8                = 1 << 2,
 	UFS_MTK_CAP_BROKEN_VCC                 = 1 << 3,
+	UFS_MTK_CAP_PMC_VIA_FASTAUTO           = 1 << 6,
 };
 
 struct ufs_mtk_crypt_cfg {
diff --git a/include/ufs/unipro.h b/include/ufs/unipro.h
index 0521f887e3ac..4b13fbf8ee18 100755
--- a/include/ufs/unipro.h
+++ b/include/ufs/unipro.h
@@ -229,6 +229,7 @@ enum ufs_hs_gear_tag {
 	UFS_HS_G2,		/* HS Gear 2 */
 	UFS_HS_G3,		/* HS Gear 3 */
 	UFS_HS_G4,		/* HS Gear 4 */
+	UFS_HS_G5		/* HS Gear 5 */
 };
 
 enum ufs_unipro_ver {
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 04/10] scsi: ufs-mediatek: Fix the timing of configuring device regulators
  2022-06-15  3:51 [PATCH v4 00/10] csi: ufs: Fix PMC and low-power mode on MediaTek UFS platforms Stanley Chu
                   ` (2 preceding siblings ...)
  2022-06-15  3:51 ` [PATCH v4 03/10] scsi: ufs-mediatek: Introduce workaround for power mode change Stanley Chu
@ 2022-06-15  3:51 ` Stanley Chu
  2022-06-15  3:51 ` [PATCH v4 05/10] scsi: ufs-mediatek: Prevent device regulators setting as LPM incorrectly Stanley Chu
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Stanley Chu @ 2022-06-15  3:51 UTC (permalink / raw)
  To: linux-scsi, linux-kernel, martin.petersen, avri.altman,
	alim.akhtar, jejb, bvanassche
  Cc: peter.wang, chun-hung.wu, alice.chao, powen.kao, mason.zhang,
	qilin.tan, lin.gui, eddie.huang, tun-yu.yu, cc.chou,
	chaotian.jing, jiajie.hao, stanley.chu

From: Po-Wen Kao <powen.kao@mediatek.com>

Currently the LPM configurations of device regulators
may not work since VCC is not disabled yet while
ufs_mtk_vreg_set_lpm() is executed.

Fix it by changing the timing of invoking
ufs_mtk_vreg_set_lpm().

Reviewed-by: Stanley Chu <stanley.chu@mediatek.com>
Signed-off-by: Po-Wen Kao <powen.kao@mediatek.com>
Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
---
 drivers/ufs/host/ufs-mediatek.c | 58 ++++++++++++++++++++++++++++++---
 1 file changed, 53 insertions(+), 5 deletions(-)

diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index 2931fd21e38a..817d957512a3 100755
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -1082,7 +1082,6 @@ static int ufs_mtk_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op,
 		 * 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;
@@ -1106,12 +1105,13 @@ static int ufs_mtk_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
 {
 	int err;
 
+	if (hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL)
+		ufs_mtk_vreg_set_lpm(hba, false);
+
 	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)) {
 		err = ufs_mtk_link_set_hpm(hba);
 		if (err)
@@ -1276,9 +1276,57 @@ static int ufs_mtk_remove(struct platform_device *pdev)
 	return 0;
 }
 
+int ufs_mtk_system_suspend(struct device *dev)
+{
+	struct ufs_hba *hba = dev_get_drvdata(dev);
+	int ret;
+
+	ret = ufshcd_system_suspend(dev);
+	if (ret)
+		return ret;
+
+	ufs_mtk_vreg_set_lpm(hba, true);
+
+	return 0;
+}
+
+int ufs_mtk_system_resume(struct device *dev)
+{
+	struct ufs_hba *hba = dev_get_drvdata(dev);
+
+	ufs_mtk_vreg_set_lpm(hba, false);
+
+	return ufshcd_system_resume(dev);
+}
+
+int ufs_mtk_runtime_suspend(struct device *dev)
+{
+	struct ufs_hba *hba = dev_get_drvdata(dev);
+	int ret = 0;
+
+	ret = ufshcd_runtime_suspend(dev);
+	if (ret)
+		return ret;
+
+	ufs_mtk_vreg_set_lpm(hba, true);
+
+	return 0;
+}
+
+int ufs_mtk_runtime_resume(struct device *dev)
+{
+	struct ufs_hba *hba = dev_get_drvdata(dev);
+
+	ufs_mtk_vreg_set_lpm(hba, false);
+
+	return ufshcd_runtime_resume(dev);
+}
+
 static const struct dev_pm_ops ufs_mtk_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(ufshcd_system_suspend, ufshcd_system_resume)
-	SET_RUNTIME_PM_OPS(ufshcd_runtime_suspend, ufshcd_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(ufs_mtk_system_suspend,
+				ufs_mtk_system_resume)
+	SET_RUNTIME_PM_OPS(ufs_mtk_runtime_suspend,
+			   ufs_mtk_runtime_resume, NULL)
 	.prepare	 = ufshcd_suspend_prepare,
 	.complete	 = ufshcd_resume_complete,
 };
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 05/10] scsi: ufs-mediatek: Prevent device regulators setting as LPM incorrectly
  2022-06-15  3:51 [PATCH v4 00/10] csi: ufs: Fix PMC and low-power mode on MediaTek UFS platforms Stanley Chu
                   ` (3 preceding siblings ...)
  2022-06-15  3:51 ` [PATCH v4 04/10] scsi: ufs-mediatek: Fix the timing of configuring device regulators Stanley Chu
@ 2022-06-15  3:51 ` Stanley Chu
  2022-06-15  3:51 ` [PATCH v4 06/10] scsi: ufs-mediatek: Support low-power mode for VCCQ Stanley Chu
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Stanley Chu @ 2022-06-15  3:51 UTC (permalink / raw)
  To: linux-scsi, linux-kernel, martin.petersen, avri.altman,
	alim.akhtar, jejb, bvanassche
  Cc: peter.wang, chun-hung.wu, alice.chao, powen.kao, mason.zhang,
	qilin.tan, lin.gui, eddie.huang, tun-yu.yu, cc.chou,
	chaotian.jing, jiajie.hao, stanley.chu

From: Po-Wen Kao <powen.kao@mediatek.com>

Device regulatrs are allowed to enter low-power mode
if neither device is not in active mode, nor VCC does not
keep on.

Simply fix this by adding conditions before LPM decision.

Reviewed-by: Stanley Chu <stanley.chu@mediatek.com>
Signed-off-by: Po-Wen Kao <powen.kao@mediatek.com>
Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
---
 drivers/ufs/host/ufs-mediatek.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index 817d957512a3..03762ecaaaf8 100755
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -1034,10 +1034,18 @@ static void ufs_mtk_vreg_set_lpm(struct ufs_hba *hba, bool lpm)
 	if (!hba->vreg_info.vccq2 || !hba->vreg_info.vcc)
 		return;
 
-	if (lpm && !hba->vreg_info.vcc->enabled)
+	/* Bypass LPM when device is still active */
+	if (lpm && ufshcd_is_ufs_dev_active(hba))
+		return;
+
+	/* Bypass LPM if VCC is enabled */
+	if (lpm && hba->vreg_info.vcc->enabled)
+		return;
+
+	if (lpm)
 		regulator_set_mode(hba->vreg_info.vccq2->reg,
 				   REGULATOR_MODE_IDLE);
-	else if (!lpm)
+	else
 		regulator_set_mode(hba->vreg_info.vccq2->reg,
 				   REGULATOR_MODE_NORMAL);
 }
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 06/10] scsi: ufs-mediatek: Support low-power mode for VCCQ
  2022-06-15  3:51 [PATCH v4 00/10] csi: ufs: Fix PMC and low-power mode on MediaTek UFS platforms Stanley Chu
                   ` (4 preceding siblings ...)
  2022-06-15  3:51 ` [PATCH v4 05/10] scsi: ufs-mediatek: Prevent device regulators setting as LPM incorrectly Stanley Chu
@ 2022-06-15  3:51 ` Stanley Chu
  2022-06-15  3:51 ` [PATCH v4 07/10] scsi: ufs-mediatek: Support flexible parameters for smc calls Stanley Chu
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Stanley Chu @ 2022-06-15  3:51 UTC (permalink / raw)
  To: linux-scsi, linux-kernel, martin.petersen, avri.altman,
	alim.akhtar, jejb, bvanassche
  Cc: peter.wang, chun-hung.wu, alice.chao, powen.kao, mason.zhang,
	qilin.tan, lin.gui, eddie.huang, tun-yu.yu, cc.chou,
	chaotian.jing, jiajie.hao, stanley.chu

From: Peter Wang <peter.wang@mediatek.com>

Also allow VCCQ to enter low-power mode, and meanwhile
remove the restriction of VCC because VCCQ/VCCQ2 can
be changed to low-power mode even if VCC keeps on while
the device is not in active power mode.

Reviewed-by: Stanley Chu <stanley.chu@mediatek.com>
Signed-off-by: Peter Wang <peter.wang@mediatek.com>
Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
---
 drivers/ufs/host/ufs-mediatek.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index 03762ecaaaf8..65a2a4185ef6 100755
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -1031,7 +1031,13 @@ static int ufs_mtk_link_set_lpm(struct ufs_hba *hba)
 
 static void ufs_mtk_vreg_set_lpm(struct ufs_hba *hba, bool lpm)
 {
-	if (!hba->vreg_info.vccq2 || !hba->vreg_info.vcc)
+	struct ufs_vreg *vccqx = NULL;
+
+	if (!hba->vreg_info.vccq && !hba->vreg_info.vccq2)
+		return;
+
+	/* Skip if VCC is assumed always-on */
+	if (!hba->vreg_info.vcc)
 		return;
 
 	/* Bypass LPM when device is still active */
@@ -1042,12 +1048,13 @@ static void ufs_mtk_vreg_set_lpm(struct ufs_hba *hba, bool lpm)
 	if (lpm && hba->vreg_info.vcc->enabled)
 		return;
 
-	if (lpm)
-		regulator_set_mode(hba->vreg_info.vccq2->reg,
-				   REGULATOR_MODE_IDLE);
+	if (hba->vreg_info.vccq)
+		vccqx = hba->vreg_info.vccq;
 	else
-		regulator_set_mode(hba->vreg_info.vccq2->reg,
-				   REGULATOR_MODE_NORMAL);
+		vccqx = hba->vreg_info.vccq2;
+
+	regulator_set_mode(vccqx->reg,
+			   lpm ? REGULATOR_MODE_IDLE : REGULATOR_MODE_NORMAL);
 }
 
 static void ufs_mtk_auto_hibern8_disable(struct ufs_hba *hba)
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 07/10] scsi: ufs-mediatek: Support flexible parameters for smc calls
  2022-06-15  3:51 [PATCH v4 00/10] csi: ufs: Fix PMC and low-power mode on MediaTek UFS platforms Stanley Chu
                   ` (5 preceding siblings ...)
  2022-06-15  3:51 ` [PATCH v4 06/10] scsi: ufs-mediatek: Support low-power mode for VCCQ Stanley Chu
@ 2022-06-15  3:51 ` Stanley Chu
  2022-06-15  3:51 ` [PATCH v4 08/10] scsi: ufs-mediatek: Support low-power mode for parents of VCCQx Stanley Chu
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Stanley Chu @ 2022-06-15  3:51 UTC (permalink / raw)
  To: linux-scsi, linux-kernel, martin.petersen, avri.altman,
	alim.akhtar, jejb, bvanassche
  Cc: peter.wang, chun-hung.wu, alice.chao, powen.kao, mason.zhang,
	qilin.tan, lin.gui, eddie.huang, tun-yu.yu, cc.chou,
	chaotian.jing, jiajie.hao, stanley.chu

Provide flexible number of parameters for UFS SMC calls to be
easily used for future SMC usages.

This is a preparation patch for the next patch.

Signed-off-by: Alice Chao <alice.chao@mediatek.com>
Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
---
 drivers/ufs/host/ufs-mediatek.c | 16 --------------
 drivers/ufs/host/ufs-mediatek.h | 39 +++++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+), 16 deletions(-)

diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index 65a2a4185ef6..9c5d1213c290 100755
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -30,22 +30,6 @@
 #define CREATE_TRACE_POINTS
 #include "ufs-mediatek-trace.h"
 
-#define ufs_mtk_smc(cmd, val, res) \
-	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)
-
-#define ufs_mtk_ref_clk_notify(on, res) \
-	ufs_mtk_smc(UFS_MTK_SIP_REF_CLK_NOTIFICATION, on, res)
-
-#define ufs_mtk_device_reset_ctrl(high, res) \
-	ufs_mtk_smc(UFS_MTK_SIP_DEVICE_RESET, high, res)
-
 static const struct ufs_dev_quirk ufs_mtk_dev_fixups[] = {
 	{ .wmanufacturerid = UFS_VENDOR_MICRON,
 	  .model = UFS_ANY_MODEL,
diff --git a/drivers/ufs/host/ufs-mediatek.h b/drivers/ufs/host/ufs-mediatek.h
index 7e1913769671..bf6ca96cafb6 100755
--- a/drivers/ufs/host/ufs-mediatek.h
+++ b/drivers/ufs/host/ufs-mediatek.h
@@ -143,4 +143,43 @@ struct ufs_mtk_host {
 	u32 ip_ver;
 };
 
+/*
+ * SMC call wrapper function
+ */
+struct ufs_mtk_smc_arg {
+	unsigned long cmd;
+	struct arm_smccc_res *res;
+	unsigned long v1;
+	unsigned long v2;
+	unsigned long v3;
+	unsigned long v4;
+	unsigned long v5;
+	unsigned long v6;
+	unsigned long v7;
+};
+
+static void _ufs_mtk_smc(struct ufs_mtk_smc_arg s)
+{
+	arm_smccc_smc(MTK_SIP_UFS_CONTROL,
+		      s.cmd, s.v1, s.v2, s.v3, s.v4, s.v5, s.v6, s.res);
+}
+
+#define ufs_mtk_smc(...) \
+	_ufs_mtk_smc((struct ufs_mtk_smc_arg) {__VA_ARGS__})
+
+/*
+ * SMC call interface
+ */
+#define ufs_mtk_va09_pwr_ctrl(res, on) \
+	ufs_mtk_smc(UFS_MTK_SIP_VA09_PWR_CTRL, &(res), on)
+
+#define ufs_mtk_crypto_ctrl(res, enable) \
+	ufs_mtk_smc(UFS_MTK_SIP_CRYPTO_CTRL, &(res), enable)
+
+#define ufs_mtk_ref_clk_notify(on, res) \
+	ufs_mtk_smc(UFS_MTK_SIP_REF_CLK_NOTIFICATION, &(res), on)
+
+#define ufs_mtk_device_reset_ctrl(high, res) \
+	ufs_mtk_smc(UFS_MTK_SIP_DEVICE_RESET, &(res), high)
+
 #endif /* !_UFS_MEDIATEK_H */
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 08/10] scsi: ufs-mediatek: Support low-power mode for parents of VCCQx
  2022-06-15  3:51 [PATCH v4 00/10] csi: ufs: Fix PMC and low-power mode on MediaTek UFS platforms Stanley Chu
                   ` (6 preceding siblings ...)
  2022-06-15  3:51 ` [PATCH v4 07/10] scsi: ufs-mediatek: Support flexible parameters for smc calls Stanley Chu
@ 2022-06-15  3:51 ` Stanley Chu
  2022-06-15  3:51 ` [PATCH v4 09/10] scsi: ufs: Export regulator functions Stanley Chu
  2022-06-15  3:51 ` [PATCH v4 10/10] scsi: ufs-mediatek: Support multiple VCC sources Stanley Chu
  9 siblings, 0 replies; 13+ messages in thread
From: Stanley Chu @ 2022-06-15  3:51 UTC (permalink / raw)
  To: linux-scsi, linux-kernel, martin.petersen, avri.altman,
	alim.akhtar, jejb, bvanassche
  Cc: peter.wang, chun-hung.wu, alice.chao, powen.kao, mason.zhang,
	qilin.tan, lin.gui, eddie.huang, tun-yu.yu, cc.chou,
	chaotian.jing, jiajie.hao, stanley.chu

Provide the facility to configure parents of VCCQx power rails
as low-power or full-power mode in MediaTek UFS platforms.

Signed-off-by: Alice Chao <alice.chao@mediatek.com>
Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
---
 drivers/ufs/host/ufs-mediatek.c | 46 +++++++++++++++++++++++----------
 drivers/ufs/host/ufs-mediatek.h |  4 +++
 2 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index 9c5d1213c290..e756aba45acd 100755
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -1013,10 +1013,30 @@ static int ufs_mtk_link_set_lpm(struct ufs_hba *hba)
 	return 0;
 }
 
-static void ufs_mtk_vreg_set_lpm(struct ufs_hba *hba, bool lpm)
+static void ufs_mtk_vccqx_set_lpm(struct ufs_hba *hba, bool lpm)
 {
 	struct ufs_vreg *vccqx = NULL;
 
+	if (hba->vreg_info.vccq)
+		vccqx = hba->vreg_info.vccq;
+	else
+		vccqx = hba->vreg_info.vccq2;
+
+	regulator_set_mode(vccqx->reg,
+			   lpm ? REGULATOR_MODE_IDLE : REGULATOR_MODE_NORMAL);
+}
+
+static void ufs_mtk_vsx_set_lpm(struct ufs_hba *hba, bool lpm)
+{
+	struct arm_smccc_res res;
+
+	ufs_mtk_device_pwr_ctrl(!lpm,
+				(unsigned long)hba->dev_info.wspecversion,
+				res);
+}
+
+static void ufs_mtk_dev_vreg_set_lpm(struct ufs_hba *hba, bool lpm)
+{
 	if (!hba->vreg_info.vccq && !hba->vreg_info.vccq2)
 		return;
 
@@ -1032,13 +1052,13 @@ static void ufs_mtk_vreg_set_lpm(struct ufs_hba *hba, bool lpm)
 	if (lpm && hba->vreg_info.vcc->enabled)
 		return;
 
-	if (hba->vreg_info.vccq)
-		vccqx = hba->vreg_info.vccq;
-	else
-		vccqx = hba->vreg_info.vccq2;
-
-	regulator_set_mode(vccqx->reg,
-			   lpm ? REGULATOR_MODE_IDLE : REGULATOR_MODE_NORMAL);
+	if (lpm) {
+		ufs_mtk_vccqx_set_lpm(hba, lpm);
+		ufs_mtk_vsx_set_lpm(hba, lpm);
+	} else {
+		ufs_mtk_vsx_set_lpm(hba, lpm);
+		ufs_mtk_vccqx_set_lpm(hba, lpm);
+	}
 }
 
 static void ufs_mtk_auto_hibern8_disable(struct ufs_hba *hba)
@@ -1105,7 +1125,7 @@ static int ufs_mtk_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
 	int err;
 
 	if (hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL)
-		ufs_mtk_vreg_set_lpm(hba, false);
+		ufs_mtk_dev_vreg_set_lpm(hba, false);
 
 	err = ufs_mtk_mphy_power_on(hba, true);
 	if (err)
@@ -1284,7 +1304,7 @@ int ufs_mtk_system_suspend(struct device *dev)
 	if (ret)
 		return ret;
 
-	ufs_mtk_vreg_set_lpm(hba, true);
+	ufs_mtk_dev_vreg_set_lpm(hba, true);
 
 	return 0;
 }
@@ -1293,7 +1313,7 @@ int ufs_mtk_system_resume(struct device *dev)
 {
 	struct ufs_hba *hba = dev_get_drvdata(dev);
 
-	ufs_mtk_vreg_set_lpm(hba, false);
+	ufs_mtk_dev_vreg_set_lpm(hba, false);
 
 	return ufshcd_system_resume(dev);
 }
@@ -1307,7 +1327,7 @@ int ufs_mtk_runtime_suspend(struct device *dev)
 	if (ret)
 		return ret;
 
-	ufs_mtk_vreg_set_lpm(hba, true);
+	ufs_mtk_dev_vreg_set_lpm(hba, true);
 
 	return 0;
 }
@@ -1316,7 +1336,7 @@ int ufs_mtk_runtime_resume(struct device *dev)
 {
 	struct ufs_hba *hba = dev_get_drvdata(dev);
 
-	ufs_mtk_vreg_set_lpm(hba, false);
+	ufs_mtk_dev_vreg_set_lpm(hba, false);
 
 	return ufshcd_runtime_resume(dev);
 }
diff --git a/drivers/ufs/host/ufs-mediatek.h b/drivers/ufs/host/ufs-mediatek.h
index bf6ca96cafb6..5c6101ac518f 100755
--- a/drivers/ufs/host/ufs-mediatek.h
+++ b/drivers/ufs/host/ufs-mediatek.h
@@ -83,6 +83,7 @@ enum {
 #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)
+#define UFS_MTK_SIP_DEVICE_PWR_CTRL       BIT(7)
 
 /*
  * VS_DEBUGCLOCKENABLE
@@ -182,4 +183,7 @@ static void _ufs_mtk_smc(struct ufs_mtk_smc_arg s)
 #define ufs_mtk_device_reset_ctrl(high, res) \
 	ufs_mtk_smc(UFS_MTK_SIP_DEVICE_RESET, &(res), high)
 
+#define ufs_mtk_device_pwr_ctrl(on, ufs_ver, res) \
+	ufs_mtk_smc(UFS_MTK_SIP_DEVICE_PWR_CTRL, &(res), on, ufs_ver)
+
 #endif /* !_UFS_MEDIATEK_H */
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 09/10] scsi: ufs: Export regulator functions
  2022-06-15  3:51 [PATCH v4 00/10] csi: ufs: Fix PMC and low-power mode on MediaTek UFS platforms Stanley Chu
                   ` (7 preceding siblings ...)
  2022-06-15  3:51 ` [PATCH v4 08/10] scsi: ufs-mediatek: Support low-power mode for parents of VCCQx Stanley Chu
@ 2022-06-15  3:51 ` Stanley Chu
  2022-06-15  3:51 ` [PATCH v4 10/10] scsi: ufs-mediatek: Support multiple VCC sources Stanley Chu
  9 siblings, 0 replies; 13+ messages in thread
From: Stanley Chu @ 2022-06-15  3:51 UTC (permalink / raw)
  To: linux-scsi, linux-kernel, martin.petersen, avri.altman,
	alim.akhtar, jejb, bvanassche
  Cc: peter.wang, chun-hung.wu, alice.chao, powen.kao, mason.zhang,
	qilin.tan, lin.gui, eddie.huang, tun-yu.yu, cc.chou,
	chaotian.jing, jiajie.hao, stanley.chu

Export below regulator functions to allow vendors to
customize regulator configuration in their own platforms.

int ufshcd_populate_vreg(struct device *dev, const char *name,
                         struct ufs_vreg **out_vreg);
int ufshcd_get_vreg(struct device *dev, struct ufs_vreg *vreg);

Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
---
 drivers/ufs/core/ufshcd.c        | 3 ++-
 drivers/ufs/host/ufshcd-pltfrm.c | 5 +++--
 drivers/ufs/host/ufshcd-pltfrm.h | 2 ++
 include/ufs/ufshcd.h             | 2 ++
 4 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 0d16739c67bb..8131a75e41e5 100755
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -8408,7 +8408,7 @@ static int ufshcd_setup_hba_vreg(struct ufs_hba *hba, bool on)
 	return ufshcd_toggle_vreg(hba->dev, info->vdd_hba, on);
 }
 
-static int ufshcd_get_vreg(struct device *dev, struct ufs_vreg *vreg)
+int ufshcd_get_vreg(struct device *dev, struct ufs_vreg *vreg)
 {
 	int ret = 0;
 
@@ -8424,6 +8424,7 @@ static int ufshcd_get_vreg(struct device *dev, struct ufs_vreg *vreg)
 out:
 	return ret;
 }
+EXPORT_SYMBOL_GPL(ufshcd_get_vreg);
 
 static int ufshcd_init_vreg(struct ufs_hba *hba)
 {
diff --git a/drivers/ufs/host/ufshcd-pltfrm.c b/drivers/ufs/host/ufshcd-pltfrm.c
index e7332cc65b1f..2dd9c660531b 100755
--- a/drivers/ufs/host/ufshcd-pltfrm.c
+++ b/drivers/ufs/host/ufshcd-pltfrm.c
@@ -109,8 +109,8 @@ static int ufshcd_parse_clock_info(struct ufs_hba *hba)
 }
 
 #define MAX_PROP_SIZE 32
-static int ufshcd_populate_vreg(struct device *dev, const char *name,
-		struct ufs_vreg **out_vreg)
+int ufshcd_populate_vreg(struct device *dev, const char *name,
+			 struct ufs_vreg **out_vreg)
 {
 	char prop_name[MAX_PROP_SIZE];
 	struct ufs_vreg *vreg = NULL;
@@ -145,6 +145,7 @@ static int ufshcd_populate_vreg(struct device *dev, const char *name,
 	*out_vreg = vreg;
 	return 0;
 }
+EXPORT_SYMBOL_GPL(ufshcd_populate_vreg);
 
 /**
  * ufshcd_parse_regulator_info - get regulator info from device tree
diff --git a/drivers/ufs/host/ufshcd-pltfrm.h b/drivers/ufs/host/ufshcd-pltfrm.h
index 43c2e412bd99..5130c9471dc2 100755
--- a/drivers/ufs/host/ufshcd-pltfrm.h
+++ b/drivers/ufs/host/ufshcd-pltfrm.h
@@ -32,5 +32,7 @@ void ufshcd_init_pwr_dev_param(struct ufs_dev_params *dev_param);
 int ufshcd_pltfrm_init(struct platform_device *pdev,
 		       const struct ufs_hba_variant_ops *vops);
 void ufshcd_pltfrm_shutdown(struct platform_device *pdev);
+int ufshcd_populate_vreg(struct device *dev, const char *name,
+			 struct ufs_vreg **out_vreg);
 
 #endif /* UFSHCD_PLTFRM_H_ */
diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h
index aa778418703f..18eb253cfd91 100755
--- a/include/ufs/ufshcd.h
+++ b/include/ufs/ufshcd.h
@@ -1187,6 +1187,8 @@ void ufshcd_map_desc_id_to_length(struct ufs_hba *hba, enum desc_idn desc_id,
 
 u32 ufshcd_get_local_unipro_ver(struct ufs_hba *hba);
 
+int ufshcd_get_vreg(struct device *dev, struct ufs_vreg *vreg);
+
 int ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd);
 
 int ufshcd_exec_raw_upiu_cmd(struct ufs_hba *hba,
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 10/10] scsi: ufs-mediatek: Support multiple VCC sources
  2022-06-15  3:51 [PATCH v4 00/10] csi: ufs: Fix PMC and low-power mode on MediaTek UFS platforms Stanley Chu
                   ` (8 preceding siblings ...)
  2022-06-15  3:51 ` [PATCH v4 09/10] scsi: ufs: Export regulator functions Stanley Chu
@ 2022-06-15  3:51 ` Stanley Chu
  9 siblings, 0 replies; 13+ messages in thread
From: Stanley Chu @ 2022-06-15  3:51 UTC (permalink / raw)
  To: linux-scsi, linux-kernel, martin.petersen, avri.altman,
	alim.akhtar, jejb, bvanassche
  Cc: peter.wang, chun-hung.wu, alice.chao, powen.kao, mason.zhang,
	qilin.tan, lin.gui, eddie.huang, tun-yu.yu, cc.chou,
	chaotian.jing, jiajie.hao, stanley.chu

Support multiple VCC source in MediaTek UFS platforms.

Two options are provided and distinguished by specific
device tree attributes as below examples,

[Option 1: By numbering]
mediatek,ufs-vcc-by-num;
vcc-opt1-supply = <&mt6373_vbuck4_ufs>;
vcc-opt2-supply = <&mt6363_vemc>;

[Option 2: By UFS version]
mediatek,ufs-vcc-by-ver;
vcc-ufs3-supply = <&mt6373_vbuck4_ufs>;

Signed-off-by: Alice Chao <alice.chao@mediatek.com>
Signed-off-by: Peter Wang <peter.wang@mediatek.com>
Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
---
 drivers/ufs/host/ufs-mediatek.c | 46 +++++++++++++++++++++++++++++++++
 drivers/ufs/host/ufs-mediatek.h | 14 ++++++++++
 2 files changed, 60 insertions(+)

diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index e756aba45acd..df6f77aacdc3 100755
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -669,6 +669,50 @@ static u32 ufs_mtk_get_ufs_hci_version(struct ufs_hba *hba)
 	return hba->ufs_version;
 }
 
+#define MAX_VCC_NAME 30
+static int ufs_mtk_vreg_fix_vcc(struct ufs_hba *hba)
+{
+	struct ufs_vreg_info *info = &hba->vreg_info;
+	struct device_node *np = hba->dev->of_node;
+	struct device *dev = hba->dev;
+	char vcc_name[MAX_VCC_NAME];
+	struct arm_smccc_res res;
+	int err = 0;
+	int ver;
+
+	if (hba->vreg_info.vcc)
+		return 0;
+
+	if (of_property_read_bool(np, "mediatek,ufs-vcc-by-num")) {
+		ufs_mtk_get_vcc_num(res);
+		if (res.a1 > UFS_VCC_NONE && res.a1 < UFS_VCC_MAX)
+			snprintf(vcc_name, MAX_VCC_NAME, "vcc-opt%u", res.a1);
+		else
+			return -ENODEV;
+	} else if (of_property_read_bool(np, "mediatek,ufs-vcc-by-ver")) {
+		ver = (hba->dev_info.wspecversion & 0xF00) >> 8;
+		snprintf(vcc_name, MAX_VCC_NAME, "vcc-ufs%u", ver);
+	} else {
+		return 0;
+	}
+
+	err = ufshcd_populate_vreg(dev, vcc_name, &info->vcc);
+	if (err)
+		return err;
+
+	err = ufshcd_get_vreg(dev, info->vcc);
+	if (err)
+		return err;
+
+	err = regulator_enable(info->vcc->reg);
+	if (!err) {
+		info->vcc->enabled = true;
+		dev_info(dev, "%s: %s enabled\n", __func__, vcc_name);
+	}
+
+	return err;
+}
+
 /**
  * ufs_mtk_init - find other essential mmio bases
  * @hba: host controller instance
@@ -1180,6 +1224,8 @@ static int ufs_mtk_apply_dev_quirks(struct ufs_hba *hba)
 		ufs_mtk_setup_ref_clk_wait_us(hba,
 					      REFCLK_DEFAULT_WAIT_US);
 
+	ufs_mtk_vreg_fix_vcc(hba);
+
 	return 0;
 }
 
diff --git a/drivers/ufs/host/ufs-mediatek.h b/drivers/ufs/host/ufs-mediatek.h
index 5c6101ac518f..49a2137fb251 100755
--- a/drivers/ufs/host/ufs-mediatek.h
+++ b/drivers/ufs/host/ufs-mediatek.h
@@ -83,6 +83,7 @@ enum {
 #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)
+#define UFS_MTK_SIP_GET_VCC_NUM           BIT(6)
 #define UFS_MTK_SIP_DEVICE_PWR_CTRL       BIT(7)
 
 /*
@@ -144,6 +145,16 @@ struct ufs_mtk_host {
 	u32 ip_ver;
 };
 
+/*
+ * Multi-VCC by Numbering
+ */
+enum ufs_mtk_vcc_num {
+	UFS_VCC_NONE = 0,
+	UFS_VCC_1,
+	UFS_VCC_2,
+	UFS_VCC_MAX
+};
+
 /*
  * SMC call wrapper function
  */
@@ -183,6 +194,9 @@ static void _ufs_mtk_smc(struct ufs_mtk_smc_arg s)
 #define ufs_mtk_device_reset_ctrl(high, res) \
 	ufs_mtk_smc(UFS_MTK_SIP_DEVICE_RESET, &(res), high)
 
+#define ufs_mtk_get_vcc_num(res) \
+	ufs_mtk_smc(UFS_MTK_SIP_GET_VCC_NUM, &(res))
+
 #define ufs_mtk_device_pwr_ctrl(on, ufs_ver, res) \
 	ufs_mtk_smc(UFS_MTK_SIP_DEVICE_PWR_CTRL, &(res), on, ufs_ver)
 
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 01/10] scsi: ufs: Export ufshcd_uic_change_pwr_mode()
  2022-06-15  3:51 ` [PATCH v4 01/10] scsi: ufs: Export ufshcd_uic_change_pwr_mode() Stanley Chu
@ 2022-06-15 16:44   ` Bart Van Assche
  0 siblings, 0 replies; 13+ messages in thread
From: Bart Van Assche @ 2022-06-15 16:44 UTC (permalink / raw)
  To: Stanley Chu, linux-scsi, linux-kernel, martin.petersen,
	avri.altman, alim.akhtar, jejb
  Cc: peter.wang, chun-hung.wu, alice.chao, powen.kao, mason.zhang,
	qilin.tan, lin.gui, eddie.huang, tun-yu.yu, cc.chou,
	chaotian.jing, jiajie.hao

On 6/14/22 20:51, Stanley Chu wrote:
> Export ufshcd_uic_change_pwr_mode() to allow vendors to
> use it for SoC-specific power mode change design limitation.

Reviewed-by: Bart Van Assche <bvanassche@acm.org>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 02/10] scsi: ufs: Fix ADAPT logic for HS-G5
  2022-06-15  3:51 ` [PATCH v4 02/10] scsi: ufs: Fix ADAPT logic for HS-G5 Stanley Chu
@ 2022-06-15 16:44   ` Bart Van Assche
  0 siblings, 0 replies; 13+ messages in thread
From: Bart Van Assche @ 2022-06-15 16:44 UTC (permalink / raw)
  To: Stanley Chu, linux-scsi, linux-kernel, martin.petersen,
	avri.altman, alim.akhtar, jejb
  Cc: peter.wang, chun-hung.wu, alice.chao, powen.kao, mason.zhang,
	qilin.tan, lin.gui, eddie.huang, tun-yu.yu, cc.chou,
	chaotian.jing, jiajie.hao

On 6/14/22 20:51, Stanley Chu wrote:
> ADAPT now is added not only for HS Gear4 mode but also higher gears.
> Fix the logic for higher gears.

Reviewed-by: Bart Van Assche <bvanassche@acm.org>


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2022-06-15 16:44 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-15  3:51 [PATCH v4 00/10] csi: ufs: Fix PMC and low-power mode on MediaTek UFS platforms Stanley Chu
2022-06-15  3:51 ` [PATCH v4 01/10] scsi: ufs: Export ufshcd_uic_change_pwr_mode() Stanley Chu
2022-06-15 16:44   ` Bart Van Assche
2022-06-15  3:51 ` [PATCH v4 02/10] scsi: ufs: Fix ADAPT logic for HS-G5 Stanley Chu
2022-06-15 16:44   ` Bart Van Assche
2022-06-15  3:51 ` [PATCH v4 03/10] scsi: ufs-mediatek: Introduce workaround for power mode change Stanley Chu
2022-06-15  3:51 ` [PATCH v4 04/10] scsi: ufs-mediatek: Fix the timing of configuring device regulators Stanley Chu
2022-06-15  3:51 ` [PATCH v4 05/10] scsi: ufs-mediatek: Prevent device regulators setting as LPM incorrectly Stanley Chu
2022-06-15  3:51 ` [PATCH v4 06/10] scsi: ufs-mediatek: Support low-power mode for VCCQ Stanley Chu
2022-06-15  3:51 ` [PATCH v4 07/10] scsi: ufs-mediatek: Support flexible parameters for smc calls Stanley Chu
2022-06-15  3:51 ` [PATCH v4 08/10] scsi: ufs-mediatek: Support low-power mode for parents of VCCQx Stanley Chu
2022-06-15  3:51 ` [PATCH v4 09/10] scsi: ufs: Export regulator functions Stanley Chu
2022-06-15  3:51 ` [PATCH v4 10/10] scsi: ufs-mediatek: Support multiple VCC sources Stanley Chu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).