Message ID | 20250324062647.1891896-5-hongxing.zhu@nxp.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Krzysztof WilczyĆski |
Headers | show |
Series | Add some enhancements for i.MX95 PCIe | expand |
On Mon, Mar 24, 2025 at 02:26:46PM +0800, Richard Zhu wrote: > Workaround for 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 | 29 +++++++++++++++++++++++++++ > 1 file changed, 29 insertions(+) > > diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c > index 52aa8bd66cde..dda3eed99bb8 100644 > --- a/drivers/pci/controller/dwc/pci-imx6.c > +++ b/drivers/pci/controller/dwc/pci-imx6.c > @@ -131,6 +131,7 @@ struct imx_pcie_drvdata { > int (*init_phy)(struct imx_pcie *pcie); > int (*enable_ref_clk)(struct imx_pcie *pcie, bool enable); > int (*core_reset)(struct imx_pcie *pcie, bool assert); > + void (*post_config)(struct imx_pcie *pcie); > const struct dw_pcie_host_ops *ops; > }; > > @@ -1158,6 +1159,29 @@ static void imx_pcie_disable_device(struct pci_host_bridge *bridge, > imx_pcie_remove_lut(imx_pcie, pci_dev_id(pdev)); > } > > +static void imx95_pcie_post_config(struct imx_pcie *imx_pcie) There are already have post_init in dwc dw_pcie_host_ops struct dw_pcie_host_ops { int (*init)(struct dw_pcie_rp *pp); void (*deinit)(struct dw_pcie_rp *pp); void (*post_init)(struct dw_pcie_rp *pp); int (*msi_init)(struct dw_pcie_rp *pp); void (*pme_turn_off)(struct dw_pcie_rp *pp); }; Can you use it directly? Frank > +{ > + u32 val; > + struct dw_pcie *pci = imx_pcie->pci; struct dw_pcie *pci = imx_pcie->pci; u32 val; > + > + /* > + * Workaround for 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 int imx_pcie_host_init(struct dw_pcie_rp *pp) > { > struct dw_pcie *pci = to_dw_pcie_from_pp(pp); > @@ -1222,6 +1246,9 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp) > > imx_setup_phy_mpll(imx_pcie); > > + if (imx_pcie->drvdata->post_config) > + imx_pcie->drvdata->post_config(imx_pcie); > + > return 0; > > err_phy_off: > @@ -1808,6 +1835,7 @@ static const struct imx_pcie_drvdata drvdata[] = { > .mode_mask[0] = IMX95_PCIE_DEVICE_TYPE, > .core_reset = imx95_pcie_core_reset, > .init_phy = imx95_pcie_init_phy, > + .post_config = imx95_pcie_post_config, > }, > [IMX8MQ_EP] = { > .variant = IMX8MQ_EP, > @@ -1863,6 +1891,7 @@ static const struct imx_pcie_drvdata drvdata[] = { > .core_reset = imx95_pcie_core_reset, > .epc_features = &imx95_pcie_epc_features, > .mode = DW_PCIE_EP_TYPE, > + .post_config = imx95_pcie_post_config, > }, > }; > > -- > 2.37.1 >
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 52aa8bd66cde..dda3eed99bb8 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -131,6 +131,7 @@ struct imx_pcie_drvdata { int (*init_phy)(struct imx_pcie *pcie); int (*enable_ref_clk)(struct imx_pcie *pcie, bool enable); int (*core_reset)(struct imx_pcie *pcie, bool assert); + void (*post_config)(struct imx_pcie *pcie); const struct dw_pcie_host_ops *ops; }; @@ -1158,6 +1159,29 @@ static void imx_pcie_disable_device(struct pci_host_bridge *bridge, imx_pcie_remove_lut(imx_pcie, pci_dev_id(pdev)); } +static void imx95_pcie_post_config(struct imx_pcie *imx_pcie) +{ + u32 val; + struct dw_pcie *pci = imx_pcie->pci; + + /* + * Workaround for 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 int imx_pcie_host_init(struct dw_pcie_rp *pp) { struct dw_pcie *pci = to_dw_pcie_from_pp(pp); @@ -1222,6 +1246,9 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp) imx_setup_phy_mpll(imx_pcie); + if (imx_pcie->drvdata->post_config) + imx_pcie->drvdata->post_config(imx_pcie); + return 0; err_phy_off: @@ -1808,6 +1835,7 @@ static const struct imx_pcie_drvdata drvdata[] = { .mode_mask[0] = IMX95_PCIE_DEVICE_TYPE, .core_reset = imx95_pcie_core_reset, .init_phy = imx95_pcie_init_phy, + .post_config = imx95_pcie_post_config, }, [IMX8MQ_EP] = { .variant = IMX8MQ_EP, @@ -1863,6 +1891,7 @@ static const struct imx_pcie_drvdata drvdata[] = { .core_reset = imx95_pcie_core_reset, .epc_features = &imx95_pcie_epc_features, .mode = DW_PCIE_EP_TYPE, + .post_config = imx95_pcie_post_config, }, };
Workaround for 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 | 29 +++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)