The probe sets APP_HOLD_PHY_RST and clears it again straight away, before the PHY is initialised, so the controller's PIPE interface comes out of reset while the PHY is still unconfigured and its PLL unlocked.
Linux's pcie-spacemit-k1 driver sets APP_HOLD_PHY_RST at probe and clears it only in start_link(), in the same write that sets LTSSM_EN. FreeBSD's spacemit_pcie driver, which runs these controllers on the OrangePi RV2 and R2S, does the same and notes that releasing the PIPE interface before the PHY is ready leaves the LTSSM stuck in Detect. Keep the bit set through PHY init. The write that enables the LTSSM already clears it. Signed-off-by: Dave Klotz <[email protected]> --- drivers/pci/pcie_dw_spacemit.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/pci/pcie_dw_spacemit.c b/drivers/pci/pcie_dw_spacemit.c index 7ca5a5ad1a..04b3161e94 100644 --- a/drivers/pci/pcie_dw_spacemit.c +++ b/drivers/pci/pcie_dw_spacemit.c @@ -245,12 +245,14 @@ static int pcie_dw_spacemit_probe(struct udevice *dev) ret = generic_phy_get_by_index_nodev(port, 0, &phy0); if (!ret) { + /* + * Hold the PHY interface in reset through PHY init; it is + * released together with LTSSM_EN when link training starts. + */ reg = spacemit_pcie_readl(pci, PCIECTRL_K1X_CONF_DEVICE_CMD); reg |= DEVICE_TYPE_RC | APP_HOLD_PHY_RST | PCIE_PHY_LANE_CTRL_MASK; reg &= ~GLOBAL_PHY_RST; spacemit_pcie_writel(pci, PCIECTRL_K1X_CONF_DEVICE_CMD, reg); - reg &= ~(u32)APP_HOLD_PHY_RST; - spacemit_pcie_writel(pci, PCIECTRL_K1X_CONF_DEVICE_CMD, reg); ret = generic_phy_init(&phy0); if (ret) { -- 2.55.0
