From fc59a282e70cd4ab12cc1ec7ebc1e9e442a351f7 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Mon, 21 Oct 2024 15:45:03 +0800 Subject: [PATCH] PCI: rockchip: dw: Add rockchip,wait-for-link-ms support Some devices like FPGA or AI cards need a long period of time after powering up and releasing #PERST. This is due to the slow firmware loading process happened inside the devices. Without this support, link will be failed during the limitation. Signed-off-by: Shawn Lin Change-Id: I01ecb64ca1b1a1917eb5434c374517387ab11ffc --- drivers/pci/controller/dwc/pcie-dw-rockchip.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c index af1155b388c8..238a58053c9c 100644 --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c @@ -127,6 +127,7 @@ struct rk_pcie { struct gpio_desc *rst_gpio; u32 perst_inactive_ms; u32 s2r_perst_inactive_ms; + u32 wait_for_link_ms; struct gpio_desc *prsnt_gpio; struct dma_trx_obj *dma_obj; bool in_suspend; @@ -398,12 +399,14 @@ static int rk_pcie_establish_link(struct dw_pcie *pci) gpiod_set_value_cansleep(rk_pcie->rst_gpio, 1); /* - * Add this 1ms delay because we observe link is always up stably after it and - * could help us save 20ms for scanning devices. + * Add this delay because we observe devices need a period of time to be able to + * work, so the link is always up stably after it. And the default 1ms could help us + * save 20ms for scanning devices. If the devices need longer than 2s to be able to + * work, please change wait_for_link_ms via dts. */ usleep_range(1000, 1100); - for (retries = 0; retries < 100; retries++) { + for (retries = 0; retries < rk_pcie->wait_for_link_ms / 20; retries++) { if (dw_pcie_link_up(pci)) { /* * We may be here in case of L0 in Gen1. But if EP is capable @@ -427,7 +430,7 @@ static int rk_pcie_establish_link(struct dw_pcie *pci) dev_info_ratelimited(pci->dev, "PCIe Linking... LTSSM is 0x%x\n", rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS)); rk_pcie_debug_dump(rk_pcie); - msleep(20); + usleep_range(20000, 21000); } /* @@ -682,6 +685,10 @@ static int rk_pcie_resource_get(struct platform_device *pdev, &rk_pcie->s2r_perst_inactive_ms)) rk_pcie->s2r_perst_inactive_ms = rk_pcie->perst_inactive_ms; + device_property_read_u32(&pdev->dev, "rockchip,wait-for-link-ms", + &rk_pcie->wait_for_link_ms); + rk_pcie->wait_for_link_ms = max_t(u32, rk_pcie->wait_for_link_ms, 2000); + rk_pcie->prsnt_gpio = devm_gpiod_get_optional(&pdev->dev, "prsnt", GPIOD_IN); if (IS_ERR_OR_NULL(rk_pcie->prsnt_gpio)) dev_info(&pdev->dev, "invalid prsnt-gpios property in node\n");