]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
PCI: cadence: Add post-link delay for LGA and j721e glue driver
authorHans Zhang <18255117159@163.com>
Mon, 18 May 2026 00:42:41 +0000 (08:42 +0800)
committerManivannan Sadhasivam <mani@kernel.org>
Tue, 9 Jun 2026 15:22:25 +0000 (20:52 +0530)
The Cadence LGA (Legacy Architecture IP) PCIe host controller currently
lacks the mandatory 100 ms delay after link training completes for speeds
> 5.0 GT/s, as required by PCIe r6.0 sec 6.6.1.

Add a 'max_link_speed' field to struct cdns_pcie. In the common host
layer function cdns_pcie_host_start_link(), after the link has been
successfully established, call pci_host_common_link_train_delay() to
insert the required delay.

For the j721e glue driver, set cdns_pcie.max_link_speed from the existing
link speed logic. For other LGA-based glue drivers (sky1, sg2042), the
common LGA host setup (pcie-cadence-host.c) provides a fallback reading
of the device tree property "max-link-speed" when available. This ensures
that the delay is not missed on those platforms once they enable the
property.

Signed-off-by: Hans Zhang <18255117159@163.com>
Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
Link: https://patch.msgid.link/20260518004246.1384532-3-18255117159@163.com
drivers/pci/controller/cadence/pci-j721e.c
drivers/pci/controller/cadence/pcie-cadence-host-common.c
drivers/pci/controller/cadence/pcie-cadence-host.c
drivers/pci/controller/cadence/pcie-cadence.h

index bfdfe98d5aba73d417a32be5541666a10e4b80aa..ae916e7b1927a47652dc48041baa82ebd33a706d 100644 (file)
@@ -206,6 +206,7 @@ static int j721e_pcie_set_link_speed(struct j721e_pcie *pcie,
            (pcie_get_link_speed(link_speed) == PCI_SPEED_UNKNOWN))
                link_speed = 2;
 
+       pcie->cdns_pcie->max_link_speed = link_speed;
        val = link_speed - 1;
        ret = regmap_update_bits(syscon, offset, GENERATION_SEL_MASK, val);
        if (ret)
index 2b0211870f02ab559af0b237ec346f33f58c3b5d..18e4b6c760b512195414b7aa6998cb675bd90010 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "pcie-cadence.h"
 #include "pcie-cadence-host-common.h"
+#include "../pci-host-common.h"
 
 #define LINK_RETRAIN_TIMEOUT HZ
 
@@ -115,6 +116,9 @@ int cdns_pcie_host_start_link(struct cdns_pcie_rc *rc,
        if (!ret && rc->quirk_retrain_flag)
                ret = cdns_pcie_retrain(pcie, pcie_link_up);
 
+       if (!ret)
+               pci_host_common_link_train_delay(pcie->max_link_speed);
+
        return ret;
 }
 EXPORT_SYMBOL_GPL(cdns_pcie_host_start_link);
index 0bc9e6e90e0e0075b933cd5fb442bf73a94d48c6..058e4e619654c4ab757b5545739156d5aac44d3e 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "pcie-cadence.h"
 #include "pcie-cadence-host-common.h"
+#include "../../pci.h"
 
 static u8 bar_aperture_mask[] = {
        [RP_BAR0] = 0x1F,
@@ -397,6 +398,9 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
        rc->device_id = 0xffff;
        of_property_read_u32(np, "device-id", &rc->device_id);
 
+       if (pcie->max_link_speed < 1)
+               pcie->max_link_speed = of_pci_get_max_link_speed(np);
+
        pcie->reg_base = devm_platform_ioremap_resource_byname(pdev, "reg");
        if (IS_ERR(pcie->reg_base)) {
                dev_err(dev, "missing \"reg\"\n");
index 574e9cf4d003f4f50b773c053b507e58fe7bee8f..042a4c49bb9aede660b527bd1e02333b1d57f442 100644 (file)
@@ -86,6 +86,7 @@ struct cdns_plat_pcie_of_data {
  * @ops: Platform-specific ops to control various inputs from Cadence PCIe
  *       wrapper
  * @cdns_pcie_reg_offsets: Register bank offsets for different SoC
+ * @max_link_speed: Maximum supported link speed
  */
 struct cdns_pcie {
        void __iomem                         *reg_base;
@@ -98,6 +99,7 @@ struct cdns_pcie {
        struct device_link                   **link;
        const  struct cdns_pcie_ops          *ops;
        const  struct cdns_plat_pcie_of_data *cdns_pcie_reg_offsets;
+       int                                  max_link_speed;
 };
 
 /**