diff options
author | Richard Zhu <hongxing.zhu@nxp.com> | 2020-05-19 11:49:32 +0800 |
---|---|---|
committer | Max Krummenacher <max.krummenacher@toradex.com> | 2020-11-26 13:51:58 +0000 |
commit | e2e303b77b3f714687928e27f7a26a31f68a9b58 (patch) | |
tree | 1aa4dc6e5b64aee6e55e8105c3261baba2647d2c | |
parent | fbd3db7f9ea1b2900e12d19bf8ab8db6f3bce121 (diff) |
MLK-24170 PCI: imx: configure the l1 latency for imx8m pcie rc
Configure the L1 latency of iMX8M's RC to less than 64us, otherwise,
the L1/L1SS wouldn't be enabled by ASPM.
Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Reviewed-by: Fugang Duan <fugang.duan@nxp.com>
(cherry picked from commit eb9fdb1d10c10dc4d4bbe9bc6fc060afe1485989)
-rw-r--r-- | drivers/pci/controller/dwc/pci-imx6.c | 54 |
1 files changed, 39 insertions, 15 deletions
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index f37b805fd730..f7fcc1f6c300 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -1150,6 +1150,33 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie) } } +static void imx6_pcie_set_l1_latency(struct imx6_pcie *imx6_pcie) +{ + u32 val; + struct dw_pcie *pci = imx6_pcie->pci; + + switch (imx6_pcie->drvdata->variant) { + case IMX8MQ: + case IMX8MM: + case IMX8MP: + /* + * Configure the L1 latency of rc to less than 64us + * Otherwise, the L1/L1SUB wouldn't be enable by ASPM. + */ + dw_pcie_dbi_ro_wr_en(pci); + val = readl(pci->dbi_base + SZ_1M + + IMX8MQ_PCIE_LINK_CAP_REG_OFFSET); + val &= ~PCI_EXP_LNKCAP_L1EL; + val |= IMX8MQ_PCIE_LINK_CAP_L1EL_64US; + writel(val, pci->dbi_base + SZ_1M + + IMX8MQ_PCIE_LINK_CAP_REG_OFFSET); + dw_pcie_dbi_ro_wr_dis(pci); + break; + default: + break; + } +} + static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) { struct dw_pcie *pci = imx6_pcie->pci; @@ -1252,25 +1279,13 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN, IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN); - if (imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_SUPPORTS_L1SS) { + if (imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_SUPPORTS_L1SS) /* * Configure the CLK_REQ# high, let the L1SS * automatically controlled by HW later. */ reset_control_deassert(imx6_pcie->clkreq_reset); - /* - * Configure the L1 latency of rc to less than 64us - * Otherwise, the L1/L1SUB wouldn't be enable by ASPM. - */ - dw_pcie_dbi_ro_wr_en(pci); - val = readl(pci->dbi_base + SZ_1M + - IMX8MQ_PCIE_LINK_CAP_REG_OFFSET); - val &= ~PCI_EXP_LNKCAP_L1EL; - val |= IMX8MQ_PCIE_LINK_CAP_L1EL_64US; - writel(val, pci->dbi_base + SZ_1M + - IMX8MQ_PCIE_LINK_CAP_REG_OFFSET); - dw_pcie_dbi_ro_wr_dis(pci); - } + imx6_pcie_set_l1_latency(imx6_pcie); break; case IMX8MP: if (phy_power_on(imx6_pcie->phy) < 0) @@ -1318,6 +1333,14 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) if(imx8_pcie_wait_for_phy_pll_lock(imx6_pcie) != 0) goto err_pll; + + if (imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_SUPPORTS_L1SS) + /* + * Configure the CLK_REQ# high, let the L1SS + * automatically controlled by HW later. + */ + reset_control_deassert(imx6_pcie->clkreq_reset); + imx6_pcie_set_l1_latency(imx6_pcie); break; case IMX7D: reset_control_deassert(imx6_pcie->pciephy_reset); @@ -3110,7 +3133,8 @@ static const struct imx6_pcie_drvdata drvdata[] = { }, [IMX8MP] = { .variant = IMX8MP, - .flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND, + .flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND | + IMX6_PCIE_FLAG_SUPPORTS_L1SS, }, }; |