diff options
| author | Tom Rini <[email protected]> | 2026-02-04 10:40:37 -0600 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2026-02-04 10:40:37 -0600 |
| commit | 5f0b0ad72246382cadcd469ef6724961c7720b0e (patch) | |
| tree | 04b83904fe22dfd08c51430757f3867c1b363741 /drivers/pci | |
| parent | e7a21a985da632fcaaed1cf7b90f6c025fcb389f (diff) | |
| parent | 0cf1b43dbbb317efbdacf144e050e1d4adf886d8 (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.c | 35 | ||||
| -rw-r--r-- | drivers/pci/pcie_cdns_ti.c | 23 |
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, + ®, 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, + }, {}, }; |
