From 1389ab9bf9f627d4daed86f492091b00f110aa86 Mon Sep 17 00:00:00 2001 From: Rong Zhang Date: Fri, 1 May 2026 02:45:23 +0800 Subject: [PATCH 1/2] 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: 2410e3301fcc ("PCI: loongson: Don't access non-existent devices") Co-developed-by: Jiaxun Yang Signed-off-by: Jiaxun Yang Co-developed-by: Lain "Fearyncess" Yang Signed-off-by: Lain "Fearyncess" Yang Signed-off-by: Rong Zhang Signed-off-by: Manivannan Sadhasivam Link: https://oshwhub.com/wesd/b650 [1] Link: https://patch.msgid.link/20260501-ls7a-bridge-fixes-v2-1-69fa93683805@rong.moe --- drivers/pci/controller/pci-loongson.c | 31 ++++++++++++++------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/drivers/pci/controller/pci-loongson.c b/drivers/pci/controller/pci-loongson.c index bc630ab8a283..de5e809a537d 100644 --- a/drivers/pci/controller/pci-loongson.c +++ b/drivers/pci/controller/pci-loongson.c @@ -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; } From e373c789bac0ad73b472d8b44714df3bd18a4edf Mon Sep 17 00:00:00 2001 From: Ziyao Li Date: Sun, 12 Apr 2026 18:17:31 +0800 Subject: [PATCH 2/2] PCI: loongson: Override PCIe bridge supported speeds for Loongson-3C6000 series Older steppings of the Loongson-3C6000 series incorrectly report the supported link speeds on their PCIe bridges (device IDs 0x3c19, 0x3c29) as only 2.5 GT/s, despite the upstream bus supporting speeds from 2.5 GT/s up to 16 GT/s. As a result, since commit 774c71c52aa4 ("PCI/bwctrl: Enable only if more than one speed is supported"), bwctrl will be disabled if there's only one 2.5 GT/s value in vector 'supported_speeds'. Manually override the 'supported_speeds' field for affected PCIe bridges with those found on the upstream bus to correctly reflect the supported link speeds. Updating the speeds to reflect what the hardware actually supports avoids quirks in drivers consuming the speed information. This commit was originally found from AOSC OS[1]. Fixes: cd89edda4002 ("PCI: loongson: Add ACPI init support") Signed-off-by: Ayden Meng Signed-off-by: Mingcong Bai [Ziyao Li: move from drivers/pci/quirks.c to drivers/pci/controller/pci-loongson.c] Signed-off-by: Ziyao Li [Xi Ruoyao: Fixed falling through logic, added debug log, Fixes tag and rebased to 7.0-rc7] Signed-off-by: Xi Ruoyao Signed-off-by: Manivannan Sadhasivam [bhelgaas: commit log, https://lore.kernel.org/all/9d815df3b33a63223112b97440c01247935363c1.camel@xry111.site] Signed-off-by: Bjorn Helgaas Tested-by: Lain Fearyncess Yang Tested-by: Ayden Meng Tested-by: Mingcong Bai Reviewed-by: Huacai Chen Cc: stable@vger.kernel.org Link: https://github.com/AOSC-Tracking/linux/commit/4392f441363abdf6fa0a0433d73175a17f493454 Link: https://github.com/AOSC-Tracking/linux/pull/2 #1 Link: https://patch.msgid.link/20260412101731.107059-1-xry111@xry111.site --- drivers/pci/controller/pci-loongson.c | 36 +++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/drivers/pci/controller/pci-loongson.c b/drivers/pci/controller/pci-loongson.c index de5e809a537d..d0c643996476 100644 --- a/drivers/pci/controller/pci-loongson.c +++ b/drivers/pci/controller/pci-loongson.c @@ -177,6 +177,42 @@ static void loongson_pci_msi_quirk(struct pci_dev *dev) } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, DEV_LS7A_PCIE_PORT5, loongson_pci_msi_quirk); +/* + * Older steppings of the Loongson-3C6000 series incorrectly report the + * supported link speeds on their PCIe bridges (device IDs 0x3c19, + * 0x3c29) as only 2.5 GT/s, despite the upstream bus supporting speeds + * from 2.5 GT/s up to 16 GT/s. + */ +static void loongson_pci_bridge_speed_quirk(struct pci_dev *pdev) +{ + u8 old_supported_speeds = pdev->supported_speeds; + + switch (pdev->bus->max_bus_speed) { + case PCIE_SPEED_16_0GT: + pdev->supported_speeds |= PCI_EXP_LNKCAP2_SLS_16_0GB; + fallthrough; + case PCIE_SPEED_8_0GT: + pdev->supported_speeds |= PCI_EXP_LNKCAP2_SLS_8_0GB; + fallthrough; + case PCIE_SPEED_5_0GT: + pdev->supported_speeds |= PCI_EXP_LNKCAP2_SLS_5_0GB; + fallthrough; + case PCIE_SPEED_2_5GT: + pdev->supported_speeds |= PCI_EXP_LNKCAP2_SLS_2_5GB; + break; + default: + pci_warn(pdev, "unexpected max bus speed"); + + return; + } + + if (pdev->supported_speeds != old_supported_speeds) + pci_info(pdev, "fixed up supported link speeds: 0x%x => 0x%x", + old_supported_speeds, pdev->supported_speeds); +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_LOONGSON, 0x3c19, loongson_pci_bridge_speed_quirk); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_LOONGSON, 0x3c29, loongson_pci_bridge_speed_quirk); + static struct loongson_pci *pci_bus_to_loongson_pci(struct pci_bus *bus) { struct pci_config_window *cfg;