summaryrefslogtreecommitdiff
path: root/drivers/pci
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2026-02-04 10:40:37 -0600
committerTom Rini <[email protected]>2026-02-04 10:40:37 -0600
commit5f0b0ad72246382cadcd469ef6724961c7720b0e (patch)
tree04b83904fe22dfd08c51430757f3867c1b363741 /drivers/pci
parente7a21a985da632fcaaed1cf7b90f6c025fcb389f (diff)
parent0cf1b43dbbb317efbdacf144e050e1d4adf886d8 (diff)
Merge patch series "arm: k3: j722s: add PCIe support"
George McCollister <[email protected]> says: This patch series brings over several changes from Linux that are required to get PCIe working on the j722s and also enables PCIe in j722s_evm_a53_defconfig. This allows Linux to be booted from an NVMe drive. The J722S SoC provides pcie0 (using pcie_cdns_ti) thru serdes1 (using phy-cadence-torrent) thru serdes_wiz1 (using phy-j721e-wiz). Changes to the three drivers needed to be ported from Linux to enable the REFCLK output which is used with this SoC. These changes should be tested on other platforms using these drivers by those with the hardware available to make sure no problems were introduced. The PCIe controller in this SoC relies on the code performing the PCI scan not scanning devices which cannot exist. In Linux this is implemented as only_one_child() in probe.c. If this mechanism is not used, PCI config reads for subsequent functions will return information for device 0 resulting in U-Boot detecting 32 devices when only 1 is present. This change should be tested on other platforms with PCI to ensure the same PCI devices are enumerated before and after the patch is applied. I would like to thank Opto 22 for sponsoring the initial development and anyone that is able to contribute to testing of patches. Link: https://lore.kernel.org/r/[email protected]
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/pci-uclass.c35
-rw-r--r--drivers/pci/pcie_cdns_ti.c23
2 files changed, 58 insertions, 0 deletions
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index c370f8c6400..83b76d01f24 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -872,6 +872,38 @@ __weak extern void board_pci_fixup_dev(struct udevice *bus, struct udevice *dev)
{
}
+static int only_one_child(struct udevice *bus)
+{
+ int pos;
+
+ if (!dev_get_parent_plat(bus))
+ return 0;
+
+ /*
+ * A PCIe Downstream Port normally leads to a Link with only Device
+ * 0 on it (PCIe spec r3.1, sec 7.3.1). As an optimization, scan
+ * only for Device 0 in that situation.
+ */
+ pos = dm_pci_find_capability(bus, PCI_CAP_ID_EXP);
+ if (pos) {
+ ulong reg;
+ ulong pcie_type;
+
+ dm_pci_read_config(bus, pos + PCI_EXP_FLAGS,
+ &reg, PCI_SIZE_16);
+
+ pcie_type = (reg & PCI_EXP_FLAGS_TYPE) >> 4;
+
+ if (pcie_type == PCI_EXP_TYPE_ROOT_PORT ||
+ pcie_type == PCI_EXP_TYPE_DOWNSTREAM ||
+ pcie_type == PCI_EXP_TYPE_PCIE_BRIDGE) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
int pci_bind_bus_devices(struct udevice *bus)
{
ulong vendor, device;
@@ -895,6 +927,9 @@ int pci_bind_bus_devices(struct udevice *bus)
if (PCI_FUNC(bdf) && !found_multi)
continue;
+ if (only_one_child(bus) && (PCI_MASK_BUS(bdf) > 0))
+ continue;
+
/* Check only the first access, we don't expect problems */
ret = pci_bus_read_config(bus, bdf, PCI_VENDOR_ID, &vendor,
PCI_SIZE_16);
diff --git a/drivers/pci/pcie_cdns_ti.c b/drivers/pci/pcie_cdns_ti.c
index 9d1d123a18c..38804f1c09c 100644
--- a/drivers/pci/pcie_cdns_ti.c
+++ b/drivers/pci/pcie_cdns_ti.c
@@ -742,6 +742,20 @@ static int pcie_cdns_ti_probe(struct udevice *dev)
}
generic_phy_reset(&serdes);
generic_phy_init(&serdes);
+
+ clk = devm_clk_get_optional(dev, "pcie_refclk");
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+ dev_err(dev, "failed to get pcie_refclk\n");
+ return ret;
+ }
+
+ ret = clk_prepare_enable(clk);
+ if (ret) {
+ dev_err(dev, "failed to enable pcie_refclk\n");
+ return ret;
+ }
+
generic_phy_power_on(&serdes);
ret = pcie_cdns_ti_ctrl_init(pcie);
@@ -841,6 +855,11 @@ static const struct pcie_cdns_ti_data am64_pcie_rc_data = {
.max_lanes = 1,
};
+static const struct pcie_cdns_ti_data j722s_pcie_rc_data = {
+ .mode = PCIE_MODE_RC,
+ .max_lanes = 1,
+};
+
static const struct udevice_id pcie_cdns_ti_ids[] = {
{
.compatible = "ti,j7200-pcie-host",
@@ -850,6 +869,10 @@ static const struct udevice_id pcie_cdns_ti_ids[] = {
.compatible = "ti,am64-pcie-host",
.data = (ulong)&am64_pcie_rc_data,
},
+ {
+ .compatible = "ti,j722s-pcie-host",
+ .data = (ulong)&j722s_pcie_rc_data,
+ },
{},
};