Commit b28820a8 authored by Peter Wang's avatar Peter Wang Committed by Martin K. Petersen

scsi: ufs: mediatek: Support mphy reset

Reset mphy when resetting host. Backup mphy setting after mphy reset
control get. Restore mphy setting after mphy reset.
Acked-by: default avatarChun-Hung Wu <Chun-Hung.Wu@mediatek.com>
Signed-off-by: default avatarPeter Wang <peter.wang@mediatek.com>
Link: https://lore.kernel.org/r/20240315083448.7185-7-peter.wang@mediatek.comSigned-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 3a887a38
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#define UFS_MTK_SIP_SRAM_PWR_CTRL BIT(5) #define UFS_MTK_SIP_SRAM_PWR_CTRL BIT(5)
#define UFS_MTK_SIP_GET_VCC_NUM BIT(6) #define UFS_MTK_SIP_GET_VCC_NUM BIT(6)
#define UFS_MTK_SIP_DEVICE_PWR_CTRL BIT(7) #define UFS_MTK_SIP_DEVICE_PWR_CTRL BIT(7)
#define UFS_MTK_SIP_MPHY_CTRL BIT(8)
/* /*
* Multi-VCC by Numbering * Multi-VCC by Numbering
...@@ -31,6 +31,10 @@ enum ufs_mtk_vcc_num { ...@@ -31,6 +31,10 @@ enum ufs_mtk_vcc_num {
UFS_VCC_MAX UFS_VCC_MAX
}; };
enum ufs_mtk_mphy_op {
UFS_MPHY_BACKUP = 0,
UFS_MPHY_RESTORE
};
/* /*
* SMC call wrapper function * SMC call wrapper function
...@@ -80,4 +84,7 @@ static inline void _ufs_mtk_smc(struct ufs_mtk_smc_arg s) ...@@ -80,4 +84,7 @@ static inline void _ufs_mtk_smc(struct ufs_mtk_smc_arg s)
#define ufs_mtk_device_pwr_ctrl(on, ufs_version, res) \ #define ufs_mtk_device_pwr_ctrl(on, ufs_version, res) \
ufs_mtk_smc(UFS_MTK_SIP_DEVICE_PWR_CTRL, &(res), on, ufs_version) ufs_mtk_smc(UFS_MTK_SIP_DEVICE_PWR_CTRL, &(res), on, ufs_version)
#define ufs_mtk_mphy_ctrl(op, res) \
ufs_mtk_smc(UFS_MTK_SIP_MPHY_CTRL, &(res), op)
#endif /* !_UFS_MEDIATEK_SIP_H */ #endif /* !_UFS_MEDIATEK_SIP_H */
...@@ -184,16 +184,23 @@ static void ufs_mtk_crypto_enable(struct ufs_hba *hba) ...@@ -184,16 +184,23 @@ static void ufs_mtk_crypto_enable(struct ufs_hba *hba)
static void ufs_mtk_host_reset(struct ufs_hba *hba) static void ufs_mtk_host_reset(struct ufs_hba *hba)
{ {
struct ufs_mtk_host *host = ufshcd_get_variant(hba); struct ufs_mtk_host *host = ufshcd_get_variant(hba);
struct arm_smccc_res res;
reset_control_assert(host->hci_reset); reset_control_assert(host->hci_reset);
reset_control_assert(host->crypto_reset); reset_control_assert(host->crypto_reset);
reset_control_assert(host->unipro_reset); reset_control_assert(host->unipro_reset);
reset_control_assert(host->mphy_reset);
usleep_range(100, 110); usleep_range(100, 110);
reset_control_deassert(host->unipro_reset); reset_control_deassert(host->unipro_reset);
reset_control_deassert(host->crypto_reset); reset_control_deassert(host->crypto_reset);
reset_control_deassert(host->hci_reset); reset_control_deassert(host->hci_reset);
reset_control_deassert(host->mphy_reset);
/* restore mphy setting aftre mphy reset */
if (host->mphy_reset)
ufs_mtk_mphy_ctrl(UFS_MPHY_RESTORE, res);
} }
static void ufs_mtk_init_reset_control(struct ufs_hba *hba, static void ufs_mtk_init_reset_control(struct ufs_hba *hba,
...@@ -218,6 +225,8 @@ static void ufs_mtk_init_reset(struct ufs_hba *hba) ...@@ -218,6 +225,8 @@ static void ufs_mtk_init_reset(struct ufs_hba *hba)
"unipro_rst"); "unipro_rst");
ufs_mtk_init_reset_control(hba, &host->crypto_reset, ufs_mtk_init_reset_control(hba, &host->crypto_reset,
"crypto_rst"); "crypto_rst");
ufs_mtk_init_reset_control(hba, &host->mphy_reset,
"mphy_rst");
} }
static int ufs_mtk_hce_enable_notify(struct ufs_hba *hba, static int ufs_mtk_hce_enable_notify(struct ufs_hba *hba,
...@@ -947,6 +956,7 @@ static int ufs_mtk_init(struct ufs_hba *hba) ...@@ -947,6 +956,7 @@ static int ufs_mtk_init(struct ufs_hba *hba)
struct ufs_mtk_host *host; struct ufs_mtk_host *host;
struct Scsi_Host *shost = hba->host; struct Scsi_Host *shost = hba->host;
int err = 0; int err = 0;
struct arm_smccc_res res;
host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
if (!host) { if (!host) {
...@@ -975,6 +985,10 @@ static int ufs_mtk_init(struct ufs_hba *hba) ...@@ -975,6 +985,10 @@ static int ufs_mtk_init(struct ufs_hba *hba)
ufs_mtk_init_reset(hba); ufs_mtk_init_reset(hba);
/* backup mphy setting if mphy can reset */
if (host->mphy_reset)
ufs_mtk_mphy_ctrl(UFS_MPHY_BACKUP, res);
/* Enable runtime autosuspend */ /* Enable runtime autosuspend */
hba->caps |= UFSHCD_CAP_RPM_AUTOSUSPEND; hba->caps |= UFSHCD_CAP_RPM_AUTOSUSPEND;
......
...@@ -165,6 +165,7 @@ struct ufs_mtk_host { ...@@ -165,6 +165,7 @@ struct ufs_mtk_host {
struct reset_control *hci_reset; struct reset_control *hci_reset;
struct reset_control *unipro_reset; struct reset_control *unipro_reset;
struct reset_control *crypto_reset; struct reset_control *crypto_reset;
struct reset_control *mphy_reset;
struct ufs_hba *hba; struct ufs_hba *hba;
struct ufs_mtk_crypt_cfg *crypt; struct ufs_mtk_crypt_cfg *crypt;
struct ufs_mtk_clk mclk; struct ufs_mtk_clk mclk;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment