mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-09-20 19:34:46 +00:00
scsi: ufs-msm-phy-qmp-20nm: fix hibern8 exit failure
If UFS link is put into Hibern8 and if UFS PHY analog hardware is power collapsed (by clearing UFS_PHY_POWER_DOWN_CONTROL), Hibern8 exit might fail even after powering on UFS PHY analog hardware. This change provides workaround to solve above issue by doing custom PHY settings just before PHY analog power collapse. Change-Id: I63d43329798c5475e07511248ac35450b8fe208d Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
This commit is contained in:
parent
6459505bac
commit
3d4dab853d
|
@ -82,36 +82,41 @@ void ufs_msm_phy_qmp_20nm_power_control(struct ufs_msm_phy *phy, bool val)
|
|||
writel_relaxed(0x1, phy->mmio + UFS_PHY_POWER_DOWN_CONTROL);
|
||||
/*
|
||||
* Before any transactions involving PHY, ensure PHY knows
|
||||
* that it's analog rail is powered ON. This also ensures
|
||||
* that PHY is out of power collapse before enabling the
|
||||
* SIGDET.
|
||||
* that it's analog rail is powered ON.
|
||||
*/
|
||||
mb();
|
||||
|
||||
if (phy->quirks &
|
||||
MSM_UFS_PHY_DIS_SIGDET_BEFORE_PWR_COLLAPSE) {
|
||||
writel_relaxed(0xC0,
|
||||
phy->mmio + QSERDES_RX_SIGDET_CNTRL(0));
|
||||
writel_relaxed(0xC0,
|
||||
phy->mmio + QSERDES_RX_SIGDET_CNTRL(1));
|
||||
MSM_UFS_PHY_QUIRK_HIBERN8_EXIT_AFTER_PHY_PWR_COLLAPSE) {
|
||||
/*
|
||||
* make sure that SIGDET is enabled before proceeding
|
||||
* further.
|
||||
* Give atleast 1us delay after restoring PHY analog
|
||||
* power.
|
||||
*/
|
||||
mb();
|
||||
}
|
||||
} else {
|
||||
if (phy->quirks &
|
||||
MSM_UFS_PHY_DIS_SIGDET_BEFORE_PWR_COLLAPSE) {
|
||||
writel_relaxed(0x0,
|
||||
phy->mmio + QSERDES_RX_SIGDET_CNTRL(0));
|
||||
writel_relaxed(0x0,
|
||||
phy->mmio + QSERDES_RX_SIGDET_CNTRL(1));
|
||||
usleep_range(1, 2);
|
||||
writel_relaxed(0x0A, phy->mmio +
|
||||
QSERDES_COM_SYSCLK_EN_SEL_TXBAND);
|
||||
writel_relaxed(0x08, phy->mmio +
|
||||
QSERDES_COM_SYSCLK_EN_SEL_TXBAND);
|
||||
/*
|
||||
* Ensure that SIGDET is disabled before PHY power
|
||||
* collapse
|
||||
* Make sure workaround is deactivated before proceeding
|
||||
* with normal PHY operations.
|
||||
*/
|
||||
mb();
|
||||
}
|
||||
} else {
|
||||
if (phy->quirks &
|
||||
MSM_UFS_PHY_QUIRK_HIBERN8_EXIT_AFTER_PHY_PWR_COLLAPSE) {
|
||||
writel_relaxed(0x0A, phy->mmio +
|
||||
QSERDES_COM_SYSCLK_EN_SEL_TXBAND);
|
||||
writel_relaxed(0x02, phy->mmio +
|
||||
QSERDES_COM_SYSCLK_EN_SEL_TXBAND);
|
||||
/*
|
||||
* Make sure that above workaround is activated before
|
||||
* PHY analog power collapse.
|
||||
*/
|
||||
mb();
|
||||
}
|
||||
|
||||
writel_relaxed(0x0, phy->mmio + UFS_PHY_POWER_DOWN_CONTROL);
|
||||
/*
|
||||
* ensure that PHY knows its PHY analog rail is going
|
||||
|
@ -158,7 +163,8 @@ static void ufs_msm_phy_qmp_20nm_advertise_quirks(struct phy *generic_phy)
|
|||
struct ufs_msm_phy_qmp_20nm *phy = phy_get_drvdata(generic_phy);
|
||||
struct ufs_msm_phy *phy_common = &(phy->common_cfg);
|
||||
|
||||
phy_common->quirks = 0;
|
||||
phy_common->quirks =
|
||||
MSM_UFS_PHY_QUIRK_HIBERN8_EXIT_AFTER_PHY_PWR_COLLAPSE;
|
||||
}
|
||||
|
||||
struct phy_ops ufs_msm_phy_qmp_20nm_phy_ops = {
|
||||
|
|
|
@ -108,6 +108,15 @@ struct ufs_msm_phy {
|
|||
*/
|
||||
#define MSM_UFS_PHY_DIS_SIGDET_BEFORE_PWR_COLLAPSE (1 << 1)
|
||||
|
||||
/*
|
||||
* If UFS link is put into Hibern8 and if UFS PHY analog hardware is
|
||||
* power collapsed (by clearing UFS_PHY_POWER_DOWN_CONTROL), Hibern8
|
||||
* exit might fail even after powering on UFS PHY analog hardware.
|
||||
* Enabling this quirk will help to solve above issue by doing
|
||||
* custom PHY settings just before PHY analog power collapse.
|
||||
*/
|
||||
#define MSM_UFS_PHY_QUIRK_HIBERN8_EXIT_AFTER_PHY_PWR_COLLAPSE (1 << 2)
|
||||
|
||||
char name[UFS_MSM_PHY_NAME_LEN];
|
||||
struct ufs_msm_phy_calibration *cached_regs;
|
||||
int cached_regs_table_size;
|
||||
|
|
Loading…
Reference in a new issue