From 6523be7278e4e37142e90a07129d892f86bd8b74 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Mon, 18 Oct 2021 14:51:35 +0800 Subject: [PATCH] PCI: rockchip: dw: Fix gen switch case when link is up L0 may be detected just in time if Gen1 training is finished. But if EP supports higher Gen mode, Gen switch just happen there but we keep on accessing devices, which leads unstable link state and fail to detect the device finally. And a bit more time before accessing devices to avoid this risky case. Signed-off-by: Shawn Lin Change-Id: If7eddce430b4590922b5c8f765be8a240b562d92 --- drivers/pci/controller/dwc/pcie-dw-rockchip.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c index 6f7ce06a7683..8f0a06c2e9b8 100644 --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c @@ -698,18 +698,24 @@ static int rk_pcie_establish_link(struct dw_pcie *pci) /* * PCIe requires the refclk to be stable for 100µs prior to releasing - * PERST. See table 2-4 in section 2.6.2 AC Specifications of the PCI - * Express Card Electromechanical Specification, 1.1. However, we don't - * know if the refclk is coming from RC's PHY or external OSC. If it's - * from RC, so enabling LTSSM is the just right place to release #PERST. - * We need a little more extra time as before, rather than setting just - * 100us as we don't know how long should the device need to reset. + * PERST and T_PVPERL (Power stable to PERST# inactive) should be a + * minimum of 100ms. See table 2-4 in section 2.6.2 AC, the PCI Express + * Card Electromechanical Specification 3.0. So 100ms in total is the min + * requuirement here. We add a 1s for sake of hoping everthings work fine. */ msleep(1000); gpiod_set_value_cansleep(rk_pcie->rst_gpio, 1); for (retries = 0; retries < 10; retries++) { if (dw_pcie_link_up(pci)) { + /* + * We may be here in case of L0 in Gen1. But if EP is capable + * of Gen2 or Gen3, Gen switch may happen just in this time, but + * we keep on accessing devices in unstable link status. Given + * that LTSSM max timeout is 24ms per period, we can wait a bit + * more for Gen switch. + */ + msleep(100); dev_info(pci->dev, "PCIe Link up, LTSSM is 0x%x\n", rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS)); rk_pcie_debug_dump(rk_pcie);