Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <stanley.chu@mediatek.com>
Signed-off-by: Peter Wang <peter.wang@mediatek.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Peter Wang and committed by
Martin K. Petersen
87bd0501 0f85e747

+19 -5
+2 -1
drivers/ufs/core/ufs-sysfs.c
··· 225 225 unsigned int wb_enable; 226 226 ssize_t res; 227 227 228 - if (!ufshcd_is_wb_allowed(hba) || ufshcd_is_clkscaling_supported(hba)) { 228 + if (!ufshcd_is_wb_allowed(hba) || (ufshcd_is_clkscaling_supported(hba) 229 + && ufshcd_enable_wb_if_scaling_up(hba))) { 229 230 /* 230 231 * If the platform supports UFSHCD_CAP_CLK_SCALING, turn WB 231 232 * on/off will be done while clock scaling up/down.
+5 -3
drivers/ufs/core/ufshcd.c
··· 1299 1299 } 1300 1300 1301 1301 /* Enable Write Booster if we have scaled up else disable it */ 1302 - downgrade_write(&hba->clk_scaling_lock); 1303 - is_writelock = false; 1304 - ufshcd_wb_toggle(hba, scale_up); 1302 + if (ufshcd_enable_wb_if_scaling_up(hba)) { 1303 + downgrade_write(&hba->clk_scaling_lock); 1304 + is_writelock = false; 1305 + ufshcd_wb_toggle(hba, scale_up); 1306 + } 1305 1307 1306 1308 out_unprepare: 1307 1309 ufshcd_clock_scaling_unprepare(hba, is_writelock);
+1 -1
drivers/ufs/host/ufs-qcom.c
··· 846 846 struct ufs_qcom_host *host = ufshcd_get_variant(hba); 847 847 848 848 hba->caps |= UFSHCD_CAP_CLK_GATING | UFSHCD_CAP_HIBERN8_WITH_CLK_GATING; 849 - hba->caps |= UFSHCD_CAP_CLK_SCALING; 849 + hba->caps |= UFSHCD_CAP_CLK_SCALING | UFSHCD_CAP_WB_WITH_CLK_SCALING; 850 850 hba->caps |= UFSHCD_CAP_AUTO_BKOPS_SUSPEND; 851 851 hba->caps |= UFSHCD_CAP_WB_EN; 852 852 hba->caps |= UFSHCD_CAP_CRYPTO;
+11
include/ufs/ufshcd.h
··· 664 664 * notification if it is supported by the UFS device. 665 665 */ 666 666 UFSHCD_CAP_TEMP_NOTIF = 1 << 11, 667 + 668 + /* 669 + * Enable WriteBooster when scaling up the clock and disable 670 + * WriteBooster when scaling the clock down. 671 + */ 672 + UFSHCD_CAP_WB_WITH_CLK_SCALING = 1 << 12, 667 673 }; 668 674 669 675 struct ufs_hba_variant_params { ··· 1025 1019 static inline bool ufshcd_is_wb_allowed(struct ufs_hba *hba) 1026 1020 { 1027 1021 return hba->caps & UFSHCD_CAP_WB_EN; 1022 + } 1023 + 1024 + static inline bool ufshcd_enable_wb_if_scaling_up(struct ufs_hba *hba) 1025 + { 1026 + return hba->caps & UFSHCD_CAP_WB_WITH_CLK_SCALING; 1028 1027 } 1029 1028 1030 1029 #define ufshcd_writel(hba, val, reg) \