mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
PCI: loongson: Do not ignore downstream devices on external bridges
Loongson PCI host controllers have a hardware quirk that requires
software to ignore downstream devices with device number > 0 on the
internal bridges. The current implementation applies the workaround to
all non-root buses, which breaks external bridges (e.g., PCIe switches)
with multiple downstream devices.
Fix it by only applying the workaround to internal bridges.
Tested on Loongson-LS3A4000-7A1000-NUC-SE, using AMD Promontory 21
chipset add-in card [1].
$ lspci -tnnnvvv
-[0000:00]-+-00.0 Loongson Technology LLC 7A1000 Chipset Hyper Transport Bridge Controller [0014:7a00]
+-00.1 Loongson Technology LLC 7A2000 Chipset Hyper Transport Bridge Controller [0014:7a10]
+-03.0 Loongson Technology LLC 2K1000/2000 / 7A1000 Chipset Gigabit Ethernet Controller [0014:7a03]
+-04.0 Loongson Technology LLC 2K1000 / 7A1000/2000 Chipset USB OHCI Controller [0014:7a24]
+-04.1 Loongson Technology LLC 2K1000 / 7A1000/2000 Chipset USB EHCI Controller [0014:7a14]
+-05.0 Loongson Technology LLC 2K1000 / 7A1000/2000 Chipset USB OHCI Controller [0014:7a24]
+-05.1 Loongson Technology LLC 2K1000 / 7A1000/2000 Chipset USB EHCI Controller [0014:7a14]
+-06.0 Loongson Technology LLC 7A1000 Chipset Vivante GC1000 GPU [0014:7a15]
+-06.1 Loongson Technology LLC 2K1000 / 7A1000 Chipset Display Controller [0014:7a06]
+-07.0 Loongson Technology LLC 2K1000/2000/3000 / 3B6000M / 7A1000/2000 Chipset HD Audio Controller [0014:7a07]
+-08.0 Loongson Technology LLC 2K1000 / 7A1000 Chipset 3Gb/s SATA AHCI Controller [0014:7a08]
+-08.1 Loongson Technology LLC 2K1000 / 7A1000 Chipset 3Gb/s SATA AHCI Controller [0014:7a08]
+-08.2 Loongson Technology LLC 2K1000 / 7A1000 Chipset 3Gb/s SATA AHCI Controller [0014:7a08]
+-09.0-[01]----00.0 Qualcomm Technologies, Inc QCNFA765 Wireless Network Adapter [17cb:1103]
+-0a.0-[02]----00.0 Etron Technology, Inc. EJ188/EJ198 USB 3.0 Host Controller [1b6f:7052]
+-0f.0-[03-08]----00.0-[04-08]--+-00.0-[05]----00.0 Shenzhen Longsys Electronics Co., Ltd. FORESEE XP1000 / Lexar Professional CFexpress Type B Gold series, NM620 PCIe NVME SSD (DRAM-less) [1d97:5216]
| +-08.0-[06]----00.0 MAXIO Technology (Hangzhou) Ltd. NVMe SSD Controller MAP1202 (DRAM-less) [1e4b:1202]
| +-0c.0-[07]----00.0 Advanced Micro Devices, Inc. [AMD] 600 Series Chipset USB 3.2 Controller [1022:43f7]
| \-0d.0-[08]----00.0 Advanced Micro Devices, Inc. [AMD] 600 Series Chipset SATA Controller [1022:43f6]
\-16.0 Loongson Technology LLC 7A1000 Chipset SPI Controller [0014:7a0b]
Fixes: 2410e3301f ("PCI: loongson: Don't access non-existent devices")
Co-developed-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Co-developed-by: Lain "Fearyncess" Yang <i@lain.vg>
Signed-off-by: Lain "Fearyncess" Yang <i@lain.vg>
Signed-off-by: Rong Zhang <i@rong.moe>
Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
Link: https://oshwhub.com/wesd/b650 [1]
Link: https://patch.msgid.link/20260501-ls7a-bridge-fixes-v2-1-69fa93683805@rong.moe
This commit is contained in:
parent
254f49634e
commit
1389ab9bf9
|
|
@ -80,6 +80,18 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON,
|
|||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON,
|
||||
DEV_LS7A_LPC, system_bus_quirk);
|
||||
|
||||
static const struct pci_device_id loongson_internal_bridge_devids[] = {
|
||||
{ PCI_VDEVICE(LOONGSON, DEV_LS2K_PCIE_PORT0) },
|
||||
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT0) },
|
||||
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT1) },
|
||||
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT2) },
|
||||
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT3) },
|
||||
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT4) },
|
||||
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT5) },
|
||||
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT6) },
|
||||
{ 0, },
|
||||
};
|
||||
|
||||
/*
|
||||
* Some Loongson PCIe ports have hardware limitations on their Maximum Read
|
||||
* Request Size. They can't handle anything larger than this. Sane
|
||||
|
|
@ -92,24 +104,13 @@ static void loongson_set_min_mrrs_quirk(struct pci_dev *pdev)
|
|||
{
|
||||
struct pci_bus *bus = pdev->bus;
|
||||
struct pci_dev *bridge;
|
||||
static const struct pci_device_id bridge_devids[] = {
|
||||
{ PCI_VDEVICE(LOONGSON, DEV_LS2K_PCIE_PORT0) },
|
||||
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT0) },
|
||||
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT1) },
|
||||
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT2) },
|
||||
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT3) },
|
||||
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT4) },
|
||||
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT5) },
|
||||
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT6) },
|
||||
{ 0, },
|
||||
};
|
||||
|
||||
/* look for the matching bridge */
|
||||
while (!pci_is_root_bus(bus)) {
|
||||
bridge = bus->self;
|
||||
bus = bus->parent;
|
||||
|
||||
if (pci_match_id(bridge_devids, bridge)) {
|
||||
if (pci_match_id(loongson_internal_bridge_devids, bridge)) {
|
||||
if (pcie_get_readrq(pdev) > 256) {
|
||||
pci_info(pdev, "limiting MRRS to 256\n");
|
||||
pcie_set_readrq(pdev, 256);
|
||||
|
|
@ -230,11 +231,11 @@ static void __iomem *pci_loongson_map_bus(struct pci_bus *bus,
|
|||
struct loongson_pci *priv = pci_bus_to_loongson_pci(bus);
|
||||
|
||||
/*
|
||||
* Do not read more than one device on the bus other than
|
||||
* the host bus.
|
||||
* Do not read more than one device on the internal bridges.
|
||||
*/
|
||||
if ((priv->data->flags & FLAG_DEV_FIX) && bus->self) {
|
||||
if (!pci_is_root_bus(bus) && (device > 0))
|
||||
if (!pci_is_root_bus(bus) && (device > 0) &&
|
||||
pci_match_id(loongson_internal_bridge_devids, bus->self))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user