mirror of
https://github.com/torvalds/linux.git
synced 2026-05-22 14:12:07 +02:00
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:
parent
744a1c20ce
commit
047e8b6b3b
|
|
@ -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,
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user