Skip to content

Commit 744a1c2

Browse files
Richard ZhuMani-Sadhasivam
authored andcommitted
PCI: imx6: Add workaround for errata ERR051586
ERR051586: Compliance with 8GT/s Receiver Impedance ECN. The default value of GEN3_RELATED_OFF[GEN3_ZRXDC_NONCOMPL] is 1 which makes receiver non-compliant with the ZRX-DC parameter for 2.5 GT/s when operating at 8 GT/s or higher. It causes unnecessary timeout in L1. So the workaround is to set GEN3_RELATED_OFF[GEN3_ZRXDC_NONCOMPL] to 0. Add this workaround in the dw_pcie_host_ops::post_init() callback for i.MX95 platforms. Signed-off-by: Richard Zhu <[email protected]> [mani: subject and description rewording] Signed-off-by: Manivannan Sadhasivam <[email protected]> Reviewed-by: Frank Li <[email protected]> Reviewed-by: Manivannan Sadhasivam <[email protected]> Link: https://patch.msgid.link/[email protected]
1 parent ce0c43e commit 744a1c2

File tree

1 file changed

+31
-0
lines changed

1 file changed

+31
-0
lines changed

drivers/pci/controller/dwc/pci-imx6.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ enum imx_pcie_variants {
110110
*/
111111
#define IMX_PCIE_FLAG_BROKEN_SUSPEND BIT(9)
112112
#define IMX_PCIE_FLAG_HAS_LUT BIT(10)
113+
#define IMX_PCIE_FLAG_8GT_ECN_ERR051586 BIT(11)
113114

114115
#define imx_check_flag(pci, val) (pci->drvdata->flags & val)
115116

@@ -1256,6 +1257,32 @@ static void imx_pcie_host_exit(struct dw_pcie_rp *pp)
12561257
regulator_disable(imx_pcie->vpcie);
12571258
}
12581259

1260+
static void imx_pcie_host_post_init(struct dw_pcie_rp *pp)
1261+
{
1262+
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
1263+
struct imx_pcie *imx_pcie = to_imx_pcie(pci);
1264+
u32 val;
1265+
1266+
if (imx_pcie->drvdata->flags & IMX_PCIE_FLAG_8GT_ECN_ERR051586) {
1267+
/*
1268+
* ERR051586: Compliance with 8GT/s Receiver Impedance ECN
1269+
*
1270+
* The default value of GEN3_RELATED_OFF[GEN3_ZRXDC_NONCOMPL]
1271+
* is 1 which makes receiver non-compliant with the ZRX-DC
1272+
* parameter for 2.5 GT/s when operating at 8 GT/s or higher.
1273+
* It causes unnecessary timeout in L1.
1274+
*
1275+
* Workaround: Program GEN3_RELATED_OFF[GEN3_ZRXDC_NONCOMPL]
1276+
* to 0.
1277+
*/
1278+
dw_pcie_dbi_ro_wr_en(pci);
1279+
val = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF);
1280+
val &= ~GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL;
1281+
dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, val);
1282+
dw_pcie_dbi_ro_wr_dis(pci);
1283+
}
1284+
}
1285+
12591286
/*
12601287
* In old DWC implementations, PCIE_ATU_INHIBIT_PAYLOAD in iATU Ctrl2
12611288
* register is reserved, so the generic DWC implementation of sending the
@@ -1281,6 +1308,7 @@ static const struct dw_pcie_host_ops imx_pcie_host_ops = {
12811308
static const struct dw_pcie_host_ops imx_pcie_host_dw_pme_ops = {
12821309
.init = imx_pcie_host_init,
12831310
.deinit = imx_pcie_host_exit,
1311+
.post_init = imx_pcie_host_post_init,
12841312
};
12851313

12861314
static const struct dw_pcie_ops dw_pcie_ops = {
@@ -1392,6 +1420,7 @@ static int imx_add_pcie_ep(struct imx_pcie *imx_pcie,
13921420
dev_err(dev, "failed to initialize endpoint\n");
13931421
return ret;
13941422
}
1423+
imx_pcie_host_post_init(pp);
13951424

13961425
ret = dw_pcie_ep_init_registers(ep);
13971426
if (ret) {
@@ -1789,6 +1818,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
17891818
.variant = IMX95,
17901819
.flags = IMX_PCIE_FLAG_HAS_SERDES |
17911820
IMX_PCIE_FLAG_HAS_LUT |
1821+
IMX_PCIE_FLAG_8GT_ECN_ERR051586 |
17921822
IMX_PCIE_FLAG_SUPPORTS_SUSPEND,
17931823
.ltssm_off = IMX95_PE0_GEN_CTRL_3,
17941824
.ltssm_mask = IMX95_PCIE_LTSSM_EN,
@@ -1842,6 +1872,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
18421872
[IMX95_EP] = {
18431873
.variant = IMX95_EP,
18441874
.flags = IMX_PCIE_FLAG_HAS_SERDES |
1875+
IMX_PCIE_FLAG_8GT_ECN_ERR051586 |
18451876
IMX_PCIE_FLAG_SUPPORT_64BIT,
18461877
.ltssm_off = IMX95_PE0_GEN_CTRL_3,
18471878
.ltssm_mask = IMX95_PCIE_LTSSM_EN,

0 commit comments

Comments
 (0)