Merge branch 'pci/controller/link_train_delay'

- Add pci_host_common_link_train_delay() for the mandatory delay after
  > 5GT/s Link training completes and use it for cadence HPA, j721e, LGA;
  dwc; aardvark, mediatek-gen3, rzg3s (Hans Zhang)

* pci/controller/link_train_delay:
  PCI: rzg3s-host: Use common pci_host_common_link_train_delay() helper
  PCI: mediatek-gen3: Add 100 ms delay after link up
  PCI: aardvark: Add 100 ms delay after link training
  PCI: dwc: Use common pci_host_common_link_train_delay() helper
  PCI: cadence-hpa: Add post-link delay
  PCI: cadence: Add post-link delay for LGA and j721e glue driver
  PCI: Add pci_host_common_link_train_delay() helper

# Conflicts:
#	drivers/pci/controller/pci-host-common.h
This commit is contained in:
Bjorn Helgaas 2026-06-23 17:32:22 -05:00
commit dd81c6524b
10 changed files with 47 additions and 9 deletions

View 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)

View 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);

View File

@ -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);

View 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");

View 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;
};
/**

View File

@ -22,6 +22,7 @@
#include <linux/sizes.h>
#include <linux/types.h>
#include "../pci-host-common.h"
#include "../../pci.h"
#include "pcie-designware.h"
@ -803,13 +804,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);

View File

@ -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);
}

View File

@ -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;
/**
@ -51,4 +54,18 @@ struct pci_config_window *pci_host_common_ecam_create(struct device *dev,
bool pci_host_common_d3cold_possible(struct pci_host_bridge *bridge,
bool *pme_capable);
/**
* 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

View File

@ -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
@ -590,6 +591,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:

View File

@ -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;