* [PATCH v4 1/7] PCI: Add pci_host_common_link_train_delay() helper
2026-05-18 0:42 [PATCH v4 0/7] PCI: Add common helper for 100 ms delay after link training Hans Zhang
@ 2026-05-18 0:42 ` Hans Zhang
2026-05-18 0:42 ` [PATCH v4 2/7] PCI: cadence: Add post-link delay for LGA and j721e glue driver Hans Zhang
` (6 subsequent siblings)
7 siblings, 0 replies; 16+ messages in thread
From: Hans Zhang @ 2026-05-18 0:42 UTC (permalink / raw)
To: bhelgaas, lpieralisi, kwilczynski, mani, vigneshr, jingoohan1,
thomas.petazzoni, ryder.lee, claudiu.beznea.uj, mpillai
Cc: robh, s-vadapalli, linux-omap, linux-arm-kernel, claudiu.beznea,
linux-mediatek, linux-renesas-soc, linux-pci, linux-kernel,
Hans Zhang
PCIe r6.0, sec 6.6.1 (Conventional Reset) requires that for a Downstream
Port supporting Link speeds greater than 5.0 GT/s, software must wait a
minimum of 100 ms after Link training completes before sending any
Configuration Request.
Introduce a static inline helper pci_host_common_link_train_delay() that
checks the given max_link_speed (2 = 5.0 GT/s, 3 = 8.0 GT/s, etc.) and
calls msleep(100) only when the speed is greater than 5.0 GT/s.
This allows multiple host controller drivers to share the same mandatory
delay without duplicating the logic.
Signed-off-by: Hans Zhang <18255117159@163.com>
---
drivers/pci/controller/pci-host-common.h | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/drivers/pci/controller/pci-host-common.h b/drivers/pci/controller/pci-host-common.h
index b5075d4bd7eb..d709f7e3e11a 100644
--- a/drivers/pci/controller/pci-host-common.h
+++ b/drivers/pci/controller/pci-host-common.h
@@ -10,6 +10,9 @@
#ifndef _PCI_HOST_COMMON_H
#define _PCI_HOST_COMMON_H
+#include <linux/delay.h>
+#include "../pci.h"
+
struct pci_ecam_ops;
int pci_host_common_probe(struct platform_device *pdev);
@@ -20,4 +23,18 @@ void pci_host_common_remove(struct platform_device *pdev);
struct pci_config_window *pci_host_common_ecam_create(struct device *dev,
struct pci_host_bridge *bridge, const struct pci_ecam_ops *ops);
+
+/**
+ * pci_host_common_link_train_delay - Wait 100 ms if link speed > 5 GT/s
+ * @max_link_speed: the maximum link speed (2 = 5.0 GT/s, 3 = 8.0 GT/s, ...)
+ *
+ * Must be called after Link training completes and before the first
+ * Configuration Request is sent.
+ */
+static inline void pci_host_common_link_train_delay(int max_link_speed)
+{
+ if (max_link_speed > 2)
+ msleep(PCIE_RESET_CONFIG_WAIT_MS);
+}
+
#endif
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v4 2/7] PCI: cadence: Add post-link delay for LGA and j721e glue driver
2026-05-18 0:42 [PATCH v4 0/7] PCI: Add common helper for 100 ms delay after link training Hans Zhang
2026-05-18 0:42 ` [PATCH v4 1/7] PCI: Add pci_host_common_link_train_delay() helper Hans Zhang
@ 2026-05-18 0:42 ` Hans Zhang
2026-05-18 2:12 ` Manikandan Karunakaran Pillai
2026-05-18 0:42 ` [PATCH v4 3/7] PCI: cadence: HPA: Add post-link delay Hans Zhang
` (5 subsequent siblings)
7 siblings, 1 reply; 16+ messages in thread
From: Hans Zhang @ 2026-05-18 0:42 UTC (permalink / raw)
To: bhelgaas, lpieralisi, kwilczynski, mani, vigneshr, jingoohan1,
thomas.petazzoni, ryder.lee, claudiu.beznea.uj, mpillai
Cc: robh, s-vadapalli, linux-omap, linux-arm-kernel, claudiu.beznea,
linux-mediatek, linux-renesas-soc, linux-pci, linux-kernel,
Hans Zhang
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>
---
drivers/pci/controller/cadence/pci-j721e.c | 1 +
drivers/pci/controller/cadence/pcie-cadence-host-common.c | 4 ++++
drivers/pci/controller/cadence/pcie-cadence-host.c | 4 ++++
drivers/pci/controller/cadence/pcie-cadence.h | 2 ++
4 files changed, 11 insertions(+)
diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
index bfdfe98d5aba..ae916e7b1927 100644
--- a/drivers/pci/controller/cadence/pci-j721e.c
+++ b/drivers/pci/controller/cadence/pci-j721e.c
@@ -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)
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host-common.c b/drivers/pci/controller/cadence/pcie-cadence-host-common.c
index 2b0211870f02..18e4b6c760b5 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-host-common.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-host-common.c
@@ -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);
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
index 0bc9e6e90e0e..058e4e619654 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-host.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
@@ -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");
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index 574e9cf4d003..042a4c49bb9a 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -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;
};
/**
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* RE: [PATCH v4 2/7] PCI: cadence: Add post-link delay for LGA and j721e glue driver
2026-05-18 0:42 ` [PATCH v4 2/7] PCI: cadence: Add post-link delay for LGA and j721e glue driver Hans Zhang
@ 2026-05-18 2:12 ` Manikandan Karunakaran Pillai
2026-05-18 2:26 ` Hans Zhang
0 siblings, 1 reply; 16+ messages in thread
From: Manikandan Karunakaran Pillai @ 2026-05-18 2:12 UTC (permalink / raw)
To: Hans Zhang, bhelgaas@google.com, lpieralisi@kernel.org,
kwilczynski@kernel.org, mani@kernel.org, vigneshr@ti.com,
jingoohan1@gmail.com, thomas.petazzoni@bootlin.com,
ryder.lee@mediatek.com, claudiu.beznea.uj@bp.renesas.com
Cc: robh@kernel.org, s-vadapalli@ti.com, linux-omap@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, claudiu.beznea@tuxon.dev,
linux-mediatek@lists.infradead.org,
linux-renesas-soc@vger.kernel.org, linux-pci@vger.kernel.org,
linux-kernel@vger.kernel.org
>EXTERNAL MAIL
>
>
>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>
>---
> drivers/pci/controller/cadence/pci-j721e.c | 1 +
> drivers/pci/controller/cadence/pcie-cadence-host-common.c | 4 ++++
> drivers/pci/controller/cadence/pcie-cadence-host.c | 4 ++++
> drivers/pci/controller/cadence/pcie-cadence.h | 2 ++
> 4 files changed, 11 insertions(+)
>
>diff --git a/drivers/pci/controller/cadence/pci-j721e.c
>b/drivers/pci/controller/cadence/pci-j721e.c
>index bfdfe98d5aba..ae916e7b1927 100644
>--- a/drivers/pci/controller/cadence/pci-j721e.c
>+++ b/drivers/pci/controller/cadence/pci-j721e.c
>@@ -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)
>diff --git a/drivers/pci/controller/cadence/pcie-cadence-host-common.c
>b/drivers/pci/controller/cadence/pcie-cadence-host-common.c
>index 2b0211870f02..18e4b6c760b5 100644
>--- a/drivers/pci/controller/cadence/pcie-cadence-host-common.c
>+++ b/drivers/pci/controller/cadence/pcie-cadence-host-common.c
>@@ -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);
>diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c
>b/drivers/pci/controller/cadence/pcie-cadence-host.c
>index 0bc9e6e90e0e..058e4e619654 100644
>--- a/drivers/pci/controller/cadence/pcie-cadence-host.c
>+++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
>@@ -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);
>+
Why is the conditional if required here as during cdns_pcie_host_setup(), the value of
max_link_speed is expected to be '0', unless specifically initialized by the platform code separately.
What happens if the max_link_speed is not defined in the corresponding dts ? Would not the -EINVAL returned from the function create issues ?
> pcie->reg_base = devm_platform_ioremap_resource_byname(pdev,
>"reg");
> if (IS_ERR(pcie->reg_base)) {
> dev_err(dev, "missing \"reg\"\n");
>diff --git a/drivers/pci/controller/cadence/pcie-cadence.h
>b/drivers/pci/controller/cadence/pcie-cadence.h
>index 574e9cf4d003..042a4c49bb9a 100644
>--- a/drivers/pci/controller/cadence/pcie-cadence.h
>+++ b/drivers/pci/controller/cadence/pcie-cadence.h
>@@ -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;
> };
>
> /**
>--
>2.43.0
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [PATCH v4 2/7] PCI: cadence: Add post-link delay for LGA and j721e glue driver
2026-05-18 2:12 ` Manikandan Karunakaran Pillai
@ 2026-05-18 2:26 ` Hans Zhang
2026-05-18 2:38 ` Manikandan Karunakaran Pillai
0 siblings, 1 reply; 16+ messages in thread
From: Hans Zhang @ 2026-05-18 2:26 UTC (permalink / raw)
To: Manikandan Karunakaran Pillai, bhelgaas@google.com,
lpieralisi@kernel.org, kwilczynski@kernel.org, mani@kernel.org,
vigneshr@ti.com, jingoohan1@gmail.com,
thomas.petazzoni@bootlin.com, ryder.lee@mediatek.com,
claudiu.beznea.uj@bp.renesas.com
Cc: robh@kernel.org, s-vadapalli@ti.com, linux-omap@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, claudiu.beznea@tuxon.dev,
linux-mediatek@lists.infradead.org,
linux-renesas-soc@vger.kernel.org, linux-pci@vger.kernel.org,
linux-kernel@vger.kernel.org
On 5/18/26 10:12, Manikandan Karunakaran Pillai wrote:
>
>
>> EXTERNAL MAIL
>>
>>
>> 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>
>> ---
>> drivers/pci/controller/cadence/pci-j721e.c | 1 +
>> drivers/pci/controller/cadence/pcie-cadence-host-common.c | 4 ++++
>> drivers/pci/controller/cadence/pcie-cadence-host.c | 4 ++++
>> drivers/pci/controller/cadence/pcie-cadence.h | 2 ++
>> 4 files changed, 11 insertions(+)
>>
>> diff --git a/drivers/pci/controller/cadence/pci-j721e.c
>> b/drivers/pci/controller/cadence/pci-j721e.c
>> index bfdfe98d5aba..ae916e7b1927 100644
>> --- a/drivers/pci/controller/cadence/pci-j721e.c
>> +++ b/drivers/pci/controller/cadence/pci-j721e.c
>> @@ -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)
>> diff --git a/drivers/pci/controller/cadence/pcie-cadence-host-common.c
>> b/drivers/pci/controller/cadence/pcie-cadence-host-common.c
>> index 2b0211870f02..18e4b6c760b5 100644
>> --- a/drivers/pci/controller/cadence/pcie-cadence-host-common.c
>> +++ b/drivers/pci/controller/cadence/pcie-cadence-host-common.c
>> @@ -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);
>> diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c
>> b/drivers/pci/controller/cadence/pcie-cadence-host.c
>> index 0bc9e6e90e0e..058e4e619654 100644
>> --- a/drivers/pci/controller/cadence/pcie-cadence-host.c
>> +++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
>> @@ -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);
>> +
> Why is the conditional if required here as during cdns_pcie_host_setup(), the value of
> max_link_speed is expected to be '0', unless specifically initialized by the platform code separately.
>
> What happens if the max_link_speed is not defined in the corresponding dts ? Would not the -EINVAL returned from the function create issues ?
Hi Manikandan,
Please see:
https://github.com/torvalds/linux/blob/v7.1-rc4/drivers/pci/controller/dwc/pcie-designware.c#L191
Best regards,
Hans
>
>> pcie->reg_base = devm_platform_ioremap_resource_byname(pdev,
>> "reg");
>> if (IS_ERR(pcie->reg_base)) {
>> dev_err(dev, "missing \"reg\"\n");
>> diff --git a/drivers/pci/controller/cadence/pcie-cadence.h
>> b/drivers/pci/controller/cadence/pcie-cadence.h
>> index 574e9cf4d003..042a4c49bb9a 100644
>> --- a/drivers/pci/controller/cadence/pcie-cadence.h
>> +++ b/drivers/pci/controller/cadence/pcie-cadence.h
>> @@ -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;
>> };
>>
>> /**
>> --
>> 2.43.0
^ permalink raw reply [flat|nested] 16+ messages in thread* RE: [PATCH v4 2/7] PCI: cadence: Add post-link delay for LGA and j721e glue driver
2026-05-18 2:26 ` Hans Zhang
@ 2026-05-18 2:38 ` Manikandan Karunakaran Pillai
2026-05-18 3:03 ` Hans Zhang
0 siblings, 1 reply; 16+ messages in thread
From: Manikandan Karunakaran Pillai @ 2026-05-18 2:38 UTC (permalink / raw)
To: Hans Zhang, bhelgaas@google.com, lpieralisi@kernel.org,
kwilczynski@kernel.org, mani@kernel.org, vigneshr@ti.com,
jingoohan1@gmail.com, thomas.petazzoni@bootlin.com,
ryder.lee@mediatek.com, claudiu.beznea.uj@bp.renesas.com
Cc: robh@kernel.org, s-vadapalli@ti.com, linux-omap@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, claudiu.beznea@tuxon.dev,
linux-mediatek@lists.infradead.org,
linux-renesas-soc@vger.kernel.org, linux-pci@vger.kernel.org,
linux-kernel@vger.kernel.org
>EXTERNAL MAIL
>
>
>
>
>On 5/18/26 10:12, Manikandan Karunakaran Pillai wrote:
>>
>>
>>> EXTERNAL MAIL
>>>
>>>
>>> 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>
>>> ---
>>> drivers/pci/controller/cadence/pci-j721e.c | 1 +
>>> drivers/pci/controller/cadence/pcie-cadence-host-common.c | 4 ++++
>>> drivers/pci/controller/cadence/pcie-cadence-host.c | 4 ++++
>>> drivers/pci/controller/cadence/pcie-cadence.h | 2 ++
>>> 4 files changed, 11 insertions(+)
>>>
>>> diff --git a/drivers/pci/controller/cadence/pci-j721e.c
>>> b/drivers/pci/controller/cadence/pci-j721e.c
>>> index bfdfe98d5aba..ae916e7b1927 100644
>>> --- a/drivers/pci/controller/cadence/pci-j721e.c
>>> +++ b/drivers/pci/controller/cadence/pci-j721e.c
>>> @@ -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)
>>> diff --git a/drivers/pci/controller/cadence/pcie-cadence-host-common.c
>>> b/drivers/pci/controller/cadence/pcie-cadence-host-common.c
>>> index 2b0211870f02..18e4b6c760b5 100644
>>> --- a/drivers/pci/controller/cadence/pcie-cadence-host-common.c
>>> +++ b/drivers/pci/controller/cadence/pcie-cadence-host-common.c
>>> @@ -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);
>>> diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c
>>> b/drivers/pci/controller/cadence/pcie-cadence-host.c
>>> index 0bc9e6e90e0e..058e4e619654 100644
>>> --- a/drivers/pci/controller/cadence/pcie-cadence-host.c
>>> +++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
>>> @@ -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);
>>> +
>> Why is the conditional if required here as during cdns_pcie_host_setup(), the
>value of
>> max_link_speed is expected to be '0', unless specifically initialized by the
>platform code separately.
>>
>> What happens if the max_link_speed is not defined in the corresponding dts
>? Would not the -EINVAL returned from the function create issues ?
>
>Hi Manikandan,
>
>Please see:
>
>https://urldefense.com/v3/__https://github.com/torvalds/linux/blob/v7.1-
>rc4/drivers/pci/controller/dwc/pcie-
>designware.c*L191__;Iw!!EHscmS1ygiU1lA!EDHVakD3QN0gGza3V1__qzHgDG9
>RZlq7LzC5AFsYLV2i5FcoveNFsjWORRgRdHCAmOI-LizY5cJvGIWBOFJG$
>
>
>Best regards,
>Hans
>
That is how Designware has implemented it but that does not answer my query. Becos both these implementations do
not take care of the error returned, and it could well be the case for many of the current implementations.
>>
>>> pcie->reg_base = devm_platform_ioremap_resource_byname(pdev,
>>> "reg");
>>> if (IS_ERR(pcie->reg_base)) {
>>> dev_err(dev, "missing \"reg\"\n");
>>> diff --git a/drivers/pci/controller/cadence/pcie-cadence.h
>>> b/drivers/pci/controller/cadence/pcie-cadence.h
>>> index 574e9cf4d003..042a4c49bb9a 100644
>>> --- a/drivers/pci/controller/cadence/pcie-cadence.h
>>> +++ b/drivers/pci/controller/cadence/pcie-cadence.h
>>> @@ -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;
>>> };
>>>
>>> /**
>>> --
>>> 2.43.0
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [PATCH v4 2/7] PCI: cadence: Add post-link delay for LGA and j721e glue driver
2026-05-18 2:38 ` Manikandan Karunakaran Pillai
@ 2026-05-18 3:03 ` Hans Zhang
2026-05-18 3:17 ` Manikandan Karunakaran Pillai
0 siblings, 1 reply; 16+ messages in thread
From: Hans Zhang @ 2026-05-18 3:03 UTC (permalink / raw)
To: Manikandan Karunakaran Pillai, bhelgaas@google.com,
lpieralisi@kernel.org, kwilczynski@kernel.org, mani@kernel.org,
vigneshr@ti.com, jingoohan1@gmail.com,
thomas.petazzoni@bootlin.com, ryder.lee@mediatek.com,
claudiu.beznea.uj@bp.renesas.com
Cc: robh@kernel.org, s-vadapalli@ti.com, linux-omap@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, claudiu.beznea@tuxon.dev,
linux-mediatek@lists.infradead.org,
linux-renesas-soc@vger.kernel.org, linux-pci@vger.kernel.org,
linux-kernel@vger.kernel.org
On 5/18/26 10:38, Manikandan Karunakaran Pillai wrote:
>
>
>> EXTERNAL MAIL
>>
>>
>>
>>
>> On 5/18/26 10:12, Manikandan Karunakaran Pillai wrote:
>>>
>>>
>>>> EXTERNAL MAIL
>>>>
>>>>
>>>> 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>
>>>> ---
>>>> drivers/pci/controller/cadence/pci-j721e.c | 1 +
>>>> drivers/pci/controller/cadence/pcie-cadence-host-common.c | 4 ++++
>>>> drivers/pci/controller/cadence/pcie-cadence-host.c | 4 ++++
>>>> drivers/pci/controller/cadence/pcie-cadence.h | 2 ++
>>>> 4 files changed, 11 insertions(+)
>>>>
>>>> diff --git a/drivers/pci/controller/cadence/pci-j721e.c
>>>> b/drivers/pci/controller/cadence/pci-j721e.c
>>>> index bfdfe98d5aba..ae916e7b1927 100644
>>>> --- a/drivers/pci/controller/cadence/pci-j721e.c
>>>> +++ b/drivers/pci/controller/cadence/pci-j721e.c
>>>> @@ -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)
>>>> diff --git a/drivers/pci/controller/cadence/pcie-cadence-host-common.c
>>>> b/drivers/pci/controller/cadence/pcie-cadence-host-common.c
>>>> index 2b0211870f02..18e4b6c760b5 100644
>>>> --- a/drivers/pci/controller/cadence/pcie-cadence-host-common.c
>>>> +++ b/drivers/pci/controller/cadence/pcie-cadence-host-common.c
>>>> @@ -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);
>>>> diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c
>>>> b/drivers/pci/controller/cadence/pcie-cadence-host.c
>>>> index 0bc9e6e90e0e..058e4e619654 100644
>>>> --- a/drivers/pci/controller/cadence/pcie-cadence-host.c
>>>> +++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
>>>> @@ -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);
>>>> +
>>> Why is the conditional if required here as during cdns_pcie_host_setup(), the
>> value of
>>> max_link_speed is expected to be '0', unless specifically initialized by the
>> platform code separately.
>>>
>>> What happens if the max_link_speed is not defined in the corresponding dts
>> ? Would not the -EINVAL returned from the function create issues ?
>>
>> Hi Manikandan,
>>
>> Please see:
>>
>> https://urldefense.com/v3/__https://github.com/torvalds/linux/blob/v7.1-
>> rc4/drivers/pci/controller/dwc/pcie-
>> designware.c*L191__;Iw!!EHscmS1ygiU1lA!EDHVakD3QN0gGza3V1__qzHgDG9
>> RZlq7LzC5AFsYLV2i5FcoveNFsjWORRgRdHCAmOI-LizY5cJvGIWBOFJG$
>>
>>
>> Best regards,
>> Hans
>>
> That is how Designware has implemented it but that does not answer my query. Becos both these implementations do
> not take care of the error returned, and it could well be the case for many of the current implementations.
Hi Manikandan,
If "max-link-speed" is not defined in the DT, then:
of_pci_get_max_link_speed
of_property_read_u32
of_property_read_u32_array
of_property_read_variable_u32_array
return -EINVAL;
For patch 0001, no actions will be executed. I wonder if this answers
your question?
Best regards,
Hans
>
>>>
>>>> pcie->reg_base = devm_platform_ioremap_resource_byname(pdev,
>>>> "reg");
>>>> if (IS_ERR(pcie->reg_base)) {
>>>> dev_err(dev, "missing \"reg\"\n");
>>>> diff --git a/drivers/pci/controller/cadence/pcie-cadence.h
>>>> b/drivers/pci/controller/cadence/pcie-cadence.h
>>>> index 574e9cf4d003..042a4c49bb9a 100644
>>>> --- a/drivers/pci/controller/cadence/pcie-cadence.h
>>>> +++ b/drivers/pci/controller/cadence/pcie-cadence.h
>>>> @@ -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;
>>>> };
>>>>
>>>> /**
>>>> --
>>>> 2.43.0
>
^ permalink raw reply [flat|nested] 16+ messages in thread* RE: [PATCH v4 2/7] PCI: cadence: Add post-link delay for LGA and j721e glue driver
2026-05-18 3:03 ` Hans Zhang
@ 2026-05-18 3:17 ` Manikandan Karunakaran Pillai
0 siblings, 0 replies; 16+ messages in thread
From: Manikandan Karunakaran Pillai @ 2026-05-18 3:17 UTC (permalink / raw)
To: Hans Zhang, bhelgaas@google.com, lpieralisi@kernel.org,
kwilczynski@kernel.org, mani@kernel.org, vigneshr@ti.com,
jingoohan1@gmail.com, thomas.petazzoni@bootlin.com,
ryder.lee@mediatek.com, claudiu.beznea.uj@bp.renesas.com
Cc: robh@kernel.org, s-vadapalli@ti.com, linux-omap@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, claudiu.beznea@tuxon.dev,
linux-mediatek@lists.infradead.org,
linux-renesas-soc@vger.kernel.org, linux-pci@vger.kernel.org,
linux-kernel@vger.kernel.org
>>>>>
>>>>> #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);
>>>>> diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c
>>>>> b/drivers/pci/controller/cadence/pcie-cadence-host.c
>>>>> index 0bc9e6e90e0e..058e4e619654 100644
>>>>> --- a/drivers/pci/controller/cadence/pcie-cadence-host.c
>>>>> +++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
>>>>> @@ -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);
>>>>> +
>>>> Why is the conditional if required here as during cdns_pcie_host_setup(),
>the
>>> value of
>>>> max_link_speed is expected to be '0', unless specifically initialized by the
>>> platform code separately.
>>>>
>>>> What happens if the max_link_speed is not defined in the corresponding
>dts
>>> ? Would not the -EINVAL returned from the function create issues ?
>>>
>>> Hi Manikandan,
>>>
>>> Please see:
>>>
>>> https://urldefense.com/v3/__https://github.com/torvalds/linux/blob/v7.1-
>>> rc4/drivers/pci/controller/dwc/pcie-
>>>
>designware.c*L191__;Iw!!EHscmS1ygiU1lA!EDHVakD3QN0gGza3V1__qzHgDG9
>>> RZlq7LzC5AFsYLV2i5FcoveNFsjWORRgRdHCAmOI-LizY5cJvGIWBOFJG$
>>>
>>>
>>> Best regards,
>>> Hans
>>>
>> That is how Designware has implemented it but that does not answer my
>query. Becos both these implementations do
>> not take care of the error returned, and it could well be the case for many of
>the current implementations.
>
>Hi Manikandan,
>
>If "max-link-speed" is not defined in the DT, then:
>
>of_pci_get_max_link_speed
> of_property_read_u32
> of_property_read_u32_array
> of_property_read_variable_u32_array
> return -EINVAL;
>
>
>For patch 0001, no actions will be executed. I wonder if this answers
>your question?
>
Yes, got it. Thanks Hans.
>Best regards,
>Hans
>
>
>>
>>>>
>>>>> pcie->reg_base = devm_platform_ioremap_resource_byname(pdev,
>>>>> "reg");
>>>>> if (IS_ERR(pcie->reg_base)) {
>>>>> dev_err(dev, "missing \"reg\"\n");
>>>>> diff --git a/drivers/pci/controller/cadence/pcie-cadence.h
>>>>> b/drivers/pci/controller/cadence/pcie-cadence.h
>>>>> index 574e9cf4d003..042a4c49bb9a 100644
>>>>> --- a/drivers/pci/controller/cadence/pcie-cadence.h
>>>>> +++ b/drivers/pci/controller/cadence/pcie-cadence.h
>>>>> @@ -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;
>>>>> };
>>>>>
>>>>> /**
>>>>> --
>>>>> 2.43.0
>>
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v4 3/7] PCI: cadence: HPA: Add post-link delay
2026-05-18 0:42 [PATCH v4 0/7] PCI: Add common helper for 100 ms delay after link training Hans Zhang
2026-05-18 0:42 ` [PATCH v4 1/7] PCI: Add pci_host_common_link_train_delay() helper Hans Zhang
2026-05-18 0:42 ` [PATCH v4 2/7] PCI: cadence: Add post-link delay for LGA and j721e glue driver Hans Zhang
@ 2026-05-18 0:42 ` Hans Zhang
2026-05-18 2:16 ` Manikandan Karunakaran Pillai
2026-05-18 0:42 ` [PATCH v4 4/7] PCI: dwc: Use common pci_host_common_link_train_delay() helper Hans Zhang
` (4 subsequent siblings)
7 siblings, 1 reply; 16+ messages in thread
From: Hans Zhang @ 2026-05-18 0:42 UTC (permalink / raw)
To: bhelgaas, lpieralisi, kwilczynski, mani, vigneshr, jingoohan1,
thomas.petazzoni, ryder.lee, claudiu.beznea.uj, mpillai
Cc: robh, s-vadapalli, linux-omap, linux-arm-kernel, claudiu.beznea,
linux-mediatek, linux-renesas-soc, linux-pci, linux-kernel,
Hans Zhang
The Cadence HPA (High Performance Architecture IP) specific link setup
function cdns_pcie_hpa_host_link_setup() waits for the link to come up
but does not implement the required 100 ms delay after link training
completes for speeds > 5.0 GT/s (PCIe r6.0 sec 6.6.1).
Add a call to pci_host_common_link_train_delay() immediately after the
link is confirmed to be up, using the max_link_speed field. Also, in the
HPA host setup function, read the device tree property "max-link-speed"
to initialize max_link_speed if not already set by a glue driver.
This ensures compliance for HPA-based platforms.
Signed-off-by: Hans Zhang <18255117159@163.com>
---
drivers/pci/controller/cadence/pcie-cadence-host-hpa.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c b/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
index 0f540bed58e8..8ef58ed01daa 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
@@ -15,6 +15,8 @@
#include "pcie-cadence.h"
#include "pcie-cadence-host-common.h"
+#include "../pci-host-common.h"
+#include "../../pci.h"
static u8 bar_aperture_mask[] = {
[RP_BAR0] = 0x3F,
@@ -304,6 +306,8 @@ int cdns_pcie_hpa_host_link_setup(struct cdns_pcie_rc *rc)
ret = cdns_pcie_host_wait_for_link(pcie, cdns_pcie_hpa_link_up);
if (ret)
dev_dbg(dev, "PCIe link never came up\n");
+ else
+ pci_host_common_link_train_delay(pcie->max_link_speed);
return ret;
}
@@ -313,6 +317,7 @@ int cdns_pcie_hpa_host_setup(struct cdns_pcie_rc *rc)
{
struct device *dev = rc->pcie.dev;
struct platform_device *pdev = to_platform_device(dev);
+ struct device_node *np = dev->of_node;
struct pci_host_bridge *bridge;
enum cdns_pcie_rp_bar bar;
struct cdns_pcie *pcie;
@@ -343,6 +348,9 @@ int cdns_pcie_hpa_host_setup(struct cdns_pcie_rc *rc)
rc->cfg_res = res;
}
+ if (pcie->max_link_speed < 1)
+ pcie->max_link_speed = of_pci_get_max_link_speed(np);
+
/* Put EROM Bar aperture to 0 */
cdns_pcie_hpa_writel(pcie, REG_BANK_IP_CFG_CTRL_REG, CDNS_PCIE_EROM, 0x0);
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* RE: [PATCH v4 3/7] PCI: cadence: HPA: Add post-link delay
2026-05-18 0:42 ` [PATCH v4 3/7] PCI: cadence: HPA: Add post-link delay Hans Zhang
@ 2026-05-18 2:16 ` Manikandan Karunakaran Pillai
2026-05-18 2:27 ` Hans Zhang
0 siblings, 1 reply; 16+ messages in thread
From: Manikandan Karunakaran Pillai @ 2026-05-18 2:16 UTC (permalink / raw)
To: Hans Zhang, bhelgaas@google.com, lpieralisi@kernel.org,
kwilczynski@kernel.org, mani@kernel.org, vigneshr@ti.com,
jingoohan1@gmail.com, thomas.petazzoni@bootlin.com,
ryder.lee@mediatek.com, claudiu.beznea.uj@bp.renesas.com
Cc: robh@kernel.org, s-vadapalli@ti.com, linux-omap@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, claudiu.beznea@tuxon.dev,
linux-mediatek@lists.infradead.org,
linux-renesas-soc@vger.kernel.org, linux-pci@vger.kernel.org,
linux-kernel@vger.kernel.org
>EXTERNAL MAIL
>
>
>The Cadence HPA (High Performance Architecture IP) specific link setup
>function cdns_pcie_hpa_host_link_setup() waits for the link to come up
>but does not implement the required 100 ms delay after link training
>completes for speeds > 5.0 GT/s (PCIe r6.0 sec 6.6.1).
>
>Add a call to pci_host_common_link_train_delay() immediately after the
>link is confirmed to be up, using the max_link_speed field. Also, in the
>HPA host setup function, read the device tree property "max-link-speed"
>to initialize max_link_speed if not already set by a glue driver.
>
>This ensures compliance for HPA-based platforms.
>
>Signed-off-by: Hans Zhang <18255117159@163.com>
>---
> drivers/pci/controller/cadence/pcie-cadence-host-hpa.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
>diff --git a/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
>b/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
>index 0f540bed58e8..8ef58ed01daa 100644
>--- a/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
>+++ b/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
>@@ -15,6 +15,8 @@
>
> #include "pcie-cadence.h"
> #include "pcie-cadence-host-common.h"
>+#include "../pci-host-common.h"
>+#include "../../pci.h"
>
> static u8 bar_aperture_mask[] = {
> [RP_BAR0] = 0x3F,
>@@ -304,6 +306,8 @@ int cdns_pcie_hpa_host_link_setup(struct cdns_pcie_rc
>*rc)
> ret = cdns_pcie_host_wait_for_link(pcie, cdns_pcie_hpa_link_up);
> if (ret)
> dev_dbg(dev, "PCIe link never came up\n");
>+ else
>+ pci_host_common_link_train_delay(pcie->max_link_speed);
>
> return ret;
> }
>@@ -313,6 +317,7 @@ int cdns_pcie_hpa_host_setup(struct cdns_pcie_rc *rc)
> {
> struct device *dev = rc->pcie.dev;
> struct platform_device *pdev = to_platform_device(dev);
>+ struct device_node *np = dev->of_node;
> struct pci_host_bridge *bridge;
> enum cdns_pcie_rp_bar bar;
> struct cdns_pcie *pcie;
>@@ -343,6 +348,9 @@ int cdns_pcie_hpa_host_setup(struct cdns_pcie_rc *rc)
> rc->cfg_res = res;
> }
>
>+ if (pcie->max_link_speed < 1)
>+ pcie->max_link_speed = of_pci_get_max_link_speed(np);
>+
Similar queries as for Cadence LGA controllers. Why do you need the max_link_speed check for "<1" and
What would be the consequences of not defining the max-link-speed in dts ?
> /* Put EROM Bar aperture to 0 */
> cdns_pcie_hpa_writel(pcie, REG_BANK_IP_CFG_CTRL_REG,
>CDNS_PCIE_EROM, 0x0);
>
>--
>2.43.0
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [PATCH v4 3/7] PCI: cadence: HPA: Add post-link delay
2026-05-18 2:16 ` Manikandan Karunakaran Pillai
@ 2026-05-18 2:27 ` Hans Zhang
0 siblings, 0 replies; 16+ messages in thread
From: Hans Zhang @ 2026-05-18 2:27 UTC (permalink / raw)
To: Manikandan Karunakaran Pillai, bhelgaas@google.com,
lpieralisi@kernel.org, kwilczynski@kernel.org, mani@kernel.org,
vigneshr@ti.com, jingoohan1@gmail.com,
thomas.petazzoni@bootlin.com, ryder.lee@mediatek.com,
claudiu.beznea.uj@bp.renesas.com
Cc: robh@kernel.org, s-vadapalli@ti.com, linux-omap@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, claudiu.beznea@tuxon.dev,
linux-mediatek@lists.infradead.org,
linux-renesas-soc@vger.kernel.org, linux-pci@vger.kernel.org,
linux-kernel@vger.kernel.org
On 5/18/26 10:16, Manikandan Karunakaran Pillai wrote:
>
>
>> EXTERNAL MAIL
>>
>>
>> The Cadence HPA (High Performance Architecture IP) specific link setup
>> function cdns_pcie_hpa_host_link_setup() waits for the link to come up
>> but does not implement the required 100 ms delay after link training
>> completes for speeds > 5.0 GT/s (PCIe r6.0 sec 6.6.1).
>>
>> Add a call to pci_host_common_link_train_delay() immediately after the
>> link is confirmed to be up, using the max_link_speed field. Also, in the
>> HPA host setup function, read the device tree property "max-link-speed"
>> to initialize max_link_speed if not already set by a glue driver.
>>
>> This ensures compliance for HPA-based platforms.
>>
>> Signed-off-by: Hans Zhang <18255117159@163.com>
>> ---
>> drivers/pci/controller/cadence/pcie-cadence-host-hpa.c | 8 ++++++++
>> 1 file changed, 8 insertions(+)
>>
>> diff --git a/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
>> b/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
>> index 0f540bed58e8..8ef58ed01daa 100644
>> --- a/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
>> +++ b/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
>> @@ -15,6 +15,8 @@
>>
>> #include "pcie-cadence.h"
>> #include "pcie-cadence-host-common.h"
>> +#include "../pci-host-common.h"
>> +#include "../../pci.h"
>>
>> static u8 bar_aperture_mask[] = {
>> [RP_BAR0] = 0x3F,
>> @@ -304,6 +306,8 @@ int cdns_pcie_hpa_host_link_setup(struct cdns_pcie_rc
>> *rc)
>> ret = cdns_pcie_host_wait_for_link(pcie, cdns_pcie_hpa_link_up);
>> if (ret)
>> dev_dbg(dev, "PCIe link never came up\n");
>> + else
>> + pci_host_common_link_train_delay(pcie->max_link_speed);
>>
>> return ret;
>> }
>> @@ -313,6 +317,7 @@ int cdns_pcie_hpa_host_setup(struct cdns_pcie_rc *rc)
>> {
>> struct device *dev = rc->pcie.dev;
>> struct platform_device *pdev = to_platform_device(dev);
>> + struct device_node *np = dev->of_node;
>> struct pci_host_bridge *bridge;
>> enum cdns_pcie_rp_bar bar;
>> struct cdns_pcie *pcie;
>> @@ -343,6 +348,9 @@ int cdns_pcie_hpa_host_setup(struct cdns_pcie_rc *rc)
>> rc->cfg_res = res;
>> }
>>
>> + if (pcie->max_link_speed < 1)
>> + pcie->max_link_speed = of_pci_get_max_link_speed(np);
>> +
>
> Similar queries as for Cadence LGA controllers. Why do you need the max_link_speed check for "<1" and
> What would be the consequences of not defining the max-link-speed in dts ?
Hi Manikandan,
It has been replied in patch 0002.
Best regards,
Hans
>
>> /* Put EROM Bar aperture to 0 */
>> cdns_pcie_hpa_writel(pcie, REG_BANK_IP_CFG_CTRL_REG,
>> CDNS_PCIE_EROM, 0x0);
>>
>> --
>> 2.43.0
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v4 4/7] PCI: dwc: Use common pci_host_common_link_train_delay() helper
2026-05-18 0:42 [PATCH v4 0/7] PCI: Add common helper for 100 ms delay after link training Hans Zhang
` (2 preceding siblings ...)
2026-05-18 0:42 ` [PATCH v4 3/7] PCI: cadence: HPA: Add post-link delay Hans Zhang
@ 2026-05-18 0:42 ` Hans Zhang
2026-05-18 0:42 ` [PATCH v4 5/7] PCI: aardvark: Add 100 ms delay after link training Hans Zhang
` (3 subsequent siblings)
7 siblings, 0 replies; 16+ messages in thread
From: Hans Zhang @ 2026-05-18 0:42 UTC (permalink / raw)
To: bhelgaas, lpieralisi, kwilczynski, mani, vigneshr, jingoohan1,
thomas.petazzoni, ryder.lee, claudiu.beznea.uj, mpillai
Cc: robh, s-vadapalli, linux-omap, linux-arm-kernel, claudiu.beznea,
linux-mediatek, linux-renesas-soc, linux-pci, linux-kernel,
Hans Zhang
The DWC driver already implements the 100 ms delay required by PCIe
r6.0 sec 6.6.1 by checking pci->max_link_speed and calling msleep(100).
Replace the open-coded msleep() with the new common helper
pci_host_common_link_train_delay() to reduce code duplication and
improve maintainability. No functional change intended.
Signed-off-by: Hans Zhang <18255117159@163.com>
---
drivers/pci/controller/dwc/pcie-designware.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
index c11cf61b8319..7021d21bb601 100644
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -22,6 +22,7 @@
#include <linux/sizes.h>
#include <linux/types.h>
+#include "../pci-host-common.h"
#include "../../pci.h"
#include "pcie-designware.h"
@@ -799,13 +800,7 @@ int dw_pcie_wait_for_link(struct dw_pcie *pci)
return -ETIMEDOUT;
}
- /*
- * As per PCIe r6.0, sec 6.6.1, a Downstream Port that supports Link
- * speeds greater than 5.0 GT/s, software must wait a minimum of 100 ms
- * after Link training completes before sending a Configuration Request.
- */
- if (pci->max_link_speed > 2)
- msleep(PCIE_RESET_CONFIG_WAIT_MS);
+ pci_host_common_link_train_delay(pci->max_link_speed);
offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
val = dw_pcie_readw_dbi(pci, offset + PCI_EXP_LNKSTA);
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v4 5/7] PCI: aardvark: Add 100 ms delay after link training
2026-05-18 0:42 [PATCH v4 0/7] PCI: Add common helper for 100 ms delay after link training Hans Zhang
` (3 preceding siblings ...)
2026-05-18 0:42 ` [PATCH v4 4/7] PCI: dwc: Use common pci_host_common_link_train_delay() helper Hans Zhang
@ 2026-05-18 0:42 ` Hans Zhang
2026-05-18 0:42 ` [PATCH v4 6/7] PCI: mediatek-gen3: Add 100 ms delay after link up Hans Zhang
` (2 subsequent siblings)
7 siblings, 0 replies; 16+ messages in thread
From: Hans Zhang @ 2026-05-18 0:42 UTC (permalink / raw)
To: bhelgaas, lpieralisi, kwilczynski, mani, vigneshr, jingoohan1,
thomas.petazzoni, ryder.lee, claudiu.beznea.uj, mpillai
Cc: robh, s-vadapalli, linux-omap, linux-arm-kernel, claudiu.beznea,
linux-mediatek, linux-renesas-soc, linux-pci, linux-kernel,
Hans Zhang
The Aardvark PCIe controller driver waits for the link to come up but
does not implement the mandatory 100 ms delay after link training
completes for speeds greater than 5.0 GT/s (PCIe r6.0 sec 6.6.1).
The driver already maintains a 'link_gen' field that holds the negotiated
link speed. Use it together with pci_host_common_link_train_delay() to
insert the required delay immediately after confirming that the link
is up.
Signed-off-by: Hans Zhang <18255117159@163.com>
---
drivers/pci/controller/pci-aardvark.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index e34bea1ff0ac..fd9c7d53e8a7 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -26,6 +26,7 @@
#include <linux/of_address.h>
#include <linux/of_pci.h>
+#include "pci-host-common.h"
#include "../pci.h"
#include "../pci-bridge-emul.h"
@@ -350,8 +351,10 @@ static int advk_pcie_wait_for_link(struct advk_pcie *pcie)
/* check if the link is up or not */
for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
- if (advk_pcie_link_up(pcie))
+ if (advk_pcie_link_up(pcie)) {
+ pci_host_common_link_train_delay(pcie->link_gen);
return 0;
+ }
usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v4 6/7] PCI: mediatek-gen3: Add 100 ms delay after link up
2026-05-18 0:42 [PATCH v4 0/7] PCI: Add common helper for 100 ms delay after link training Hans Zhang
` (4 preceding siblings ...)
2026-05-18 0:42 ` [PATCH v4 5/7] PCI: aardvark: Add 100 ms delay after link training Hans Zhang
@ 2026-05-18 0:42 ` Hans Zhang
2026-05-18 0:42 ` [PATCH v4 7/7] PCI: rzg3s-host: Use common pci_host_common_link_train_delay() helper Hans Zhang
2026-06-09 15:25 ` [PATCH v4 0/7] PCI: Add common helper for 100 ms delay after link training Manivannan Sadhasivam
7 siblings, 0 replies; 16+ messages in thread
From: Hans Zhang @ 2026-05-18 0:42 UTC (permalink / raw)
To: bhelgaas, lpieralisi, kwilczynski, mani, vigneshr, jingoohan1,
thomas.petazzoni, ryder.lee, claudiu.beznea.uj, mpillai
Cc: robh, s-vadapalli, linux-omap, linux-arm-kernel, claudiu.beznea,
linux-mediatek, linux-renesas-soc, linux-pci, linux-kernel,
Hans Zhang
The MediaTek Gen3 PCIe host driver lacks the required 100 ms delay after
link training completes for speeds > 5.0 GT/s, as specified in PCIe r6.0
sec 6.6.1.
The driver already stores max_link_speed (from the device tree). After
mtk_pcie_startup_port() successfully brings up the link, call
pci_host_common_link_train_delay() to comply with the specification.
Signed-off-by: Hans Zhang <18255117159@163.com>
---
drivers/pci/controller/pcie-mediatek-gen3.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c
index b0accd828589..5abddec4e9be 100644
--- a/drivers/pci/controller/pcie-mediatek-gen3.c
+++ b/drivers/pci/controller/pcie-mediatek-gen3.c
@@ -30,6 +30,7 @@
#include <linux/regmap.h>
#include <linux/reset.h>
+#include "pci-host-common.h"
#include "../pci.h"
#define PCIE_BASE_CFG_REG 0x14
@@ -570,6 +571,8 @@ static int mtk_pcie_startup_port(struct mtk_gen3_pcie *pcie)
goto err_power_down_device;
}
+ pci_host_common_link_train_delay(pcie->max_link_speed);
+
return 0;
err_power_down_device:
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v4 7/7] PCI: rzg3s-host: Use common pci_host_common_link_train_delay() helper
2026-05-18 0:42 [PATCH v4 0/7] PCI: Add common helper for 100 ms delay after link training Hans Zhang
` (5 preceding siblings ...)
2026-05-18 0:42 ` [PATCH v4 6/7] PCI: mediatek-gen3: Add 100 ms delay after link up Hans Zhang
@ 2026-05-18 0:42 ` Hans Zhang
2026-06-09 15:25 ` [PATCH v4 0/7] PCI: Add common helper for 100 ms delay after link training Manivannan Sadhasivam
7 siblings, 0 replies; 16+ messages in thread
From: Hans Zhang @ 2026-05-18 0:42 UTC (permalink / raw)
To: bhelgaas, lpieralisi, kwilczynski, mani, vigneshr, jingoohan1,
thomas.petazzoni, ryder.lee, claudiu.beznea.uj, mpillai
Cc: robh, s-vadapalli, linux-omap, linux-arm-kernel, claudiu.beznea,
linux-mediatek, linux-renesas-soc, linux-pci, linux-kernel,
Hans Zhang
Replace the unconditional msleep(100) with the common helper
pci_host_common_link_train_delay(). The helper only waits when
max_link_speed > 2, as required by PCIe r6.0 sec 6.6.1.
This avoids unnecessary delay for Gen1/Gen2 links while retaining
the mandatory 100 ms for higher speeds.
Signed-off-by: Hans Zhang <18255117159@163.com>
---
drivers/pci/controller/pcie-rzg3s-host.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/controller/pcie-rzg3s-host.c b/drivers/pci/controller/pcie-rzg3s-host.c
index d86e7516dcc2..66f687304c1c 100644
--- a/drivers/pci/controller/pcie-rzg3s-host.c
+++ b/drivers/pci/controller/pcie-rzg3s-host.c
@@ -35,6 +35,7 @@
#include <linux/slab.h>
#include <linux/units.h>
+#include "pci-host-common.h"
#include "../pci.h"
/* AXI registers */
@@ -1663,7 +1664,7 @@ rzg3s_pcie_host_setup(struct rzg3s_pcie_host *host,
if (ret)
dev_info(dev, "Failed to set max link speed\n");
- msleep(PCIE_RESET_CONFIG_WAIT_MS);
+ pci_host_common_link_train_delay(host->max_link_speed);
return 0;
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* Re: [PATCH v4 0/7] PCI: Add common helper for 100 ms delay after link training
2026-05-18 0:42 [PATCH v4 0/7] PCI: Add common helper for 100 ms delay after link training Hans Zhang
` (6 preceding siblings ...)
2026-05-18 0:42 ` [PATCH v4 7/7] PCI: rzg3s-host: Use common pci_host_common_link_train_delay() helper Hans Zhang
@ 2026-06-09 15:25 ` Manivannan Sadhasivam
7 siblings, 0 replies; 16+ messages in thread
From: Manivannan Sadhasivam @ 2026-06-09 15:25 UTC (permalink / raw)
To: bhelgaas, lpieralisi, kwilczynski, vigneshr, jingoohan1,
thomas.petazzoni, ryder.lee, claudiu.beznea.uj, mpillai,
Hans Zhang
Cc: robh, s-vadapalli, linux-omap, linux-arm-kernel, claudiu.beznea,
linux-mediatek, linux-renesas-soc, linux-pci, linux-kernel
On Mon, 18 May 2026 08:42:39 +0800, Hans Zhang wrote:
> PCIe r6.0, sec 6.6.1 (Conventional Reset) requires that for a Downstream
> Port supporting Link speeds greater than 5.0 GT/s, software must wait a
> minimum of 100 ms after Link training completes before sending any
> Configuration Request.
>
> Several PCIe host controller drivers currently omit this 100 ms delay
> when the negotiated link speed is Gen3 (8 GT/s) or higher. Only the DWC
> driver already implements it. The missing delay can lead to violations
> of the PCIe specification and cause enumeration failures with high-speed
> devices (e.g., NVIDIA RTX5070 GPU, PCIe 5.0 NVMe SSDs).
>
> [...]
Applied, thanks!
[1/7] PCI: Add pci_host_common_link_train_delay() helper
commit: 29fbf582e75015c031e7965fdd4084af123b9ca2
[2/7] PCI: cadence: Add post-link delay for LGA and j721e glue driver
commit: 869317b95fd735684057666a65dd8ef95d4bd669
[3/7] PCI: cadence: HPA: Add post-link delay
commit: 8dd5d65d0dc750b6890c0102c3992f4cef516196
[4/7] PCI: dwc: Use common pci_host_common_link_train_delay() helper
commit: 681adc339e4c972b9f7a5ef8c2fb6a2f7737d4db
[5/7] PCI: aardvark: Add 100 ms delay after link training
commit: 8a602b8bfebbf9a755e8f4732132719a3b298b29
[6/7] PCI: mediatek-gen3: Add 100 ms delay after link up
commit: 798a96740d61c24f193b82388b681b6a4f102d3b
[7/7] PCI: rzg3s-host: Use common pci_host_common_link_train_delay() helper
commit: 0ae259d0434bc31fc71696355538fd21027d6ebe
Best regards,
--
Manivannan Sadhasivam <mani@kernel.org>
^ permalink raw reply [flat|nested] 16+ messages in thread