All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.