mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
scsi: ufs: host: mediatek: Fix auto-hibern8 timer configuration
[ Upstream commit aa86602a483ba48f51044fbaefa1ebbf6da194a4 ] Move the configuration of the Auto-Hibern8 (AHIT) timer from the post-link stage to the 'fixup_dev_quirks' function. This change allows setting the AHIT based on the vendor requirements: (a) Samsung: 3.5 ms (b) Micron: 2 ms (c) Others: 1 ms Additionally, the clock gating timer is adjusted based on the AHIT scale, with a maximum setting of 10 ms. This ensures that the clock gating delay is appropriately configured to match the AHIT settings. Signed-off-by: Peter Wang <peter.wang@mediatek.com> Link: https://lore.kernel.org/r/20250811131423.3444014-3-peter.wang@mediatek.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
68245d8fe2
commit
137dea7d7d
@@ -847,6 +847,69 @@ static void ufs_mtk_vreg_fix_vccqx(struct ufs_hba *hba)
|
||||
}
|
||||
}
|
||||
|
||||
static void ufs_mtk_setup_clk_gating(struct ufs_hba *hba)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 ah_ms = 10;
|
||||
u32 ah_scale, ah_timer;
|
||||
u32 scale_us[] = {1, 10, 100, 1000, 10000, 100000};
|
||||
|
||||
if (ufshcd_is_clkgating_allowed(hba)) {
|
||||
if (ufshcd_is_auto_hibern8_supported(hba) && hba->ahit) {
|
||||
ah_scale = FIELD_GET(UFSHCI_AHIBERN8_SCALE_MASK,
|
||||
hba->ahit);
|
||||
ah_timer = FIELD_GET(UFSHCI_AHIBERN8_TIMER_MASK,
|
||||
hba->ahit);
|
||||
if (ah_scale <= 5)
|
||||
ah_ms = ah_timer * scale_us[ah_scale] / 1000;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(hba->host->host_lock, flags);
|
||||
hba->clk_gating.delay_ms = max(ah_ms, 10U);
|
||||
spin_unlock_irqrestore(hba->host->host_lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert microseconds to Auto-Hibernate Idle Timer register value */
|
||||
static u32 ufs_mtk_us_to_ahit(unsigned int timer)
|
||||
{
|
||||
unsigned int scale;
|
||||
|
||||
for (scale = 0; timer > UFSHCI_AHIBERN8_TIMER_MASK; ++scale)
|
||||
timer /= UFSHCI_AHIBERN8_SCALE_FACTOR;
|
||||
|
||||
return FIELD_PREP(UFSHCI_AHIBERN8_TIMER_MASK, timer) |
|
||||
FIELD_PREP(UFSHCI_AHIBERN8_SCALE_MASK, scale);
|
||||
}
|
||||
|
||||
static void ufs_mtk_fix_ahit(struct ufs_hba *hba)
|
||||
{
|
||||
unsigned int us;
|
||||
|
||||
if (ufshcd_is_auto_hibern8_supported(hba)) {
|
||||
switch (hba->dev_info.wmanufacturerid) {
|
||||
case UFS_VENDOR_SAMSUNG:
|
||||
/* configure auto-hibern8 timer to 3.5 ms */
|
||||
us = 3500;
|
||||
break;
|
||||
|
||||
case UFS_VENDOR_MICRON:
|
||||
/* configure auto-hibern8 timer to 2 ms */
|
||||
us = 2000;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* configure auto-hibern8 timer to 1 ms */
|
||||
us = 1000;
|
||||
break;
|
||||
}
|
||||
|
||||
hba->ahit = ufs_mtk_us_to_ahit(us);
|
||||
}
|
||||
|
||||
ufs_mtk_setup_clk_gating(hba);
|
||||
}
|
||||
|
||||
static void ufs_mtk_init_mcq_irq(struct ufs_hba *hba)
|
||||
{
|
||||
struct ufs_mtk_host *host = ufshcd_get_variant(hba);
|
||||
@@ -1119,32 +1182,10 @@ static int ufs_mtk_pre_link(struct ufs_hba *hba)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ufs_mtk_setup_clk_gating(struct ufs_hba *hba)
|
||||
{
|
||||
u32 ah_ms;
|
||||
|
||||
if (ufshcd_is_clkgating_allowed(hba)) {
|
||||
if (ufshcd_is_auto_hibern8_supported(hba) && hba->ahit)
|
||||
ah_ms = FIELD_GET(UFSHCI_AHIBERN8_TIMER_MASK,
|
||||
hba->ahit);
|
||||
else
|
||||
ah_ms = 10;
|
||||
ufshcd_clkgate_delay_set(hba->dev, ah_ms + 5);
|
||||
}
|
||||
}
|
||||
|
||||
static void ufs_mtk_post_link(struct ufs_hba *hba)
|
||||
{
|
||||
/* enable unipro clock gating feature */
|
||||
ufs_mtk_cfg_unipro_cg(hba, true);
|
||||
|
||||
/* will be configured during probe hba */
|
||||
if (ufshcd_is_auto_hibern8_supported(hba))
|
||||
hba->ahit = FIELD_PREP(UFSHCI_AHIBERN8_TIMER_MASK, 10) |
|
||||
FIELD_PREP(UFSHCI_AHIBERN8_SCALE_MASK, 3);
|
||||
|
||||
ufs_mtk_setup_clk_gating(hba);
|
||||
}
|
||||
|
||||
static int ufs_mtk_link_startup_notify(struct ufs_hba *hba,
|
||||
@@ -1444,6 +1485,7 @@ static void ufs_mtk_fixup_dev_quirks(struct ufs_hba *hba)
|
||||
|
||||
ufs_mtk_vreg_fix_vcc(hba);
|
||||
ufs_mtk_vreg_fix_vccqx(hba);
|
||||
ufs_mtk_fix_ahit(hba);
|
||||
}
|
||||
|
||||
static void ufs_mtk_event_notify(struct ufs_hba *hba,
|
||||
|
||||
Reference in New Issue
Block a user