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
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.
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;