xref: /freebsd/sys/powerpc/mpc85xx/platform_mpc85xx.c (revision fed1ca4b719c56c930f2259d80663cd34be812bb)
1 /*-
2  * Copyright (c) 2008-2012 Semihalf.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #include "opt_platform.h"
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30 
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/kernel.h>
34 #include <sys/bus.h>
35 #include <sys/pcpu.h>
36 #include <sys/proc.h>
37 #include <sys/smp.h>
38 
39 #include <machine/bus.h>
40 #include <machine/cpu.h>
41 #include <machine/hid.h>
42 #include <machine/machdep.h>
43 #include <machine/platform.h>
44 #include <machine/platformvar.h>
45 #include <machine/smp.h>
46 #include <machine/spr.h>
47 #include <machine/vmparam.h>
48 
49 #include <dev/fdt/fdt_common.h>
50 #include <dev/ofw/ofw_bus.h>
51 #include <dev/ofw/ofw_bus_subr.h>
52 #include <dev/ofw/openfirm.h>
53 
54 #include <vm/vm.h>
55 #include <vm/pmap.h>
56 
57 #include <powerpc/mpc85xx/mpc85xx.h>
58 
59 #include "platform_if.h"
60 
61 #ifdef SMP
62 extern void *ap_pcpu;
63 extern vm_paddr_t kernload;		/* Kernel physical load address */
64 extern uint8_t __boot_page[];		/* Boot page body */
65 extern uint32_t bp_kernload;
66 #endif
67 
68 extern uint32_t *bootinfo;
69 vm_offset_t ccsrbar_va;
70 
71 static int cpu, maxcpu;
72 
73 static int mpc85xx_probe(platform_t);
74 static void mpc85xx_mem_regions(platform_t, struct mem_region *phys,
75     int *physsz, struct mem_region *avail, int *availsz);
76 static u_long mpc85xx_timebase_freq(platform_t, struct cpuref *cpuref);
77 static int mpc85xx_smp_first_cpu(platform_t, struct cpuref *cpuref);
78 static int mpc85xx_smp_next_cpu(platform_t, struct cpuref *cpuref);
79 static int mpc85xx_smp_get_bsp(platform_t, struct cpuref *cpuref);
80 static int mpc85xx_smp_start_cpu(platform_t, struct pcpu *cpu);
81 static void mpc85xx_idle(platform_t, int cpu);
82 static int mpc85xx_idle_wakeup(platform_t plat, int cpu);
83 
84 static void mpc85xx_reset(platform_t);
85 
86 static platform_method_t mpc85xx_methods[] = {
87 	PLATFORMMETHOD(platform_probe,		mpc85xx_probe),
88 	PLATFORMMETHOD(platform_attach,		mpc85xx_attach),
89 	PLATFORMMETHOD(platform_mem_regions,	mpc85xx_mem_regions),
90 	PLATFORMMETHOD(platform_timebase_freq,	mpc85xx_timebase_freq),
91 
92 	PLATFORMMETHOD(platform_smp_first_cpu,	mpc85xx_smp_first_cpu),
93 	PLATFORMMETHOD(platform_smp_next_cpu,	mpc85xx_smp_next_cpu),
94 	PLATFORMMETHOD(platform_smp_get_bsp,	mpc85xx_smp_get_bsp),
95 	PLATFORMMETHOD(platform_smp_start_cpu,	mpc85xx_smp_start_cpu),
96 
97 	PLATFORMMETHOD(platform_reset,		mpc85xx_reset),
98 	PLATFORMMETHOD(platform_idle,		mpc85xx_idle),
99 	PLATFORMMETHOD(platform_idle_wakeup,	mpc85xx_idle_wakeup),
100 
101 	PLATFORMMETHOD_END
102 };
103 
104 DEFINE_CLASS_0(mpc85xx, mpc85xx_platform, mpc85xx_methods, 0);
105 
106 PLATFORM_DEF(mpc85xx_platform);
107 
108 static int
109 mpc85xx_probe(platform_t plat)
110 {
111 	u_int pvr = mfpvr() >> 16;
112 
113 	if ((pvr & 0xfff0) == FSL_E500v1)
114 		return (BUS_PROBE_DEFAULT);
115 
116 	return (ENXIO);
117 }
118 
119 int
120 mpc85xx_attach(platform_t plat)
121 {
122 	phandle_t cpus, child, ccsr;
123 	const char *soc_name_guesses[] = {"/soc", "soc", NULL};
124 	const char **name;
125 	pcell_t ranges[6], acells, pacells, scells;
126 	uint32_t sr;
127 	uint64_t ccsrbar, ccsrsize;
128 	int i, law_max, tgt;
129 
130 	if ((cpus = OF_finddevice("/cpus")) != -1) {
131 		for (maxcpu = 0, child = OF_child(cpus); child != 0;
132 		    child = OF_peer(child), maxcpu++)
133 			;
134 	} else
135 		maxcpu = 1;
136 
137 	/*
138 	 * Locate CCSR region. Irritatingly, there is no way to find it
139 	 * unless you already know where it is. Try to infer its location
140 	 * from the device tree.
141 	 */
142 
143 	ccsr = -1;
144 	for (name = soc_name_guesses; *name != NULL && ccsr == -1; name++)
145 		ccsr = OF_finddevice(*name);
146 	if (ccsr == -1) {
147 		char type[64];
148 
149 	 	/* That didn't work. Search for devices of type "soc" */
150 		child = OF_child(OF_peer(0));
151 		for (OF_child(child); child != 0; child = OF_peer(child)) {
152 			if (OF_getprop(child, "device_type", type, sizeof(type))
153 			    <= 0)
154 				continue;
155 
156 			if (strcmp(type, "soc") == 0) {
157 				ccsr = child;
158 				break;
159 			}
160 		}
161 	}
162 
163 	if (ccsr == -1)
164 		panic("Could not locate CCSR window!");
165 
166 	OF_getprop(ccsr, "#size-cells", &scells, sizeof(scells));
167 	OF_getprop(ccsr, "#address-cells", &acells, sizeof(acells));
168 	OF_searchprop(OF_parent(ccsr), "#address-cells", &pacells,
169 	    sizeof(pacells));
170 	OF_getprop(ccsr, "ranges", ranges, sizeof(ranges));
171 	ccsrbar = ccsrsize = 0;
172 	for (i = acells; i < acells + pacells; i++) {
173 		ccsrbar <<= 32;
174 		ccsrbar |= ranges[i];
175 	}
176 	for (i = acells + pacells; i < acells + pacells + scells; i++) {
177 		ccsrsize <<= 32;
178 		ccsrsize |= ranges[i];
179 	}
180 	ccsrbar_va = pmap_early_io_map(ccsrbar, ccsrsize);
181 
182 	mpc85xx_fix_errata(ccsrbar_va);
183 	mpc85xx_enable_l3_cache();
184 
185 	/*
186 	 * Clear local access windows. Skip DRAM entries, so we don't shoot
187 	 * ourselves in the foot.
188 	 */
189 	law_max = law_getmax();
190 	for (i = 0; i < law_max; i++) {
191 		sr = ccsr_read4(OCP85XX_LAWSR(i));
192 		if ((sr & OCP85XX_ENA_MASK) == 0)
193 			continue;
194 		tgt = (sr & 0x01f00000) >> 20;
195 		if (tgt == OCP85XX_TGTIF_RAM1 || tgt == OCP85XX_TGTIF_RAM2 ||
196 		    tgt == OCP85XX_TGTIF_RAM_INTL)
197 			continue;
198 
199 		ccsr_write4(OCP85XX_LAWSR(i), sr & OCP85XX_DIS_MASK);
200 	}
201 
202 	return (0);
203 }
204 
205 void
206 mpc85xx_mem_regions(platform_t plat, struct mem_region *phys, int *physsz,
207     struct mem_region *avail, int *availsz)
208 {
209 
210 	ofw_mem_regions(phys, physsz, avail, availsz);
211 }
212 
213 static u_long
214 mpc85xx_timebase_freq(platform_t plat, struct cpuref *cpuref)
215 {
216 	u_long ticks;
217 	phandle_t cpus, child;
218 	pcell_t freq;
219 
220 	if (bootinfo != NULL) {
221 		if (bootinfo[0] == 1) {
222 			/* Backward compatibility. See 8-STABLE. */
223 			ticks = bootinfo[3] >> 3;
224 		} else {
225 			/* Compatibility with Juniper's loader. */
226 			ticks = bootinfo[5] >> 3;
227 		}
228 	} else
229 		ticks = 0;
230 
231 	if ((cpus = OF_finddevice("/cpus")) == -1)
232 		goto out;
233 
234 	if ((child = OF_child(cpus)) == 0)
235 		goto out;
236 
237 	switch (OF_getproplen(child, "timebase-frequency")) {
238 	case 4:
239 	{
240 		uint32_t tbase;
241 		OF_getprop(child, "timebase-frequency", &tbase, sizeof(tbase));
242 		ticks = tbase;
243 		return (ticks);
244 	}
245 	case 8:
246 	{
247 		uint64_t tbase;
248 		OF_getprop(child, "timebase-frequency", &tbase, sizeof(tbase));
249 		ticks = tbase;
250 		return (ticks);
251 	}
252 	default:
253 		break;
254 	}
255 
256 	freq = 0;
257 	if (OF_getprop(child, "bus-frequency", (void *)&freq,
258 	    sizeof(freq)) <= 0)
259 		goto out;
260 
261 	/*
262 	 * Time Base and Decrementer are updated every 8 CCB bus clocks.
263 	 * HID0[SEL_TBCLK] = 0
264 	 */
265 	if (freq != 0)
266 #ifdef QORIQ_DPAA
267 		ticks = freq / 32;
268 #else
269 		ticks = freq / 8;
270 #endif
271 
272 out:
273 	if (ticks <= 0)
274 		panic("Unable to determine timebase frequency!");
275 
276 	return (ticks);
277 }
278 
279 static int
280 mpc85xx_smp_first_cpu(platform_t plat, struct cpuref *cpuref)
281 {
282 
283 	cpu = 0;
284 	cpuref->cr_cpuid = cpu;
285 	cpuref->cr_hwref = cpuref->cr_cpuid;
286 	if (bootverbose)
287 		printf("powerpc_smp_first_cpu: cpuid %d\n", cpuref->cr_cpuid);
288 	cpu++;
289 
290 	return (0);
291 }
292 
293 static int
294 mpc85xx_smp_next_cpu(platform_t plat, struct cpuref *cpuref)
295 {
296 
297 	if (cpu >= maxcpu)
298 		return (ENOENT);
299 
300 	cpuref->cr_cpuid = cpu++;
301 	cpuref->cr_hwref = cpuref->cr_cpuid;
302 	if (bootverbose)
303 		printf("powerpc_smp_next_cpu: cpuid %d\n", cpuref->cr_cpuid);
304 
305 	return (0);
306 }
307 
308 static int
309 mpc85xx_smp_get_bsp(platform_t plat, struct cpuref *cpuref)
310 {
311 
312 	cpuref->cr_cpuid = mfspr(SPR_PIR);
313 	cpuref->cr_hwref = cpuref->cr_cpuid;
314 
315 	return (0);
316 }
317 
318 static int
319 mpc85xx_smp_start_cpu(platform_t plat, struct pcpu *pc)
320 {
321 #ifdef SMP
322 	vm_paddr_t bptr;
323 	uint32_t reg;
324 	int timeout;
325 	uintptr_t brr;
326 	int cpuid;
327 
328 #ifdef QORIQ_DPAA
329 	uint32_t tgt;
330 
331 	reg = ccsr_read4(OCP85XX_COREDISR);
332 	cpuid = pc->pc_cpuid;
333 
334 	if ((reg & cpuid) != 0) {
335 		printf("%s: CPU %d is disabled!\n", __func__, pc->pc_cpuid);
336 		return (-1);
337 	}
338 
339 	brr = OCP85XX_BRR;
340 #else /* QORIQ_DPAA */
341 	brr = OCP85XX_EEBPCR;
342 	cpuid = pc->pc_cpuid + 24;
343 #endif
344 	bp_kernload = kernload;
345 	reg = ccsr_read4(brr);
346 	if ((reg & (1 << cpuid)) != 0) {
347 		printf("SMP: CPU %d already out of hold-off state!\n",
348 		    pc->pc_cpuid);
349 		return (ENXIO);
350 	}
351 
352 	ap_pcpu = pc;
353 	__asm __volatile("msync; isync");
354 
355 	/* Flush caches to have our changes hit DRAM. */
356 	cpu_flush_dcache(__boot_page, 4096);
357 
358 	bptr = ((vm_paddr_t)(uintptr_t)__boot_page - KERNBASE) + kernload;
359 	KASSERT((bptr & 0xfff) == 0,
360 	    ("%s: boot page is not aligned (%#jx)", __func__, (uintmax_t)bptr));
361 #ifdef QORIQ_DPAA
362 
363 	/*
364 	 * Read DDR controller configuration to select proper BPTR target ID.
365 	 *
366 	 * On P5020 bit 29 of DDR1_CS0_CONFIG enables DDR controllers
367 	 * interleaving. If this bit is set, we have to use
368 	 * OCP85XX_TGTIF_RAM_INTL as BPTR target ID. On other QorIQ DPAA SoCs,
369 	 * this bit is reserved and always 0.
370 	 */
371 
372 	reg = ccsr_read4(OCP85XX_DDR1_CS0_CONFIG);
373 	if (reg & (1 << 29))
374 		tgt = OCP85XX_TGTIF_RAM_INTL;
375 	else
376 		tgt = OCP85XX_TGTIF_RAM1;
377 
378 	/*
379 	 * Set BSTR to the physical address of the boot page
380 	 */
381 	ccsr_write4(OCP85XX_BSTRH, bptr >> 32);
382 	ccsr_write4(OCP85XX_BSTRL, bptr);
383 	ccsr_write4(OCP85XX_BSTAR, OCP85XX_ENA_MASK |
384 	    (tgt << OCP85XX_TRGT_SHIFT) | (ffsl(PAGE_SIZE) - 2));
385 
386 	/* Read back OCP85XX_BSTAR to synchronize write */
387 	ccsr_read4(OCP85XX_BSTAR);
388 
389 	/*
390 	 * Enable and configure time base on new CPU.
391 	 */
392 
393 	/* Set TB clock source to platform clock / 32 */
394 	reg = ccsr_read4(CCSR_CTBCKSELR);
395 	ccsr_write4(CCSR_CTBCKSELR, reg & ~(1 << pc->pc_cpuid));
396 
397 	/* Enable TB */
398 	reg = ccsr_read4(CCSR_CTBENR);
399 	ccsr_write4(CCSR_CTBENR, reg | (1 << pc->pc_cpuid));
400 #else
401 
402 	/*
403 	 * Set BPTR to the physical address of the boot page
404 	 */
405 	bptr = (bptr >> 12) | 0x80000000u;
406 	ccsr_write4(OCP85XX_BPTR, bptr);
407 	__asm __volatile("isync; msync");
408 
409 #endif /* QORIQ_DPAA */
410 
411 	/*
412 	 * Release AP from hold-off state
413 	 */
414 	reg = ccsr_read4(brr);
415 	ccsr_write4(brr, reg | (1 << cpuid));
416 	__asm __volatile("isync; msync");
417 
418 	timeout = 500;
419 	while (!pc->pc_awake && timeout--)
420 		DELAY(1000);	/* wait 1ms */
421 
422 	/*
423 	 * Disable boot page translation so that the 4K page at the default
424 	 * address (= 0xfffff000) isn't permanently remapped and thus not
425 	 * usable otherwise.
426 	 */
427 #ifdef QORIQ_DPAA
428 	ccsr_write4(OCP85XX_BSTAR, 0);
429 #else
430 	ccsr_write4(OCP85XX_BPTR, 0);
431 #endif
432 	__asm __volatile("isync; msync");
433 
434 	if (!pc->pc_awake)
435 		printf("SMP: CPU %d didn't wake up.\n", pc->pc_cpuid);
436 	return ((pc->pc_awake) ? 0 : EBUSY);
437 #else
438 	/* No SMP support */
439 	return (ENXIO);
440 #endif
441 }
442 
443 static void
444 mpc85xx_reset(platform_t plat)
445 {
446 
447 	/*
448 	 * Try the dedicated reset register first.
449 	 * If the SoC doesn't have one, we'll fall
450 	 * back to using the debug control register.
451 	 */
452 	ccsr_write4(OCP85XX_RSTCR, 2);
453 
454 	/* Clear DBCR0, disables debug interrupts and events. */
455 	mtspr(SPR_DBCR0, 0);
456 	__asm __volatile("isync");
457 
458 	/* Enable Debug Interrupts in MSR. */
459 	mtmsr(mfmsr() | PSL_DE);
460 
461 	/* Enable debug interrupts and issue reset. */
462 	mtspr(SPR_DBCR0, mfspr(SPR_DBCR0) | DBCR0_IDM | DBCR0_RST_SYSTEM);
463 
464 	printf("Reset failed...\n");
465 	while (1)
466 		;
467 }
468 
469 static void
470 mpc85xx_idle(platform_t plat, int cpu)
471 {
472 #ifdef QORIQ_DPAA
473 	uint32_t reg;
474 
475 	reg = ccsr_read4(OCP85XX_RCPM_CDOZCR);
476 	ccsr_write4(OCP85XX_RCPM_CDOZCR, reg | (1 << cpu));
477 	ccsr_read4(OCP85XX_RCPM_CDOZCR);
478 #else
479 	register_t msr;
480 
481 	msr = mfmsr();
482 	/* Freescale E500 core RM section 6.4.1. */
483 	__asm __volatile("msync; mtmsr %0; isync" ::
484 	    "r" (msr | PSL_WE));
485 #endif
486 }
487 
488 static int
489 mpc85xx_idle_wakeup(platform_t plat, int cpu)
490 {
491 #ifdef QORIQ_DPAA
492 	uint32_t reg;
493 
494 	reg = ccsr_read4(OCP85XX_RCPM_CDOZCR);
495 	ccsr_write4(OCP85XX_RCPM_CDOZCR, reg & ~(1 << cpu));
496 	ccsr_read4(OCP85XX_RCPM_CDOZCR);
497 
498 	return (1);
499 #endif
500 	return (0);
501 }
502