diff options
author | Richard Zhu <hongxing.zhu@nxp.com> | 2018-08-30 12:57:42 +0800 |
---|---|---|
committer | Richard Zhu <hongxing.zhu@nxp.com> | 2018-09-03 12:42:08 +0800 |
commit | b57268bcb9f049b4f8cee717d975b58fd81d50a3 (patch) | |
tree | ceffafcae5de1bbc305df565ae204723f7dbba48 /drivers/pci/host/pci-imx6.c | |
parent | d47cc975a606019f1200bbb865d60e64f8ad850b (diff) |
MLK-19412 PCI: imx: keep clkreq# active in compliance tests
- Do not de-assert the clkreq# when compliance tests mode
is enabled, make sure that the ref_clk is turned on.
- Correct the PLL lock bit check point.
- Adjust the TRSV PHY registers to pass the compliance tests.
Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
(cherry picked from commit 5b0a24521116b4a2be8e1592acf9d3eca5600f97)
Diffstat (limited to 'drivers/pci/host/pci-imx6.c')
-rw-r--r-- | drivers/pci/host/pci-imx6.c | 85 |
1 files changed, 58 insertions, 27 deletions
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c index 822a438a9068..c3cc315473ce 100644 --- a/drivers/pci/host/pci-imx6.c +++ b/drivers/pci/host/pci-imx6.c @@ -213,6 +213,10 @@ struct imx_pcie { #define PCIE_PHY_CMN_REG64_AUX_RX_TX_TERM 0x8C #define PCIE_PHY_CMN_REG75 0x1D4 #define PCIE_PHY_CMN_REG75_PLL_DONE 0x3 +#define PCIE_PHY_TRSV_REG5 0x414 +#define PCIE_PHY_TRSV_REG5_GEN1_DEEMP 0x2D +#define PCIE_PHY_TRSV_REG6 0x418 +#define PCIE_PHY_TRSV_REG6_GEN2_DEEMP 0xF /* iMX8 HSIO registers */ #define IMX8QM_LPCG_PHYX2_OFFSET 0x00000 @@ -563,9 +567,10 @@ static void imx_pcie_assert_core_reset(struct imx_pcie *imx_pcie) static int imx_pcie_enable_ref_clk(struct imx_pcie *imx_pcie) { + u32 val; + int ret = 0; struct pcie_port *pp = &imx_pcie->pp; struct device *dev = pp->dev; - int ret = 0; switch (imx_pcie->variant) { case IMX6SX: @@ -594,8 +599,25 @@ static int imx_pcie_enable_ref_clk(struct imx_pcie *imx_pcie) IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16); break; case IMX7D: + break; case IMX8MQ: case IMX8MM: + /* + * Set the over ride low and enabled + * make sure that REF_CLK is turned on. + */ + if (imx_pcie->ctrl_id == 0) + val = IOMUXC_GPR14; + else + val = IOMUXC_GPR16; + + regmap_update_bits(imx_pcie->iomuxc_gpr, val, + IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE, + 0); + regmap_update_bits(imx_pcie->iomuxc_gpr, val, + IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN, + IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN); + break; case IMX8QXP: case IMX8QM: @@ -625,8 +647,8 @@ static int pci_imx_phy_pll_locked(struct imx_pcie *imx_pcie) struct device *dev = pp->dev; if (imx_pcie->variant == IMX8MM) { - tmp = readl(imx_pcie->phy_base + PCIE_PHY_CMN_REG75); for (i = 0; i < 100; i++) { + tmp = readl(imx_pcie->phy_base + PCIE_PHY_CMN_REG75); if (tmp == PCIE_PHY_CMN_REG75_PLL_DONE) break; udelay(10); @@ -880,10 +902,6 @@ static int imx_pcie_deassert_core_reset(struct imx_pcie *imx_pcie) break; } - regmap_update_bits(imx_pcie->reg_src, val, - IMX8MQ_PCIE_CTRL_APPS_EN | - IMX8MQ_PCIEPHY_DOMAIN_EN, - IMX8MQ_PCIEPHY_DOMAIN_EN); /* * Configure the CLK_REQ# high, let the L1SS * automatically controlled by HW. @@ -891,21 +909,10 @@ static int imx_pcie_deassert_core_reset(struct imx_pcie *imx_pcie) regmap_update_bits(imx_pcie->reg_src, val, IMX8MQ_PCIE_CTRL_APPS_CLK_REQ, IMX8MQ_PCIE_CTRL_APPS_CLK_REQ); - /* - * Set the over ride low and enabled - * make sure that REF_CLK is turned on. - */ - if (imx_pcie->ctrl_id == 0) - val = IOMUXC_GPR14; - else - val = IOMUXC_GPR16; - - regmap_update_bits(imx_pcie->iomuxc_gpr, val, - IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE, - 0); - regmap_update_bits(imx_pcie->iomuxc_gpr, val, - IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN, - IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN); + regmap_update_bits(imx_pcie->reg_src, val, + IMX8MQ_PCIE_CTRL_APPS_EN | + IMX8MQ_PCIEPHY_DOMAIN_EN, + IMX8MQ_PCIEPHY_DOMAIN_EN); if (dw_pcie_readl_rc(pp, PCIE_MISC_CTRL) == 0) dw_pcie_writel_rc(pp, PCIE_MISC_CTRL, @@ -1247,6 +1254,16 @@ static void imx_pcie_init_phy(struct imx_pcie *imx_pcie) writel(val, base + IMX8MQ_ANA_PLLOUT_REG); } } + /* + * In order to pass the compliance tests. + * Configure the TRSV regiser of iMX8MM PCIe PHY. + */ + if (imx_pcie->variant == IMX8MM) { + writel(PCIE_PHY_TRSV_REG5_GEN1_DEEMP, + imx_pcie->phy_base + PCIE_PHY_TRSV_REG5); + writel(PCIE_PHY_TRSV_REG6_GEN2_DEEMP, + imx_pcie->phy_base + PCIE_PHY_TRSV_REG6); + } } else if (imx_pcie->variant == IMX7D) { /* Enable PCIe PHY 1P0D */ regulator_set_voltage(imx_pcie->pcie_phy_regulator, @@ -1407,6 +1424,7 @@ static irqreturn_t imx_pcie_msi_handler(int irq, void *arg) static void pci_imx_clk_disable(struct device *dev) { + u32 val; struct imx_pcie *imx_pcie = dev_get_drvdata(dev); clk_disable_unprepare(imx_pcie->pcie); @@ -1430,8 +1448,22 @@ static void pci_imx_clk_disable(struct device *dev) regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12, BIT(5), BIT(5)); break; + /* + * Disable the over ride. + * Configure the CLK_REQ# high, let the L1SS automatically + * controlled by HW when link is up. + * Otherwise, turn off the REF_CLK to save power consumption. + */ case IMX8MQ: case IMX8MM: + if (imx_pcie->ctrl_id == 0) + val = IOMUXC_GPR14; + else + val = IOMUXC_GPR16; + + regmap_update_bits(imx_pcie->iomuxc_gpr, val, + IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN, + 0); break; case IMX8QXP: case IMX8QM: @@ -1582,11 +1614,12 @@ static int imx_pcie_host_init(struct pcie_port *pp) if (!IS_ENABLED(CONFIG_EP_MODE_IN_EP_RC_SYS)) { dw_pcie_setup_rc(pp); ret = imx_pcie_establish_link(imx_pcie); + if (ret < 0) + return ret; /* - * Disable the over ride. - * Configure the CLK_REQ# high, let the L1SS automatically - * controlled by HW when link is up. - * Otherwise, turn off the REF_CLK to save power consumption. + * Disable the over ride after link up. + * Let the the CLK_REQ# controlled by HW L1SS + * automatically. */ switch (imx_pcie->variant) { case IMX8MQ: @@ -1603,8 +1636,6 @@ static int imx_pcie_host_init(struct pcie_port *pp) default: break; } - if (ret < 0) - return ret; if (IS_ENABLED(CONFIG_PCI_MSI)) dw_pcie_msi_init(pp); |