aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2014-09-10 09:35:38 -0400
committerVineet Gupta <vgupta@synopsys.com>2015-06-22 04:36:56 -0400
commit82fea5a1bbbe8c3b56d5f3efbf8880c7b25b1758 (patch)
tree736061a26f019af1912dd6824f8ab4eb5a20eb33
parent173eaafaed284fc95209902f68f011d01d1eda02 (diff)
ARCv2: SMP: Support ARConnect (MCIP) for Inter-Core-Interrupts et al
Cc: Jason Cooper <jason@lakedaemon.net> Cc: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
-rw-r--r--arch/arc/Kconfig21
-rw-r--r--arch/arc/include/asm/irq.h1
-rw-r--r--arch/arc/include/asm/mcip.h91
-rw-r--r--arch/arc/kernel/Makefile1
-rw-r--r--arch/arc/kernel/intc-arcv2.c2
-rw-r--r--arch/arc/kernel/mcip.c117
-rw-r--r--arch/arc/plat-sim/platform.c5
7 files changed, 230 insertions, 8 deletions
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index f09e03a0d604..301525020af7 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -160,12 +160,12 @@ config CPU_BIG_ENDIAN
160 Build kernel for Big Endian Mode of ARC CPU 160 Build kernel for Big Endian Mode of ARC CPU
161 161
162config SMP 162config SMP
163 bool "Symmetric Multi-Processing (Incomplete)" 163 bool "Symmetric Multi-Processing"
164 default n 164 default n
165 select ARC_HAS_COH_CACHES if ISA_ARCV2
166 select ARC_MCIP if ISA_ARCV2
165 help 167 help
166 This enables support for systems with more than one CPU. If you have 168 This enables support for systems with more than one CPU.
167 a system with only one CPU, say N. If you have a system with more
168 than one CPU, say Y.
169 169
170if SMP 170if SMP
171 171
@@ -175,13 +175,20 @@ config ARC_HAS_COH_CACHES
175config ARC_HAS_REENTRANT_IRQ_LV2 175config ARC_HAS_REENTRANT_IRQ_LV2
176 def_bool n 176 def_bool n
177 177
178endif #SMP 178config ARC_MCIP
179 bool "ARConnect Multicore IP (MCIP) Support "
180 depends on ISA_ARCV2
181 help
182 This IP block enables SMP in ARC-HS38 cores.
183 It provides for cross-core interrupts, multi-core debug
184 hardware semaphores, shared memory,....
179 185
180config NR_CPUS 186config NR_CPUS
181 int "Maximum number of CPUs (2-4096)" 187 int "Maximum number of CPUs (2-4096)"
182 range 2 4096 188 range 2 4096
183 depends on SMP 189 default "4"
184 default "2" 190
191endif #SMP
185 192
186menuconfig ARC_CACHE 193menuconfig ARC_CACHE
187 bool "Enable Cache Support" 194 bool "Enable Cache Support"
diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h
index 49014f0ef36d..bc5103637326 100644
--- a/arch/arc/include/asm/irq.h
+++ b/arch/arc/include/asm/irq.h
@@ -19,6 +19,7 @@
19#else 19#else
20#define TIMER0_IRQ 16 20#define TIMER0_IRQ 16
21#define TIMER1_IRQ 17 21#define TIMER1_IRQ 17
22#define IPI_IRQ 19
22#endif 23#endif
23 24
24#include <linux/interrupt.h> 25#include <linux/interrupt.h>
diff --git a/arch/arc/include/asm/mcip.h b/arch/arc/include/asm/mcip.h
new file mode 100644
index 000000000000..31f9bac77a27
--- /dev/null
+++ b/arch/arc/include/asm/mcip.h
@@ -0,0 +1,91 @@
1/*
2 * ARConnect IP Support (Multi core enabler: Cross core IPI, RTC ...)
3 *
4 * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com)
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __ASM_MCIP_H
12#define __ASM_MCIP_H
13
14#ifdef CONFIG_ISA_ARCV2
15
16#include <asm/arcregs.h>
17
18#define ARC_REG_MCIP_BCR 0x0d0
19#define ARC_REG_MCIP_CMD 0x600
20#define ARC_REG_MCIP_WDATA 0x601
21#define ARC_REG_MCIP_READBACK 0x602
22
23struct mcip_cmd {
24#ifdef CONFIG_CPU_BIG_ENDIAN
25 unsigned int pad:8, param:16, cmd:8;
26#else
27 unsigned int cmd:8, param:16, pad:8;
28#endif
29
30#define CMD_INTRPT_GENERATE_IRQ 0x01
31#define CMD_INTRPT_GENERATE_ACK 0x02
32#define CMD_INTRPT_READ_STATUS 0x03
33#define CMD_INTRPT_CHECK_SOURCE 0x04
34
35/* Semaphore Commands */
36#define CMD_SEMA_CLAIM_AND_READ 0x11
37#define CMD_SEMA_RELEASE 0x12
38
39#define CMD_DEBUG_SET_MASK 0x34
40#define CMD_DEBUG_SET_SELECT 0x36
41
42#define CMD_IDU_ENABLE 0x71
43#define CMD_IDU_DISABLE 0x72
44#define CMD_IDU_SET_MODE 0x74
45#define CMD_IDU_SET_DEST 0x76
46#define CMD_IDU_SET_MASK 0x7C
47
48#define IDU_M_TRIG_LEVEL 0x0
49#define IDU_M_TRIG_EDGE 0x1
50
51#define IDU_M_DISTRI_RR 0x0
52#define IDU_M_DISTRI_DEST 0x2
53};
54
55/*
56 * MCIP programming model
57 *
58 * - Simple commands write {cmd:8,param:16} to MCIP_CMD aux reg
59 * (param could be irq, common_irq, core_id ...)
60 * - More involved commands setup MCIP_WDATA with cmd specific data
61 * before invoking the simple command
62 */
63static inline void __mcip_cmd(unsigned int cmd, unsigned int param)
64{
65 struct mcip_cmd buf;
66
67 buf.pad = 0;
68 buf.cmd = cmd;
69 buf.param = param;
70
71 WRITE_AUX(ARC_REG_MCIP_CMD, buf);
72}
73
74/*
75 * Setup additional data for a cmd
76 * Callers need to lock to ensure atomicity
77 */
78static inline void __mcip_cmd_data(unsigned int cmd, unsigned int param,
79 unsigned int data)
80{
81 write_aux_reg(ARC_REG_MCIP_WDATA, data);
82
83 __mcip_cmd(cmd, param);
84}
85
86extern void mcip_init_early_smp(void);
87extern void mcip_init_smp(unsigned int cpu);
88
89#endif
90
91#endif
diff --git a/arch/arc/kernel/Makefile b/arch/arc/kernel/Makefile
index 0be7ba087260..e7f3625a19b5 100644
--- a/arch/arc/kernel/Makefile
+++ b/arch/arc/kernel/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_ISA_ARCV2) += entry-arcv2.o intc-arcv2.o
15 15
16obj-$(CONFIG_MODULES) += arcksyms.o module.o 16obj-$(CONFIG_MODULES) += arcksyms.o module.o
17obj-$(CONFIG_SMP) += smp.o 17obj-$(CONFIG_SMP) += smp.o
18obj-$(CONFIG_ARC_MCIP) += mcip.o
18obj-$(CONFIG_ARC_DW2_UNWIND) += unwind.o 19obj-$(CONFIG_ARC_DW2_UNWIND) += unwind.o
19obj-$(CONFIG_KPROBES) += kprobes.o 20obj-$(CONFIG_KPROBES) += kprobes.o
20obj-$(CONFIG_ARC_EMUL_UNALIGNED) += unaligned.o 21obj-$(CONFIG_ARC_EMUL_UNALIGNED) += unaligned.o
diff --git a/arch/arc/kernel/intc-arcv2.c b/arch/arc/kernel/intc-arcv2.c
index c5c64dc47655..6208c630abed 100644
--- a/arch/arc/kernel/intc-arcv2.c
+++ b/arch/arc/kernel/intc-arcv2.c
@@ -107,7 +107,7 @@ static struct irq_chip arcv2_irq_chip = {
107static int arcv2_irq_map(struct irq_domain *d, unsigned int irq, 107static int arcv2_irq_map(struct irq_domain *d, unsigned int irq,
108 irq_hw_number_t hw) 108 irq_hw_number_t hw)
109{ 109{
110 if (irq == TIMER0_IRQ) 110 if (irq == TIMER0_IRQ || irq == IPI_IRQ)
111 irq_set_chip_and_handler(irq, &arcv2_irq_chip, handle_percpu_irq); 111 irq_set_chip_and_handler(irq, &arcv2_irq_chip, handle_percpu_irq);
112 else 112 else
113 irq_set_chip_and_handler(irq, &arcv2_irq_chip, handle_level_irq); 113 irq_set_chip_and_handler(irq, &arcv2_irq_chip, handle_level_irq);
diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c
new file mode 100644
index 000000000000..e6ad6e64440a
--- /dev/null
+++ b/arch/arc/kernel/mcip.c
@@ -0,0 +1,117 @@
1/*
2 * ARC ARConnect (MultiCore IP) support (formerly known as MCIP)
3 *
4 * Copyright (C) 2013 Synopsys, Inc. (www.synopsys.com)
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/smp.h>
12#include <linux/irq.h>
13#include <linux/spinlock.h>
14#include <asm/mcip.h>
15
16static char smp_cpuinfo_buf[128];
17
18static DEFINE_RAW_SPINLOCK(mcip_lock);
19
20
21/*
22 * Any SMP specific init any CPU does when it comes up.
23 * Here we setup the CPU to enable Inter-Processor-Interrupts
24 * Called for each CPU
25 * -Master : init_IRQ()
26 * -Other(s) : start_kernel_secondary()
27 */
28void mcip_init_smp(unsigned int cpu)
29{
30 smp_ipi_irq_setup(cpu, IPI_IRQ);
31}
32
33static void mcip_ipi_send(int cpu)
34{
35 unsigned long flags;
36
37 raw_spin_lock_irqsave(&mcip_lock, flags);
38 __mcip_cmd(CMD_INTRPT_GENERATE_IRQ, cpu);
39 raw_spin_unlock_irqrestore(&mcip_lock, flags);
40}
41
42static void mcip_ipi_clear(int irq)
43{
44 unsigned int cpu;
45 unsigned long flags;
46
47 raw_spin_lock_irqsave(&mcip_lock, flags);
48
49 /* Who sent the IPI */
50 __mcip_cmd(CMD_INTRPT_CHECK_SOURCE, 0);
51
52 cpu = read_aux_reg(ARC_REG_MCIP_READBACK); /* 1,2,4,8... */
53
54 __mcip_cmd(CMD_INTRPT_GENERATE_ACK, __ffs(cpu)); /* 0,1,2,3... */
55
56 raw_spin_unlock_irqrestore(&mcip_lock, flags);
57}
58
59volatile int wake_flag;
60
61static void mcip_wakeup_cpu(int cpu, unsigned long pc)
62{
63 BUG_ON(cpu == 0);
64 wake_flag = cpu;
65}
66
67void arc_platform_smp_wait_to_boot(int cpu)
68{
69 while (wake_flag != cpu)
70 ;
71
72 wake_flag = 0;
73 __asm__ __volatile__("j @first_lines_of_secondary \n");
74}
75
76struct plat_smp_ops plat_smp_ops = {
77 .info = smp_cpuinfo_buf,
78 .cpu_kick = mcip_wakeup_cpu,
79 .ipi_send = mcip_ipi_send,
80 .ipi_clear = mcip_ipi_clear,
81};
82
83void mcip_init_early_smp(void)
84{
85#define IS_AVAIL1(var, str) ((var) ? str : "")
86
87 struct mcip_bcr {
88#ifdef CONFIG_CPU_BIG_ENDIAN
89 unsigned int pad3:8,
90 idu:1, llm:1, num_cores:6,
91 iocoh:1, grtc:1, dbg:1, pad2:1,
92 msg:1, sem:1, ipi:1, pad:1,
93 ver:8;
94#else
95 unsigned int ver:8,
96 pad:1, ipi:1, sem:1, msg:1,
97 pad2:1, dbg:1, grtc:1, iocoh:1,
98 num_cores:6, llm:1, idu:1,
99 pad3:8;
100#endif
101 } mp;
102
103 READ_BCR(ARC_REG_MCIP_BCR, mp);
104
105 sprintf(smp_cpuinfo_buf,
106 "Extn [SMP]\t: ARConnect (v%d): %d cores with %s%s%s%s\n",
107 mp.ver, mp.num_cores,
108 IS_AVAIL1(mp.ipi, "IPI "),
109 IS_AVAIL1(mp.idu, "IDU "),
110 IS_AVAIL1(mp.dbg, "DEBUG "),
111 IS_AVAIL1(mp.grtc, "GRTC"));
112
113 if (mp.dbg) {
114 __mcip_cmd_data(CMD_DEBUG_SET_SELECT, 0, 0xf);
115 __mcip_cmd_data(CMD_DEBUG_SET_MASK, 0xf, 0xf);
116 }
117}
diff --git a/arch/arc/plat-sim/platform.c b/arch/arc/plat-sim/platform.c
index 114fdc30941c..8795ae2ef48a 100644
--- a/arch/arc/plat-sim/platform.c
+++ b/arch/arc/plat-sim/platform.c
@@ -10,6 +10,7 @@
10 10
11#include <linux/init.h> 11#include <linux/init.h>
12#include <asm/mach_desc.h> 12#include <asm/mach_desc.h>
13#include <asm/mcip.h>
13 14
14/*----------------------- Machine Descriptions ------------------------------ 15/*----------------------- Machine Descriptions ------------------------------
15 * 16 *
@@ -27,4 +28,8 @@ static const char *simulation_compat[] __initconst = {
27 28
28MACHINE_START(SIMULATION, "simulation") 29MACHINE_START(SIMULATION, "simulation")
29 .dt_compat = simulation_compat, 30 .dt_compat = simulation_compat,
31#ifdef CONFIG_ARC_MCIP
32 .init_early = mcip_init_early_smp,
33 .init_smp = mcip_init_smp,
34#endif
30MACHINE_END 35MACHINE_END