mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-10 17:09:04 -04:00
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 <hongxing.zhu@nxp.com> [mani: subject and description rewording] Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Reviewed-by: Frank Li <Frank.Li@nxp.com> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Link: https://patch.msgid.link/20250416081314.3929794-6-hongxing.zhu@nxp.com
This commit is contained in:
committed by
Manivannan Sadhasivam
parent
ce0c43e855
commit
744a1c20ce
@@ -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)
|
||||
|
||||
@@ -1256,6 +1257,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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* In old DWC implementations, PCIE_ATU_INHIBIT_PAYLOAD in iATU Ctrl2
|
||||
* 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 = {
|
||||
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 = {
|
||||
@@ -1392,6 +1420,7 @@ static int imx_add_pcie_ep(struct imx_pcie *imx_pcie,
|
||||
dev_err(dev, "failed to initialize endpoint\n");
|
||||
return ret;
|
||||
}
|
||||
imx_pcie_host_post_init(pp);
|
||||
|
||||
ret = dw_pcie_ep_init_registers(ep);
|
||||
if (ret) {
|
||||
@@ -1789,6 +1818,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,
|
||||
@@ -1842,6 +1872,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,
|
||||
|
||||
Reference in New Issue
Block a user