mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
ufs: Add mphy TX calibration support
Added mphy TX calibration support. Bug 4199271 Change-Id: Ia48945b026ac9d264d24937f9737484de8f203cd Signed-off-by: Mallikarjun Kasoju <mkasoju@nvidia.com>
This commit is contained in:
committed by
Jon Hunter
parent
055bd73cbb
commit
248a85dbbc
@@ -304,6 +304,126 @@ fail:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void ufs_tegra_mphy_tx_calibration_enable(struct ufs_tegra_host *ufs_tegra)
|
||||
{
|
||||
struct device *dev = ufs_tegra->hba->dev;
|
||||
|
||||
if ((tegra_sku_info.platform == TEGRA_PLATFORM_VDK) ||
|
||||
(tegra_sku_info.platform == TEGRA_PLATFORM_SYSTEM_FPGA) ||
|
||||
(tegra_sku_info.platform == TEGRA_PLATFORM_VSP) ||
|
||||
(ufs_tegra->soc->chip_id != TEGRA264))
|
||||
return;
|
||||
|
||||
/* Enable TX Calibration */
|
||||
mphy_update(ufs_tegra->mphy_l0_base,
|
||||
MPHY_TX_APB_VENDOR2_0_TX_CAL_EN, MPHY_TX_APB_TX_VENDOR2_0_T264);
|
||||
if (ufs_tegra->x2config == true) {
|
||||
dev_err(dev, "%s:x2config is true so invoking mphy_update\n",
|
||||
__func__);
|
||||
mphy_update(ufs_tegra->mphy_l1_base,
|
||||
MPHY_TX_APB_VENDOR2_0_TX_CAL_EN,
|
||||
MPHY_TX_APB_TX_VENDOR2_0_T264);
|
||||
}
|
||||
|
||||
mphy_update(ufs_tegra->mphy_l0_base, MPHY_GO_BIT,
|
||||
MPHY_TX_APB_TX_VENDOR0_0_T234);
|
||||
|
||||
if (ufs_tegra->x2config == true) {
|
||||
mphy_update(ufs_tegra->mphy_l1_base,
|
||||
MPHY_GO_BIT, MPHY_TX_APB_TX_VENDOR0_0_T234);
|
||||
}
|
||||
}
|
||||
|
||||
static int ufs_tegra_mphy_tx_calibration_status(struct ufs_tegra_host *ufs_tegra,
|
||||
void __iomem *mphy_base)
|
||||
{
|
||||
int err = 0;
|
||||
u32 mphy_tx_vendor2;
|
||||
unsigned int timeout;
|
||||
struct device *dev = ufs_tegra->hba->dev;
|
||||
|
||||
/* Wait till lane calibration is done */
|
||||
timeout = 100U; /* Number of iterations */
|
||||
while (timeout != 0U) {
|
||||
mphy_tx_vendor2 = mphy_readl(mphy_base,
|
||||
MPHY_TX_APB_TX_VENDOR2_0_T264);
|
||||
|
||||
if ((mphy_tx_vendor2 & MPHY_TX_APB_VENDOR2_0_TX_CAL_DONE) != 0U) {
|
||||
dev_err(dev, "%s: MPhy TX Calibration done\n", __func__);
|
||||
|
||||
/* Clear TX lane calibration */
|
||||
mphy_tx_vendor2 &=~(MPHY_TX_APB_VENDOR2_0_TX_CAL_EN);
|
||||
mphy_writel(mphy_base, mphy_tx_vendor2, MPHY_TX_APB_TX_VENDOR2_0_T264);
|
||||
break;
|
||||
} else {
|
||||
udelay(1);
|
||||
}
|
||||
timeout--;
|
||||
}
|
||||
if (timeout == 0U) {
|
||||
dev_err(dev, "%s: MPhy TX Calibration failed\n", __func__);
|
||||
err = -ETIMEDOUT;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
mphy_update(mphy_base, MPHY_GO_BIT,
|
||||
MPHY_TX_APB_TX_VENDOR0_0_T234);
|
||||
|
||||
/* Wait till lane calibration clear is done */
|
||||
timeout = 100U; /* Number of iterations */
|
||||
while (timeout != 0U) {
|
||||
mphy_tx_vendor2 = mphy_readl(mphy_base,
|
||||
MPHY_TX_APB_TX_VENDOR2_0_T264);
|
||||
if ((mphy_tx_vendor2 & MPHY_TX_APB_VENDOR2_0_TX_CAL_DONE) == 0U) {
|
||||
dev_err(dev,
|
||||
"%s: MPhy TX Calibration clear completed\n",
|
||||
__func__);
|
||||
break;
|
||||
} else {
|
||||
udelay(1);
|
||||
}
|
||||
timeout--;
|
||||
}
|
||||
if (timeout == 0U) {
|
||||
dev_err(dev, "%s: MPhy TX Calibration clear failed\n", __func__);
|
||||
err = -ETIMEDOUT;
|
||||
}
|
||||
fail:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ufs_tegra_mphy_check_tx_calibration_done_status(struct ufs_tegra_host *ufs_tegra)
|
||||
{
|
||||
int err = 0;
|
||||
struct device *dev = ufs_tegra->hba->dev;
|
||||
|
||||
if ((tegra_sku_info.platform == TEGRA_PLATFORM_VDK) ||
|
||||
(tegra_sku_info.platform == TEGRA_PLATFORM_SYSTEM_FPGA) ||
|
||||
(tegra_sku_info.platform == TEGRA_PLATFORM_VSP) ||
|
||||
(ufs_tegra->soc->chip_id != TEGRA264))
|
||||
return 0;
|
||||
|
||||
if (ufs_tegra->x2config == true) {
|
||||
err = ufs_tegra_mphy_tx_calibration_status(ufs_tegra,
|
||||
ufs_tegra->mphy_l1_base);
|
||||
if (err ) {
|
||||
dev_err(dev, "%s: MPhy1 TX Calibration status check failed \n", __func__);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
err = ufs_tegra_mphy_tx_calibration_status(ufs_tegra,
|
||||
ufs_tegra->mphy_l0_base);
|
||||
if (err ) {
|
||||
dev_err(dev, "%s: MPhy0 TX Calibration status check failed \n", __func__);
|
||||
goto fail;
|
||||
}
|
||||
dev_err(dev, "%s: MPhy TX Calibration completed\n", __func__);
|
||||
|
||||
fail:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void ufs_tegra_mphy_war(struct ufs_tegra_host *ufs_tegra)
|
||||
{
|
||||
if ((ufs_tegra->soc->chip_id == TEGRA234) && (ufs_tegra->x2config)) {
|
||||
@@ -1538,9 +1658,15 @@ static int ufs_tegra_link_startup_notify(struct ufs_hba *hba,
|
||||
} else {
|
||||
ufs_tegra_mphy_rx_sync_capability(ufs_tegra);
|
||||
ufs_tegra_unipro_pre_linkup(hba);
|
||||
/* Enable TX link calibration */
|
||||
ufs_tegra_mphy_tx_calibration_enable(ufs_tegra);
|
||||
}
|
||||
break;
|
||||
case POST_CHANGE:
|
||||
/* Check TX link calibration status */
|
||||
err = ufs_tegra_mphy_check_tx_calibration_done_status(ufs_tegra);
|
||||
if (err)
|
||||
return err;
|
||||
/*POST_CHANGE case is called on success of link start-up*/
|
||||
dev_info(hba->dev, "dme-link-startup Successful\n");
|
||||
ufs_tegra_unipro_post_linkup(hba);
|
||||
|
||||
@@ -122,6 +122,10 @@
|
||||
#define MPHY_RX_APB_VENDOR2_0_RX_CAL_DONE (1 << 19)
|
||||
#define MPHY_ENABLE_RX_MPHY2UPHY_IF_OVR_CTRL (1 << 26)
|
||||
|
||||
#define MPHY_TX_APB_TX_VENDOR2_0_T264 0x1108
|
||||
#define MPHY_TX_APB_VENDOR2_0_TX_CAL_EN (1 << 15)
|
||||
#define MPHY_TX_APB_VENDOR2_0_TX_CAL_DONE (1 << 19)
|
||||
|
||||
#define MPHY_RX_CAPABILITY_88_8B_VAL_FPGA 0x4f00fa1a
|
||||
#define MPHY_RX_CAPABILITY_8C_8F_VAL_FPGA 0x50e080e
|
||||
#define MPHY_RX_CAPABILITY_94_97_VAL_FPGA 0xe0e4f4f
|
||||
|
||||
Reference in New Issue
Block a user