diff options
| author | Subhash Jadavani <subhashj@codeaurora.org> | 2015-02-12 17:34:25 -0800 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-22 11:01:17 -0700 |
| commit | ec3be61698ae54b7e658c5bc3f277d1a656a4ea0 (patch) | |
| tree | b8c3fe33c746e394ac4884c1bb4ed07bc2d6751e /drivers/phy | |
| parent | 9afc3bb60a4e87b86779ce224d51bd4aa11cb0e6 (diff) | |
phy: qcom-ufs-qmp-14nm: add workaround to program tuned VCO code
On some UFS PHY HW revisions, UFS PHY power up calibration sequence
requires manual VCO tuning code and its better to rely on the VCO
tuning code programmed by boot loader. This change enables the quirk
to program the manually tuned VCO code.
Change-Id: Id1bb2b28816b8de6df7ca22cda5788288b11328a
Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
[venkatg@codeaurora.org: resolved trivial merge conflicts]
Signed-off-by: Venkat Gopalakrishnan <venkatg@codeaurora.org>
Diffstat (limited to 'drivers/phy')
| -rw-r--r-- | drivers/phy/phy-qcom-ufs-i.h | 18 | ||||
| -rw-r--r-- | drivers/phy/phy-qcom-ufs-qmp-14nm.c | 16 | ||||
| -rw-r--r-- | drivers/phy/phy-qcom-ufs-qmp-14nm.h | 1 |
3 files changed, 32 insertions, 3 deletions
diff --git a/drivers/phy/phy-qcom-ufs-i.h b/drivers/phy/phy-qcom-ufs-i.h index f0ed60f3bc9e..9c56264889be 100644 --- a/drivers/phy/phy-qcom-ufs-i.h +++ b/drivers/phy/phy-qcom-ufs-i.h @@ -107,6 +107,23 @@ struct ufs_qcom_phy { */ #define UFS_QCOM_PHY_QUIRK_HIBERN8_EXIT_AFTER_PHY_PWR_COLLAPSE BIT(0) + /* + * On some UFS PHY HW revisions, UFS PHY power up calibration sequence + * cannot have SVS mode configuration otherwise calibration result + * cannot be used in HS-G3. So there are additional register writes must + * be done after the PHY is initialized but before the controller + * requests hibernate exit. + */ + #define UFS_QCOM_PHY_QUIRK_SVS_MODE BIT(1) + + /* + * On some UFS PHY HW revisions, UFS PHY power up calibration sequence + * requires manual VCO tuning code and its better to rely on the VCO + * tuning code programmed by boot loader. Enable this quirk to enable + * programming the manually tuned VCO code. + */ + #define UFS_QCOM_PHY_QUIRK_VCO_MANUAL_TUNING BIT(2) + u8 host_ctrl_rev_major; u16 host_ctrl_rev_minor; u16 host_ctrl_rev_step; @@ -116,6 +133,7 @@ struct ufs_qcom_phy { int cached_regs_table_size; bool is_powered_on; struct ufs_qcom_phy_specific_ops *phy_spec_ops; + u32 vco_tune1_mode1; }; /** diff --git a/drivers/phy/phy-qcom-ufs-qmp-14nm.c b/drivers/phy/phy-qcom-ufs-qmp-14nm.c index 6495681a4291..132a1f1f6be7 100644 --- a/drivers/phy/phy-qcom-ufs-qmp-14nm.c +++ b/drivers/phy/phy-qcom-ufs-qmp-14nm.c @@ -48,7 +48,11 @@ int ufs_qcom_phy_qmp_14nm_phy_calibrate(struct ufs_qcom_phy *ufs_qcom_phy, err = ufs_qcom_phy_calibrate(ufs_qcom_phy, tbl_A, tbl_size_A, tbl_B, tbl_size_B, - rate); + is_rate_B); + + if (ufs_qcom_phy->quirks & UFS_QCOM_PHY_QUIRK_VCO_MANUAL_TUNING) + writel_relaxed(ufs_qcom_phy->vco_tune1_mode1, + ufs_qcom_phy->mmio + QSERDES_COM_VCO_TUNE1_MODE1); out: if (err) dev_err(ufs_qcom_phy->dev, @@ -67,7 +71,8 @@ void ufs_qcom_phy_qmp_14nm_advertise_quirks(struct ufs_qcom_phy *phy_common) if ((major == 0x2) && (minor == 0x000) && (step == 0x0000)) phy_common->quirks = UFS_QCOM_PHY_QUIRK_HIBERN8_EXIT_AFTER_PHY_PWR_COLLAPSE | - UFS_QCOM_PHY_QUIRK_SVS_MODE; + UFS_QCOM_PHY_QUIRK_SVS_MODE | + UFS_QCOM_PHY_QUIRK_VCO_MANUAL_TUNING; } static int ufs_qcom_phy_qmp_14nm_init(struct phy *generic_phy) @@ -94,6 +99,13 @@ static int ufs_qcom_phy_qmp_14nm_init(struct phy *generic_phy) ufs_qcom_phy_qmp_14nm_advertise_quirks(phy_common); + if (phy_common->quirks & UFS_QCOM_PHY_QUIRK_VCO_MANUAL_TUNING) { + phy_common->vco_tune1_mode1 = readl_relaxed(phy_common->mmio + + QSERDES_COM_VCO_TUNE1_MODE1); + dev_info(phy_common->dev, "%s: vco_tune1_mode1 0x%x\n", + __func__, phy_common->vco_tune1_mode1); + } + out: return err; } diff --git a/drivers/phy/phy-qcom-ufs-qmp-14nm.h b/drivers/phy/phy-qcom-ufs-qmp-14nm.h index 41397bea5f0e..3eaa0ef3b8c6 100644 --- a/drivers/phy/phy-qcom-ufs-qmp-14nm.h +++ b/drivers/phy/phy-qcom-ufs-qmp-14nm.h @@ -162,7 +162,6 @@ static struct ufs_qcom_phy_calibration phy_cal_table_rate_A_2_0_0[] = { UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_PLL_CCTRL_MODE1, 0x28), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00), - UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_VCO_TUNE1_MODE1, 0x7F), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_VCO_TUNE2_MODE1, 0x00), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_LOCK_CMP1_MODE1, 0x32), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f), |
