i2c: sun6-p2wi: fix call to snprintf
[linux-2.6-block.git] / arch / powerpc / platforms / wsp / scom_smp.c
CommitLineData
a1d0d98d
DG
1/*
2 * SCOM support for A2 platforms
3 *
4 * Copyright 2007-2011 Benjamin Herrenschmidt, David Gibson,
5 * Michael Ellerman, IBM Corp.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 */
12
13#include <linux/cpumask.h>
14#include <linux/io.h>
15#include <linux/of.h>
16#include <linux/spinlock.h>
17#include <linux/types.h>
18
19#include <asm/cputhreads.h>
20#include <asm/reg_a2.h>
21#include <asm/scom.h>
22#include <asm/udbg.h>
2751b628 23#include <asm/code-patching.h>
a1d0d98d
DG
24
25#include "wsp.h"
26
27#define SCOM_RAMC 0x2a /* Ram Command */
28#define SCOM_RAMC_TGT1_EXT 0x80000000
29#define SCOM_RAMC_SRC1_EXT 0x40000000
30#define SCOM_RAMC_SRC2_EXT 0x20000000
31#define SCOM_RAMC_SRC3_EXT 0x10000000
32#define SCOM_RAMC_ENABLE 0x00080000
33#define SCOM_RAMC_THREADSEL 0x00060000
34#define SCOM_RAMC_EXECUTE 0x00010000
35#define SCOM_RAMC_MSR_OVERRIDE 0x00008000
36#define SCOM_RAMC_MSR_PR 0x00004000
37#define SCOM_RAMC_MSR_GS 0x00002000
38#define SCOM_RAMC_FORCE 0x00001000
39#define SCOM_RAMC_FLUSH 0x00000800
40#define SCOM_RAMC_INTERRUPT 0x00000004
41#define SCOM_RAMC_ERROR 0x00000002
42#define SCOM_RAMC_DONE 0x00000001
43#define SCOM_RAMI 0x29 /* Ram Instruction */
44#define SCOM_RAMIC 0x28 /* Ram Instruction and Command */
45#define SCOM_RAMIC_INSN 0xffffffff00000000
46#define SCOM_RAMD 0x2d /* Ram Data */
47#define SCOM_RAMDH 0x2e /* Ram Data High */
48#define SCOM_RAMDL 0x2f /* Ram Data Low */
49#define SCOM_PCCR0 0x33 /* PC Configuration Register 0 */
50#define SCOM_PCCR0_ENABLE_DEBUG 0x80000000
51#define SCOM_PCCR0_ENABLE_RAM 0x40000000
52#define SCOM_THRCTL 0x30 /* Thread Control and Status */
53#define SCOM_THRCTL_T0_STOP 0x80000000
54#define SCOM_THRCTL_T1_STOP 0x40000000
55#define SCOM_THRCTL_T2_STOP 0x20000000
56#define SCOM_THRCTL_T3_STOP 0x10000000
57#define SCOM_THRCTL_T0_STEP 0x08000000
58#define SCOM_THRCTL_T1_STEP 0x04000000
59#define SCOM_THRCTL_T2_STEP 0x02000000
60#define SCOM_THRCTL_T3_STEP 0x01000000
61#define SCOM_THRCTL_T0_RUN 0x00800000
62#define SCOM_THRCTL_T1_RUN 0x00400000
63#define SCOM_THRCTL_T2_RUN 0x00200000
64#define SCOM_THRCTL_T3_RUN 0x00100000
65#define SCOM_THRCTL_T0_PM 0x00080000
66#define SCOM_THRCTL_T1_PM 0x00040000
67#define SCOM_THRCTL_T2_PM 0x00020000
68#define SCOM_THRCTL_T3_PM 0x00010000
69#define SCOM_THRCTL_T0_UDE 0x00008000
70#define SCOM_THRCTL_T1_UDE 0x00004000
71#define SCOM_THRCTL_T2_UDE 0x00002000
72#define SCOM_THRCTL_T3_UDE 0x00001000
73#define SCOM_THRCTL_ASYNC_DIS 0x00000800
74#define SCOM_THRCTL_TB_DIS 0x00000400
75#define SCOM_THRCTL_DEC_DIS 0x00000200
76#define SCOM_THRCTL_AND 0x31 /* Thread Control and Status */
77#define SCOM_THRCTL_OR 0x32 /* Thread Control and Status */
78
79
80static DEFINE_PER_CPU(scom_map_t, scom_ptrs);
81
82static scom_map_t get_scom(int cpu, struct device_node *np, int *first_thread)
83{
84 scom_map_t scom = per_cpu(scom_ptrs, cpu);
85 int tcpu;
86
87 if (scom_map_ok(scom)) {
88 *first_thread = 0;
89 return scom;
90 }
91
92 *first_thread = 1;
93
94 scom = scom_map_device(np, 0);
95
96 for (tcpu = cpu_first_thread_sibling(cpu);
97 tcpu <= cpu_last_thread_sibling(cpu); tcpu++)
98 per_cpu(scom_ptrs, tcpu) = scom;
99
100 /* Hack: for the boot core, this will actually get called on
101 * the second thread up, not the first so our test above will
102 * set first_thread incorrectly. */
103 if (cpu_first_thread_sibling(cpu) == 0)
104 *first_thread = 0;
105
106 return scom;
107}
108
109static int a2_scom_ram(scom_map_t scom, int thread, u32 insn, int extmask)
110{
111 u64 cmd, mask, val;
112 int n = 0;
113
114 cmd = ((u64)insn << 32) | (((u64)extmask & 0xf) << 28)
115 | ((u64)thread << 17) | SCOM_RAMC_ENABLE | SCOM_RAMC_EXECUTE;
116 mask = SCOM_RAMC_DONE | SCOM_RAMC_INTERRUPT | SCOM_RAMC_ERROR;
117
118 scom_write(scom, SCOM_RAMIC, cmd);
119
aaa63093
BH
120 for (;;) {
121 if (scom_read(scom, SCOM_RAMC, &val) != 0) {
122 pr_err("SCOM error on instruction 0x%08x, thread %d\n",
123 insn, thread);
124 return -1;
125 }
126 if (val & mask)
127 break;
a1d0d98d
DG
128 pr_devel("Waiting on RAMC = 0x%llx\n", val);
129 if (++n == 3) {
130 pr_err("RAMC timeout on instruction 0x%08x, thread %d\n",
131 insn, thread);
132 return -1;
133 }
134 }
135
136 if (val & SCOM_RAMC_INTERRUPT) {
137 pr_err("RAMC interrupt on instruction 0x%08x, thread %d\n",
138 insn, thread);
139 return -SCOM_RAMC_INTERRUPT;
140 }
141
142 if (val & SCOM_RAMC_ERROR) {
143 pr_err("RAMC error on instruction 0x%08x, thread %d\n",
144 insn, thread);
145 return -SCOM_RAMC_ERROR;
146 }
147
148 return 0;
149}
150
151static int a2_scom_getgpr(scom_map_t scom, int thread, int gpr, int alt,
152 u64 *out_gpr)
153{
154 int rc;
155
156 /* or rN, rN, rN */
157 u32 insn = 0x7c000378 | (gpr << 21) | (gpr << 16) | (gpr << 11);
158 rc = a2_scom_ram(scom, thread, insn, alt ? 0xf : 0x0);
159 if (rc)
160 return rc;
161
aaa63093 162 return scom_read(scom, SCOM_RAMD, out_gpr);
a1d0d98d
DG
163}
164
165static int a2_scom_getspr(scom_map_t scom, int thread, int spr, u64 *out_spr)
166{
167 int rc, sprhi, sprlo;
168 u32 insn;
169
170 sprhi = spr >> 5;
171 sprlo = spr & 0x1f;
172 insn = 0x7c2002a6 | (sprlo << 16) | (sprhi << 11); /* mfspr r1,spr */
173
174 if (spr == 0x0ff0)
175 insn = 0x7c2000a6; /* mfmsr r1 */
176
177 rc = a2_scom_ram(scom, thread, insn, 0xf);
178 if (rc)
179 return rc;
180 return a2_scom_getgpr(scom, thread, 1, 1, out_spr);
181}
182
183static int a2_scom_setgpr(scom_map_t scom, int thread, int gpr,
184 int alt, u64 val)
185{
186 u32 lis = 0x3c000000 | (gpr << 21);
187 u32 li = 0x38000000 | (gpr << 21);
188 u32 oris = 0x64000000 | (gpr << 21) | (gpr << 16);
189 u32 ori = 0x60000000 | (gpr << 21) | (gpr << 16);
190 u32 rldicr32 = 0x780007c6 | (gpr << 21) | (gpr << 16);
191 u32 highest = val >> 48;
192 u32 higher = (val >> 32) & 0xffff;
193 u32 high = (val >> 16) & 0xffff;
194 u32 low = val & 0xffff;
195 int lext = alt ? 0x8 : 0x0;
196 int oext = alt ? 0xf : 0x0;
197 int rc = 0;
198
199 if (highest)
200 rc |= a2_scom_ram(scom, thread, lis | highest, lext);
201
202 if (higher) {
203 if (highest)
204 rc |= a2_scom_ram(scom, thread, oris | higher, oext);
205 else
206 rc |= a2_scom_ram(scom, thread, li | higher, lext);
207 }
208
209 if (highest || higher)
210 rc |= a2_scom_ram(scom, thread, rldicr32, oext);
211
212 if (high) {
213 if (highest || higher)
214 rc |= a2_scom_ram(scom, thread, oris | high, oext);
215 else
216 rc |= a2_scom_ram(scom, thread, lis | high, lext);
217 }
218
219 if (highest || higher || high)
220 rc |= a2_scom_ram(scom, thread, ori | low, oext);
221 else
222 rc |= a2_scom_ram(scom, thread, li | low, lext);
223
224 return rc;
225}
226
227static int a2_scom_setspr(scom_map_t scom, int thread, int spr, u64 val)
228{
229 int sprhi = spr >> 5;
230 int sprlo = spr & 0x1f;
231 /* mtspr spr, r1 */
232 u32 insn = 0x7c2003a6 | (sprlo << 16) | (sprhi << 11);
233
234 if (spr == 0x0ff0)
235 insn = 0x7c200124; /* mtmsr r1 */
236
237 if (a2_scom_setgpr(scom, thread, 1, 1, val))
238 return -1;
239
240 return a2_scom_ram(scom, thread, insn, 0xf);
241}
242
243static int a2_scom_initial_tlb(scom_map_t scom, int thread)
244{
245 extern u32 a2_tlbinit_code_start[], a2_tlbinit_code_end[];
246 extern u32 a2_tlbinit_after_iprot_flush[];
247 extern u32 a2_tlbinit_after_linear_map[];
248 u32 assoc, entries, i;
249 u64 epn, tlbcfg;
250 u32 *p;
251 int rc;
252
253 /* Invalidate all entries (including iprot) */
254
255 rc = a2_scom_getspr(scom, thread, SPRN_TLB0CFG, &tlbcfg);
256 if (rc)
257 goto scom_fail;
258 entries = tlbcfg & TLBnCFG_N_ENTRY;
259 assoc = (tlbcfg & TLBnCFG_ASSOC) >> 24;
260 epn = 0;
261
262 /* Set MMUCR2 to enable 4K, 64K, 1M, 16M and 1G pages */
263 a2_scom_setspr(scom, thread, SPRN_MMUCR2, 0x000a7531);
264 /* Set MMUCR3 to write all thids bit to the TLB */
265 a2_scom_setspr(scom, thread, SPRN_MMUCR3, 0x0000000f);
266
267 /* Set MAS1 for 1G page size, and MAS2 to our initial EPN */
268 a2_scom_setspr(scom, thread, SPRN_MAS1, MAS1_TSIZE(BOOK3E_PAGESZ_1GB));
269 a2_scom_setspr(scom, thread, SPRN_MAS2, epn);
270 for (i = 0; i < entries; i++) {
271
272 a2_scom_setspr(scom, thread, SPRN_MAS0, MAS0_ESEL(i % assoc));
273
274 /* tlbwe */
275 rc = a2_scom_ram(scom, thread, 0x7c0007a4, 0);
276 if (rc)
277 goto scom_fail;
278
279 /* Next entry is new address? */
280 if((i + 1) % assoc == 0) {
281 epn += (1 << 30);
282 a2_scom_setspr(scom, thread, SPRN_MAS2, epn);
283 }
284 }
285
286 /* Setup args for linear mapping */
287 rc = a2_scom_setgpr(scom, thread, 3, 0, MAS0_TLBSEL(0));
288 if (rc)
289 goto scom_fail;
290
291 /* Linear mapping */
292 for (p = a2_tlbinit_code_start; p < a2_tlbinit_after_linear_map; p++) {
293 rc = a2_scom_ram(scom, thread, *p, 0);
294 if (rc)
295 goto scom_fail;
296 }
297
298 /*
299 * For the boot thread, between the linear mapping and the debug
300 * mappings there is a loop to flush iprot mappings. Ramming doesn't do
301 * branches, but the secondary threads don't need to be nearly as smart
302 * (i.e. we don't need to worry about invalidating the mapping we're
303 * standing on).
304 */
305
306 /* Debug mappings. Expects r11 = MAS0 from linear map (set above) */
307 for (p = a2_tlbinit_after_iprot_flush; p < a2_tlbinit_code_end; p++) {
308 rc = a2_scom_ram(scom, thread, *p, 0);
309 if (rc)
310 goto scom_fail;
311 }
312
313scom_fail:
314 if (rc)
315 pr_err("Setting up initial TLB failed, err %d\n", rc);
316
317 if (rc == -SCOM_RAMC_INTERRUPT) {
318 /* Interrupt, dump some status */
319 int rc[10];
320 u64 iar, srr0, srr1, esr, mas0, mas1, mas2, mas7_3, mas8, ccr2;
321 rc[0] = a2_scom_getspr(scom, thread, SPRN_IAR, &iar);
322 rc[1] = a2_scom_getspr(scom, thread, SPRN_SRR0, &srr0);
323 rc[2] = a2_scom_getspr(scom, thread, SPRN_SRR1, &srr1);
324 rc[3] = a2_scom_getspr(scom, thread, SPRN_ESR, &esr);
325 rc[4] = a2_scom_getspr(scom, thread, SPRN_MAS0, &mas0);
326 rc[5] = a2_scom_getspr(scom, thread, SPRN_MAS1, &mas1);
327 rc[6] = a2_scom_getspr(scom, thread, SPRN_MAS2, &mas2);
328 rc[7] = a2_scom_getspr(scom, thread, SPRN_MAS7_MAS3, &mas7_3);
329 rc[8] = a2_scom_getspr(scom, thread, SPRN_MAS8, &mas8);
330 rc[9] = a2_scom_getspr(scom, thread, SPRN_A2_CCR2, &ccr2);
331 pr_err(" -> retreived IAR =0x%llx (err %d)\n", iar, rc[0]);
332 pr_err(" retreived SRR0=0x%llx (err %d)\n", srr0, rc[1]);
333 pr_err(" retreived SRR1=0x%llx (err %d)\n", srr1, rc[2]);
334 pr_err(" retreived ESR =0x%llx (err %d)\n", esr, rc[3]);
335 pr_err(" retreived MAS0=0x%llx (err %d)\n", mas0, rc[4]);
336 pr_err(" retreived MAS1=0x%llx (err %d)\n", mas1, rc[5]);
337 pr_err(" retreived MAS2=0x%llx (err %d)\n", mas2, rc[6]);
338 pr_err(" retreived MS73=0x%llx (err %d)\n", mas7_3, rc[7]);
339 pr_err(" retreived MAS8=0x%llx (err %d)\n", mas8, rc[8]);
340 pr_err(" retreived CCR2=0x%llx (err %d)\n", ccr2, rc[9]);
341 }
342
343 return rc;
344}
345
cad5cef6 346int a2_scom_startup_cpu(unsigned int lcpu, int thr_idx, struct device_node *np)
a1d0d98d
DG
347{
348 u64 init_iar, init_msr, init_ccr2;
349 unsigned long start_here;
350 int rc, core_setup;
351 scom_map_t scom;
352 u64 pccr0;
353
354 scom = get_scom(lcpu, np, &core_setup);
355 if (!scom) {
356 printk(KERN_ERR "Couldn't map SCOM for CPU%d\n", lcpu);
357 return -1;
358 }
359
360 pr_devel("Bringing up CPU%d using SCOM...\n", lcpu);
361
aaa63093
BH
362 if (scom_read(scom, SCOM_PCCR0, &pccr0) != 0) {
363 printk(KERN_ERR "XSCOM failure readng PCCR0 on CPU%d\n", lcpu);
364 return -1;
365 }
a1d0d98d
DG
366 scom_write(scom, SCOM_PCCR0, pccr0 | SCOM_PCCR0_ENABLE_DEBUG |
367 SCOM_PCCR0_ENABLE_RAM);
368
369 /* Stop the thead with THRCTL. If we are setting up the TLB we stop all
370 * threads. We also disable asynchronous interrupts while RAMing.
371 */
372 if (core_setup)
373 scom_write(scom, SCOM_THRCTL_OR,
374 SCOM_THRCTL_T0_STOP |
375 SCOM_THRCTL_T1_STOP |
376 SCOM_THRCTL_T2_STOP |
377 SCOM_THRCTL_T3_STOP |
378 SCOM_THRCTL_ASYNC_DIS);
379 else
380 scom_write(scom, SCOM_THRCTL_OR, SCOM_THRCTL_T0_STOP >> thr_idx);
381
382 /* Flush its pipeline just in case */
383 scom_write(scom, SCOM_RAMC, ((u64)thr_idx << 17) |
384 SCOM_RAMC_FLUSH | SCOM_RAMC_ENABLE);
385
386 a2_scom_getspr(scom, thr_idx, SPRN_IAR, &init_iar);
387 a2_scom_getspr(scom, thr_idx, 0x0ff0, &init_msr);
388 a2_scom_getspr(scom, thr_idx, SPRN_A2_CCR2, &init_ccr2);
389
390 /* Set MSR to MSR_CM (0x0ff0 is magic value for MSR_CM) */
391 rc = a2_scom_setspr(scom, thr_idx, 0x0ff0, MSR_CM);
392 if (rc) {
393 pr_err("Failed to set MSR ! err %d\n", rc);
394 return rc;
395 }
396
397 /* RAM in an sync/isync for the sake of it */
398 a2_scom_ram(scom, thr_idx, 0x7c0004ac, 0);
399 a2_scom_ram(scom, thr_idx, 0x4c00012c, 0);
400
401 if (core_setup) {
402 pr_devel("CPU%d is first thread in core, initializing TLB...\n",
403 lcpu);
404 rc = a2_scom_initial_tlb(scom, thr_idx);
405 if (rc)
406 goto fail;
407 }
408
2751b628 409 start_here = ppc_function_entry(core_setup ? generic_secondary_smp_init
a1d0d98d
DG
410 : generic_secondary_thread_init);
411 pr_devel("CPU%d entry point at 0x%lx...\n", lcpu, start_here);
412
413 rc |= a2_scom_setspr(scom, thr_idx, SPRN_IAR, start_here);
414 rc |= a2_scom_setgpr(scom, thr_idx, 3, 0,
415 get_hard_smp_processor_id(lcpu));
416 /*
417 * Tell book3e_secondary_core_init not to set up the TLB, we've
418 * already done that.
419 */
420 rc |= a2_scom_setgpr(scom, thr_idx, 4, 0, 1);
421
422 rc |= a2_scom_setspr(scom, thr_idx, SPRN_TENS, 0x1 << thr_idx);
423
424 scom_write(scom, SCOM_RAMC, 0);
425 scom_write(scom, SCOM_THRCTL_AND, ~(SCOM_THRCTL_T0_STOP >> thr_idx));
426 scom_write(scom, SCOM_PCCR0, pccr0);
427fail:
428 pr_devel(" SCOM initialization %s\n", rc ? "failed" : "succeeded");
429 if (rc) {
430 pr_err("Old IAR=0x%08llx MSR=0x%08llx CCR2=0x%08llx\n",
431 init_iar, init_msr, init_ccr2);
432 }
433
434 return rc;
435}