gaojuxin (1): LoongArch: Add workaround for 3C6000 about io wr/rd
wusheng (1): pci/quirks: LS7A2000 enble msi
zhangtianyang (1): Loongarch: Dynamic enable writecombine
zhenghaowei (1): acpi: mcfg quirk: Increased multi-chip support for the 3C6000
arch/loongarch/include/asm/irq.h | 4 +- arch/loongarch/kernel/setup.c | 30 ++++++++++- arch/loongarch/kernel/smp.c | 20 ++++++- drivers/acpi/pci_mcfg.c | 13 +++++ drivers/pci/quirks.c | 13 +++++ include/asm-generic/io.h | 90 ++++++++++++++++++++++++++++++-- include/drm/drm_cache.h | 2 +- 7 files changed, 162 insertions(+), 10 deletions(-)
From: wusheng wusheng@loongson.cn
LoongArch inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IAZ38J
--------------------------------
7A2000 pcie of port H need to enable MSI when host bridge
Signed-off-by: wusheng wusheng@loongson.cn --- drivers/pci/quirks.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 86a4930ff54e..d4e34d2c8e38 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -383,6 +383,20 @@ static void quirk_tigerpoint_bm_sts(struct pci_dev *dev) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TGP_LPC, quirk_tigerpoint_bm_sts); #endif
+static void loongson_pcie_msi_quirk(struct pci_dev *dev) +{ + u16 val; + u16 class; + + class = dev->class >> 8; + if (class == PCI_CLASS_BRIDGE_HOST) { + pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &val); + val |= PCI_MSI_FLAGS_ENABLE; + pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, val); + } +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, 0x7a59, loongson_pcie_msi_quirk); + /* Chipsets where PCI->PCI transfers vanish or hang */ static void quirk_nopcipci(struct pci_dev *dev) {
From: gaojuxin gaojuxin@loongson.cn
LoongArch inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IAZ38J
--------------------------------
Signed-off-by: gaojuxin gaojuxin@loongson.cn --- arch/loongarch/kernel/smp.c | 20 +++++++- include/asm-generic/io.h | 91 +++++++++++++++++++++++++++++++++++-- 2 files changed, 106 insertions(+), 5 deletions(-)
diff --git a/arch/loongarch/kernel/smp.c b/arch/loongarch/kernel/smp.c index ea69606fd9f5..3e904356df3c 100644 --- a/arch/loongarch/kernel/smp.c +++ b/arch/loongarch/kernel/smp.c @@ -35,6 +35,8 @@ #include <asm/time.h> #include "legacy_boot.h"
+spinlock_t lcl_node_lock[16]; +EXPORT_SYMBOL(lcl_node_lock); int __cpu_number_map[NR_CPUS]; /* Map physical to logical */ EXPORT_SYMBOL(__cpu_number_map);
@@ -196,7 +198,19 @@ static void ipi_write_action(int cpu, u32 action)
static void loongson_send_ipi_single(int cpu, unsigned int action) { + unsigned int curr_cpu = cpu_logical_map(smp_processor_id()); + unsigned int t_cpu = cpu_logical_map(cpu); + int flag = -1; + unsigned long irq_flag; + + if ((curr_cpu / 32) != (t_cpu / 32)) { + flag = curr_cpu / 32; + spin_lock_irqsave(&lcl_node_lock[flag], irq_flag); + asm ("dbar 0x0"); + } ipi_write_action(cpu_logical_map(cpu), (u32)action); + if (flag >= 0) + spin_unlock_irqrestore(&lcl_node_lock[flag], irq_flag); }
static void loongson_send_ipi_mask(const struct cpumask *mask, unsigned int action) @@ -204,7 +218,7 @@ static void loongson_send_ipi_mask(const struct cpumask *mask, unsigned int acti unsigned int i;
for_each_cpu(i, mask) - ipi_write_action(cpu_logical_map(i), (u32)action); + loongson_send_ipi_single(i, (u32)action); }
void arch_send_call_function_single_ipi(int cpu) @@ -305,6 +319,10 @@ static void __init fdt_smp_setup(void)
void __init loongson_smp_setup(void) { + int i; + + for (i = 0; i < 16; i++) + spin_lock_init(&lcl_node_lock[i]); fdt_smp_setup();
cpu_data[0].core = cpu_logical_map(0) % loongson_sysconf.cores_per_package; diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h index bac63e874c7b..0f80b79cc640 100644 --- a/include/asm-generic/io.h +++ b/include/asm-generic/io.h @@ -16,9 +16,11 @@ #include <asm-generic/iomap.h> #endif
+#include <linux/spinlock.h> #include <asm/mmiowb.h> #include <asm-generic/pci_iomap.h>
+extern spinlock_t lcl_node_lock[16]; #ifndef __io_br #define __io_br() barrier() #endif @@ -113,7 +115,19 @@ static inline void log_post_read_mmio(u64 val, u8 width, const volatile void __i #define __raw_readb __raw_readb static inline u8 __raw_readb(const volatile void __iomem *addr) { - return *(const volatile u8 __force *)addr; + unsigned long dst_node, node; + unsigned long irq_flag; + u8 val; + + dst_node = ((unsigned long)addr >> 44) & 0xf; + node = get_csr_cpuid() / 32; + if (node != dst_node) + spin_lock_irqsave(&lcl_node_lock[node + 8], irq_flag); + val = *(const volatile u8 __force *)addr; + if (node != dst_node) + spin_unlock_irqrestore(&lcl_node_lock[node + 8], irq_flag); + rmb(); + return val; } #endif
@@ -121,7 +135,18 @@ static inline u8 __raw_readb(const volatile void __iomem *addr) #define __raw_readw __raw_readw static inline u16 __raw_readw(const volatile void __iomem *addr) { - return *(const volatile u16 __force *)addr; + unsigned long dst_node, node; + unsigned long irq_flag; + u16 val; + dst_node = ((unsigned long)addr >> 44) & 0xf; + node = get_csr_cpuid() / 32; + if (node != dst_node) + spin_lock_irqsave(&lcl_node_lock[node + 8], irq_flag); + val = *(const volatile u16 __force *)addr; + if (node != dst_node) + spin_unlock_irqrestore(&lcl_node_lock[node + 8], irq_flag); + rmb(); + return val; } #endif
@@ -129,7 +154,18 @@ static inline u16 __raw_readw(const volatile void __iomem *addr) #define __raw_readl __raw_readl static inline u32 __raw_readl(const volatile void __iomem *addr) { - return *(const volatile u32 __force *)addr; + unsigned long dst_node, node; + unsigned long irq_flag; + u32 val; + dst_node = ((unsigned long)addr >> 44) & 0xf; + node = get_csr_cpuid() / 32; + if (node != dst_node) + spin_lock_irqsave(&lcl_node_lock[node + 8], irq_flag); + val = *(const volatile u32 __force *)addr; + if (node != dst_node) + spin_unlock_irqrestore(&lcl_node_lock[node + 8], irq_flag); + rmb(); + return val; } #endif
@@ -138,7 +174,18 @@ static inline u32 __raw_readl(const volatile void __iomem *addr) #define __raw_readq __raw_readq static inline u64 __raw_readq(const volatile void __iomem *addr) { - return *(const volatile u64 __force *)addr; + unsigned long dst_node, node; + unsigned long irq_flag; + u64 val; + dst_node = ((unsigned long)addr >> 44) & 0xf; + node = get_csr_cpuid() / 32; + if (node != dst_node) + spin_lock_irqsave(&lcl_node_lock[node + 8], irq_flag); + val = *(const volatile u64 __force *)addr; + if (node != dst_node) + spin_unlock_irqrestore(&lcl_node_lock[node + 8], irq_flag); + rmb(); + return val; } #endif #endif /* CONFIG_64BIT */ @@ -147,7 +194,16 @@ static inline u64 __raw_readq(const volatile void __iomem *addr) #define __raw_writeb __raw_writeb static inline void __raw_writeb(u8 value, volatile void __iomem *addr) { + unsigned long dst_node, node; + unsigned long irq_flag; + wmb(); + dst_node = ((unsigned long)addr >> 44) & 0xf; + node = get_csr_cpuid() / 32; + if (node != dst_node) + spin_lock_irqsave(&lcl_node_lock[node], irq_flag); *(volatile u8 __force *)addr = value; + if (node != dst_node) + spin_unlock_irqrestore(&lcl_node_lock[node], irq_flag); } #endif
@@ -155,7 +211,16 @@ static inline void __raw_writeb(u8 value, volatile void __iomem *addr) #define __raw_writew __raw_writew static inline void __raw_writew(u16 value, volatile void __iomem *addr) { + unsigned long dst_node, node; + unsigned long irq_flag; + wmb(); + dst_node = ((unsigned long)addr >> 44) & 0xf; + node = get_csr_cpuid() / 32; + if (node != dst_node) + spin_lock_irqsave(&lcl_node_lock[node], irq_flag); *(volatile u16 __force *)addr = value; + if (node != dst_node) + spin_unlock_irqrestore(&lcl_node_lock[node], irq_flag); } #endif
@@ -163,7 +228,16 @@ static inline void __raw_writew(u16 value, volatile void __iomem *addr) #define __raw_writel __raw_writel static inline void __raw_writel(u32 value, volatile void __iomem *addr) { + unsigned long dst_node, node; + unsigned long irq_flag; + wmb(); + dst_node = ((unsigned long)addr >> 44) & 0xf; + node = get_csr_cpuid() / 32; + if (node != dst_node) + spin_lock_irqsave(&lcl_node_lock[node], irq_flag); *(volatile u32 __force *)addr = value; + if (node != dst_node) + spin_unlock_irqrestore(&lcl_node_lock[node], irq_flag); } #endif
@@ -172,7 +246,16 @@ static inline void __raw_writel(u32 value, volatile void __iomem *addr) #define __raw_writeq __raw_writeq static inline void __raw_writeq(u64 value, volatile void __iomem *addr) { + unsigned long dst_node, node; + unsigned long irq_flag; + wmb(); + dst_node = ((unsigned long)addr >> 44) & 0xf; + node = get_csr_cpuid() / 32; + if (node != dst_node) + spin_lock_irqsave(&lcl_node_lock[node], irq_flag); *(volatile u64 __force *)addr = value; + if (node != dst_node) + spin_unlock_irqrestore(&lcl_node_lock[node], irq_flag); } #endif #endif /* CONFIG_64BIT */
From: Haowei Zheng zhenghaowei@loongson.cn
LoongArch inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IAZ38J
--------------------------------
After this, capable of supporting up to eight chips.
Signed-off-by: Haowei Zheng zhenghaowei@loongson.cn --- arch/loongarch/include/asm/irq.h | 4 ++-- drivers/acpi/pci_mcfg.c | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/arch/loongarch/include/asm/irq.h b/arch/loongarch/include/asm/irq.h index 79f4c834ffe8..b65f8ffc6a0e 100644 --- a/arch/loongarch/include/asm/irq.h +++ b/arch/loongarch/include/asm/irq.h @@ -43,8 +43,8 @@ void spurious_interrupt(void); extern bool arch_trigger_cpumask_backtrace(const cpumask_t *mask, int exclude_cpu);
-#define MAX_IO_PICS 2 -#define NR_IRQS (64 + (256 * MAX_IO_PICS)) +#define MAX_IO_PICS 16 +#define NR_IRQS (64 + NR_VECTORS * (NR_CPUS + MAX_IO_PICS))
struct acpi_vector_group { int node; diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c index 8c04e71ac544..70ceb6905c0a 100644 --- a/drivers/acpi/pci_mcfg.c +++ b/drivers/acpi/pci_mcfg.c @@ -185,6 +185,19 @@ static struct mcfg_fixup mcfg_quirks[] = { LOONGSON_ECAM_MCFG("LOONGSON", 0), LOONGSON_ECAM_MCFG("\0", 1), LOONGSON_ECAM_MCFG("LOONGSON", 1), + LOONGSON_ECAM_MCFG("\0", 2), + LOONGSON_ECAM_MCFG("LOONGSON", 2), + LOONGSON_ECAM_MCFG("\0", 3), + LOONGSON_ECAM_MCFG("LOONGSON", 3), + LOONGSON_ECAM_MCFG("\0", 4), + LOONGSON_ECAM_MCFG("LOONGSON", 4), + LOONGSON_ECAM_MCFG("\0", 5), + LOONGSON_ECAM_MCFG("LOONGSON", 5), + LOONGSON_ECAM_MCFG("\0", 6), + LOONGSON_ECAM_MCFG("LOONGSON", 6), + LOONGSON_ECAM_MCFG("\0", 7), + LOONGSON_ECAM_MCFG("LOONGSON", 7), + #endif /* LOONGARCH */
#ifdef CONFIG_SW64
From: zhangtianyang zhangtianyang@loongson.cn
LoongArch inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IAZ38J
--------------------------------
Signed-off-by: zhangtianyang zhangtianyang@loongson.cn --- arch/loongarch/kernel/setup.c | 28 ++++++++++++++++++++++++++-- include/drm/drm_cache.h | 2 +- 2 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c index 481c85a5f1b5..a210e2507368 100644 --- a/arch/loongarch/kernel/setup.c +++ b/arch/loongarch/kernel/setup.c @@ -184,12 +184,14 @@ bool wc_enabled = false;
EXPORT_SYMBOL(wc_enabled);
+static int wc_arg = -1; + static int __init setup_writecombine(char *p) { if (!strcmp(p, "on")) - wc_enabled = true; + wc_arg = true; else if (!strcmp(p, "off")) - wc_enabled = false; + wc_arg = false; else pr_warn("Unknown writecombine setting "%s".\n", p);
@@ -371,6 +373,26 @@ static void __init bootcmdline_init(char **cmdline_p) *cmdline_p = boot_command_line; }
+static void __init writecombine_detect(void) +{ + u64 cpuname; + + if (wc_arg >= 0) { + wc_enabled = wc_arg; + return; + } + + cpuname = iocsr_read64(LOONGARCH_IOCSR_CPUNAME); + + switch (cpuname) { + case 0x0000303030364333: + wc_enabled = true; + break; + default: + break; + } +} + void __init platform_init(void) { arch_reserve_vmcore(); @@ -394,6 +416,8 @@ void __init platform_init(void) smbios_parse(); pr_info("The BIOS Version: %s\n", b_info.bios_version);
+ writecombine_detect(); + pr_info("WriteCombine: %s\n", wc_enabled ? "on":"off"); efi_runtime_init(); }
diff --git a/include/drm/drm_cache.h b/include/drm/drm_cache.h index 08e0e3ffad13..667fb0368ef6 100644 --- a/include/drm/drm_cache.h +++ b/include/drm/drm_cache.h @@ -74,7 +74,7 @@ static inline bool drm_arch_can_wc_memory(void) * cache coherency machanism. This means WUC can only used for write-only * memory regions. */ - return false; + return wc_enabled; #else return true; #endif
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/12347 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/Z...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/12347 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/Z...