diff options
author | Richard Zhu <hongxing.zhu@nxp.com> | 2020-05-19 11:49:32 +0800 |
---|---|---|
committer | Richard Zhu <hongxing.zhu@nxp.com> | 2020-06-17 16:16:05 +0800 |
commit | eb9fdb1d10c10dc4d4bbe9bc6fc060afe1485989 (patch) | |
tree | a06ebbc4db0148dd1f8c2b85892b0418c2ea6285 /drivers/pci/controller/dwc/pci-imx6.c | |
parent | 1a418446c32d897aa4695bfe44ad4947ed54513a (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>
Diffstat (limited to 'drivers/pci/controller/dwc/pci-imx6.c')
-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 8a0c5c760108..852c4bf949a0 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -1134,6 +1134,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 void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) { struct dw_pcie *pci = imx6_pcie->pci; @@ -1213,25 +1240,13 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) imx8_pcie_wait_for_phy_pll_lock(imx6_pcie); - 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: case IMX8MP_EP: @@ -1279,6 +1294,14 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) udelay(10); imx8_pcie_wait_for_phy_pll_lock(imx6_pcie); + + 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: case IMX7D_EP: @@ -2760,7 +2783,8 @@ static const struct imx6_pcie_drvdata drvdata[] = { [IMX8MP] = { .variant = IMX8MP, .mode = DW_PCIE_RC_TYPE, - .flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND, + .flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND | + IMX6_PCIE_FLAG_SUPPORTS_L1SS, }, [IMX8QXP_EP] = { .variant = IMX8QXP_EP, |