From e2e303b77b3f714687928e27f7a26a31f68a9b58 Mon Sep 17 00:00:00 2001 From: Richard Zhu Date: Tue, 19 May 2020 11:49:32 +0800 Subject: 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 Reviewed-by: Fugang Duan (cherry picked from commit eb9fdb1d10c10dc4d4bbe9bc6fc060afe1485989) --- drivers/pci/controller/dwc/pci-imx6.c | 54 +++++++++++++++++++++++++---------- 1 file 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, }, }; -- cgit v1.2.3