From de90ff822269df88aa71987aa7e616de0131d15f Mon Sep 17 00:00:00 2001 From: Tianli Xiong Date: Fri, 9 Sep 2022 17:46:10 +0800 Subject: [PATCH 1/9] PCI: Check if entry->offset already exist for mem resource LoongArch inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I6BWFP -------------------------------- Fix patch "LoongArch: Add PCI controller support" Signed-off-by: Tianli Xiong Change-Id: I796b1224d8990fed952643adac491228d6541696 (cherry picked from commit 4fcec2019f42323a4aa020b697d9133aaf1effc0) --- arch/loongarch/pci/acpi.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/arch/loongarch/pci/acpi.c b/arch/loongarch/pci/acpi.c index 7706acd4c290..06a33cbf76d2 100644 --- a/arch/loongarch/pci/acpi.c +++ b/arch/loongarch/pci/acpi.c @@ -210,9 +210,11 @@ static int acpi_prepare_root_resources(struct acpi_pci_root_info *ci) if (status > 0) { resource_list_for_each_entry_safe(entry, tmp, &ci->resources) { if (entry->res->flags & IORESOURCE_MEM) { - entry->offset = ci->root->mcfg_addr & GENMASK_ULL(63, 40); - entry->res->start |= entry->offset; - entry->res->end |= entry->offset; + if(!entry->offset) { + entry->offset = ci->root->mcfg_addr & GENMASK_ULL(63, 40); + entry->res->start |= entry->offset; + entry->res->end |= entry->offset; + } } } return status; -- Gitee From e79635362b2f35c181705d1fc0e452abe8b04570 Mon Sep 17 00:00:00 2001 From: Tianli Xiong Date: Fri, 9 Sep 2022 18:03:19 +0800 Subject: [PATCH 2/9] PCI: Check if the pci controller can use both CFG0 and CFG1 mode to access configuration space LoongArch inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I6BWFP -------------------------------- Fix patch "PCI: loongson: Use generic 8/16/32-bit config ops on LS2K/LS7A" Signed-off-by: Tianli Xiong Change-Id: I59f2de29370d5d9085254d8c4337f4bbcae99de0 (cherry picked from commit d4a1d525e97c852d9dab4f8242a01c51cb814822) --- drivers/pci/controller/pci-loongson.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/pci/controller/pci-loongson.c b/drivers/pci/controller/pci-loongson.c index 679ff66f9c29..f0ace5748f81 100644 --- a/drivers/pci/controller/pci-loongson.c +++ b/drivers/pci/controller/pci-loongson.c @@ -282,6 +282,7 @@ static int loongson_pci_probe(struct platform_device *pdev) struct device_node *node = dev->of_node; struct pci_host_bridge *bridge; struct resource *regs; + unsigned int num = 0; if (!node) return -ENODEV; @@ -306,7 +307,9 @@ static int loongson_pci_probe(struct platform_device *pdev) } if (priv->data->flags & FLAG_CFG1) { - regs = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (priv->cfg0_base) + num = 1; + regs = platform_get_resource(pdev, IORESOURCE_MEM, num); if (!regs) dev_info(dev, "missing mem resource for cfg1\n"); else { -- Gitee From a6470d0a7d2879c0c948d913dee8d64065bcd188 Mon Sep 17 00:00:00 2001 From: Jianmin Lv Date: Tue, 6 Sep 2022 16:41:32 +0800 Subject: [PATCH 3/9] PCI: PM: Fix pcie mrrs restoring LoongArch inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I6BWFP -------------------------------- Don't limit mmrs during resume, so that saved value can be restored. Fix patch "PCI: loongson: Improve the MRRS quirk for LS7A" Signed-off-by: Jianmin Lv Change-Id: I63c49e5c1d7e2a0a6eb3de9faa13cef1f94a4462 (cherry picked from commit 269d4b0686bb448b07f9df26b2231cd1d981a234) --- drivers/pci/pci.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 8ace56c8141b..99eeafead49e 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "pci.h" DEFINE_MUTEX(pci_slot_mutex); @@ -147,6 +148,11 @@ static bool pci_bridge_d3_disable; /* Force bridge_d3 for all PCIe ports */ static bool pci_bridge_d3_force; +#ifndef CONFIG_PM_SLEEP +suspend_state_t pm_suspend_target_state; +#define pm_suspend_target_state (PM_SUSPEND_ON) +#endif + static int __init pcie_port_pm_setup(char *str) { if (!strcmp(str, "off")) @@ -5769,7 +5775,8 @@ int pcie_set_readrq(struct pci_dev *dev, int rq) v = (ffs(rq) - 8) << 12; - if (bridge->no_inc_mrrs) { + if (pm_suspend_target_state == PM_SUSPEND_ON && + bridge->no_inc_mrrs) { if (rq > pcie_get_readrq(dev)) return -EINVAL; } -- Gitee From 938826ed48637b15895dd9cd3e45f132b6a9ea34 Mon Sep 17 00:00:00 2001 From: Hongchen Zhang Date: Sun, 29 Jan 2023 17:43:12 +0800 Subject: [PATCH 4/9] pci: fix kabi error caused by pm_suspend_target_state LoongArch inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I6BWFP -------------------------------- fix kabi error caused by pm_suspend_target_state,used only by loongson devices. Signed-off-by: Hongchen Zhang (cherry picked from commit 60c8da76f3b1ffc33a6f0b7f0c5ac67dcd466e1b) --- drivers/pci/pci.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 99eeafead49e..8405594e50a9 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -31,7 +31,9 @@ #include #include #include +#ifdef CONFIG_MACH_LOONGSON64 #include +#endif #include "pci.h" DEFINE_MUTEX(pci_slot_mutex); @@ -148,11 +150,15 @@ static bool pci_bridge_d3_disable; /* Force bridge_d3 for all PCIe ports */ static bool pci_bridge_d3_force; +#ifdef CONFIG_MACH_LOONGSON64 + #ifndef CONFIG_PM_SLEEP suspend_state_t pm_suspend_target_state; #define pm_suspend_target_state (PM_SUSPEND_ON) #endif +#endif + static int __init pcie_port_pm_setup(char *str) { if (!strcmp(str, "off")) @@ -5756,8 +5762,9 @@ int pcie_set_readrq(struct pci_dev *dev, int rq) { u16 v; int ret; +#ifdef CONFIG_MACH_LOONGSON64 struct pci_host_bridge *bridge = pci_find_host_bridge(dev->bus); - +#endif if (rq < 128 || rq > 4096 || !is_power_of_2(rq)) return -EINVAL; @@ -5774,12 +5781,13 @@ int pcie_set_readrq(struct pci_dev *dev, int rq) } v = (ffs(rq) - 8) << 12; - +#ifdef CONFIG_MACH_LOONGSON64 if (pm_suspend_target_state == PM_SUSPEND_ON && bridge->no_inc_mrrs) { if (rq > pcie_get_readrq(dev)) return -EINVAL; } +#endif ret = pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_READRQ, v); -- Gitee From de2faa02d0c17ef35de0391eecfa6b3e275c8ce4 Mon Sep 17 00:00:00 2001 From: Tianli Xiong Date: Wed, 7 Sep 2022 16:47:51 +0800 Subject: [PATCH 5/9] LoongArch: Fixed some pcie card not scanning properly LoongArch inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I6BWFP -------------------------------- Fix some pcie card not scanning properly when bus number is inconsistent during firmware and kernel scan phases. Signed-off-by: liuyun Signed-off-by: Tianli Xiong Change-Id: Iac9c07463569ca08da93ab0fa279b1880206e816 (cherry picked from commit ef7e64c881c2d29032236a92ffdd81bb276452bb) --- drivers/pci/controller/pci-loongson.c | 34 +++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/drivers/pci/controller/pci-loongson.c b/drivers/pci/controller/pci-loongson.c index f0ace5748f81..2777b9c0ed1d 100644 --- a/drivers/pci/controller/pci-loongson.c +++ b/drivers/pci/controller/pci-loongson.c @@ -216,6 +216,36 @@ static void __iomem *pci_loongson_map_bus(struct pci_bus *bus, return NULL; } +static int pci_loongson_config_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *val) +{ + void __iomem *addr; + + addr = bus->ops->map_bus(bus, devfn, where); + if (!addr) { + *val = ~0; + return PCIBIOS_DEVICE_NOT_FOUND; + } + + if (size == 1) + *val = readb(addr); + else if (size == 2) + *val = readw(addr); + else + *val = readl(addr); + /* + * fix some pcie card not scanning properly when bus number is + * inconsistent during firmware and kernel scan phases. + */ + if (*val == 0x0 && where == PCI_VENDOR_ID) { + writel(*val, addr); + *val = readl(addr); + } + + + return PCIBIOS_SUCCESSFUL; +} + #ifdef CONFIG_OF static int loongson_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) @@ -239,7 +269,7 @@ static int loongson_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) /* LS2K/LS7A accept 8/16/32-bit PCI config operations */ static struct pci_ops loongson_pci_ops = { .map_bus = pci_loongson_map_bus, - .read = pci_generic_config_read, + .read = pci_loongson_config_read, .write = pci_generic_config_write, }; @@ -366,7 +396,7 @@ const struct pci_ecam_ops loongson_pci_ecam_ops = { .init = loongson_pci_ecam_init, .pci_ops = { .map_bus = pci_loongson_map_bus, - .read = pci_generic_config_read, + .read = pci_loongson_config_read, .write = pci_generic_config_write, } }; -- Gitee From 20a3868ffc846db2d434f5ee2ea0bcc14eff39fd Mon Sep 17 00:00:00 2001 From: Jianmin Lv Date: Mon, 5 Sep 2022 17:26:21 +0800 Subject: [PATCH 6/9] pci/quirks: ls7a2000: fix pm transition of devices under pcie port LoongArch inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I6BWFP -------------------------------- Signed-off-by: Jianmin Lv Change-Id: Ie2c78cc46aa7bde00395906f7e6ab6a09e09a190 (cherry picked from commit d6ac51fcf32e8cc70cbc9a7e61b65d0a10d54cbb) --- drivers/pci/controller/pci-loongson.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/pci/controller/pci-loongson.c b/drivers/pci/controller/pci-loongson.c index 2777b9c0ed1d..24441c1cf02c 100644 --- a/drivers/pci/controller/pci-loongson.c +++ b/drivers/pci/controller/pci-loongson.c @@ -19,6 +19,12 @@ #define DEV_PCIE_PORT_1 0x7a19 #define DEV_PCIE_PORT_2 0x7a29 +#define DEV_PCIE_PORT_4 0x7a39 +#define DEV_PCIE_PORT_5 0x7a49 +#define DEV_PCIE_PORT_6 0x7a59 +#define DEV_PCIE_PORT_7 0x7a69 + + #define DEV_LS2K_APB 0x7a02 #define DEV_LS7A_GMAC 0x7a03 #define DEV_LS7A_DC1 0x7a06 @@ -76,6 +82,20 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, DEV_LS7A_LPC, system_bus_quirk); +static void loongson_d3_quirk(struct pci_dev *pdev) +{ + pdev->dev_flags |= PCI_DEV_FLAGS_NO_D3; + pdev->no_d1d2 = 1; +} +DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_LOONGSON, + DEV_PCIE_PORT_4, loongson_d3_quirk); +DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_LOONGSON, + DEV_PCIE_PORT_5, loongson_d3_quirk); +DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_LOONGSON, + DEV_PCIE_PORT_6, loongson_d3_quirk); +DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_LOONGSON, + DEV_PCIE_PORT_7, loongson_d3_quirk); + static void loongson_mrrs_quirk(struct pci_dev *pdev) { /* -- Gitee From 67559d43b1fff34caf71f8623c0d4fcd94073881 Mon Sep 17 00:00:00 2001 From: Baoqi Zhang Date: Mon, 5 Sep 2022 18:07:34 +0800 Subject: [PATCH 7/9] LS7A2000: PCIE: Fixup GPU card error LoongArch inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I6BWFP -------------------------------- Add window to solve GPU access error Signed-off-by: Baoqi Zhang Change-Id: Idb607fa22e68e06fc4448af57247bd4e51616a7d (cherry picked from commit a1c119e335520f604286acf56c8090c80bbdb3b7) --- drivers/pci/controller/pci-loongson.c | 38 +++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/drivers/pci/controller/pci-loongson.c b/drivers/pci/controller/pci-loongson.c index 24441c1cf02c..2d54cb8a6d85 100644 --- a/drivers/pci/controller/pci-loongson.c +++ b/drivers/pci/controller/pci-loongson.c @@ -157,6 +157,44 @@ static void loongson_ohci_quirk(struct pci_dev *dev) } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, DEV_LS7A_OHCI, loongson_ohci_quirk); +static void loongson_display_quirk(struct pci_dev *dev) +{ + u32 val; + u64 mask, size; + u64 max_size = 0; + int i, num; + struct pci_bus *bus = dev->bus; + + if (!dev->bus->number) { + if (!(dev->vendor == PCI_VENDOR_ID_LOONGSON && dev->device == 0x7a25)) + return; + } else { + while (!pci_is_root_bus(bus->parent)) + bus = bus->parent; + + /* ensure slot is 7a2000 */ + if (bus->self->vendor != PCI_VENDOR_ID_LOONGSON || bus->self->device < 0x7a39) + return; + } + max_size = 0; + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + if (dev->resource[i].flags & IORESOURCE_MEM) { + size = dev->resource[i].end - dev->resource[i].start; + if (size > max_size) { + max_size = size; + num = i; + } + } + } + mask = ~(dev->resource[num].end - dev->resource[num].start); + val = (dev->resource[num].start >> (24 - 16)) | ((mask >> 24) & 0xffff); + writel(val, (volatile void *)0x80000efdfb000174UL); + writel(0x80000000, (volatile void *)0x80000efdfb000170UL); +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, 0x7a25, loongson_display_quirk); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID, + PCI_BASE_CLASS_DISPLAY, 16, loongson_display_quirk); + static struct loongson_pci *pci_bus_to_loongson_pci(struct pci_bus *bus) { struct pci_config_window *cfg; -- Gitee From ef1724b689fc3e0844e229789b5f556919b9d846 Mon Sep 17 00:00:00 2001 From: suijingfeng Date: Mon, 5 Sep 2022 18:18:06 +0800 Subject: [PATCH 8/9] pci: fix X server auto probe fail when both ast and etnaviv drm present LoongArch inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I6BWFP -------------------------------- According to PCI-to-PCI bridge spec, bit 3 of Bridge Control Register is VGA Enable bit which modifies the response by the bridge to VGA compatible addresses. The Bridge Control register provides extensions to the Command register that are specific to a bridge. The Bridge Control register provides many of the same controls for the secondary interface that are provided by the Command register for the primary interface. There are some bits that affect the operation of both interfaces of the bridge. If the VGA Enable bit is set, the bridge will positively decode and forward the following accesses on the primary interface to the secondary interface (and, conversely, block the forwarding of these addresses from the secondary to primary interface) Forwarding of these accesses is qualified by the I/O Enable and Memory Enable bits in the Command register.) The default state of this bit after reset must be 0. Bit 3 of Bridge Control Register is VGA Enable bit which modifies the response by the bridge to VGA compatible addresses. when 0: do not forward VGA compatible memory and I/O addresses from the primary to secondary interface (addresses defined below) unless they are enabled for forwarding by the defined I/O when 1: forward VGA compatible memory and I/O addresses (addresses defined below) from the primary interface to the secondary interface (if the I/O Enable and Memory Enable bits are set) independent of the I/O and memory address ranges and independent of the ISA Enable bit * memory accesses in the range 000A 0000h to 000B FFFFh * I/O addresses in the first 64 KB of the I/O address space (AD[31:16] are 0000h) where AD[9:: 0] are in the ranges 3B0h to 3BBh and 3C0h to 3DFh (inclusive of ISA address aliases - AD[15::10] are not decoded) If the VGA Enable bit is set, forwarding of these accesses is independent of the I/O address range and memory address ranges defined by the I/O Base and Limit registers, the Memory Base and Limit registers, and the Prefetchable Memory Base and Limit registers of the bridge. Forwarding of these accesses is also independent of the settings of the ISA Enable bit (in the Bridge Control register) or VGA Palette Snoop bits (in the Command register). The AST2500 hardward we are using do not set the VGA Enable bit on its bridge control reg, this cause vgaarb subsystem don't think the VGA card behind this pridge as a valid boot vga device which made X server choose wrong video card to use when multiple video card present in the system. Its seems more vgaarb's fault than the ast2500 bmc itself. even through bit 3 of Bridge Control Register is 0, it should still allow to forward the accesses when the addresses is in the range of IO/MEM Base and Limit registers. Nevertheless, in order to support loongson CPU product line, we provide a workaround to this bug for the Sugon L620-G30 and Sugon L820-G30 server. see similar bug: https://patchwork.kernel.org/project/linux-pci/patch/20170619023528.11532-1-dja@axtens.net/ Signed-off-by: suijingfeng Change-Id: I53b6dee11c17b06866bdd927ac82cd6db88e16aa (cherry picked from commit c74913219f9b5129db2691ca3600b90f2499a724) --- drivers/pci/controller/pci-loongson.c | 48 +++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/drivers/pci/controller/pci-loongson.c b/drivers/pci/controller/pci-loongson.c index 2d54cb8a6d85..7fd53b8a567e 100644 --- a/drivers/pci/controller/pci-loongson.c +++ b/drivers/pci/controller/pci-loongson.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "../pci.h" @@ -195,6 +196,53 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, 0x7a25, loongson_display_quirk); DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY, 16, loongson_display_quirk); +static void pci_fixup_aspeed(struct pci_dev *pdev) +{ + struct pci_dev *bridge; + struct pci_bus *bus; + struct pci_dev *vdevp = NULL; + u16 config; + + bus = pdev->bus; + bridge = bus->self; + + /* Is VGA routed to us? */ + if (bridge && (pci_is_bridge(bridge))) { + pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, &config); + + /* Yes, this bridge is PCI bridge-to-bridge spec compliant, + * just return! + */ + if (config & PCI_BRIDGE_CTL_VGA) + return; + + dev_warn(&pdev->dev, "VGA bridge control is not enabled\n"); + } + + /* Just return if the system already have a default device */ + if (vga_default_device()) + return; + + /* No default vga device */ + while ((vdevp = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, vdevp))) { + if (vdevp->vendor != 0x1a03) { + /* Have other vga devcie in the system, do nothing */ + dev_info(&pdev->dev, + "Another boot vga device: 0x%x:0x%x\n", + vdevp->vendor, vdevp->device); + return; + } + } + + vga_set_default_device(pdev); + + dev_info(&pdev->dev, + "Boot vga device set as 0x%x:0x%x\n", + pdev->vendor, pdev->device); +} +DECLARE_PCI_FIXUP_CLASS_FINAL(0x1a03, 0x2000, + PCI_CLASS_DISPLAY_VGA, 8, pci_fixup_aspeed); + static struct loongson_pci *pci_bus_to_loongson_pci(struct pci_bus *bus) { struct pci_config_window *cfg; -- Gitee From 223871eb1c45bf0337aa3915e32b70384214f813 Mon Sep 17 00:00:00 2001 From: Tianli Xiong Date: Tue, 13 Sep 2022 10:22:49 +0800 Subject: [PATCH 9/9] LoongArch: pci root bridige set acpi companion only when not acpi_disabled. LoongArch inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I6BWFP -------------------------------- Fix patch "LoongArch: Add PCI controller support" Signed-off-by: Tianli Xiong Change-Id: If6084f05cc42ac33b44a7b6aeabdd1366a0bccdd (cherry picked from commit a62d9cc0ddaf4f3c9ebcde27fd0e8fa05b2205e2) --- arch/loongarch/pci/acpi.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/arch/loongarch/pci/acpi.c b/arch/loongarch/pci/acpi.c index 06a33cbf76d2..0f227d9ae764 100644 --- a/arch/loongarch/pci/acpi.c +++ b/arch/loongarch/pci/acpi.c @@ -26,12 +26,14 @@ void pcibios_add_bus(struct pci_bus *bus) int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) { - struct pci_config_window *cfg = bridge->bus->sysdata; - struct acpi_device *adev = to_acpi_device(cfg->parent); - struct device *bus_dev = &bridge->bus->dev; + if (!acpi_disabled) { + struct pci_config_window *cfg = bridge->bus->sysdata; + struct acpi_device *adev = to_acpi_device(cfg->parent); + struct device *bus_dev = &bridge->bus->dev; - ACPI_COMPANION_SET(&bridge->dev, adev); - set_dev_node(bus_dev, pa_to_nid(cfg->res.start)); + ACPI_COMPANION_SET(&bridge->dev, adev); + set_dev_node(bus_dev, pa_to_nid(cfg->res.start)); + } return 0; } -- Gitee