Commit 722adbbd authored by Stanley Chu's avatar Stanley Chu Committed by Martin K. Petersen

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.comReviewed-by: default avatarAlim Akhtar <alim.akhtar@samsung.com>
Reviewed-by: default avatarBean Huo <beanhuo@micron.com>
Signed-off-by: default avatarStanley Chu <stanley.chu@mediatek.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 5a244e0e
...@@ -143,6 +143,17 @@ static int ufs_mtk_setup_ref_clk(struct ufs_hba *hba, bool on) ...@@ -143,6 +143,17 @@ static int ufs_mtk_setup_ref_clk(struct ufs_hba *hba, bool on)
return 0; 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 * ufs_mtk_setup_clocks - enables/disable clocks
* @hba: host controller instance * @hba: host controller instance
...@@ -155,7 +166,7 @@ static int ufs_mtk_setup_clocks(struct ufs_hba *hba, bool on, ...@@ -155,7 +166,7 @@ static int ufs_mtk_setup_clocks(struct ufs_hba *hba, bool on,
enum ufs_notify_change_status status) enum ufs_notify_change_status status)
{ {
struct ufs_mtk_host *host = ufshcd_get_variant(hba); 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. * 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, ...@@ -165,19 +176,24 @@ static int ufs_mtk_setup_clocks(struct ufs_hba *hba, bool on,
if (!host) if (!host)
return 0; return 0;
switch (status) { if (!on && status == PRE_CHANGE) {
case PRE_CHANGE: if (!ufshcd_is_link_active(hba)) {
if (!on && !ufshcd_is_link_active(hba)) {
ufs_mtk_setup_ref_clk(hba, on); ufs_mtk_setup_ref_clk(hba, on);
ret = phy_power_off(host->mphy); 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; } else if (on && status == POST_CHANGE) {
case POST_CHANGE: ret = phy_power_on(host->mphy);
if (on) { ufs_mtk_setup_ref_clk(hba, on);
ret = phy_power_on(host->mphy);
ufs_mtk_setup_ref_clk(hba, on);
}
break;
} }
return ret; return ret;
......
...@@ -53,6 +53,18 @@ ...@@ -53,6 +53,18 @@
#define VS_SAVEPOWERCONTROL 0xD0A6 #define VS_SAVEPOWERCONTROL 0xD0A6
#define VS_UNIPROPOWERDOWNCONTROL 0xD0A8 #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 * SiP commands
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment