PCI: imx6: Add PLL lock check for i.MX95 SoC

PLL lock is required to ensure that the PLL clock is stable before enabling
the controller in i.MX95 SoC.

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-7-hongxing.zhu@nxp.com
This commit is contained in:
Richard Zhu 2025-04-16 16:13:13 +08:00 committed by Manivannan Sadhasivam
parent 744a1c20ce
commit 047e8b6b3b

View File

@ -45,6 +45,9 @@
#define IMX95_PCIE_PHY_GEN_CTRL 0x0
#define IMX95_PCIE_REF_USE_PAD BIT(17)
#define IMX95_PCIE_PHY_MPLLA_CTRL 0x10
#define IMX95_PCIE_PHY_MPLL_STATE BIT(30)
#define IMX95_PCIE_SS_RW_REG_0 0xf0
#define IMX95_PCIE_REF_CLKEN BIT(23)
#define IMX95_PCIE_PHY_CR_PARA_SEL BIT(9)
@ -132,6 +135,7 @@ struct imx_pcie_drvdata {
int (*init_phy)(struct imx_pcie *pcie);
int (*enable_ref_clk)(struct imx_pcie *pcie, bool enable);
int (*core_reset)(struct imx_pcie *pcie, bool assert);
int (*wait_pll_lock)(struct imx_pcie *pcie);
const struct dw_pcie_host_ops *ops;
};
@ -479,6 +483,23 @@ static void imx7d_pcie_wait_for_phy_pll_lock(struct imx_pcie *imx_pcie)
dev_err(dev, "PCIe PLL lock timeout\n");
}
static int imx95_pcie_wait_for_phy_pll_lock(struct imx_pcie *imx_pcie)
{
u32 val;
struct device *dev = imx_pcie->pci->dev;
if (regmap_read_poll_timeout(imx_pcie->iomuxc_gpr,
IMX95_PCIE_PHY_MPLLA_CTRL, val,
val & IMX95_PCIE_PHY_MPLL_STATE,
PHY_PLL_LOCK_WAIT_USLEEP_MAX,
PHY_PLL_LOCK_WAIT_TIMEOUT)) {
dev_err(dev, "PCIe PLL lock timeout\n");
return -ETIMEDOUT;
}
return 0;
}
static int imx_setup_phy_mpll(struct imx_pcie *imx_pcie)
{
unsigned long phy_rate = 0;
@ -1225,6 +1246,12 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
goto err_phy_off;
}
if (imx_pcie->drvdata->wait_pll_lock) {
ret = imx_pcie->drvdata->wait_pll_lock(imx_pcie);
if (ret < 0)
goto err_phy_off;
}
imx_setup_phy_mpll(imx_pcie);
return 0;
@ -1826,6 +1853,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
.core_reset = imx95_pcie_core_reset,
.init_phy = imx95_pcie_init_phy,
.wait_pll_lock = imx95_pcie_wait_for_phy_pll_lock,
},
[IMX8MQ_EP] = {
.variant = IMX8MQ_EP,
@ -1880,6 +1908,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
.init_phy = imx95_pcie_init_phy,
.core_reset = imx95_pcie_core_reset,
.wait_pll_lock = imx95_pcie_wait_for_phy_pll_lock,
.epc_features = &imx95_pcie_epc_features,
.mode = DW_PCIE_EP_TYPE,
},