Merge branch 'for-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/jlawall...
[linux-2.6-microblaze.git] / arch / mips / loongson64 / smp.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2010, 2011, 2012, Lemote, Inc.
4  * Author: Chen Huacai, chenhc@lemote.com
5  */
6
7 #include <irq.h>
8 #include <linux/init.h>
9 #include <linux/cpu.h>
10 #include <linux/sched.h>
11 #include <linux/sched/hotplug.h>
12 #include <linux/sched/task_stack.h>
13 #include <linux/smp.h>
14 #include <linux/cpufreq.h>
15 #include <linux/kexec.h>
16 #include <asm/processor.h>
17 #include <asm/time.h>
18 #include <asm/tlbflush.h>
19 #include <asm/cacheflush.h>
20 #include <loongson.h>
21 #include <loongson_regs.h>
22 #include <workarounds.h>
23
24 #include "smp.h"
25
26 DEFINE_PER_CPU(int, cpu_state);
27
28 #define LS_IPI_IRQ (MIPS_CPU_IRQ_BASE + 6)
29
30 static void *ipi_set0_regs[16];
31 static void *ipi_clear0_regs[16];
32 static void *ipi_status0_regs[16];
33 static void *ipi_en0_regs[16];
34 static void *ipi_mailbox_buf[16];
35 static uint32_t core0_c0count[NR_CPUS];
36
37 /* read a 32bit value from ipi register */
38 #define loongson3_ipi_read32(addr) readl(addr)
39 /* read a 64bit value from ipi register */
40 #define loongson3_ipi_read64(addr) readq(addr)
41 /* write a 32bit value to ipi register */
42 #define loongson3_ipi_write32(action, addr)     \
43         do {                                    \
44                 writel(action, addr);           \
45                 __wbflush();                    \
46         } while (0)
47 /* write a 64bit value to ipi register */
48 #define loongson3_ipi_write64(action, addr)     \
49         do {                                    \
50                 writeq(action, addr);           \
51                 __wbflush();                    \
52         } while (0)
53
54 static u32 (*ipi_read_clear)(int cpu);
55 static void (*ipi_write_action)(int cpu, u32 action);
56 static void (*ipi_write_enable)(int cpu);
57 static void (*ipi_clear_buf)(int cpu);
58 static void (*ipi_write_buf)(int cpu, struct task_struct *idle);
59
60 /* send mail via Mail_Send register for 3A4000+ CPU */
61 static void csr_mail_send(uint64_t data, int cpu, int mailbox)
62 {
63         uint64_t val;
64
65         /* send high 32 bits */
66         val = CSR_MAIL_SEND_BLOCK;
67         val |= (CSR_MAIL_SEND_BOX_HIGH(mailbox) << CSR_MAIL_SEND_BOX_SHIFT);
68         val |= (cpu << CSR_MAIL_SEND_CPU_SHIFT);
69         val |= (data & CSR_MAIL_SEND_H32_MASK);
70         csr_writeq(val, LOONGSON_CSR_MAIL_SEND);
71
72         /* send low 32 bits */
73         val = CSR_MAIL_SEND_BLOCK;
74         val |= (CSR_MAIL_SEND_BOX_LOW(mailbox) << CSR_MAIL_SEND_BOX_SHIFT);
75         val |= (cpu << CSR_MAIL_SEND_CPU_SHIFT);
76         val |= (data << CSR_MAIL_SEND_BUF_SHIFT);
77         csr_writeq(val, LOONGSON_CSR_MAIL_SEND);
78 };
79
80 static u32 csr_ipi_read_clear(int cpu)
81 {
82         u32 action;
83
84         /* Load the ipi register to figure out what we're supposed to do */
85         action = csr_readl(LOONGSON_CSR_IPI_STATUS);
86         /* Clear the ipi register to clear the interrupt */
87         csr_writel(action, LOONGSON_CSR_IPI_CLEAR);
88
89         return action;
90 }
91
92 static void csr_ipi_write_action(int cpu, u32 action)
93 {
94         unsigned int irq = 0;
95
96         while ((irq = ffs(action))) {
97                 uint32_t val = CSR_IPI_SEND_BLOCK;
98                 val |= (irq - 1);
99                 val |= (cpu << CSR_IPI_SEND_CPU_SHIFT);
100                 csr_writel(val, LOONGSON_CSR_IPI_SEND);
101                 action &= ~BIT(irq - 1);
102         }
103 }
104
105 static void csr_ipi_write_enable(int cpu)
106 {
107         csr_writel(0xffffffff, LOONGSON_CSR_IPI_EN);
108 }
109
110 static void csr_ipi_clear_buf(int cpu)
111 {
112         csr_writeq(0, LOONGSON_CSR_MAIL_BUF0);
113 }
114
115 static void csr_ipi_write_buf(int cpu, struct task_struct *idle)
116 {
117         unsigned long startargs[4];
118
119         /* startargs[] are initial PC, SP and GP for secondary CPU */
120         startargs[0] = (unsigned long)&smp_bootstrap;
121         startargs[1] = (unsigned long)__KSTK_TOS(idle);
122         startargs[2] = (unsigned long)task_thread_info(idle);
123         startargs[3] = 0;
124
125         pr_debug("CPU#%d, func_pc=%lx, sp=%lx, gp=%lx\n",
126                 cpu, startargs[0], startargs[1], startargs[2]);
127
128         csr_mail_send(startargs[3], cpu_logical_map(cpu), 3);
129         csr_mail_send(startargs[2], cpu_logical_map(cpu), 2);
130         csr_mail_send(startargs[1], cpu_logical_map(cpu), 1);
131         csr_mail_send(startargs[0], cpu_logical_map(cpu), 0);
132 }
133
134 static u32 legacy_ipi_read_clear(int cpu)
135 {
136         u32 action;
137
138         /* Load the ipi register to figure out what we're supposed to do */
139         action = loongson3_ipi_read32(ipi_status0_regs[cpu_logical_map(cpu)]);
140         /* Clear the ipi register to clear the interrupt */
141         loongson3_ipi_write32(action, ipi_clear0_regs[cpu_logical_map(cpu)]);
142
143         return action;
144 }
145
146 static void legacy_ipi_write_action(int cpu, u32 action)
147 {
148         loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu]);
149 }
150
151 static void legacy_ipi_write_enable(int cpu)
152 {
153         loongson3_ipi_write32(0xffffffff, ipi_en0_regs[cpu_logical_map(cpu)]);
154 }
155
156 static void legacy_ipi_clear_buf(int cpu)
157 {
158         loongson3_ipi_write64(0, ipi_mailbox_buf[cpu_logical_map(cpu)] + 0x0);
159 }
160
161 static void legacy_ipi_write_buf(int cpu, struct task_struct *idle)
162 {
163         unsigned long startargs[4];
164
165         /* startargs[] are initial PC, SP and GP for secondary CPU */
166         startargs[0] = (unsigned long)&smp_bootstrap;
167         startargs[1] = (unsigned long)__KSTK_TOS(idle);
168         startargs[2] = (unsigned long)task_thread_info(idle);
169         startargs[3] = 0;
170
171         pr_debug("CPU#%d, func_pc=%lx, sp=%lx, gp=%lx\n",
172                         cpu, startargs[0], startargs[1], startargs[2]);
173
174         loongson3_ipi_write64(startargs[3],
175                         ipi_mailbox_buf[cpu_logical_map(cpu)] + 0x18);
176         loongson3_ipi_write64(startargs[2],
177                         ipi_mailbox_buf[cpu_logical_map(cpu)] + 0x10);
178         loongson3_ipi_write64(startargs[1],
179                         ipi_mailbox_buf[cpu_logical_map(cpu)] + 0x8);
180         loongson3_ipi_write64(startargs[0],
181                         ipi_mailbox_buf[cpu_logical_map(cpu)] + 0x0);
182 }
183
184 static void csr_ipi_probe(void)
185 {
186         if (cpu_has_csr() && csr_readl(LOONGSON_CSR_FEATURES) & LOONGSON_CSRF_IPI) {
187                 ipi_read_clear = csr_ipi_read_clear;
188                 ipi_write_action = csr_ipi_write_action;
189                 ipi_write_enable = csr_ipi_write_enable;
190                 ipi_clear_buf = csr_ipi_clear_buf;
191                 ipi_write_buf = csr_ipi_write_buf;
192         } else {
193                 ipi_read_clear = legacy_ipi_read_clear;
194                 ipi_write_action = legacy_ipi_write_action;
195                 ipi_write_enable = legacy_ipi_write_enable;
196                 ipi_clear_buf = legacy_ipi_clear_buf;
197                 ipi_write_buf = legacy_ipi_write_buf;
198         }
199 }
200
201 static void ipi_set0_regs_init(void)
202 {
203         ipi_set0_regs[0] = (void *)
204                 (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + SET0);
205         ipi_set0_regs[1] = (void *)
206                 (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + SET0);
207         ipi_set0_regs[2] = (void *)
208                 (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + SET0);
209         ipi_set0_regs[3] = (void *)
210                 (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + SET0);
211         ipi_set0_regs[4] = (void *)
212                 (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + SET0);
213         ipi_set0_regs[5] = (void *)
214                 (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + SET0);
215         ipi_set0_regs[6] = (void *)
216                 (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + SET0);
217         ipi_set0_regs[7] = (void *)
218                 (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + SET0);
219         ipi_set0_regs[8] = (void *)
220                 (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + SET0);
221         ipi_set0_regs[9] = (void *)
222                 (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + SET0);
223         ipi_set0_regs[10] = (void *)
224                 (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + SET0);
225         ipi_set0_regs[11] = (void *)
226                 (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + SET0);
227         ipi_set0_regs[12] = (void *)
228                 (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + SET0);
229         ipi_set0_regs[13] = (void *)
230                 (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + SET0);
231         ipi_set0_regs[14] = (void *)
232                 (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + SET0);
233         ipi_set0_regs[15] = (void *)
234                 (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + SET0);
235 }
236
237 static void ipi_clear0_regs_init(void)
238 {
239         ipi_clear0_regs[0] = (void *)
240                 (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + CLEAR0);
241         ipi_clear0_regs[1] = (void *)
242                 (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + CLEAR0);
243         ipi_clear0_regs[2] = (void *)
244                 (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + CLEAR0);
245         ipi_clear0_regs[3] = (void *)
246                 (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + CLEAR0);
247         ipi_clear0_regs[4] = (void *)
248                 (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + CLEAR0);
249         ipi_clear0_regs[5] = (void *)
250                 (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + CLEAR0);
251         ipi_clear0_regs[6] = (void *)
252                 (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + CLEAR0);
253         ipi_clear0_regs[7] = (void *)
254                 (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + CLEAR0);
255         ipi_clear0_regs[8] = (void *)
256                 (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + CLEAR0);
257         ipi_clear0_regs[9] = (void *)
258                 (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + CLEAR0);
259         ipi_clear0_regs[10] = (void *)
260                 (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + CLEAR0);
261         ipi_clear0_regs[11] = (void *)
262                 (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + CLEAR0);
263         ipi_clear0_regs[12] = (void *)
264                 (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + CLEAR0);
265         ipi_clear0_regs[13] = (void *)
266                 (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + CLEAR0);
267         ipi_clear0_regs[14] = (void *)
268                 (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + CLEAR0);
269         ipi_clear0_regs[15] = (void *)
270                 (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + CLEAR0);
271 }
272
273 static void ipi_status0_regs_init(void)
274 {
275         ipi_status0_regs[0] = (void *)
276                 (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + STATUS0);
277         ipi_status0_regs[1] = (void *)
278                 (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + STATUS0);
279         ipi_status0_regs[2] = (void *)
280                 (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + STATUS0);
281         ipi_status0_regs[3] = (void *)
282                 (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + STATUS0);
283         ipi_status0_regs[4] = (void *)
284                 (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + STATUS0);
285         ipi_status0_regs[5] = (void *)
286                 (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + STATUS0);
287         ipi_status0_regs[6] = (void *)
288                 (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + STATUS0);
289         ipi_status0_regs[7] = (void *)
290                 (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + STATUS0);
291         ipi_status0_regs[8] = (void *)
292                 (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + STATUS0);
293         ipi_status0_regs[9] = (void *)
294                 (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + STATUS0);
295         ipi_status0_regs[10] = (void *)
296                 (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + STATUS0);
297         ipi_status0_regs[11] = (void *)
298                 (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + STATUS0);
299         ipi_status0_regs[12] = (void *)
300                 (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + STATUS0);
301         ipi_status0_regs[13] = (void *)
302                 (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + STATUS0);
303         ipi_status0_regs[14] = (void *)
304                 (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + STATUS0);
305         ipi_status0_regs[15] = (void *)
306                 (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + STATUS0);
307 }
308
309 static void ipi_en0_regs_init(void)
310 {
311         ipi_en0_regs[0] = (void *)
312                 (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + EN0);
313         ipi_en0_regs[1] = (void *)
314                 (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + EN0);
315         ipi_en0_regs[2] = (void *)
316                 (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + EN0);
317         ipi_en0_regs[3] = (void *)
318                 (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + EN0);
319         ipi_en0_regs[4] = (void *)
320                 (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + EN0);
321         ipi_en0_regs[5] = (void *)
322                 (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + EN0);
323         ipi_en0_regs[6] = (void *)
324                 (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + EN0);
325         ipi_en0_regs[7] = (void *)
326                 (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + EN0);
327         ipi_en0_regs[8] = (void *)
328                 (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + EN0);
329         ipi_en0_regs[9] = (void *)
330                 (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + EN0);
331         ipi_en0_regs[10] = (void *)
332                 (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + EN0);
333         ipi_en0_regs[11] = (void *)
334                 (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + EN0);
335         ipi_en0_regs[12] = (void *)
336                 (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + EN0);
337         ipi_en0_regs[13] = (void *)
338                 (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + EN0);
339         ipi_en0_regs[14] = (void *)
340                 (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + EN0);
341         ipi_en0_regs[15] = (void *)
342                 (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + EN0);
343 }
344
345 static void ipi_mailbox_buf_init(void)
346 {
347         ipi_mailbox_buf[0] = (void *)
348                 (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + BUF);
349         ipi_mailbox_buf[1] = (void *)
350                 (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + BUF);
351         ipi_mailbox_buf[2] = (void *)
352                 (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + BUF);
353         ipi_mailbox_buf[3] = (void *)
354                 (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + BUF);
355         ipi_mailbox_buf[4] = (void *)
356                 (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + BUF);
357         ipi_mailbox_buf[5] = (void *)
358                 (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + BUF);
359         ipi_mailbox_buf[6] = (void *)
360                 (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + BUF);
361         ipi_mailbox_buf[7] = (void *)
362                 (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + BUF);
363         ipi_mailbox_buf[8] = (void *)
364                 (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + BUF);
365         ipi_mailbox_buf[9] = (void *)
366                 (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + BUF);
367         ipi_mailbox_buf[10] = (void *)
368                 (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + BUF);
369         ipi_mailbox_buf[11] = (void *)
370                 (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + BUF);
371         ipi_mailbox_buf[12] = (void *)
372                 (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + BUF);
373         ipi_mailbox_buf[13] = (void *)
374                 (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + BUF);
375         ipi_mailbox_buf[14] = (void *)
376                 (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + BUF);
377         ipi_mailbox_buf[15] = (void *)
378                 (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + BUF);
379 }
380
381 /*
382  * Simple enough, just poke the appropriate ipi register
383  */
384 static void loongson3_send_ipi_single(int cpu, unsigned int action)
385 {
386         ipi_write_action(cpu_logical_map(cpu), (u32)action);
387 }
388
389 static void
390 loongson3_send_ipi_mask(const struct cpumask *mask, unsigned int action)
391 {
392         unsigned int i;
393
394         for_each_cpu(i, mask)
395                 ipi_write_action(cpu_logical_map(i), (u32)action);
396 }
397
398
399 static irqreturn_t loongson3_ipi_interrupt(int irq, void *dev_id)
400 {
401         int i, cpu = smp_processor_id();
402         unsigned int action, c0count;
403
404         action = ipi_read_clear(cpu);
405
406         if (action & SMP_RESCHEDULE_YOURSELF)
407                 scheduler_ipi();
408
409         if (action & SMP_CALL_FUNCTION) {
410                 irq_enter();
411                 generic_smp_call_function_interrupt();
412                 irq_exit();
413         }
414
415         if (action & SMP_ASK_C0COUNT) {
416                 BUG_ON(cpu != 0);
417                 c0count = read_c0_count();
418                 c0count = c0count ? c0count : 1;
419                 for (i = 1; i < nr_cpu_ids; i++)
420                         core0_c0count[i] = c0count;
421                 __wbflush(); /* Let others see the result ASAP */
422         }
423
424         return IRQ_HANDLED;
425 }
426
427 #define MAX_LOOPS 800
428 /*
429  * SMP init and finish on secondary CPUs
430  */
431 static void loongson3_init_secondary(void)
432 {
433         int i;
434         uint32_t initcount;
435         unsigned int cpu = smp_processor_id();
436         unsigned int imask = STATUSF_IP7 | STATUSF_IP6 |
437                              STATUSF_IP3 | STATUSF_IP2;
438
439         /* Set interrupt mask, but don't enable */
440         change_c0_status(ST0_IM, imask);
441         ipi_write_enable(cpu);
442
443         per_cpu(cpu_state, cpu) = CPU_ONLINE;
444         cpu_set_core(&cpu_data[cpu],
445                      cpu_logical_map(cpu) % loongson_sysconf.cores_per_package);
446         cpu_data[cpu].package =
447                 cpu_logical_map(cpu) / loongson_sysconf.cores_per_package;
448
449         i = 0;
450         core0_c0count[cpu] = 0;
451         loongson3_send_ipi_single(0, SMP_ASK_C0COUNT);
452         while (!core0_c0count[cpu]) {
453                 i++;
454                 cpu_relax();
455         }
456
457         if (i > MAX_LOOPS)
458                 i = MAX_LOOPS;
459         if (cpu_data[cpu].package)
460                 initcount = core0_c0count[cpu] + i;
461         else /* Local access is faster for loops */
462                 initcount = core0_c0count[cpu] + i/2;
463
464         write_c0_count(initcount);
465 }
466
467 static void loongson3_smp_finish(void)
468 {
469         int cpu = smp_processor_id();
470
471         write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ);
472         local_irq_enable();
473         ipi_clear_buf(cpu);
474
475         pr_info("CPU#%d finished, CP0_ST=%x\n",
476                         smp_processor_id(), read_c0_status());
477 }
478
479 static void __init loongson3_smp_setup(void)
480 {
481         int i = 0, num = 0; /* i: physical id, num: logical id */
482
483         init_cpu_possible(cpu_none_mask);
484
485         /* For unified kernel, NR_CPUS is the maximum possible value,
486          * loongson_sysconf.nr_cpus is the really present value
487          */
488         while (i < loongson_sysconf.nr_cpus) {
489                 if (loongson_sysconf.reserved_cpus_mask & (1<<i)) {
490                         /* Reserved physical CPU cores */
491                         __cpu_number_map[i] = -1;
492                 } else {
493                         __cpu_number_map[i] = num;
494                         __cpu_logical_map[num] = i;
495                         set_cpu_possible(num, true);
496                         /* Loongson processors are always grouped by 4 */
497                         cpu_set_cluster(&cpu_data[num], i / 4);
498                         num++;
499                 }
500                 i++;
501         }
502         pr_info("Detected %i available CPU(s)\n", num);
503
504         while (num < loongson_sysconf.nr_cpus) {
505                 __cpu_logical_map[num] = -1;
506                 num++;
507         }
508
509         csr_ipi_probe();
510         ipi_set0_regs_init();
511         ipi_clear0_regs_init();
512         ipi_status0_regs_init();
513         ipi_en0_regs_init();
514         ipi_mailbox_buf_init();
515         ipi_write_enable(0);
516
517         cpu_set_core(&cpu_data[0],
518                      cpu_logical_map(0) % loongson_sysconf.cores_per_package);
519         cpu_data[0].package = cpu_logical_map(0) / loongson_sysconf.cores_per_package;
520 }
521
522 static void __init loongson3_prepare_cpus(unsigned int max_cpus)
523 {
524         if (request_irq(LS_IPI_IRQ, loongson3_ipi_interrupt,
525                         IRQF_PERCPU | IRQF_NO_SUSPEND, "SMP_IPI", NULL))
526                 pr_err("Failed to request IPI IRQ\n");
527         init_cpu_present(cpu_possible_mask);
528         per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
529 }
530
531 /*
532  * Setup the PC, SP, and GP of a secondary processor and start it runing!
533  */
534 static int loongson3_boot_secondary(int cpu, struct task_struct *idle)
535 {
536         pr_info("Booting CPU#%d...\n", cpu);
537
538         ipi_write_buf(cpu, idle);
539
540         return 0;
541 }
542
543 #ifdef CONFIG_HOTPLUG_CPU
544
545 static int loongson3_cpu_disable(void)
546 {
547         unsigned long flags;
548         unsigned int cpu = smp_processor_id();
549
550         set_cpu_online(cpu, false);
551         calculate_cpu_foreign_map();
552         local_irq_save(flags);
553         irq_cpu_offline();
554         clear_c0_status(ST0_IM);
555         local_irq_restore(flags);
556         local_flush_tlb_all();
557
558         return 0;
559 }
560
561
562 static void loongson3_cpu_die(unsigned int cpu)
563 {
564         while (per_cpu(cpu_state, cpu) != CPU_DEAD)
565                 cpu_relax();
566
567         mb();
568 }
569
570 /* To shutdown a core in Loongson 3, the target core should go to CKSEG1 and
571  * flush all L1 entries at first. Then, another core (usually Core 0) can
572  * safely disable the clock of the target core. loongson3_play_dead() is
573  * called via CKSEG1 (uncached and unmmaped)
574  */
575 static void loongson3_type1_play_dead(int *state_addr)
576 {
577         register int val;
578         register long cpuid, core, node, count;
579         register void *addr, *base, *initfunc;
580
581         __asm__ __volatile__(
582                 "   .set push                     \n"
583                 "   .set noreorder                \n"
584                 "   li %[addr], 0x80000000        \n" /* KSEG0 */
585                 "1: cache 0, 0(%[addr])           \n" /* flush L1 ICache */
586                 "   cache 0, 1(%[addr])           \n"
587                 "   cache 0, 2(%[addr])           \n"
588                 "   cache 0, 3(%[addr])           \n"
589                 "   cache 1, 0(%[addr])           \n" /* flush L1 DCache */
590                 "   cache 1, 1(%[addr])           \n"
591                 "   cache 1, 2(%[addr])           \n"
592                 "   cache 1, 3(%[addr])           \n"
593                 "   addiu %[sets], %[sets], -1    \n"
594                 "   bnez  %[sets], 1b             \n"
595                 "   addiu %[addr], %[addr], 0x20  \n"
596                 "   li    %[val], 0x7             \n" /* *state_addr = CPU_DEAD; */
597                 "   sw    %[val], (%[state_addr]) \n"
598                 "   sync                          \n"
599                 "   cache 21, (%[state_addr])     \n" /* flush entry of *state_addr */
600                 "   .set pop                      \n"
601                 : [addr] "=&r" (addr), [val] "=&r" (val)
602                 : [state_addr] "r" (state_addr),
603                   [sets] "r" (cpu_data[smp_processor_id()].dcache.sets));
604
605         __asm__ __volatile__(
606                 "   .set push                         \n"
607                 "   .set noreorder                    \n"
608                 "   .set mips64                       \n"
609                 "   mfc0  %[cpuid], $15, 1            \n"
610                 "   andi  %[cpuid], 0x3ff             \n"
611                 "   dli   %[base], 0x900000003ff01000 \n"
612                 "   andi  %[core], %[cpuid], 0x3      \n"
613                 "   sll   %[core], 8                  \n" /* get core id */
614                 "   or    %[base], %[base], %[core]   \n"
615                 "   andi  %[node], %[cpuid], 0xc      \n"
616                 "   dsll  %[node], 42                 \n" /* get node id */
617                 "   or    %[base], %[base], %[node]   \n"
618                 "1: li    %[count], 0x100             \n" /* wait for init loop */
619                 "2: bnez  %[count], 2b                \n" /* limit mailbox access */
620                 "   addiu %[count], -1                \n"
621                 "   ld    %[initfunc], 0x20(%[base])  \n" /* get PC via mailbox */
622                 "   beqz  %[initfunc], 1b             \n"
623                 "   nop                               \n"
624                 "   ld    $sp, 0x28(%[base])          \n" /* get SP via mailbox */
625                 "   ld    $gp, 0x30(%[base])          \n" /* get GP via mailbox */
626                 "   ld    $a1, 0x38(%[base])          \n"
627                 "   jr    %[initfunc]                 \n" /* jump to initial PC */
628                 "   nop                               \n"
629                 "   .set pop                          \n"
630                 : [core] "=&r" (core), [node] "=&r" (node),
631                   [base] "=&r" (base), [cpuid] "=&r" (cpuid),
632                   [count] "=&r" (count), [initfunc] "=&r" (initfunc)
633                 : /* No Input */
634                 : "a1");
635 }
636
637 static void loongson3_type2_play_dead(int *state_addr)
638 {
639         register int val;
640         register long cpuid, core, node, count;
641         register void *addr, *base, *initfunc;
642
643         __asm__ __volatile__(
644                 "   .set push                     \n"
645                 "   .set noreorder                \n"
646                 "   li %[addr], 0x80000000        \n" /* KSEG0 */
647                 "1: cache 0, 0(%[addr])           \n" /* flush L1 ICache */
648                 "   cache 0, 1(%[addr])           \n"
649                 "   cache 0, 2(%[addr])           \n"
650                 "   cache 0, 3(%[addr])           \n"
651                 "   cache 1, 0(%[addr])           \n" /* flush L1 DCache */
652                 "   cache 1, 1(%[addr])           \n"
653                 "   cache 1, 2(%[addr])           \n"
654                 "   cache 1, 3(%[addr])           \n"
655                 "   addiu %[sets], %[sets], -1    \n"
656                 "   bnez  %[sets], 1b             \n"
657                 "   addiu %[addr], %[addr], 0x20  \n"
658                 "   li    %[val], 0x7             \n" /* *state_addr = CPU_DEAD; */
659                 "   sw    %[val], (%[state_addr]) \n"
660                 "   sync                          \n"
661                 "   cache 21, (%[state_addr])     \n" /* flush entry of *state_addr */
662                 "   .set pop                      \n"
663                 : [addr] "=&r" (addr), [val] "=&r" (val)
664                 : [state_addr] "r" (state_addr),
665                   [sets] "r" (cpu_data[smp_processor_id()].dcache.sets));
666
667         __asm__ __volatile__(
668                 "   .set push                         \n"
669                 "   .set noreorder                    \n"
670                 "   .set mips64                       \n"
671                 "   mfc0  %[cpuid], $15, 1            \n"
672                 "   andi  %[cpuid], 0x3ff             \n"
673                 "   dli   %[base], 0x900000003ff01000 \n"
674                 "   andi  %[core], %[cpuid], 0x3      \n"
675                 "   sll   %[core], 8                  \n" /* get core id */
676                 "   or    %[base], %[base], %[core]   \n"
677                 "   andi  %[node], %[cpuid], 0xc      \n"
678                 "   dsll  %[node], 42                 \n" /* get node id */
679                 "   or    %[base], %[base], %[node]   \n"
680                 "   dsrl  %[node], 30                 \n" /* 15:14 */
681                 "   or    %[base], %[base], %[node]   \n"
682                 "1: li    %[count], 0x100             \n" /* wait for init loop */
683                 "2: bnez  %[count], 2b                \n" /* limit mailbox access */
684                 "   addiu %[count], -1                \n"
685                 "   ld    %[initfunc], 0x20(%[base])  \n" /* get PC via mailbox */
686                 "   beqz  %[initfunc], 1b             \n"
687                 "   nop                               \n"
688                 "   ld    $sp, 0x28(%[base])          \n" /* get SP via mailbox */
689                 "   ld    $gp, 0x30(%[base])          \n" /* get GP via mailbox */
690                 "   ld    $a1, 0x38(%[base])          \n"
691                 "   jr    %[initfunc]                 \n" /* jump to initial PC */
692                 "   nop                               \n"
693                 "   .set pop                          \n"
694                 : [core] "=&r" (core), [node] "=&r" (node),
695                   [base] "=&r" (base), [cpuid] "=&r" (cpuid),
696                   [count] "=&r" (count), [initfunc] "=&r" (initfunc)
697                 : /* No Input */
698                 : "a1");
699 }
700
701 static void loongson3_type3_play_dead(int *state_addr)
702 {
703         register int val;
704         register long cpuid, core, node, count;
705         register void *addr, *base, *initfunc;
706
707         __asm__ __volatile__(
708                 "   .set push                     \n"
709                 "   .set noreorder                \n"
710                 "   li %[addr], 0x80000000        \n" /* KSEG0 */
711                 "1: cache 0, 0(%[addr])           \n" /* flush L1 ICache */
712                 "   cache 0, 1(%[addr])           \n"
713                 "   cache 0, 2(%[addr])           \n"
714                 "   cache 0, 3(%[addr])           \n"
715                 "   cache 1, 0(%[addr])           \n" /* flush L1 DCache */
716                 "   cache 1, 1(%[addr])           \n"
717                 "   cache 1, 2(%[addr])           \n"
718                 "   cache 1, 3(%[addr])           \n"
719                 "   addiu %[sets], %[sets], -1    \n"
720                 "   bnez  %[sets], 1b             \n"
721                 "   addiu %[addr], %[addr], 0x40  \n"
722                 "   li %[addr], 0x80000000        \n" /* KSEG0 */
723                 "2: cache 2, 0(%[addr])           \n" /* flush L1 VCache */
724                 "   cache 2, 1(%[addr])           \n"
725                 "   cache 2, 2(%[addr])           \n"
726                 "   cache 2, 3(%[addr])           \n"
727                 "   cache 2, 4(%[addr])           \n"
728                 "   cache 2, 5(%[addr])           \n"
729                 "   cache 2, 6(%[addr])           \n"
730                 "   cache 2, 7(%[addr])           \n"
731                 "   cache 2, 8(%[addr])           \n"
732                 "   cache 2, 9(%[addr])           \n"
733                 "   cache 2, 10(%[addr])          \n"
734                 "   cache 2, 11(%[addr])          \n"
735                 "   cache 2, 12(%[addr])          \n"
736                 "   cache 2, 13(%[addr])          \n"
737                 "   cache 2, 14(%[addr])          \n"
738                 "   cache 2, 15(%[addr])          \n"
739                 "   addiu %[vsets], %[vsets], -1  \n"
740                 "   bnez  %[vsets], 2b            \n"
741                 "   addiu %[addr], %[addr], 0x40  \n"
742                 "   li    %[val], 0x7             \n" /* *state_addr = CPU_DEAD; */
743                 "   sw    %[val], (%[state_addr]) \n"
744                 "   sync                          \n"
745                 "   cache 21, (%[state_addr])     \n" /* flush entry of *state_addr */
746                 "   .set pop                      \n"
747                 : [addr] "=&r" (addr), [val] "=&r" (val)
748                 : [state_addr] "r" (state_addr),
749                   [sets] "r" (cpu_data[smp_processor_id()].dcache.sets),
750                   [vsets] "r" (cpu_data[smp_processor_id()].vcache.sets));
751
752         __asm__ __volatile__(
753                 "   .set push                         \n"
754                 "   .set noreorder                    \n"
755                 "   .set mips64                       \n"
756                 "   mfc0  %[cpuid], $15, 1            \n"
757                 "   andi  %[cpuid], 0x3ff             \n"
758                 "   dli   %[base], 0x900000003ff01000 \n"
759                 "   andi  %[core], %[cpuid], 0x3      \n"
760                 "   sll   %[core], 8                  \n" /* get core id */
761                 "   or    %[base], %[base], %[core]   \n"
762                 "   andi  %[node], %[cpuid], 0xc      \n"
763                 "   dsll  %[node], 42                 \n" /* get node id */
764                 "   or    %[base], %[base], %[node]   \n"
765                 "1: li    %[count], 0x100             \n" /* wait for init loop */
766                 "2: bnez  %[count], 2b                \n" /* limit mailbox access */
767                 "   addiu %[count], -1                \n"
768                 "   lw    %[initfunc], 0x20(%[base])  \n" /* check lower 32-bit as jump indicator */
769                 "   beqz  %[initfunc], 1b             \n"
770                 "   nop                               \n"
771                 "   ld    %[initfunc], 0x20(%[base])  \n" /* get PC (whole 64-bit) via mailbox */
772                 "   ld    $sp, 0x28(%[base])          \n" /* get SP via mailbox */
773                 "   ld    $gp, 0x30(%[base])          \n" /* get GP via mailbox */
774                 "   ld    $a1, 0x38(%[base])          \n"
775                 "   jr    %[initfunc]                 \n" /* jump to initial PC */
776                 "   nop                               \n"
777                 "   .set pop                          \n"
778                 : [core] "=&r" (core), [node] "=&r" (node),
779                   [base] "=&r" (base), [cpuid] "=&r" (cpuid),
780                   [count] "=&r" (count), [initfunc] "=&r" (initfunc)
781                 : /* No Input */
782                 : "a1");
783 }
784
785 void play_dead(void)
786 {
787         int prid_imp, prid_rev, *state_addr;
788         unsigned int cpu = smp_processor_id();
789         void (*play_dead_at_ckseg1)(int *);
790
791         idle_task_exit();
792
793         prid_imp = read_c0_prid() & PRID_IMP_MASK;
794         prid_rev = read_c0_prid() & PRID_REV_MASK;
795
796         if (prid_imp == PRID_IMP_LOONGSON_64G) {
797                 play_dead_at_ckseg1 =
798                         (void *)CKSEG1ADDR((unsigned long)loongson3_type3_play_dead);
799                 goto out;
800         }
801
802         switch (prid_rev) {
803         case PRID_REV_LOONGSON3A_R1:
804         default:
805                 play_dead_at_ckseg1 =
806                         (void *)CKSEG1ADDR((unsigned long)loongson3_type1_play_dead);
807                 break;
808         case PRID_REV_LOONGSON3B_R1:
809         case PRID_REV_LOONGSON3B_R2:
810                 play_dead_at_ckseg1 =
811                         (void *)CKSEG1ADDR((unsigned long)loongson3_type2_play_dead);
812                 break;
813         case PRID_REV_LOONGSON3A_R2_0:
814         case PRID_REV_LOONGSON3A_R2_1:
815         case PRID_REV_LOONGSON3A_R3_0:
816         case PRID_REV_LOONGSON3A_R3_1:
817                 play_dead_at_ckseg1 =
818                         (void *)CKSEG1ADDR((unsigned long)loongson3_type3_play_dead);
819                 break;
820         }
821
822 out:
823         state_addr = &per_cpu(cpu_state, cpu);
824         mb();
825         play_dead_at_ckseg1(state_addr);
826 }
827
828 static int loongson3_disable_clock(unsigned int cpu)
829 {
830         uint64_t core_id = cpu_core(&cpu_data[cpu]);
831         uint64_t package_id = cpu_data[cpu].package;
832
833         if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) {
834                 LOONGSON_CHIPCFG(package_id) &= ~(1 << (12 + core_id));
835         } else {
836                 if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG))
837                         LOONGSON_FREQCTRL(package_id) &= ~(1 << (core_id * 4 + 3));
838         }
839         return 0;
840 }
841
842 static int loongson3_enable_clock(unsigned int cpu)
843 {
844         uint64_t core_id = cpu_core(&cpu_data[cpu]);
845         uint64_t package_id = cpu_data[cpu].package;
846
847         if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) {
848                 LOONGSON_CHIPCFG(package_id) |= 1 << (12 + core_id);
849         } else {
850                 if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG))
851                         LOONGSON_FREQCTRL(package_id) |= 1 << (core_id * 4 + 3);
852         }
853         return 0;
854 }
855
856 static int register_loongson3_notifier(void)
857 {
858         return cpuhp_setup_state_nocalls(CPUHP_MIPS_SOC_PREPARE,
859                                          "mips/loongson:prepare",
860                                          loongson3_enable_clock,
861                                          loongson3_disable_clock);
862 }
863 early_initcall(register_loongson3_notifier);
864
865 #endif
866
867 const struct plat_smp_ops loongson3_smp_ops = {
868         .send_ipi_single = loongson3_send_ipi_single,
869         .send_ipi_mask = loongson3_send_ipi_mask,
870         .init_secondary = loongson3_init_secondary,
871         .smp_finish = loongson3_smp_finish,
872         .boot_secondary = loongson3_boot_secondary,
873         .smp_setup = loongson3_smp_setup,
874         .prepare_cpus = loongson3_prepare_cpus,
875 #ifdef CONFIG_HOTPLUG_CPU
876         .cpu_disable = loongson3_cpu_disable,
877         .cpu_die = loongson3_cpu_die,
878 #endif
879 #ifdef CONFIG_KEXEC
880         .kexec_nonboot_cpu = kexec_nonboot_cpu_jump,
881 #endif
882 };