]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
LoongArch: Architectural preparation for AVEC irqchip
authorHuacai Chen <chenhuacai@loongson.cn>
Fri, 23 Aug 2024 10:39:33 +0000 (18:39 +0800)
committerThomas Gleixner <tglx@linutronix.de>
Fri, 23 Aug 2024 18:40:27 +0000 (20:40 +0200)
Add architectural preparation for AVEC irqchip, including:
1. CPUCFG feature bits definition for AVEC;
2. Detection of AVEC irqchip in cpu_probe();
3. New IPI type definition (IPI_CLEAR_VECTOR) for AVEC;
4. Provide arch_probe_nr_irqs() for large NR_IRQS;
5. Other related changes about the number of interrupts.

Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Tianyang Zhang <zhangtianyang@loongson.cn>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20240823103936.25092-2-zhangtianyang@loongson.cn
arch/loongarch/include/asm/cpu-features.h
arch/loongarch/include/asm/cpu.h
arch/loongarch/include/asm/hardirq.h
arch/loongarch/include/asm/irq.h
arch/loongarch/include/asm/loongarch.h
arch/loongarch/include/asm/smp.h
arch/loongarch/kernel/cpu-probe.c
arch/loongarch/kernel/irq.c

index 2eafe6a6aca8189c88617c18da45c373294a6aa8..16a716f88a5ca2c2d0117184d4a6b55046fe44d7 100644 (file)
@@ -65,5 +65,6 @@
 #define cpu_has_guestid                cpu_opt(LOONGARCH_CPU_GUESTID)
 #define cpu_has_hypervisor     cpu_opt(LOONGARCH_CPU_HYPERVISOR)
 #define cpu_has_ptw            cpu_opt(LOONGARCH_CPU_PTW)
+#define cpu_has_avecint                cpu_opt(LOONGARCH_CPU_AVECINT)
 
 #endif /* __ASM_CPU_FEATURES_H */
