Hi All!
I've found another bug in PCIe driver from Linux Processor SDK (appears in latest SDK and ti git master). This bug affects initial link training sequence.
This code snippet is from drivers/pci/dwc/pci-keystone.c file:
static void ks_pcie_stop_link(struct dw_pcie *pci) { struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); u32 val; /* Disable Link training */ val = ks_pcie_app_readl(ks_pcie, CMD_STATUS); val &= ~LTSSM_EN_VAL; ks_pcie_app_writel(ks_pcie, CMD_STATUS, LTSSM_EN_VAL | val); } static int ks_pcie_start_link(struct dw_pcie *pci) { struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); struct device *dev = pci->dev; u32 val; if (dw_pcie_link_up(pci)) { dev_dbg(dev, "link is already up\n"); return 0; } /* Initiate Link Training */ val = ks_pcie_app_readl(ks_pcie, CMD_STATUS); ks_pcie_app_writel(ks_pcie, CMD_STATUS, LTSSM_EN_VAL | val); return 0; }
As you can see, ks_pcie_stop_link function never clears LTSSM_EN_VAL bit. So link training is initiated only once during kernel boot.
If the link is unstable during early boot, it will never be established. I've found this behavior on low temperature testing.
Best Regards,
Yurii
PS. Unfortunately previously reported bug () was not fixed in latest SDK.