[PATCH v3 2/4] pci: pcie_dw_rockchip: enable clocks before PHY init
Daniele Briguglio
hello at superkali.me
Wed May 20 08:05:28 CEST 2026
rockchip_pcie_init_port() calls generic_phy_init() and
generic_phy_power_on() before clk_enable_bulk(), so the PCIe PHY
tries to lock its PLL while the external reference clock can still
be off. Where the refclk is generated by an external oscillator
gated by a regulator that is not marked regulator-always-on (e.g.
the PI6C clock generator on radxa rock-3b modelled with the
gated-fixed-clock binding), this results in a PHY lock timeout:
rockchip_pcie3phy phy at fe8c0000: lock failed 0x6890000
rockchip_pcie3phy phy at fe8c0000: PHY: Failed to init phy at fe8c0000: -110.
pcie_dw_rockchip pcie at fe280000: failed to init phy (ret=-110)
Move clk_enable_bulk() ahead of generic_phy_init() so that any
clock-frequency consumer (including external gated refclks) is
powered up before the PHY PLL attempts to lock.
Reported-by: Jonas Karlman <jonas at kwiboo.se>
Signed-off-by: Daniele Briguglio <hello at superkali.me>
---
drivers/pci/pcie_dw_rockchip.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/pci/pcie_dw_rockchip.c b/drivers/pci/pcie_dw_rockchip.c
index 61117fa95..8ea51e642 100644
--- a/drivers/pci/pcie_dw_rockchip.c
+++ b/drivers/pci/pcie_dw_rockchip.c
@@ -307,10 +307,16 @@ static int rockchip_pcie_init_port(struct udevice *dev)
return ret;
}
+ ret = clk_enable_bulk(&priv->clks);
+ if (ret) {
+ dev_err(dev, "failed to enable clks (ret=%d)\n", ret);
+ goto err_disable_regulator;
+ }
+
ret = generic_phy_init(&priv->phy);
if (ret) {
dev_err(dev, "failed to init phy (ret=%d)\n", ret);
- goto err_disable_regulator;
+ goto err_disable_clks;
}
ret = generic_phy_power_on(&priv->phy);
@@ -325,12 +331,6 @@ static int rockchip_pcie_init_port(struct udevice *dev)
goto err_power_off_phy;
}
- ret = clk_enable_bulk(&priv->clks);
- if (ret) {
- dev_err(dev, "failed to enable clks (ret=%d)\n", ret);
- goto err_deassert_bulk;
- }
-
/* LTSSM EN ctrl mode */
val = rk_pcie_readl_apb(priv, PCIE_CLIENT_HOT_RESET_CTRL);
val |= PCIE_LTSSM_ENABLE_ENHANCE | (PCIE_LTSSM_ENABLE_ENHANCE << 16);
@@ -342,17 +342,17 @@ static int rockchip_pcie_init_port(struct udevice *dev)
ret = rk_pcie_link_up(priv);
if (ret < 0)
- goto err_link_up;
+ goto err_deassert_bulk;
return 0;
-err_link_up:
- clk_disable_bulk(&priv->clks);
err_deassert_bulk:
reset_assert_bulk(&priv->rsts);
err_power_off_phy:
generic_phy_power_off(&priv->phy);
err_exit_phy:
generic_phy_exit(&priv->phy);
+err_disable_clks:
+ clk_disable_bulk(&priv->clks);
err_disable_regulator:
regulator_set_enable_if_allowed(priv->vpcie3v3, false);
--
2.47.3
More information about the U-Boot
mailing list