index 48b9f7168bcca03f92a63f891a346f88055b7bfc..843f9c4ec98071b818c615272734d2cc8428b7e5 100644 (file)
@@ -99,6 +99,7 @@ enum cpu_type_enum {
 #define CPU_FEATURE_GUESTID            24      /* CPU has GuestID feature */
 #define CPU_FEATURE_HYPERVISOR         25      /* CPU has hypervisor (running in VM) */
 #define CPU_FEATURE_PTW                        26      /* CPU has hardware page table walker */
+#define CPU_FEATURE_AVECINT            27      /* CPU has avec interrupt */
 
 #define LOONGARCH_CPU_CPUCFG           BIT_ULL(CPU_FEATURE_CPUCFG)
 #define LOONGARCH_CPU_LAM              BIT_ULL(CPU_FEATURE_LAM)
@@ -127,5 +128,6 @@ enum cpu_type_enum {
 #define LOONGARCH_CPU_GUESTID          BIT_ULL(CPU_FEATURE_GUESTID)
 #define LOONGARCH_CPU_HYPERVISOR       BIT_ULL(CPU_FEATURE_HYPERVISOR)
 #define LOONGARCH_CPU_PTW              BIT_ULL(CPU_FEATURE_PTW)
+#define LOONGARCH_CPU_AVECINT          BIT_ULL(CPU_FEATURE_AVECINT)
 
 #endif /* _ASM_CPU_H */
index 1d7feb7195157206d6fa22ec756749c90d50d7b9..10da8d6961cb04d5db7e980fd8b22ca578fe6ebe 100644 (file)
 extern void ack_bad_irq(unsigned int irq);
 #define ack_bad_irq ack_bad_irq
 
-#define NR_IPI 3
+#define NR_IPI 4
 
 enum ipi_msg_type {
        IPI_RESCHEDULE,
        IPI_CALL_FUNCTION,
        IPI_IRQ_WORK,
+       IPI_CLEAR_VECTOR,
 };
 
 typedef struct {
index 65503c9eb52934e56e745e70fccc6a056ea968e9..c4835800c8b9bffbddec4286b22044d8f7f2beff 100644 (file)
@@ -39,11 +39,22 @@ void spurious_interrupt(void);
 
 #define NR_IRQS_LEGACY 16
 
+/*
+ * 256 Vectors Mapping for AVECINTC:
+ *
+ * 0 - 15: Mapping classic IPs, e.g. IP0-12.
+ * 16 - 255: Mapping vectors for external IRQ.
+ *
+ */
+#define NR_VECTORS             256
+#define NR_LEGACY_VECTORS      16
+#define IRQ_MATRIX_BITS                NR_VECTORS
+
 #define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace
 void arch_trigger_cpumask_backtrace(const struct cpumask *mask, int exclude_cpu);
 
 #define MAX_IO_PICS 2
-#define NR_IRQS        (64 + (256 * MAX_IO_PICS))
+#define NR_IRQS        (64 + NR_VECTORS * (NR_CPUS + MAX_IO_PICS))
 
 struct acpi_vector_group {
        int node;
@@ -65,7 +76,7 @@ extern struct acpi_vector_group msi_group[MAX_IO_PICS];
 #define LOONGSON_LPC_LAST_IRQ          (LOONGSON_LPC_IRQ_BASE + 15)
 
 #define LOONGSON_CPU_IRQ_BASE          16
-#define LOONGSON_CPU_LAST_IRQ          (LOONGSON_CPU_IRQ_BASE + 14)
+#define LOONGSON_CPU_LAST_IRQ          (LOONGSON_CPU_IRQ_BASE + 15)
 
 #define LOONGSON_PCH_IRQ_BASE          64
 #define LOONGSON_PCH_ACPI_IRQ          (LOONGSON_PCH_IRQ_BASE + 47)
index 04a78010fc725e5b484abf2830a90883c4a61cf6..631d249b3ef268ebefd118feaaf79d9b4f0c3e20 100644 (file)
 #define  CSR_ESTAT_EXC_WIDTH           6
 #define  CSR_ESTAT_EXC                 (_ULCAST_(0x3f) << CSR_ESTAT_EXC_SHIFT)
 #define  CSR_ESTAT_IS_SHIFT            0
-#define  CSR_ESTAT_IS_WIDTH            14
-#define  CSR_ESTAT_IS                  (_ULCAST_(0x3fff) << CSR_ESTAT_IS_SHIFT)
+#define  CSR_ESTAT_IS_WIDTH            15
+#define  CSR_ESTAT_IS                  (_ULCAST_(0x7fff) << CSR_ESTAT_IS_SHIFT)
 
 #define LOONGARCH_CSR_ERA              0x6     /* ERA */
 
 
 #define LOONGARCH_CSR_CTAG             0x98    /* TagLo + TagHi */
 
+#define LOONGARCH_CSR_ISR0             0xa0
+#define LOONGARCH_CSR_ISR1             0xa1
+#define LOONGARCH_CSR_ISR2             0xa2
+#define LOONGARCH_CSR_ISR3             0xa3
+
+#define LOONGARCH_CSR_IRR              0xa4
+
 #define LOONGARCH_CSR_PRID             0xc0
 
 /* Shadow MCSR : 0xc0 ~ 0xff */
 /*
  * CSR_ECFG IM
  */
-#define ECFG0_IM               0x00001fff
+#define ECFG0_IM               0x00005fff
 #define ECFGB_SIP0             0
 #define ECFGF_SIP0             (_ULCAST_(1) << ECFGB_SIP0)
 #define ECFGB_SIP1             1
 #define  IOCSRF_EIODECODE              BIT_ULL(9)
 #define  IOCSRF_FLATMODE               BIT_ULL(10)
 #define  IOCSRF_VM                     BIT_ULL(11)
+#define  IOCSRF_AVEC                   BIT_ULL(15)
 
 #define LOONGARCH_IOCSR_VENDOR         0x10
 
 #define  IOCSR_MISC_FUNC_SOFT_INT      BIT_ULL(10)
 #define  IOCSR_MISC_FUNC_TIMER_RESET   BIT_ULL(21)
 #define  IOCSR_MISC_FUNC_EXT_IOI_EN    BIT_ULL(48)
+#define  IOCSR_MISC_FUNC_AVEC_EN       BIT_ULL(51)
 
 #define LOONGARCH_IOCSR_CPUTEMP                0x428
 
@@ -1387,9 +1396,10 @@ __BUILD_CSR_OP(tlbidx)
 #define INT_TI         11      /* Timer */
 #define INT_IPI                12
 #define INT_NMI                13
+#define INT_AVEC       14
 
 /* ExcCodes corresponding to interrupts */
-#define EXCCODE_INT_NUM                (INT_NMI + 1)
+#define EXCCODE_INT_NUM                (INT_AVEC + 1)
 #define EXCCODE_INT_START      64
 #define EXCCODE_INT_END                (EXCCODE_INT_START + EXCCODE_INT_NUM - 1)
 
index 50db503f44e3c754ed0703e76d82075d3f020031..3383c9d24e94240f4ece78ee671457fd576a2e03 100644 (file)
@@ -70,10 +70,12 @@ extern int __cpu_logical_map[NR_CPUS];
 #define ACTION_RESCHEDULE      1
 #define ACTION_CALL_FUNCTION   2
 #define ACTION_IRQ_WORK                3
+#define ACTION_CLEAR_VECTOR    4
 #define SMP_BOOT_CPU           BIT(ACTION_BOOT_CPU)
 #define SMP_RESCHEDULE         BIT(ACTION_RESCHEDULE)
 #define SMP_CALL_FUNCTION      BIT(ACTION_CALL_FUNCTION)
 #define SMP_IRQ_WORK           BIT(ACTION_IRQ_WORK)
+#define SMP_CLEAR_VECTOR       BIT(ACTION_CLEAR_VECTOR)
 
 struct secondary_data {
        unsigned long stack;
index 55320813ee0819f0f23429361b7fc9722b710d65..14f0449f54520ac70db6a7e9d8636b391933b7af 100644 (file)
@@ -106,7 +106,6 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c)
                elf_hwcap |= HWCAP_LOONGARCH_CRC32;
        }
 
-
        config = read_cpucfg(LOONGARCH_CPUCFG2);
        if (config & CPUCFG2_LAM) {
                c->options |= LOONGARCH_CPU_LAM;
@@ -174,6 +173,8 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c)
                c->options |= LOONGARCH_CPU_FLATMODE;
        if (config & IOCSRF_EIODECODE)
                c->options |= LOONGARCH_CPU_EIODECODE;
+       if (config & IOCSRF_AVEC)
+               c->options |= LOONGARCH_CPU_AVECINT;
        if (config & IOCSRF_VM)
                c->options |= LOONGARCH_CPU_HYPERVISOR;
 
index f4991c03514f48c7396ed094994c6cb41d87da8e..414f5249d70a5ce012ed5cb9a09a9648275b80f3 100644 (file)
@@ -87,6 +87,18 @@ static void __init init_vec_parent_group(void)
        acpi_table_parse(ACPI_SIG_MCFG, early_pci_mcfg_parse);
 }
 
+int __init arch_probe_nr_irqs(void)
+{
+       int nr_io_pics = bitmap_weight(loongson_sysconf.cores_io_master, NR_CPUS);
+
+       if (!cpu_has_avecint)
+               nr_irqs = (64 + NR_VECTORS * nr_io_pics);
+       else
+               nr_irqs = (64 + NR_VECTORS * (nr_cpu_ids + nr_io_pics));
+
+       return NR_IRQS_LEGACY;
+}
+
 void __init init_IRQ(void)
 {
        int i;