scsi: ufs: check for go bit status

GO bit will be cleared after driver
writing it to 1. Need to check the
clear status. Added check for the same.

Bug 4782274

Signed-off-by: Mallikarjun Kasoju <mkasoju@nvidia.com>
Change-Id: I71f035a27fb95de3e37d515a34c48c493f827a44
This commit is contained in:
Mallikarjun Kasoju
2024-10-09 11:34:57 +00:00
committed by Jon Hunter
parent e86ab401cc
commit 24e024444b
2 changed files with 144 additions and 14 deletions

View File

@@ -48,6 +48,28 @@
static void ufs_tegra_mphy_startup_sequence(struct ufs_tegra_host *ufs_tegra); static void ufs_tegra_mphy_startup_sequence(struct ufs_tegra_host *ufs_tegra);
static int mphy_go_bit_status(void __iomem *mphy_base, u32 offset) {
unsigned int timeout;
unsigned int err = 0;
u32 mphy_rx_vendor2 = 0;
timeout = 500U; /* Number of iterations */
while (timeout != 0U) {
mphy_rx_vendor2 = mphy_readl(mphy_base, offset);
if ((mphy_rx_vendor2 & MPHY_GO_BIT) == 0U) {
break;
} else {
udelay(1);
}
timeout--;
}
if (timeout == 0U) {
err = -ETIMEDOUT;
}
return err;
}
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
static void ufs_tegra_init_debugfs(struct ufs_hba *hba) static void ufs_tegra_init_debugfs(struct ufs_hba *hba)
{ {
@@ -173,13 +195,23 @@ static int ufs_tegra_mphy_receiver_calibration(struct ufs_tegra_host *ufs_tegra,
/* TODO: GO bit has to be read back after updating it */ /* TODO: GO bit has to be read back after updating it */
mphy_update(ufs_tegra->mphy_l1_base, mphy_update(ufs_tegra->mphy_l1_base,
MPHY_GO_BIT, mphy_rx_vendor2_reg); MPHY_GO_BIT, mphy_rx_vendor2_reg);
} err = mphy_go_bit_status(ufs_tegra->mphy_l1_base, mphy_rx_vendor2_reg);
if (err) {
dev_err(dev, "%s: Go bit clear failed for mphy1\n", __func__);
goto fail;
}
}
mphy_update(ufs_tegra->mphy_l0_base, mphy_update(ufs_tegra->mphy_l0_base,
MPHY_RX_APB_VENDOR2_0_RX_CAL_EN, mphy_rx_vendor2_reg); MPHY_RX_APB_VENDOR2_0_RX_CAL_EN, mphy_rx_vendor2_reg);
/* TODO: GO bit has to be read back after updating it */ /* TODO: GO bit has to be read back after updating it */
mphy_update(ufs_tegra->mphy_l0_base, MPHY_GO_BIT, mphy_update(ufs_tegra->mphy_l0_base, MPHY_GO_BIT,
mphy_rx_vendor2_reg); mphy_rx_vendor2_reg);
err = mphy_go_bit_status(ufs_tegra->mphy_l0_base, mphy_rx_vendor2_reg);
if (err) {
dev_err(dev, "%s: Go bit clear failed for mphy0\n", __func__);
goto fail;
}
if (ufs_tegra->x2config == true) { if (ufs_tegra->x2config == true) {
/* Wait till lane calibration is done */ /* Wait till lane calibration is done */
@@ -208,6 +240,11 @@ static int ufs_tegra_mphy_receiver_calibration(struct ufs_tegra_host *ufs_tegra,
mphy_rx_vendor2_reg); mphy_rx_vendor2_reg);
mphy_update(ufs_tegra->mphy_l1_base, mphy_update(ufs_tegra->mphy_l1_base,
MPHY_GO_BIT, mphy_rx_vendor2_reg); MPHY_GO_BIT, mphy_rx_vendor2_reg);
err = mphy_go_bit_status(ufs_tegra->mphy_l1_base, mphy_rx_vendor2_reg);
if (err) {
dev_err(dev, "%s: Go bit clear failed for mphy1\n", __func__);
goto fail;
}
/* Wait till lane calibration is done */ /* Wait till lane calibration is done */
timeout = 100U; /* Number of iterations */ timeout = 100U; /* Number of iterations */
@@ -254,6 +291,11 @@ static int ufs_tegra_mphy_receiver_calibration(struct ufs_tegra_host *ufs_tegra,
mphy_rx_vendor2_reg); mphy_rx_vendor2_reg);
mphy_update(ufs_tegra->mphy_l0_base, mphy_update(ufs_tegra->mphy_l0_base,
MPHY_GO_BIT, mphy_rx_vendor2_reg); MPHY_GO_BIT, mphy_rx_vendor2_reg);
err = mphy_go_bit_status(ufs_tegra->mphy_l0_base, mphy_rx_vendor2_reg);
if (err) {
dev_err(dev, "%s: Go bit clear failed for mphy0\n", __func__);
goto fail;
}
timeout = 100U; /* Number of iterations */ timeout = 100U; /* Number of iterations */
while (timeout != 0U) { while (timeout != 0U) {
mphy_rx_vendor2 = mphy_readl(ufs_tegra->mphy_l0_base, mphy_rx_vendor2 = mphy_readl(ufs_tegra->mphy_l0_base,
@@ -287,10 +329,19 @@ static int ufs_tegra_mphy_receiver_calibration(struct ufs_tegra_host *ufs_tegra,
/* TODO: GO bit has to be read back after updating it */ /* TODO: GO bit has to be read back after updating it */
mphy_update(ufs_tegra->mphy_l1_base, mphy_update(ufs_tegra->mphy_l1_base,
MPHY_GO_BIT, mphy_rx_vendor2_reg); MPHY_GO_BIT, mphy_rx_vendor2_reg);
err = mphy_go_bit_status(ufs_tegra->mphy_l1_base, mphy_rx_vendor2_reg);
if (err) {
goto fail;
}
} }
/* TODO: GO bit has to be read back after updating it */
mphy_update(ufs_tegra->mphy_l0_base, MPHY_GO_BIT, mphy_update(ufs_tegra->mphy_l0_base, MPHY_GO_BIT,
mphy_rx_vendor2_reg); mphy_rx_vendor2_reg);
err = mphy_go_bit_status(ufs_tegra->mphy_l0_base, mphy_rx_vendor2_reg);
if (err) {
dev_err(dev, "%s: Go bit clear failed for mphy0\n", __func__);
goto fail;
}
timeout = 10U; /* Number of iterations */ timeout = 10U; /* Number of iterations */
while (timeout != 0U) { while (timeout != 0U) {
udelay(1000); udelay(1000);
@@ -314,15 +365,16 @@ fail:
return err; return err;
} }
static void ufs_tegra_mphy_tx_calibration_enable(struct ufs_tegra_host *ufs_tegra) static int ufs_tegra_mphy_tx_calibration_enable(struct ufs_tegra_host *ufs_tegra)
{ {
struct device *dev = ufs_tegra->hba->dev; struct device *dev = ufs_tegra->hba->dev;
int err = 0;
if ((tegra_sku_info.platform == TEGRA_PLATFORM_VDK) || if ((tegra_sku_info.platform == TEGRA_PLATFORM_VDK) ||
(tegra_sku_info.platform == TEGRA_PLATFORM_SYSTEM_FPGA) || (tegra_sku_info.platform == TEGRA_PLATFORM_SYSTEM_FPGA) ||
(tegra_sku_info.platform == TEGRA_PLATFORM_VSP) || (tegra_sku_info.platform == TEGRA_PLATFORM_VSP) ||
(ufs_tegra->soc->chip_id != TEGRA264)) (ufs_tegra->soc->chip_id != TEGRA264))
return; goto end;
/* Enable TX Calibration */ /* Enable TX Calibration */
mphy_update(ufs_tegra->mphy_l0_base, mphy_update(ufs_tegra->mphy_l0_base,
@@ -337,11 +389,24 @@ static void ufs_tegra_mphy_tx_calibration_enable(struct ufs_tegra_host *ufs_tegr
mphy_update(ufs_tegra->mphy_l0_base, MPHY_GO_BIT, mphy_update(ufs_tegra->mphy_l0_base, MPHY_GO_BIT,
MPHY_TX_APB_TX_VENDOR0_0_T234); MPHY_TX_APB_TX_VENDOR0_0_T234);
err = mphy_go_bit_status(ufs_tegra->mphy_l0_base, MPHY_TX_APB_TX_VENDOR0_0_T234);
if (err) {
dev_err(dev, "%s: Go bit clear failed for mphy0\n", __func__);
goto end;
}
if (ufs_tegra->x2config == true) { if (ufs_tegra->x2config == true) {
mphy_update(ufs_tegra->mphy_l1_base, mphy_update(ufs_tegra->mphy_l1_base,
MPHY_GO_BIT, MPHY_TX_APB_TX_VENDOR0_0_T234); MPHY_GO_BIT, MPHY_TX_APB_TX_VENDOR0_0_T234);
err = mphy_go_bit_status(ufs_tegra->mphy_l1_base, MPHY_TX_APB_TX_VENDOR0_0_T234);
if (err) {
dev_err(dev, "%s: Go bit clear failed for mphy1\n", __func__);
}
} }
end:
if (err)
dev_err(dev, "%s: failed\n", __func__);
return err;
} }
static int ufs_tegra_mphy_tx_calibration_status(struct ufs_tegra_host *ufs_tegra, static int ufs_tegra_mphy_tx_calibration_status(struct ufs_tegra_host *ufs_tegra,
@@ -378,6 +443,11 @@ static int ufs_tegra_mphy_tx_calibration_status(struct ufs_tegra_host *ufs_tegra
mphy_update(mphy_base, MPHY_GO_BIT, mphy_update(mphy_base, MPHY_GO_BIT,
MPHY_TX_APB_TX_VENDOR0_0_T234); MPHY_TX_APB_TX_VENDOR0_0_T234);
err = mphy_go_bit_status(mphy_base, MPHY_TX_APB_TX_VENDOR0_0_T234);
if (err) {
dev_err(dev, "%s: failed\n", __func__);
goto fail;
}
/* Wait till lane calibration clear is done */ /* Wait till lane calibration clear is done */
timeout = 100U; /* Number of iterations */ timeout = 100U; /* Number of iterations */
@@ -1083,9 +1153,11 @@ static void ufs_tegra_mphy_deassert_reset(struct ufs_tegra_host *ufs_tegra)
} }
} }
static void ufs_tegra_pwr_change_clk_boost(struct ufs_tegra_host *ufs_tegra) static int ufs_tegra_pwr_change_clk_boost(struct ufs_tegra_host *ufs_tegra)
{ {
u32 reg_vendor_0; u32 reg_vendor_0;
struct device *dev = ufs_tegra->hba->dev;
int err;
if (ufs_tegra->soc->chip_id >= TEGRA234) if (ufs_tegra->soc->chip_id >= TEGRA234)
reg_vendor_0 = MPHY_RX_APB_VENDOR2_0_T234; reg_vendor_0 = MPHY_RX_APB_VENDOR2_0_T234;
@@ -1095,22 +1167,37 @@ static void ufs_tegra_pwr_change_clk_boost(struct ufs_tegra_host *ufs_tegra)
mphy_writel(ufs_tegra->mphy_l0_base, MPHY_PWR_CHANGE_CLK_BOOST, mphy_writel(ufs_tegra->mphy_l0_base, MPHY_PWR_CHANGE_CLK_BOOST,
MPHY_RX_APB_VENDOR49_0_T234); MPHY_RX_APB_VENDOR49_0_T234);
mphy_update(ufs_tegra->mphy_l0_base, MPHY_GO_BIT, reg_vendor_0); mphy_update(ufs_tegra->mphy_l0_base, MPHY_GO_BIT, reg_vendor_0);
err = mphy_go_bit_status(ufs_tegra->mphy_l0_base, reg_vendor_0);
if (err) {
dev_err(dev, "%s: Go bit clear failed for mphy0\n", __func__);
goto end;
}
if (ufs_tegra->x2config) { if (ufs_tegra->x2config) {
mphy_writel(ufs_tegra->mphy_l1_base, MPHY_PWR_CHANGE_CLK_BOOST, mphy_writel(ufs_tegra->mphy_l1_base, MPHY_PWR_CHANGE_CLK_BOOST,
MPHY_RX_APB_VENDOR49_0_T234); MPHY_RX_APB_VENDOR49_0_T234);
mphy_update(ufs_tegra->mphy_l1_base, MPHY_GO_BIT, reg_vendor_0); mphy_update(ufs_tegra->mphy_l1_base, MPHY_GO_BIT, reg_vendor_0);
err = mphy_go_bit_status(ufs_tegra->mphy_l1_base, reg_vendor_0);
if (err) {
dev_err(dev, "%s: Go bit clear failed for for mphy1\n", __func__);
goto end;
}
} }
udelay(20); udelay(20);
end:
return err;
} }
static void ufs_tegra_mphy_rx_sync_capability(struct ufs_tegra_host *ufs_tegra) static int ufs_tegra_mphy_rx_sync_capability(struct ufs_tegra_host *ufs_tegra)
{ {
u32 val_88_8b = 0; u32 val_88_8b = 0;
u32 val_94_97 = 0; u32 val_94_97 = 0;
u32 val_8c_8f = 0; u32 val_8c_8f = 0;
u32 val_98_9b = 0; u32 val_98_9b = 0;
u32 vendor2_reg, vendor3_reg; u32 vendor2_reg, vendor3_reg;
struct device *dev = ufs_tegra->hba->dev;
int err = 0;
if (ufs_tegra->soc->chip_id >= TEGRA234) { if (ufs_tegra->soc->chip_id >= TEGRA234) {
vendor2_reg = MPHY_RX_APB_VENDOR2_0_T234; vendor2_reg = MPHY_RX_APB_VENDOR2_0_T234;
@@ -1165,6 +1252,11 @@ static void ufs_tegra_mphy_rx_sync_capability(struct ufs_tegra_host *ufs_tegra)
vendor3_reg); vendor3_reg);
mphy_update(ufs_tegra->mphy_l0_base, mphy_update(ufs_tegra->mphy_l0_base,
MPHY_GO_BIT, vendor2_reg); MPHY_GO_BIT, vendor2_reg);
err = mphy_go_bit_status(ufs_tegra->mphy_l0_base, vendor2_reg);
if (err) {
dev_err(dev, "%s: Go bit clear failed for mphy0\n", __func__);
goto fail;
}
if (ufs_tegra->x2config) { if (ufs_tegra->x2config) {
mphy_writel(ufs_tegra->mphy_l1_base, val_88_8b, mphy_writel(ufs_tegra->mphy_l1_base, val_88_8b,
@@ -1181,12 +1273,20 @@ static void ufs_tegra_mphy_rx_sync_capability(struct ufs_tegra_host *ufs_tegra)
/* set gobit */ /* set gobit */
mphy_update(ufs_tegra->mphy_l1_base, mphy_update(ufs_tegra->mphy_l1_base,
MPHY_GO_BIT, vendor2_reg); MPHY_GO_BIT, vendor2_reg);
err = mphy_go_bit_status(ufs_tegra->mphy_l1_base, vendor2_reg);
if (err) {
dev_err(dev, "%s: Go bit clear failed for mphy1\n", __func__);
}
} }
fail:
return err;
} }
static void ufs_tegra_mphy_rx_advgran(struct ufs_tegra_host *ufs_tegra) static int ufs_tegra_mphy_rx_advgran(struct ufs_tegra_host *ufs_tegra)
{ {
u32 val = 0, reg_vendor_2; u32 val = 0, reg_vendor_2;
struct device *dev = ufs_tegra->hba->dev;
int err;
if (ufs_tegra->soc->chip_id >= TEGRA234) if (ufs_tegra->soc->chip_id >= TEGRA234)
reg_vendor_2 = MPHY_RX_APB_VENDOR2_0_T234; reg_vendor_2 = MPHY_RX_APB_VENDOR2_0_T234;
@@ -1204,6 +1304,11 @@ static void ufs_tegra_mphy_rx_advgran(struct ufs_tegra_host *ufs_tegra)
MPHY_RX_APB_CAPABILITY_98_9B_0); MPHY_RX_APB_CAPABILITY_98_9B_0);
mphy_update(ufs_tegra->mphy_l0_base, MPHY_GO_BIT, mphy_update(ufs_tegra->mphy_l0_base, MPHY_GO_BIT,
reg_vendor_2); reg_vendor_2);
err = mphy_go_bit_status(ufs_tegra->mphy_l0_base, reg_vendor_2);
if (err) {
dev_err(dev, "%s: Go bit clear failed for mphy0\n", __func__);
goto end;
}
if (ufs_tegra->x2config) { if (ufs_tegra->x2config) {
val = mphy_readl(ufs_tegra->mphy_l1_base, val = mphy_readl(ufs_tegra->mphy_l1_base,
@@ -1218,7 +1323,13 @@ static void ufs_tegra_mphy_rx_advgran(struct ufs_tegra_host *ufs_tegra)
MPHY_RX_APB_CAPABILITY_98_9B_0); MPHY_RX_APB_CAPABILITY_98_9B_0);
mphy_update(ufs_tegra->mphy_l1_base, MPHY_GO_BIT, mphy_update(ufs_tegra->mphy_l1_base, MPHY_GO_BIT,
reg_vendor_2); reg_vendor_2);
err = mphy_go_bit_status(ufs_tegra->mphy_l1_base, reg_vendor_2);
if (err) {
dev_err(dev, "%s: Go bit clear failed for mphy1\n", __func__);
}
} }
end:
return err;
} }
static void ufs_tegra_ufs_aux_ref_clk_enable(struct ufs_tegra_host *ufs_tegra) static void ufs_tegra_ufs_aux_ref_clk_enable(struct ufs_tegra_host *ufs_tegra)
@@ -1623,7 +1734,9 @@ static int ufs_tegra_pwr_change_notify(struct ufs_hba *hba,
* is required as per T234 IAS document * is required as per T234 IAS document
*/ */
if (ufs_tegra->soc->chip_id == TEGRA234) { if (ufs_tegra->soc->chip_id == TEGRA234) {
ufs_tegra_pwr_change_clk_boost(ufs_tegra); ret = ufs_tegra_pwr_change_clk_boost(ufs_tegra);
if (ret)
goto out;
ufshcd_dme_configure_adapt(hba, dev_req_params->gear_rx, ufshcd_dme_configure_adapt(hba, dev_req_params->gear_rx,
PA_INITIAL_ADAPT); PA_INITIAL_ADAPT);
} }
@@ -1762,7 +1875,7 @@ static int ufs_tegra_link_startup_notify(struct ufs_hba *hba,
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 */ /* Enable TX link calibration */
ufs_tegra_mphy_tx_calibration_enable(ufs_tegra); err = ufs_tegra_mphy_tx_calibration_enable(ufs_tegra);
} }
break; break;
case POST_CHANGE: case POST_CHANGE:
@@ -1836,17 +1949,30 @@ static int ufs_tegra_config_soc_data(struct ufs_tegra_host *ufs_tegra)
return 0; return 0;
} }
static void ufs_tegra_eq_timeout(struct ufs_tegra_host *ufs_tegra) static int ufs_tegra_eq_timeout(struct ufs_tegra_host *ufs_tegra)
{ {
struct device *dev = ufs_tegra->hba->dev;
int err;
mphy_writel(ufs_tegra->mphy_l0_base, MPHY_EQ_TIMEOUT, mphy_writel(ufs_tegra->mphy_l0_base, MPHY_EQ_TIMEOUT,
MPHY_RX_APB_VENDOR3B_0_T234); MPHY_RX_APB_VENDOR3B_0_T234);
mphy_update(ufs_tegra->mphy_l0_base, MPHY_GO_BIT, MPHY_RX_APB_VENDOR2_0_T234); mphy_update(ufs_tegra->mphy_l0_base, MPHY_GO_BIT, MPHY_RX_APB_VENDOR2_0_T234);
err = mphy_go_bit_status(ufs_tegra->mphy_l0_base, MPHY_RX_APB_VENDOR2_0_T234);
if (err) {
dev_err(dev, "%s: Go bit clear failed for mphy0\n", __func__);
goto end;
}
if (ufs_tegra->x2config) { if (ufs_tegra->x2config) {
mphy_writel(ufs_tegra->mphy_l1_base, MPHY_EQ_TIMEOUT, mphy_writel(ufs_tegra->mphy_l1_base, MPHY_EQ_TIMEOUT,
MPHY_RX_APB_VENDOR3B_0_T234); MPHY_RX_APB_VENDOR3B_0_T234);
mphy_update(ufs_tegra->mphy_l1_base, MPHY_GO_BIT, MPHY_RX_APB_VENDOR2_0_T234); mphy_update(ufs_tegra->mphy_l1_base, MPHY_GO_BIT, MPHY_RX_APB_VENDOR2_0_T234);
err = mphy_go_bit_status(ufs_tegra->mphy_l1_base, MPHY_RX_APB_VENDOR2_0_T234);
if (err) {
dev_err(dev, "%s: Go bit clear failed for mphy1\n", __func__);
}
} }
end:
return err;
} }
static void ufs_tegra_jtag(struct ufs_tegra_host *ufs_tegra, u32 addr, u32 val) static void ufs_tegra_jtag(struct ufs_tegra_host *ufs_tegra, u32 addr, u32 val)
{ {
@@ -2254,14 +2380,18 @@ ufs_clk_deassert:
if (tegra_sku_info.platform == TEGRA_PLATFORM_SYSTEM_FPGA) if (tegra_sku_info.platform == TEGRA_PLATFORM_SYSTEM_FPGA)
goto end; goto end;
ufs_tegra_mphy_rx_advgran(ufs_tegra); err = ufs_tegra_mphy_rx_advgran(ufs_tegra);
if (err)
goto out_disable_mphylane_clks;
aux_init: aux_init:
ufs_tegra_ufs_aux_ref_clk_disable(ufs_tegra); ufs_tegra_ufs_aux_ref_clk_disable(ufs_tegra);
ufs_tegra_aux_reset_enable(ufs_tegra); ufs_tegra_aux_reset_enable(ufs_tegra);
ufs_tegra_ufs_aux_prog(ufs_tegra); ufs_tegra_ufs_aux_prog(ufs_tegra);
ufs_tegra_set_clk_div(hba); ufs_tegra_set_clk_div(hba);
ufs_tegra_eq_timeout(ufs_tegra); err = ufs_tegra_eq_timeout(ufs_tegra);
if (err)
goto out_disable_mphylane_clks;
end: end:
if (ufs_tegra->soc->chip_id >= TEGRA234) { if (ufs_tegra->soc->chip_id >= TEGRA234) {

View File

@@ -93,7 +93,7 @@
#define MPHY_PWR_CHANGE_CLK_BOOST 0x0017 #define MPHY_PWR_CHANGE_CLK_BOOST 0x0017
#define MPHY_EQ_TIMEOUT 0x1AADB5 #define MPHY_EQ_TIMEOUT 0x1AADB5
#define MPHY_GO_BIT 1 #define MPHY_GO_BIT 1U
#define MPHY_RX_APB_CAPABILITY_88_8B_0 0x88 #define MPHY_RX_APB_CAPABILITY_88_8B_0 0x88
#define RX_HS_G1_SYNC_LENGTH_CAPABILITY(x) (((x) & 0x3f) << 24) #define RX_HS_G1_SYNC_LENGTH_CAPABILITY(x) (((x) & 0x3f) << 24)