Commit 14ced7e3 authored by Bjorn Andersson's avatar Bjorn Andersson Committed by Kishon Vijay Abraham I

phy: qcom-qmp: Correct ready status, again

Despite extensive testing of commit 885bd765 ("phy: qcom-qmp: Correct
READY_STATUS poll break condition") I failed to conclude that the
PHYSTATUS bit of the PCS_STATUS register used in PCIe and USB3 falls as
the PHY gets ready. Similar to the prior bug with UFS the code will
generally get past the check before the transition and thereby
"succeed".

Correct the name of the register used PCIe and USB3 PHYs, replace
mask_pcs_ready with a constant expression depending on the type of the
PHY and check for the appropriate ready state.

Cc: stable@vger.kernel.org
Cc: Vivek Gautam <vivek.gautam@codeaurora.org>
Cc: Evan Green <evgreen@chromium.org>
Cc: Niklas Cassel <niklas.cassel@linaro.org>
Reported-by: default avatarMarc Gonzalez <marc.w.gonzalez@free.fr>
Fixes: 885bd765 ("phy: qcom-qmp: Correct READY_STATUS poll break condition")
Signed-off-by: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
Tested-by: default avatarMarc Gonzalez <marc.w.gonzalez@free.fr>
Signed-off-by: default avatarKishon Vijay Abraham I <kishon@ti.com>
parent be0345b2
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
#define PLL_READY_GATE_EN BIT(3) #define PLL_READY_GATE_EN BIT(3)
/* QPHY_PCS_STATUS bit */ /* QPHY_PCS_STATUS bit */
#define PHYSTATUS BIT(6) #define PHYSTATUS BIT(6)
/* QPHY_COM_PCS_READY_STATUS bit */ /* QPHY_PCS_READY_STATUS & QPHY_COM_PCS_READY_STATUS bit */
#define PCS_READY BIT(0) #define PCS_READY BIT(0)
/* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */ /* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */
...@@ -115,6 +115,7 @@ enum qphy_reg_layout { ...@@ -115,6 +115,7 @@ enum qphy_reg_layout {
QPHY_SW_RESET, QPHY_SW_RESET,
QPHY_START_CTRL, QPHY_START_CTRL,
QPHY_PCS_READY_STATUS, QPHY_PCS_READY_STATUS,
QPHY_PCS_STATUS,
QPHY_PCS_AUTONOMOUS_MODE_CTRL, QPHY_PCS_AUTONOMOUS_MODE_CTRL,
QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR, QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR,
QPHY_PCS_LFPS_RXTERM_IRQ_STATUS, QPHY_PCS_LFPS_RXTERM_IRQ_STATUS,
...@@ -133,7 +134,7 @@ static const unsigned int pciephy_regs_layout[] = { ...@@ -133,7 +134,7 @@ static const unsigned int pciephy_regs_layout[] = {
[QPHY_FLL_MAN_CODE] = 0xd4, [QPHY_FLL_MAN_CODE] = 0xd4,
[QPHY_SW_RESET] = 0x00, [QPHY_SW_RESET] = 0x00,
[QPHY_START_CTRL] = 0x08, [QPHY_START_CTRL] = 0x08,
[QPHY_PCS_READY_STATUS] = 0x174, [QPHY_PCS_STATUS] = 0x174,
}; };
static const unsigned int usb3phy_regs_layout[] = { static const unsigned int usb3phy_regs_layout[] = {
...@@ -144,7 +145,7 @@ static const unsigned int usb3phy_regs_layout[] = { ...@@ -144,7 +145,7 @@ static const unsigned int usb3phy_regs_layout[] = {
[QPHY_FLL_MAN_CODE] = 0xd0, [QPHY_FLL_MAN_CODE] = 0xd0,
[QPHY_SW_RESET] = 0x00, [QPHY_SW_RESET] = 0x00,
[QPHY_START_CTRL] = 0x08, [QPHY_START_CTRL] = 0x08,
[QPHY_PCS_READY_STATUS] = 0x17c, [QPHY_PCS_STATUS] = 0x17c,
[QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x0d4, [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x0d4,
[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0x0d8, [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0x0d8,
[QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x178, [QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x178,
...@@ -153,7 +154,7 @@ static const unsigned int usb3phy_regs_layout[] = { ...@@ -153,7 +154,7 @@ static const unsigned int usb3phy_regs_layout[] = {
static const unsigned int qmp_v3_usb3phy_regs_layout[] = { static const unsigned int qmp_v3_usb3phy_regs_layout[] = {
[QPHY_SW_RESET] = 0x00, [QPHY_SW_RESET] = 0x00,
[QPHY_START_CTRL] = 0x08, [QPHY_START_CTRL] = 0x08,
[QPHY_PCS_READY_STATUS] = 0x174, [QPHY_PCS_STATUS] = 0x174,
[QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x0d8, [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x0d8,
[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0x0dc, [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0x0dc,
[QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x170, [QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x170,
...@@ -911,7 +912,6 @@ struct qmp_phy_cfg { ...@@ -911,7 +912,6 @@ struct qmp_phy_cfg {
unsigned int start_ctrl; unsigned int start_ctrl;
unsigned int pwrdn_ctrl; unsigned int pwrdn_ctrl;
unsigned int mask_pcs_ready;
unsigned int mask_com_pcs_ready; unsigned int mask_com_pcs_ready;
/* true, if PHY has a separate PHY_COM control block */ /* true, if PHY has a separate PHY_COM control block */
...@@ -1074,7 +1074,6 @@ static const struct qmp_phy_cfg msm8996_pciephy_cfg = { ...@@ -1074,7 +1074,6 @@ static const struct qmp_phy_cfg msm8996_pciephy_cfg = {
.start_ctrl = PCS_START | PLL_READY_GATE_EN, .start_ctrl = PCS_START | PLL_READY_GATE_EN,
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
.mask_pcs_ready = PHYSTATUS,
.mask_com_pcs_ready = PCS_READY, .mask_com_pcs_ready = PCS_READY,
.has_phy_com_ctrl = true, .has_phy_com_ctrl = true,
...@@ -1106,7 +1105,6 @@ static const struct qmp_phy_cfg msm8996_usb3phy_cfg = { ...@@ -1106,7 +1105,6 @@ static const struct qmp_phy_cfg msm8996_usb3phy_cfg = {
.start_ctrl = SERDES_START | PCS_START, .start_ctrl = SERDES_START | PCS_START,
.pwrdn_ctrl = SW_PWRDN, .pwrdn_ctrl = SW_PWRDN,
.mask_pcs_ready = PHYSTATUS,
}; };
/* list of resets */ /* list of resets */
...@@ -1136,7 +1134,6 @@ static const struct qmp_phy_cfg ipq8074_pciephy_cfg = { ...@@ -1136,7 +1134,6 @@ static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
.start_ctrl = SERDES_START | PCS_START, .start_ctrl = SERDES_START | PCS_START,
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
.mask_pcs_ready = PHYSTATUS,
.has_phy_com_ctrl = false, .has_phy_com_ctrl = false,
.has_lane_rst = false, .has_lane_rst = false,
...@@ -1167,7 +1164,6 @@ static const struct qmp_phy_cfg qmp_v3_usb3phy_cfg = { ...@@ -1167,7 +1164,6 @@ static const struct qmp_phy_cfg qmp_v3_usb3phy_cfg = {
.start_ctrl = SERDES_START | PCS_START, .start_ctrl = SERDES_START | PCS_START,
.pwrdn_ctrl = SW_PWRDN, .pwrdn_ctrl = SW_PWRDN,
.mask_pcs_ready = PHYSTATUS,
.has_pwrdn_delay = true, .has_pwrdn_delay = true,
.pwrdn_delay_min = POWER_DOWN_DELAY_US_MIN, .pwrdn_delay_min = POWER_DOWN_DELAY_US_MIN,
...@@ -1199,7 +1195,6 @@ static const struct qmp_phy_cfg qmp_v3_usb3_uniphy_cfg = { ...@@ -1199,7 +1195,6 @@ static const struct qmp_phy_cfg qmp_v3_usb3_uniphy_cfg = {
.start_ctrl = SERDES_START | PCS_START, .start_ctrl = SERDES_START | PCS_START,
.pwrdn_ctrl = SW_PWRDN, .pwrdn_ctrl = SW_PWRDN,
.mask_pcs_ready = PHYSTATUS,
.has_pwrdn_delay = true, .has_pwrdn_delay = true,
.pwrdn_delay_min = POWER_DOWN_DELAY_US_MIN, .pwrdn_delay_min = POWER_DOWN_DELAY_US_MIN,
...@@ -1226,7 +1221,6 @@ static const struct qmp_phy_cfg sdm845_ufsphy_cfg = { ...@@ -1226,7 +1221,6 @@ static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
.start_ctrl = SERDES_START, .start_ctrl = SERDES_START,
.pwrdn_ctrl = SW_PWRDN, .pwrdn_ctrl = SW_PWRDN,
.mask_pcs_ready = PCS_READY,
.is_dual_lane_phy = true, .is_dual_lane_phy = true,
.no_pcs_sw_reset = true, .no_pcs_sw_reset = true,
...@@ -1254,7 +1248,6 @@ static const struct qmp_phy_cfg msm8998_pciephy_cfg = { ...@@ -1254,7 +1248,6 @@ static const struct qmp_phy_cfg msm8998_pciephy_cfg = {
.start_ctrl = SERDES_START | PCS_START, .start_ctrl = SERDES_START | PCS_START,
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
.mask_pcs_ready = PHYSTATUS,
}; };
static const struct qmp_phy_cfg msm8998_usb3phy_cfg = { static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
...@@ -1279,7 +1272,6 @@ static const struct qmp_phy_cfg msm8998_usb3phy_cfg = { ...@@ -1279,7 +1272,6 @@ static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
.start_ctrl = SERDES_START | PCS_START, .start_ctrl = SERDES_START | PCS_START,
.pwrdn_ctrl = SW_PWRDN, .pwrdn_ctrl = SW_PWRDN,
.mask_pcs_ready = PHYSTATUS,
.is_dual_lane_phy = true, .is_dual_lane_phy = true,
}; };
...@@ -1457,7 +1449,7 @@ static int qcom_qmp_phy_enable(struct phy *phy) ...@@ -1457,7 +1449,7 @@ static int qcom_qmp_phy_enable(struct phy *phy)
void __iomem *pcs = qphy->pcs; void __iomem *pcs = qphy->pcs;
void __iomem *dp_com = qmp->dp_com; void __iomem *dp_com = qmp->dp_com;
void __iomem *status; void __iomem *status;
unsigned int mask, val; unsigned int mask, val, ready;
int ret; int ret;
dev_vdbg(qmp->dev, "Initializing QMP phy\n"); dev_vdbg(qmp->dev, "Initializing QMP phy\n");
...@@ -1545,10 +1537,17 @@ static int qcom_qmp_phy_enable(struct phy *phy) ...@@ -1545,10 +1537,17 @@ static int qcom_qmp_phy_enable(struct phy *phy)
/* start SerDes and Phy-Coding-Sublayer */ /* start SerDes and Phy-Coding-Sublayer */
qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl); qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
if (cfg->type == PHY_TYPE_UFS) {
status = pcs + cfg->regs[QPHY_PCS_READY_STATUS]; status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
mask = cfg->mask_pcs_ready; mask = PCS_READY;
ready = PCS_READY;
} else {
status = pcs + cfg->regs[QPHY_PCS_STATUS];
mask = PHYSTATUS;
ready = 0;
}
ret = readl_poll_timeout(status, val, val & mask, 10, ret = readl_poll_timeout(status, val, (val & mask) == ready, 10,
PHY_INIT_COMPLETE_TIMEOUT); PHY_INIT_COMPLETE_TIMEOUT);
if (ret) { if (ret) {
dev_err(qmp->dev, "phy initialization timed-out\n"); dev_err(qmp->dev, "phy initialization timed-out\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment