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;
|
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)
|
static void ufs_tegra_mphy_war(struct ufs_tegra_host *ufs_tegra)
|
||||||
{
|
{
|
||||||
if ((ufs_tegra->soc->chip_id == TEGRA234) && (ufs_tegra->x2config)) {
|
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 {
|
} else {
|
||||||
ufs_tegra_mphy_rx_sync_capability(ufs_tegra);
|
ufs_tegra_mphy_rx_sync_capability(ufs_tegra);
|
||||||
ufs_tegra_unipro_pre_linkup(hba);
|
ufs_tegra_unipro_pre_linkup(hba);
|
||||||
|
/* Enable TX link calibration */
|
||||||
|
ufs_tegra_mphy_tx_calibration_enable(ufs_tegra);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case POST_CHANGE:
|
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*/
|
/*POST_CHANGE case is called on success of link start-up*/
|
||||||
dev_info(hba->dev, "dme-link-startup Successful\n");
|
dev_info(hba->dev, "dme-link-startup Successful\n");
|
||||||
ufs_tegra_unipro_post_linkup(hba);
|
ufs_tegra_unipro_post_linkup(hba);
|
||||||
|
|||||||
@@ -122,6 +122,10 @@
|
|||||||
#define MPHY_RX_APB_VENDOR2_0_RX_CAL_DONE (1 << 19)
|
#define MPHY_RX_APB_VENDOR2_0_RX_CAL_DONE (1 << 19)
|
||||||
#define MPHY_ENABLE_RX_MPHY2UPHY_IF_OVR_CTRL (1 << 26)
|
#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_88_8B_VAL_FPGA 0x4f00fa1a
|
||||||
#define MPHY_RX_CAPABILITY_8C_8F_VAL_FPGA 0x50e080e
|
#define MPHY_RX_CAPABILITY_8C_8F_VAL_FPGA 0x50e080e
|
||||||
#define MPHY_RX_CAPABILITY_94_97_VAL_FPGA 0xe0e4f4f
|
#define MPHY_RX_CAPABILITY_94_97_VAL_FPGA 0xe0e4f4f
|
||||||
|
|||||||
Reference in New Issue
Block a user