From a8d019ed25d91584ea780941a4f5fce826a874e3 Mon Sep 17 00:00:00 2001 From: Can Guo Date: Thu, 13 Feb 2025 16:00:07 +0800 Subject: [PATCH] BACKPORT: FROMGIT: scsi: ufs: core: Toggle Write Booster during clock scaling base on gear speed During clock scaling, Write Booster is toggled on or off based on whether the clock is scaled up or down. However, with OPP V2 powered multi-level gear scaling, the gear can be scaled amongst multiple gear speeds, e.g., it may scale down from G5 to G4, or from G4 to G2. To provide flexibilities, add a new field for clock scaling such that during clock scaling Write Booster can be enabled or disabled based on gear speeds but not based on scaling up or down. Signed-off-by: Can Guo Co-developed-by: Ziqi Chen Signed-off-by: Ziqi Chen Link: https://lore.kernel.org/r/20250213080008.2984807-8-quic_ziqichen@quicinc.com Reviewed-by: Bean Huo Tested-by: Neil Armstrong Reviewed-by: Peter Wang Signed-off-by: Martin K. Petersen Bug: 399777345 Change-Id: I50025ecbff7649444109581708a5961c06abee57 (cherry picked from commit 2a25cbaa81d27f212439576fb5d406466055cfd0 https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git 6.15/scsi-staging) (Fixed minor confliction in ufshcd.h to adapt to kernel 6.12) Signed-off-by: Ziqi Chen --- drivers/ufs/core/ufshcd.c | 12 ++++++++---- include/ufs/ufshcd.h | 3 +++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index fa15bab6a5d1..574e93d5bce3 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -1434,13 +1434,13 @@ out: return ret; } -static void ufshcd_clock_scaling_unprepare(struct ufs_hba *hba, int err, bool scale_up) +static void ufshcd_clock_scaling_unprepare(struct ufs_hba *hba, int err) { up_write(&hba->clk_scaling_lock); - /* Enable Write Booster if we have scaled up else disable it */ + /* Enable Write Booster if current gear requires it else disable it */ if (ufshcd_enable_wb_if_scaling_up(hba) && !err) - ufshcd_wb_toggle(hba, scale_up); + ufshcd_wb_toggle(hba, hba->pwr_info.gear_rx >= hba->clk_scaling.wb_gear); mutex_unlock(&hba->wb_mutex); @@ -1495,7 +1495,7 @@ static int ufshcd_devfreq_scale(struct ufs_hba *hba, unsigned long freq, } out_unprepare: - ufshcd_clock_scaling_unprepare(hba, ret, scale_up); + ufshcd_clock_scaling_unprepare(hba, ret); return ret; } @@ -1855,6 +1855,10 @@ static void ufshcd_init_clk_scaling(struct ufs_hba *hba) if (!hba->clk_scaling.min_gear) hba->clk_scaling.min_gear = UFS_HS_G1; + if (!hba->clk_scaling.wb_gear) + /* Use intermediate gear speed HS_G3 as the default wb_gear */ + hba->clk_scaling.wb_gear = UFS_HS_G3; + INIT_WORK(&hba->clk_scaling.suspend_work, ufshcd_clk_scaling_suspend_work); INIT_WORK(&hba->clk_scaling.resume_work, diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index 520fe02ef247..a406e96edf04 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -453,6 +453,8 @@ struct ufs_clk_gating { * @resume_work: worker to resume devfreq * @target_freq: frequency requested by devfreq framework * @min_gear: lowest HS gear to scale down to + * @wb_gear: enable Write Booster when HS gear scales above or equal to it, else + * disable Write Booster * @is_enabled: tracks if scaling is currently enabled or not, controlled by * clkscale_enable sysfs node * @is_allowed: tracks if scaling is currently allowed or not, used to block @@ -473,6 +475,7 @@ struct ufs_clk_scaling { struct work_struct resume_work; unsigned long target_freq; u32 min_gear; + u32 wb_gear; bool is_enabled; bool is_allowed; bool is_initialized;