scsi: ufs: ufs-mediatek: gate ref-clk during Auto-Hibern8
In current UFS driver design, hba->uic_link_state will not be changed after link enters Hibern8 state by Auto-Hibern8 mechanism. In this case, reference clock gating will be skipped unless special handling is implemented in vendor's callbacks. Support reference clock gating during Auto-Hibern8 period in MediaTek Chipsets: If link state is already in Hibern8 while Auto-Hibern8 feature is enabled, gate reference clock in setup_clocks callback. Link: https://lore.kernel.org/r/20200129105251.12466-5-stanley.chu@mediatek.com Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com> Reviewed-by: Bean Huo <beanhuo@micron.com> Signed-off-by: Stanley Chu <stanley.chu@mediatek.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Родитель
5a244e0ea6
Коммит
722adbbd70
|
@ -143,6 +143,17 @@ out:
|
|||
return 0;
|
||||
}
|
||||
|
||||
static u32 ufs_mtk_link_get_state(struct ufs_hba *hba)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
ufshcd_writel(hba, 0x20, REG_UFS_DEBUG_SEL);
|
||||
val = ufshcd_readl(hba, REG_UFS_PROBE);
|
||||
val = val >> 28;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* ufs_mtk_setup_clocks - enables/disable clocks
|
||||
* @hba: host controller instance
|
||||
|
@ -155,7 +166,7 @@ static int ufs_mtk_setup_clocks(struct ufs_hba *hba, bool on,
|
|||
enum ufs_notify_change_status status)
|
||||
{
|
||||
struct ufs_mtk_host *host = ufshcd_get_variant(hba);
|
||||
int ret = -EINVAL;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* In case ufs_mtk_init() is not yet done, simply ignore.
|
||||
|
@ -165,19 +176,24 @@ static int ufs_mtk_setup_clocks(struct ufs_hba *hba, bool on,
|
|||
if (!host)
|
||||
return 0;
|
||||
|
||||
switch (status) {
|
||||
case PRE_CHANGE:
|
||||
if (!on && !ufshcd_is_link_active(hba)) {
|
||||
if (!on && status == PRE_CHANGE) {
|
||||
if (!ufshcd_is_link_active(hba)) {
|
||||
ufs_mtk_setup_ref_clk(hba, on);
|
||||
ret = phy_power_off(host->mphy);
|
||||
} else {
|
||||
/*
|
||||
* Gate ref-clk if link state is in Hibern8
|
||||
* triggered by Auto-Hibern8.
|
||||
*/
|
||||
if (!ufshcd_can_hibern8_during_gating(hba) &&
|
||||
ufshcd_is_auto_hibern8_enabled(hba) &&
|
||||
ufs_mtk_link_get_state(hba) ==
|
||||
VS_LINK_HIBERN8)
|
||||
ufs_mtk_setup_ref_clk(hba, on);
|
||||
}
|
||||
break;
|
||||
case POST_CHANGE:
|
||||
if (on) {
|
||||
ret = phy_power_on(host->mphy);
|
||||
ufs_mtk_setup_ref_clk(hba, on);
|
||||
}
|
||||
break;
|
||||
} else if (on && status == POST_CHANGE) {
|
||||
ret = phy_power_on(host->mphy);
|
||||
ufs_mtk_setup_ref_clk(hba, on);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -53,6 +53,18 @@
|
|||
#define VS_SAVEPOWERCONTROL 0xD0A6
|
||||
#define VS_UNIPROPOWERDOWNCONTROL 0xD0A8
|
||||
|
||||
/*
|
||||
* Vendor specific link state
|
||||
*/
|
||||
enum {
|
||||
VS_LINK_DISABLED = 0,
|
||||
VS_LINK_DOWN = 1,
|
||||
VS_LINK_UP = 2,
|
||||
VS_LINK_HIBERN8 = 3,
|
||||
VS_LINK_LOST = 4,
|
||||
VS_LINK_CFG = 5,
|
||||
};
|
||||
|
||||
/*
|
||||
* SiP commands
|
||||
*/
|
||||
|
|
Загрузка…
Ссылка в новой задаче