From f827a0f5514c2e0ce0f95ecd69a895998fe65572 Mon Sep 17 00:00:00 2001 From: Peter Wang Date: Thu, 4 Aug 2022 10:54:22 +0800 Subject: [PATCH] UPSTREAM: scsi: ufs: core: Allow host driver to disable wb toggling during clock scaling 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 Change-Id: I55eb7d48b8662be9a9e17977c4ef9cf4d402c241 Signed-off-by: Peter Wang Signed-off-by: Martin K. Petersen Bug: 258234315 (cherry picked from commit 87bd05016a64864d27a640ca24ef63c760b67d73) Signed-off-by: Bart Van Assche --- drivers/ufs/core/ufs-sysfs.c | 3 ++- drivers/ufs/core/ufshcd.c | 8 +++++--- drivers/ufs/host/ufs-qcom.c | 2 +- include/ufs/ufshcd.h | 11 +++++++++++ 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/ufs/core/ufs-sysfs.c b/drivers/ufs/core/ufs-sysfs.c index 11ab1db426b0..4f8ad869f1de 100644 --- a/drivers/ufs/core/ufs-sysfs.c +++ b/drivers/ufs/core/ufs-sysfs.c @@ -227,7 +227,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. diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 94fb12031384..2780f9dbae74 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -1324,9 +1324,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); diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c index 473fad83701e..8ad1415e10b6 100644 --- a/drivers/ufs/host/ufs-qcom.c +++ b/drivers/ufs/host/ufs-qcom.c @@ -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; diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index 0689e286ac76..24ca41efc220 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -699,6 +699,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 { @@ -1066,6 +1072,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) \