@@ -13305,6 +13305,7 @@ F: Documentation/translations/zh_CN/arch/loongarch/
F: arch/loongarch/
F: drivers/*/*loongarch*
F: drivers/cpufreq/loongson3_cpufreq.c
+F: include/linux/loongson
LOONGSON GPIO DRIVER
M: Yinbo Zhu <zhuyinbo@loongson.cn>
@@ -1048,84 +1048,6 @@
#define ESTATF_IP 0x00003fff
-#define LOONGARCH_IOCSR_FEATURES 0x8
-#define IOCSRF_TEMP BIT_ULL(0)
-#define IOCSRF_NODECNT BIT_ULL(1)
-#define IOCSRF_MSI BIT_ULL(2)
-#define IOCSRF_EXTIOI BIT_ULL(3)
-#define IOCSRF_CSRIPI BIT_ULL(4)
-#define IOCSRF_FREQCSR BIT_ULL(5)
-#define IOCSRF_FREQSCALE BIT_ULL(6)
-#define IOCSRF_DVFSV1 BIT_ULL(7)
-#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 LOONGARCH_IOCSR_CPUNAME 0x20
-
-#define LOONGARCH_IOCSR_NODECNT 0x408
-
-#define LOONGARCH_IOCSR_MISC_FUNC 0x420
-#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
-
-#define LOONGARCH_IOCSR_SMCMBX 0x51c
-
-/* PerCore CSR, only accessible by local cores */
-#define LOONGARCH_IOCSR_IPI_STATUS 0x1000
-#define LOONGARCH_IOCSR_IPI_EN 0x1004
-#define LOONGARCH_IOCSR_IPI_SET 0x1008
-#define LOONGARCH_IOCSR_IPI_CLEAR 0x100c
-#define LOONGARCH_IOCSR_MBUF0 0x1020
-#define LOONGARCH_IOCSR_MBUF1 0x1028
-#define LOONGARCH_IOCSR_MBUF2 0x1030
-#define LOONGARCH_IOCSR_MBUF3 0x1038
-
-#define LOONGARCH_IOCSR_IPI_SEND 0x1040
-#define IOCSR_IPI_SEND_IP_SHIFT 0
-#define IOCSR_IPI_SEND_CPU_SHIFT 16
-#define IOCSR_IPI_SEND_BLOCKING BIT(31)
-
-#define LOONGARCH_IOCSR_MBUF_SEND 0x1048
-#define IOCSR_MBUF_SEND_BLOCKING BIT_ULL(31)
-#define IOCSR_MBUF_SEND_BOX_SHIFT 2
-#define IOCSR_MBUF_SEND_BOX_LO(box) (box << 1)
-#define IOCSR_MBUF_SEND_BOX_HI(box) ((box << 1) + 1)
-#define IOCSR_MBUF_SEND_CPU_SHIFT 16
-#define IOCSR_MBUF_SEND_BUF_SHIFT 32
-#define IOCSR_MBUF_SEND_H32_MASK 0xFFFFFFFF00000000ULL
-
-#define LOONGARCH_IOCSR_ANY_SEND 0x1158
-#define IOCSR_ANY_SEND_BLOCKING BIT_ULL(31)
-#define IOCSR_ANY_SEND_CPU_SHIFT 16
-#define IOCSR_ANY_SEND_MASK_SHIFT 27
-#define IOCSR_ANY_SEND_BUF_SHIFT 32
-#define IOCSR_ANY_SEND_H32_MASK 0xFFFFFFFF00000000ULL
-
-/* Register offset and bit definition for CSR access */
-#define LOONGARCH_IOCSR_TIMER_CFG 0x1060
-#define LOONGARCH_IOCSR_TIMER_TICK 0x1070
-#define IOCSR_TIMER_CFG_RESERVED (_ULCAST_(1) << 63)
-#define IOCSR_TIMER_CFG_PERIODIC (_ULCAST_(1) << 62)
-#define IOCSR_TIMER_CFG_EN (_ULCAST_(1) << 61)
-#define IOCSR_TIMER_MASK 0x0ffffffffffffULL
-#define IOCSR_TIMER_INITVAL_RST (_ULCAST_(0xffff) << 48)
-
-#define LOONGARCH_IOCSR_EXTIOI_NODEMAP_BASE 0x14a0
-#define LOONGARCH_IOCSR_EXTIOI_IPMAP_BASE 0x14c0
-#define LOONGARCH_IOCSR_EXTIOI_EN_BASE 0x1600
-#define LOONGARCH_IOCSR_EXTIOI_BOUNCE_BASE 0x1680
-#define LOONGARCH_IOCSR_EXTIOI_ISR_BASE 0x1800
-#define LOONGARCH_IOCSR_EXTIOI_ROUTE_BASE 0x1c00
-#define IOCSR_EXTIOI_VECTOR_NUM 256
-
#ifndef __ASSEMBLY__
static __always_inline u64 drdtime(void)
@@ -1145,18 +1067,6 @@ static inline unsigned int get_csr_cpuid(void)
return csr_read32(LOONGARCH_CSR_CPUID);
}
-static inline void csr_any_send(unsigned int addr, unsigned int data,
- unsigned int data_mask, unsigned int cpu)
-{
- uint64_t val = 0;
-
- val = IOCSR_ANY_SEND_BLOCKING | addr;
- val |= (cpu << IOCSR_ANY_SEND_CPU_SHIFT);
- val |= (data_mask << IOCSR_ANY_SEND_MASK_SHIFT);
- val |= ((uint64_t)data << IOCSR_ANY_SEND_BUF_SHIFT);
- iocsr_write64(val, LOONGARCH_IOCSR_ANY_SEND);
-}
-
static inline unsigned int read_csr_excode(void)
{
return (csr_read32(LOONGARCH_CSR_ESTAT) & CSR_ESTAT_EXC) >> CSR_ESTAT_EXC_SHIFT;
@@ -6,6 +6,7 @@
*/
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/loongson/iocsr.h>
#include <linux/ptrace.h>
#include <linux/smp.h>
#include <linux/stddef.h>
@@ -267,13 +268,13 @@ static inline void cpu_probe_loongson(struct cpuinfo_loongarch *c, unsigned int
if (!(c->options & LOONGARCH_CPU_IOCSR))
return;
- *vendor = iocsr_read64(LOONGARCH_IOCSR_VENDOR);
- *cpuname = iocsr_read64(LOONGARCH_IOCSR_CPUNAME);
+ *vendor = iocsr_read64(LOONGSON_IOCSR_VENDOR);
+ *cpuname = iocsr_read64(LOONGSON_IOCSR_CPUNAME);
if (!__cpu_full_name[cpu])
__cpu_full_name[cpu] = cpu_full_name;
- config = iocsr_read32(LOONGARCH_IOCSR_FEATURES);
+ config = iocsr_read32(LOONGSON_IOCSR_FEATURES);
if (config & IOCSRF_CSRIPI)
c->options |= LOONGARCH_CPU_CSRIPI;
if (config & IOCSRF_EXTIOI)
@@ -5,6 +5,7 @@
* Copyright (C) 2022 Loongson Technology Corporation Limited
*/
+#include <linux/loongson/iocsr.h>
#include <linux/kexec.h>
#include <asm/asm.h>
@@ -88,14 +89,14 @@ SYM_CODE_END(relocate_new_kernel)
#ifdef CONFIG_SMP
/*
* Other CPUs should wait until code is relocated and
- * then start at the entry point from LOONGARCH_IOCSR_MBUF0.
+ * then start at the entry point from LOONGSON_IOCSR_MBUF0.
*/
SYM_CODE_START(kexec_smp_wait)
UNWIND_HINT_UNDEFINED
1: li.w t0, 0x100 /* wait for init loop */
2: addi.w t0, t0, -1 /* limit mailbox access */
bnez t0, 2b
- li.w t1, LOONGARCH_IOCSR_MBUF0
+ li.w t1, LOONGSON_IOCSR_MBUF0
iocsrrd.w s0, t1 /* check PC as an indicator */
beqz s0, 1b
iocsrrd.d s0, t1 /* get PC via mailbox */
@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq_work.h>
+#include <linux/loongson/iocsr.h>
#include <linux/profile.h>
#include <linux/seq_file.h>
#include <linux/smp.h>
@@ -164,14 +165,14 @@ static void csr_mail_send(uint64_t data, int cpu, int mailbox)
val |= (IOCSR_MBUF_SEND_BOX_HI(mailbox) << IOCSR_MBUF_SEND_BOX_SHIFT);
val |= (cpu << IOCSR_MBUF_SEND_CPU_SHIFT);
val |= (data & IOCSR_MBUF_SEND_H32_MASK);
- iocsr_write64(val, LOONGARCH_IOCSR_MBUF_SEND);
+ iocsr_write64(val, LOONGSON_IOCSR_MBUF_SEND);
/* Send low 32 bits */
val = IOCSR_MBUF_SEND_BLOCKING;
val |= (IOCSR_MBUF_SEND_BOX_LO(mailbox) << IOCSR_MBUF_SEND_BOX_SHIFT);
val |= (cpu << IOCSR_MBUF_SEND_CPU_SHIFT);
val |= (data << IOCSR_MBUF_SEND_BUF_SHIFT);
- iocsr_write64(val, LOONGARCH_IOCSR_MBUF_SEND);
+ iocsr_write64(val, LOONGSON_IOCSR_MBUF_SEND);
};
static u32 ipi_read_clear(int cpu)
@@ -179,9 +180,9 @@ static u32 ipi_read_clear(int cpu)
u32 action;
/* Load the ipi register to figure out what we're supposed to do */
- action = iocsr_read32(LOONGARCH_IOCSR_IPI_STATUS);
+ action = iocsr_read32(LOONGSON_IOCSR_IPI_STATUS);
/* Clear the ipi register to clear the interrupt */
- iocsr_write32(action, LOONGARCH_IOCSR_IPI_CLEAR);
+ iocsr_write32(action, LOONGSON_IOCSR_IPI_CLEAR);
wbflush();
return action;
@@ -193,7 +194,7 @@ static void ipi_write_action(int cpu, u32 action)
val = IOCSR_IPI_SEND_BLOCKING | action;
val |= (cpu << IOCSR_IPI_SEND_CPU_SHIFT);
- iocsr_write32(val, LOONGARCH_IOCSR_IPI_SEND);
+ iocsr_write32(val, LOONGSON_IOCSR_IPI_SEND);
}
static void loongson_send_ipi_single(int cpu, unsigned int action)
@@ -322,7 +323,7 @@ void __init loongson_smp_setup(void)
cpu_data[0].package = cpu_logical_map(0) / loongson_sysconf.cores_per_package;
pv_ipi_init();
- iocsr_write32(0xffffffff, LOONGARCH_IOCSR_IPI_EN);
+ iocsr_write32(0xffffffff, LOONGSON_IOCSR_IPI_EN);
pr_info("Detected %i available CPU(s)\n", loongson_sysconf.nr_cpus);
}
@@ -370,7 +371,7 @@ void loongson_init_secondary(void)
change_csr_ecfg(ECFG0_IM, imask);
- iocsr_write32(0xffffffff, LOONGARCH_IOCSR_IPI_EN);
+ iocsr_write32(0xffffffff, LOONGSON_IOCSR_IPI_EN);
#ifdef CONFIG_NUMA
numa_add_cpu(cpu);
@@ -385,7 +386,7 @@ void loongson_init_secondary(void)
void loongson_smp_finish(void)
{
local_irq_enable();
- iocsr_write64(0, LOONGARCH_IOCSR_MBUF0);
+ iocsr_write64(0, LOONGSON_IOCSR_MBUF0);
pr_info("CPU#%d finished\n", smp_processor_id());
}
@@ -435,12 +436,12 @@ void __noreturn arch_cpu_idle_dead(void)
__smp_mb();
do {
__asm__ __volatile__("idle 0\n\t");
- addr = iocsr_read64(LOONGARCH_IOCSR_MBUF0);
+ addr = iocsr_read64(LOONGSON_IOCSR_MBUF0);
} while (addr == 0);
local_irq_disable();
init_fn = (void *)TO_CACHE(addr);
- iocsr_write32(0xffffffff, LOONGARCH_IOCSR_IPI_CLEAR);
+ iocsr_write32(0xffffffff, LOONGSON_IOCSR_IPI_CLEAR);
init_fn();
BUG();
@@ -460,7 +461,7 @@ static int loongson_ipi_suspend(void)
static void loongson_ipi_resume(void)
{
- iocsr_write32(0xffffffff, LOONGARCH_IOCSR_IPI_EN);
+ iocsr_write32(0xffffffff, LOONGSON_IOCSR_IPI_EN);
}
static struct syscore_ops loongson_ipi_syscore_ops = {
@@ -10,6 +10,7 @@
#include <linux/cpufreq.h>
#include <linux/delay.h>
#include <linux/module.h>
+#include <linux/loongson/iocsr.h>
#include <linux/platform_device.h>
#include <linux/units.h>
@@ -182,7 +183,7 @@ static inline int do_service_request(u32 id, u32 info, u32 cmd, u32 val, u32 ext
mutex_lock(&cpufreq_mutex[package]);
- last.value = iocsr_read32(LOONGARCH_IOCSR_SMCMBX);
+ last.value = iocsr_read32(LOONGSON_IOCSR_SMCMBX);
if (!last.complete) {
mutex_unlock(&cpufreq_mutex[package]);
return -EPERM;
@@ -195,12 +196,12 @@ static inline int do_service_request(u32 id, u32 info, u32 cmd, u32 val, u32 ext
msg.extra = extra;
msg.complete = 0;
- iocsr_write32(msg.value, LOONGARCH_IOCSR_SMCMBX);
- iocsr_write32(iocsr_read32(LOONGARCH_IOCSR_MISC_FUNC) | IOCSR_MISC_FUNC_SOFT_INT,
- LOONGARCH_IOCSR_MISC_FUNC);
+ iocsr_write32(msg.value, LOONGSON_IOCSR_SMCMBX);
+ iocsr_write32(iocsr_read32(LOONGSON_IOCSR_MISC_FUNC) | IOCSR_MISC_FUNC_SOFT_INT,
+ LOONGSON_IOCSR_MISC_FUNC);
for (retries = 0; retries < 10000; retries++) {
- msg.value = iocsr_read32(LOONGARCH_IOCSR_SMCMBX);
+ msg.value = iocsr_read32(LOONGSON_IOCSR_SMCMBX);
if (msg.complete)
break;
@@ -10,6 +10,7 @@
#include <linux/irqchip.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/irqdomain.h>
+#include <linux/loongson/iocsr.h>
#include <linux/kernel.h>
#include <linux/msi.h>
#include <linux/radix-tree.h>
@@ -378,9 +379,9 @@ static int __init avecintc_init(struct irq_domain *parent)
"irqchip/loongarch/avecintc:starting",
avecintc_cpu_online, avecintc_cpu_offline);
#endif
- value = iocsr_read64(LOONGARCH_IOCSR_MISC_FUNC);
+ value = iocsr_read64(LOONGSON_IOCSR_MISC_FUNC);
value |= IOCSR_MISC_FUNC_AVEC_EN;
- iocsr_write64(value, LOONGARCH_IOCSR_MISC_FUNC);
+ iocsr_write64(value, LOONGSON_IOCSR_MISC_FUNC);
return ret;
@@ -13,6 +13,7 @@
#include <linux/irqchip.h>
#include <linux/irqdomain.h>
#include <linux/irqchip/chained_irq.h>
+#include <linux/loongson/iocsr.h>
#include <linux/kernel.h>
#include <linux/syscore_ops.h>
#include <asm/numa.h>
@@ -52,9 +53,9 @@ static void eiointc_enable(void)
{
uint64_t misc;
- misc = iocsr_read64(LOONGARCH_IOCSR_MISC_FUNC);
+ misc = iocsr_read64(LOONGSON_IOCSR_MISC_FUNC);
misc |= IOCSR_MISC_FUNC_EXT_IOI_EN;
- iocsr_write64(misc, LOONGARCH_IOCSR_MISC_FUNC);
+ iocsr_write64(misc, LOONGSON_IOCSR_MISC_FUNC);
}
static int cpu_to_eio_node(int cpu)
new file mode 100644
@@ -0,0 +1,110 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
+ * Copyright (C) 2024, Jiaxun Yang <jiaxun.yang@flygoat.com>
+ */
+
+#ifndef _LOONGSON_IOCSR_H
+#define _LOONGSON_IOCSR_H
+
+#include <linux/bits.h>
+#include <linux/types.h>
+
+#ifdef CONFIG_LOONGARCH
+#include <asm/loongarch.h>
+#endif
+
+#define LOONGSON_IOCSR_FEATURES 0x8
+#define IOCSRF_TEMP BIT_ULL(0)
+#define IOCSRF_NODECNT BIT_ULL(1)
+#define IOCSRF_MSI BIT_ULL(2)
+#define IOCSRF_EXTIOI BIT_ULL(3)
+#define IOCSRF_CSRIPI BIT_ULL(4)
+#define IOCSRF_FREQCSR BIT_ULL(5)
+#define IOCSRF_FREQSCALE BIT_ULL(6)
+#define IOCSRF_DVFSV1 BIT_ULL(7)
+#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 LOONGSON_IOCSR_VENDOR 0x10
+
+#define LOONGSON_IOCSR_CPUNAME 0x20
+
+#define LOONGSON_IOCSR_NODECNT 0x408
+
+#define LOONGSON_IOCSR_MISC_FUNC 0x420
+#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 LOONGSON_IOCSR_CPUTEMP 0x428
+
+#define LOONGSON_IOCSR_SMCMBX 0x51c
+
+/* PerCore CSR, only accessible by local cores */
+#define LOONGSON_IOCSR_IPI_STATUS 0x1000
+#define LOONGSON_IOCSR_IPI_EN 0x1004
+#define LOONGSON_IOCSR_IPI_SET 0x1008
+#define LOONGSON_IOCSR_IPI_CLEAR 0x100c
+#define LOONGSON_IOCSR_MBUF0 0x1020
+#define LOONGSON_IOCSR_MBUF1 0x1028
+#define LOONGSON_IOCSR_MBUF2 0x1030
+#define LOONGSON_IOCSR_MBUF3 0x1038
+
+#define LOONGSON_IOCSR_IPI_SEND 0x1040
+#define IOCSR_IPI_SEND_IP_SHIFT 0
+#define IOCSR_IPI_SEND_CPU_SHIFT 16
+#define IOCSR_IPI_SEND_BLOCKING BIT(31)
+
+#define LOONGSON_IOCSR_MBUF_SEND 0x1048
+#define IOCSR_MBUF_SEND_BLOCKING BIT_ULL(31)
+#define IOCSR_MBUF_SEND_BOX_SHIFT 2
+#define IOCSR_MBUF_SEND_BOX_LO(box) (box << 1)
+#define IOCSR_MBUF_SEND_BOX_HI(box) ((box << 1) + 1)
+#define IOCSR_MBUF_SEND_CPU_SHIFT 16
+#define IOCSR_MBUF_SEND_BUF_SHIFT 32
+#define IOCSR_MBUF_SEND_H32_MASK 0xFFFFFFFF00000000ULL
+
+#define LOONGSON_IOCSR_ANY_SEND 0x1158
+#define IOCSR_ANY_SEND_BLOCKING BIT_ULL(31)
+#define IOCSR_ANY_SEND_CPU_SHIFT 16
+#define IOCSR_ANY_SEND_MASK_SHIFT 27
+#define IOCSR_ANY_SEND_BUF_SHIFT 32
+#define IOCSR_ANY_SEND_H32_MASK 0xFFFFFFFF00000000ULL
+
+/* Register offset and bit definition for CSR access */
+#define LOONGSON_IOCSR_TIMER_CFG 0x1060
+#define LOONGSON_IOCSR_TIMER_TICK 0x1070
+#define IOCSR_TIMER_CFG_RESERVED (_ULCAST_(1) << 63)
+#define IOCSR_TIMER_CFG_PERIODIC (_ULCAST_(1) << 62)
+#define IOCSR_TIMER_CFG_EN (_ULCAST_(1) << 61)
+#define IOCSR_TIMER_MASK 0x0ffffffffffffULL
+#define IOCSR_TIMER_INITVAL_RST (_ULCAST_(0xffff) << 48)
+
+#define LOONGSON_IOCSR_EXTIOI_NODEMAP_BASE 0x14a0
+#define LOONGSON_IOCSR_EXTIOI_IPMAP_BASE 0x14c0
+#define LOONGSON_IOCSR_EXTIOI_EN_BASE 0x1600
+#define LOONGSON_IOCSR_EXTIOI_BOUNCE_BASE 0x1680
+#define LOONGSON_IOCSR_EXTIOI_ISR_BASE 0x1800
+#define LOONGSON_IOCSR_EXTIOI_ROUTE_BASE 0x1c00
+#define IOCSR_EXTIOI_VECTOR_NUM 256
+
+#ifndef __ASSEMBLY__
+static inline void csr_any_send(unsigned int addr, unsigned int data,
+ unsigned int data_mask, unsigned int cpu)
+{
+ uint64_t val = 0;
+
+ val = IOCSR_ANY_SEND_BLOCKING | addr;
+ val |= (cpu << IOCSR_ANY_SEND_CPU_SHIFT);
+ val |= (data_mask << IOCSR_ANY_SEND_MASK_SHIFT);
+ val |= ((uint64_t)data << IOCSR_ANY_SEND_BUF_SHIFT);
+ iocsr_write64(val, LOONGSON_IOCSR_ANY_SEND);
+}
+#endif
+
+#endif
+
As IOCSR is not a part of architecture specification, it is not really appropriate to define those stuff in loongarch.h. Extract those definitions to include/linux/loongson/iocsr.h, so that they can be shared with MIPS based Loongson systems as well. Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com> --- MAINTAINERS | 1 + arch/loongarch/include/asm/loongarch.h | 90 -------------------------- arch/loongarch/kernel/cpu-probe.c | 7 +- arch/loongarch/kernel/relocate_kernel.S | 5 +- arch/loongarch/kernel/smp.c | 23 +++---- drivers/cpufreq/loongson3_cpufreq.c | 11 ++-- drivers/irqchip/irq-loongarch-avec.c | 5 +- drivers/irqchip/irq-loongson-eiointc.c | 5 +- include/linux/loongson/iocsr.h | 110 ++++++++++++++++++++++++++++++++ 9 files changed, 142 insertions(+), 115 deletions(-)