scsi: ufs-mediatek: customize the delay for enabling host
authorStanley Chu <stanley.chu@mediatek.com>
Wed, 18 Mar 2020 10:40:16 +0000 (18:40 +0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 27 Mar 2020 02:07:16 +0000 (22:07 -0400)
MediaTek platform and UFS controller can dynamically customize the delay
for host enabling according to different scenarios.

For example, if UniPro enters lower-power mode, such delay can be
minimized, otherwise longer delay shall be expected.

Link: https://lore.kernel.org/r/20200318104016.28049-8-stanley.chu@mediatek.com
Reviewed-by: Avri Altman <avri.altman@wdc.com>
Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/ufs/ufs-mediatek.c
drivers/scsi/ufs/ufs-mediatek.h

index 73bd4c2..40a66b3 100644 (file)
 #define ufs_mtk_device_reset_ctrl(high, res) \
        ufs_mtk_smc(UFS_MTK_SIP_DEVICE_RESET, high, res)
 
-#define ufs_mtk_unipro_powerdown(hba, powerdown) \
-       ufshcd_dme_set(hba, \
-                      UIC_ARG_MIB_SEL(VS_UNIPROPOWERDOWNCONTROL, 0), \
-                      powerdown)
-
 static void ufs_mtk_cfg_unipro_cg(struct ufs_hba *hba, bool enable)
 {
        u32 tmp;
@@ -71,6 +66,21 @@ static void ufs_mtk_cfg_unipro_cg(struct ufs_hba *hba, bool enable)
        }
 }
 
+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);
+
+       if (status == PRE_CHANGE) {
+               if (host->unipro_lpm)
+                       hba->hba_enable_delay_us = 0;
+               else
+                       hba->hba_enable_delay_us = 600;
+       }
+
+       return 0;
+}
+
 static int ufs_mtk_bind_mphy(struct ufs_hba *hba)
 {
        struct ufs_mtk_host *host = ufshcd_get_variant(hba);
@@ -324,12 +334,26 @@ static int ufs_mtk_pwr_change_notify(struct ufs_hba *hba,
        return ret;
 }
 
+static int ufs_mtk_unipro_set_pm(struct ufs_hba *hba, u32 lpm)
+{
+       int ret;
+       struct ufs_mtk_host *host = ufshcd_get_variant(hba);
+
+       ret = ufshcd_dme_set(hba,
+                            UIC_ARG_MIB_SEL(VS_UNIPROPOWERDOWNCONTROL, 0),
+                            lpm);
+       if (!ret)
+               host->unipro_lpm = lpm;
+
+       return ret;
+}
+
 static int ufs_mtk_pre_link(struct ufs_hba *hba)
 {
        int ret;
        u32 tmp;
 
-       ufs_mtk_unipro_powerdown(hba, 0);
+       ufs_mtk_unipro_set_pm(hba, 0);
 
        /*
         * Setting PA_Local_TX_LCC_Enable to 0 before link startup
@@ -437,7 +461,7 @@ static int ufs_mtk_link_set_hpm(struct ufs_hba *hba)
        if (err)
                return err;
 
-       err = ufs_mtk_unipro_powerdown(hba, 0);
+       err = ufs_mtk_unipro_set_pm(hba, 0);
        if (err)
                return err;
 
@@ -458,10 +482,10 @@ static int ufs_mtk_link_set_lpm(struct ufs_hba *hba)
 {
        int err;
 
-       err = ufs_mtk_unipro_powerdown(hba, 1);
+       err = ufs_mtk_unipro_set_pm(hba, 1);
        if (err) {
                /* Resume UniPro state for following error recovery */
-               ufs_mtk_unipro_powerdown(hba, 0);
+               ufs_mtk_unipro_set_pm(hba, 0);
                return err;
        }
 
@@ -552,6 +576,7 @@ static struct ufs_hba_variant_ops ufs_hba_mtk_vops = {
        .name                = "mediatek.ufshci",
        .init                = ufs_mtk_init,
        .setup_clocks        = ufs_mtk_setup_clocks,
+       .hce_enable_notify   = ufs_mtk_hce_enable_notify,
        .link_startup_notify = ufs_mtk_link_startup_notify,
        .pwr_change_notify   = ufs_mtk_pwr_change_notify,
        .apply_dev_quirks    = ufs_mtk_apply_dev_quirks,
index 4c787b9..5bbd3e9 100644 (file)
@@ -91,6 +91,7 @@ enum {
 struct ufs_mtk_host {
        struct ufs_hba *hba;
        struct phy *mphy;
+       bool unipro_lpm;
        bool ref_clk_enabled;
        u16 ref_clk_ungating_wait_us;
        u16 ref_clk_gating_wait_us;