scsi: ufs: mediatek: Support mphy reset
authorPeter Wang <peter.wang@mediatek.com>
Fri, 15 Mar 2024 08:34:47 +0000 (16:34 +0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 26 Mar 2024 01:03:00 +0000 (21:03 -0400)
Reset mphy when resetting host. Backup mphy setting after mphy reset
control get. Restore mphy setting after mphy reset.

Acked-by: Chun-Hung Wu <Chun-Hung.Wu@mediatek.com>
Signed-off-by: Peter Wang <peter.wang@mediatek.com>
Link: https://lore.kernel.org/r/20240315083448.7185-7-peter.wang@mediatek.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/ufs/host/ufs-mediatek-sip.h
drivers/ufs/host/ufs-mediatek.c
drivers/ufs/host/ufs-mediatek.h

index c26513aedee34d268b4e91068958d083214dfdc8..caeb70a6ae83d32898bb5b10e4bc5cd9b230e416 100644 (file)
@@ -19,7 +19,7 @@
 #define UFS_MTK_SIP_SRAM_PWR_CTRL         BIT(5)
 #define UFS_MTK_SIP_GET_VCC_NUM           BIT(6)
 #define UFS_MTK_SIP_DEVICE_PWR_CTRL       BIT(7)
-
+#define UFS_MTK_SIP_MPHY_CTRL             BIT(8)
 
 /*
  * Multi-VCC by Numbering
@@ -31,6 +31,10 @@ enum ufs_mtk_vcc_num {
        UFS_VCC_MAX
 };
 
+enum ufs_mtk_mphy_op {
+       UFS_MPHY_BACKUP = 0,
+       UFS_MPHY_RESTORE
+};
 
 /*
  * SMC call wrapper function
@@ -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) \
        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 */
index 06a13a333212e8b767ee0983b7fbcb9c66c288b5..5709489157ac221d6042d9c7a9f05b2dcbc4bac2 100644 (file)
@@ -184,16 +184,23 @@ static void ufs_mtk_crypto_enable(struct ufs_hba *hba)
 static void ufs_mtk_host_reset(struct ufs_hba *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->crypto_reset);
        reset_control_assert(host->unipro_reset);
+       reset_control_assert(host->mphy_reset);
 
        usleep_range(100, 110);
 
        reset_control_deassert(host->unipro_reset);
        reset_control_deassert(host->crypto_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,
@@ -218,6 +225,8 @@ static void ufs_mtk_init_reset(struct ufs_hba *hba)
                                   "unipro_rst");
        ufs_mtk_init_reset_control(hba, &host->crypto_reset,
                                   "crypto_rst");
+       ufs_mtk_init_reset_control(hba, &host->mphy_reset,
+                                  "mphy_rst");
 }
 
 static int ufs_mtk_hce_enable_notify(struct ufs_hba *hba,
@@ -947,6 +956,7 @@ static int ufs_mtk_init(struct ufs_hba *hba)
        struct ufs_mtk_host *host;
        struct Scsi_Host *shost = hba->host;
        int err = 0;
+       struct arm_smccc_res res;
 
        host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
        if (!host) {
@@ -975,6 +985,10 @@ static int ufs_mtk_init(struct ufs_hba *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 */
        hba->caps |= UFSHCD_CAP_RPM_AUTOSUSPEND;
 
index 4764a104e8d28fa23333c81a1454258a15c4c8ee..5b6676056b920d43c178cdd58f00fdd7faeeb7b1 100644 (file)
@@ -165,6 +165,7 @@ struct ufs_mtk_host {
        struct reset_control *hci_reset;
        struct reset_control *unipro_reset;
        struct reset_control *crypto_reset;
+       struct reset_control *mphy_reset;
        struct ufs_hba *hba;
        struct ufs_mtk_crypt_cfg *crypt;
        struct ufs_mtk_clk mclk;