Message ID | 20250328030213.1650990-5-hongxing.zhu@nxp.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | Add some enhancements for i.MX95 PCIe | expand |
On Fri, Mar 28, 2025 at 11:02:11AM +0800, Richard Zhu wrote: > 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. > > Workaround: Program GEN3_RELATED_OFF[GEN3_ZRXDC_NONCOMPL] to 0. > > Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com> > --- Reviewed-by: Frank Li <Frank.Li@nxp.com> > drivers/pci/controller/dwc/pci-imx6.c | 31 +++++++++++++++++++++++++++ > 1 file changed, 31 insertions(+) > > diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c > index 82402e52eff2..35194b543551 100644 > --- a/drivers/pci/controller/dwc/pci-imx6.c > +++ b/drivers/pci/controller/dwc/pci-imx6.c > @@ -110,6 +110,7 @@ enum imx_pcie_variants { > */ > #define IMX_PCIE_FLAG_BROKEN_SUSPEND BIT(9) > #define IMX_PCIE_FLAG_HAS_LUT BIT(10) > +#define IMX_PCIE_FLAG_8GT_ECN_ERR051586 BIT(11) > > #define imx_check_flag(pci, val) (pci->drvdata->flags & val) > > @@ -1263,6 +1264,32 @@ static void imx_pcie_host_exit(struct dw_pcie_rp *pp) > regulator_disable(imx_pcie->vpcie); > } > > +static void imx_pcie_host_post_init(struct dw_pcie_rp *pp) > +{ > + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); > + struct imx_pcie *imx_pcie = to_imx_pcie(pci); > + u32 val; > + > + if (imx_pcie->drvdata->flags & IMX_PCIE_FLAG_8GT_ECN_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. > + * > + * Workaround: Program GEN3_RELATED_OFF[GEN3_ZRXDC_NONCOMPL] > + * to 0. > + */ > + dw_pcie_dbi_ro_wr_en(pci); > + val = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF); > + val &= ~GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL; > + dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, val); > + dw_pcie_dbi_ro_wr_dis(pci); > + } > +} > + > static u64 imx_pcie_cpu_addr_fixup(struct dw_pcie *pcie, u64 cpu_addr) > { > struct imx_pcie *imx_pcie = to_imx_pcie(pcie); > @@ -1304,6 +1331,7 @@ static const struct dw_pcie_host_ops imx_pcie_host_ops = { > static const struct dw_pcie_host_ops imx_pcie_host_dw_pme_ops = { > .init = imx_pcie_host_init, > .deinit = imx_pcie_host_exit, > + .post_init = imx_pcie_host_post_init, > }; > > static const struct dw_pcie_ops dw_pcie_ops = { > @@ -1403,6 +1431,7 @@ static int imx_add_pcie_ep(struct imx_pcie *imx_pcie, > struct device *dev = pci->dev; > > imx_pcie_host_init(pp); > + imx_pcie_host_post_init(pp); > ep = &pci->ep; > ep->ops = &pcie_ep_ops; > > @@ -1812,6 +1841,7 @@ static const struct imx_pcie_drvdata drvdata[] = { > .variant = IMX95, > .flags = IMX_PCIE_FLAG_HAS_SERDES | > IMX_PCIE_FLAG_HAS_LUT | > + IMX_PCIE_FLAG_8GT_ECN_ERR051586 | > IMX_PCIE_FLAG_SUPPORTS_SUSPEND, > .ltssm_off = IMX95_PE0_GEN_CTRL_3, > .ltssm_mask = IMX95_PCIE_LTSSM_EN, > @@ -1865,6 +1895,7 @@ static const struct imx_pcie_drvdata drvdata[] = { > [IMX95_EP] = { > .variant = IMX95_EP, > .flags = IMX_PCIE_FLAG_HAS_SERDES | > + IMX_PCIE_FLAG_8GT_ECN_ERR051586 | > IMX_PCIE_FLAG_SUPPORT_64BIT, > .ltssm_off = IMX95_PE0_GEN_CTRL_3, > .ltssm_mask = IMX95_PCIE_LTSSM_EN, > -- > 2.37.1 >
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 82402e52eff2..35194b543551 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -110,6 +110,7 @@ enum imx_pcie_variants { */ #define IMX_PCIE_FLAG_BROKEN_SUSPEND BIT(9) #define IMX_PCIE_FLAG_HAS_LUT BIT(10) +#define IMX_PCIE_FLAG_8GT_ECN_ERR051586 BIT(11) #define imx_check_flag(pci, val) (pci->drvdata->flags & val) @@ -1263,6 +1264,32 @@ static void imx_pcie_host_exit(struct dw_pcie_rp *pp) regulator_disable(imx_pcie->vpcie); } +static void imx_pcie_host_post_init(struct dw_pcie_rp *pp) +{ + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); + struct imx_pcie *imx_pcie = to_imx_pcie(pci); + u32 val; + + if (imx_pcie->drvdata->flags & IMX_PCIE_FLAG_8GT_ECN_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. + * + * Workaround: Program GEN3_RELATED_OFF[GEN3_ZRXDC_NONCOMPL] + * to 0. + */ + dw_pcie_dbi_ro_wr_en(pci); + val = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF); + val &= ~GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL; + dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, val); + dw_pcie_dbi_ro_wr_dis(pci); + } +} + static u64 imx_pcie_cpu_addr_fixup(struct dw_pcie *pcie, u64 cpu_addr) { struct imx_pcie *imx_pcie = to_imx_pcie(pcie); @@ -1304,6 +1331,7 @@ static const struct dw_pcie_host_ops imx_pcie_host_ops = { static const struct dw_pcie_host_ops imx_pcie_host_dw_pme_ops = { .init = imx_pcie_host_init, .deinit = imx_pcie_host_exit, + .post_init = imx_pcie_host_post_init, }; static const struct dw_pcie_ops dw_pcie_ops = { @@ -1403,6 +1431,7 @@ static int imx_add_pcie_ep(struct imx_pcie *imx_pcie, struct device *dev = pci->dev; imx_pcie_host_init(pp); + imx_pcie_host_post_init(pp); ep = &pci->ep; ep->ops = &pcie_ep_ops; @@ -1812,6 +1841,7 @@ static const struct imx_pcie_drvdata drvdata[] = { .variant = IMX95, .flags = IMX_PCIE_FLAG_HAS_SERDES | IMX_PCIE_FLAG_HAS_LUT | + IMX_PCIE_FLAG_8GT_ECN_ERR051586 | IMX_PCIE_FLAG_SUPPORTS_SUSPEND, .ltssm_off = IMX95_PE0_GEN_CTRL_3, .ltssm_mask = IMX95_PCIE_LTSSM_EN, @@ -1865,6 +1895,7 @@ static const struct imx_pcie_drvdata drvdata[] = { [IMX95_EP] = { .variant = IMX95_EP, .flags = IMX_PCIE_FLAG_HAS_SERDES | + IMX_PCIE_FLAG_8GT_ECN_ERR051586 | IMX_PCIE_FLAG_SUPPORT_64BIT, .ltssm_off = IMX95_PE0_GEN_CTRL_3, .ltssm_mask = IMX95_PCIE_LTSSM_EN,
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. Workaround: Program GEN3_RELATED_OFF[GEN3_ZRXDC_NONCOMPL] to 0. Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com> --- drivers/pci/controller/dwc/pci-imx6.c | 31 +++++++++++++++++++++++++++ 1 file changed, 31 insertions(+)