scsi: ufs: core: Allow host driver to disable wb toggling during clock scaling
authorPeter Wang <peter.wang@mediatek.com>
Thu, 4 Aug 2022 02:54:22 +0000 (10:54 +0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 23 Aug 2022 03:07:50 +0000 (23:07 -0400)
Mediatek UFS does not want to toggle write booster during clock scaling.
Permit host driver to disable wb toggling during clock scaling.

Introduce a flag UFSHCD_CAP_WB_WITH_CLK_SCALING to decouple WB and clock
scaling.  UFSHCD_CAP_WB_WITH_CLK_SCALING is only valid when
UFSHCD_CAP_CLK_SCALING is set. Just like UFSHCD_CAP_HIBERN8_WITH_CLK_GATING
is valid only when UFSHCD_CAP_CLK_GATING set.

Set UFSHCD_CAP_WB_WITH_CLK_SCALING for qcom to compatible legacy design at
the same time.

Link: https://lore.kernel.org/r/20220804025422.18803-1-peter.wang@mediatek.com
Reviewed-by: Stanley Chu <stanley.chu@mediatek.com>
Signed-off-by: Peter Wang <peter.wang@mediatek.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/ufs/core/ufs-sysfs.c
drivers/ufs/core/ufshcd.c
drivers/ufs/host/ufs-qcom.c
include/ufs/ufshcd.h

index 0a088b47d5570047de5457fc93bfc53953f4ebea..7f41f2a69b0449492ab0e59adca158cbeb8d78c3 100644 (file)
@@ -225,7 +225,8 @@ static ssize_t wb_on_store(struct device *dev, struct device_attribute *attr,
        unsigned int wb_enable;
        ssize_t res;
 
-       if (!ufshcd_is_wb_allowed(hba) || ufshcd_is_clkscaling_supported(hba)) {
+       if (!ufshcd_is_wb_allowed(hba) || (ufshcd_is_clkscaling_supported(hba)
+               && ufshcd_enable_wb_if_scaling_up(hba))) {
                /*
                 * If the platform supports UFSHCD_CAP_CLK_SCALING, turn WB
                 * on/off will be done while clock scaling up/down.
index 0391b66ed632464568dd58930be11dfa9d93010e..285e099385cd92022fcc1274ec8dec1fc827d6cb 100644 (file)
@@ -1299,9 +1299,11 @@ static int ufshcd_devfreq_scale(struct ufs_hba *hba, bool scale_up)
        }
 
        /* Enable Write Booster if we have scaled up else disable it */
-       downgrade_write(&hba->clk_scaling_lock);
-       is_writelock = false;
-       ufshcd_wb_toggle(hba, scale_up);
+       if (ufshcd_enable_wb_if_scaling_up(hba)) {
+               downgrade_write(&hba->clk_scaling_lock);
+               is_writelock = false;
+               ufshcd_wb_toggle(hba, scale_up);
+       }
 
 out_unprepare:
        ufshcd_clock_scaling_unprepare(hba, is_writelock);
index 473fad83701ea8e3153726d4816f1cb6b9406c75..8ad1415e10b637ac927b4aca3a5ed7c4de801ab4 100644 (file)
@@ -846,7 +846,7 @@ static void ufs_qcom_set_caps(struct ufs_hba *hba)
        struct ufs_qcom_host *host = ufshcd_get_variant(hba);
 
        hba->caps |= UFSHCD_CAP_CLK_GATING | UFSHCD_CAP_HIBERN8_WITH_CLK_GATING;
-       hba->caps |= UFSHCD_CAP_CLK_SCALING;
+       hba->caps |= UFSHCD_CAP_CLK_SCALING | UFSHCD_CAP_WB_WITH_CLK_SCALING;
        hba->caps |= UFSHCD_CAP_AUTO_BKOPS_SUSPEND;
        hba->caps |= UFSHCD_CAP_WB_EN;
        hba->caps |= UFSHCD_CAP_CRYPTO;
index d81e9a5da59ef082ccb70015411ea4887674ce09..bd411f04d856b017cfb73a13b018934c703a3d67 100644 (file)
@@ -664,6 +664,12 @@ enum ufshcd_caps {
         * notification if it is supported by the UFS device.
         */
        UFSHCD_CAP_TEMP_NOTIF                           = 1 << 11,
+
+       /*
+        * Enable WriteBooster when scaling up the clock and disable
+        * WriteBooster when scaling the clock down.
+        */
+       UFSHCD_CAP_WB_WITH_CLK_SCALING                  = 1 << 12,
 };
 
 struct ufs_hba_variant_params {
@@ -1021,6 +1027,11 @@ static inline bool ufshcd_is_wb_allowed(struct ufs_hba *hba)
        return hba->caps & UFSHCD_CAP_WB_EN;
 }
 
+static inline bool ufshcd_enable_wb_if_scaling_up(struct ufs_hba *hba)
+{
+       return hba->caps & UFSHCD_CAP_WB_WITH_CLK_SCALING;
+}
+
 #define ufshcd_writel(hba, val, reg)   \
        writel((val), (hba)->mmio_base + (reg))
 #define ufshcd_readl(hba, reg) \