1*302acc2eSNathan Whitehorn /*- 2*302acc2eSNathan Whitehorn * Copyright (c) 2008-2012 Semihalf. 3*302acc2eSNathan Whitehorn * All rights reserved. 4*302acc2eSNathan Whitehorn * 5*302acc2eSNathan Whitehorn * Redistribution and use in source and binary forms, with or without 6*302acc2eSNathan Whitehorn * modification, are permitted provided that the following conditions 7*302acc2eSNathan Whitehorn * are met: 8*302acc2eSNathan Whitehorn * 9*302acc2eSNathan Whitehorn * 1. Redistributions of source code must retain the above copyright 10*302acc2eSNathan Whitehorn * notice, this list of conditions and the following disclaimer. 11*302acc2eSNathan Whitehorn * 2. Redistributions in binary form must reproduce the above copyright 12*302acc2eSNathan Whitehorn * notice, this list of conditions and the following disclaimer in the 13*302acc2eSNathan Whitehorn * documentation and/or other materials provided with the distribution. 14*302acc2eSNathan Whitehorn * 15*302acc2eSNathan Whitehorn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16*302acc2eSNathan Whitehorn * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17*302acc2eSNathan Whitehorn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18*302acc2eSNathan Whitehorn * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19*302acc2eSNathan Whitehorn * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20*302acc2eSNathan Whitehorn * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21*302acc2eSNathan Whitehorn * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22*302acc2eSNathan Whitehorn * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23*302acc2eSNathan Whitehorn * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24*302acc2eSNathan Whitehorn * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25*302acc2eSNathan Whitehorn */ 26*302acc2eSNathan Whitehorn 27*302acc2eSNathan Whitehorn #include <sys/cdefs.h> 28*302acc2eSNathan Whitehorn __FBSDID("$FreeBSD$"); 29*302acc2eSNathan Whitehorn 30*302acc2eSNathan Whitehorn #include <sys/param.h> 31*302acc2eSNathan Whitehorn #include <sys/systm.h> 32*302acc2eSNathan Whitehorn #include <sys/kernel.h> 33*302acc2eSNathan Whitehorn #include <sys/bus.h> 34*302acc2eSNathan Whitehorn #include <sys/pcpu.h> 35*302acc2eSNathan Whitehorn #include <sys/proc.h> 36*302acc2eSNathan Whitehorn #include <sys/smp.h> 37*302acc2eSNathan Whitehorn 38*302acc2eSNathan Whitehorn #include <machine/bus.h> 39*302acc2eSNathan Whitehorn #include <machine/cpu.h> 40*302acc2eSNathan Whitehorn #include <machine/hid.h> 41*302acc2eSNathan Whitehorn #include <machine/platform.h> 42*302acc2eSNathan Whitehorn #include <machine/platformvar.h> 43*302acc2eSNathan Whitehorn #include <machine/smp.h> 44*302acc2eSNathan Whitehorn #include <machine/spr.h> 45*302acc2eSNathan Whitehorn #include <machine/vmparam.h> 46*302acc2eSNathan Whitehorn 47*302acc2eSNathan Whitehorn #include <dev/fdt/fdt_common.h> 48*302acc2eSNathan Whitehorn #include <dev/ofw/ofw_bus.h> 49*302acc2eSNathan Whitehorn #include <dev/ofw/ofw_bus_subr.h> 50*302acc2eSNathan Whitehorn #include <dev/ofw/openfirm.h> 51*302acc2eSNathan Whitehorn 52*302acc2eSNathan Whitehorn #include <powerpc/mpc85xx/mpc85xx.h> 53*302acc2eSNathan Whitehorn 54*302acc2eSNathan Whitehorn #include "platform_if.h" 55*302acc2eSNathan Whitehorn 56*302acc2eSNathan Whitehorn #ifdef SMP 57*302acc2eSNathan Whitehorn extern void *ap_pcpu; 58*302acc2eSNathan Whitehorn extern vm_paddr_t kernload; /* Kernel physical load address */ 59*302acc2eSNathan Whitehorn extern uint8_t __boot_page[]; /* Boot page body */ 60*302acc2eSNathan Whitehorn extern uint32_t bp_ntlb1s; 61*302acc2eSNathan Whitehorn extern uint32_t bp_tlb1[]; 62*302acc2eSNathan Whitehorn extern uint32_t bp_tlb1_end[]; 63*302acc2eSNathan Whitehorn #endif 64*302acc2eSNathan Whitehorn 65*302acc2eSNathan Whitehorn extern uint32_t *bootinfo; 66*302acc2eSNathan Whitehorn 67*302acc2eSNathan Whitehorn static int cpu, maxcpu; 68*302acc2eSNathan Whitehorn 69*302acc2eSNathan Whitehorn static int mpc85xx_probe(platform_t); 70*302acc2eSNathan Whitehorn static int mpc85xx_attach(platform_t); 71*302acc2eSNathan Whitehorn static void mpc85xx_mem_regions(platform_t, struct mem_region **phys, 72*302acc2eSNathan Whitehorn int *physsz, struct mem_region **avail, int *availsz); 73*302acc2eSNathan Whitehorn static u_long mpc85xx_timebase_freq(platform_t, struct cpuref *cpuref); 74*302acc2eSNathan Whitehorn static int mpc85xx_smp_first_cpu(platform_t, struct cpuref *cpuref); 75*302acc2eSNathan Whitehorn static int mpc85xx_smp_next_cpu(platform_t, struct cpuref *cpuref); 76*302acc2eSNathan Whitehorn static int mpc85xx_smp_get_bsp(platform_t, struct cpuref *cpuref); 77*302acc2eSNathan Whitehorn static int mpc85xx_smp_start_cpu(platform_t, struct pcpu *cpu); 78*302acc2eSNathan Whitehorn 79*302acc2eSNathan Whitehorn static void mpc85xx_reset(platform_t); 80*302acc2eSNathan Whitehorn 81*302acc2eSNathan Whitehorn static platform_method_t mpc85xx_methods[] = { 82*302acc2eSNathan Whitehorn PLATFORMMETHOD(platform_probe, mpc85xx_probe), 83*302acc2eSNathan Whitehorn PLATFORMMETHOD(platform_attach, mpc85xx_attach), 84*302acc2eSNathan Whitehorn PLATFORMMETHOD(platform_mem_regions, mpc85xx_mem_regions), 85*302acc2eSNathan Whitehorn PLATFORMMETHOD(platform_timebase_freq, mpc85xx_timebase_freq), 86*302acc2eSNathan Whitehorn 87*302acc2eSNathan Whitehorn PLATFORMMETHOD(platform_smp_first_cpu, mpc85xx_smp_first_cpu), 88*302acc2eSNathan Whitehorn PLATFORMMETHOD(platform_smp_next_cpu, mpc85xx_smp_next_cpu), 89*302acc2eSNathan Whitehorn PLATFORMMETHOD(platform_smp_get_bsp, mpc85xx_smp_get_bsp), 90*302acc2eSNathan Whitehorn PLATFORMMETHOD(platform_smp_start_cpu, mpc85xx_smp_start_cpu), 91*302acc2eSNathan Whitehorn 92*302acc2eSNathan Whitehorn PLATFORMMETHOD(platform_reset, mpc85xx_reset), 93*302acc2eSNathan Whitehorn 94*302acc2eSNathan Whitehorn PLATFORMMETHOD_END 95*302acc2eSNathan Whitehorn }; 96*302acc2eSNathan Whitehorn 97*302acc2eSNathan Whitehorn static platform_def_t mpc85xx_platform = { 98*302acc2eSNathan Whitehorn "mpc85xx", 99*302acc2eSNathan Whitehorn mpc85xx_methods, 100*302acc2eSNathan Whitehorn 0 101*302acc2eSNathan Whitehorn }; 102*302acc2eSNathan Whitehorn 103*302acc2eSNathan Whitehorn PLATFORM_DEF(mpc85xx_platform); 104*302acc2eSNathan Whitehorn 105*302acc2eSNathan Whitehorn static int 106*302acc2eSNathan Whitehorn mpc85xx_probe(platform_t plat) 107*302acc2eSNathan Whitehorn { 108*302acc2eSNathan Whitehorn u_int pvr = mfpvr() >> 16; 109*302acc2eSNathan Whitehorn 110*302acc2eSNathan Whitehorn if ((pvr & 0xfff0) == FSL_E500v1) 111*302acc2eSNathan Whitehorn return (BUS_PROBE_DEFAULT); 112*302acc2eSNathan Whitehorn 113*302acc2eSNathan Whitehorn return (ENXIO); 114*302acc2eSNathan Whitehorn } 115*302acc2eSNathan Whitehorn 116*302acc2eSNathan Whitehorn static int 117*302acc2eSNathan Whitehorn mpc85xx_attach(platform_t plat) 118*302acc2eSNathan Whitehorn { 119*302acc2eSNathan Whitehorn phandle_t cpus, child; 120*302acc2eSNathan Whitehorn uint32_t sr; 121*302acc2eSNathan Whitehorn int i, law_max, tgt; 122*302acc2eSNathan Whitehorn 123*302acc2eSNathan Whitehorn if ((cpus = OF_finddevice("/cpus")) != -1) { 124*302acc2eSNathan Whitehorn for (maxcpu = 0, child = OF_child(cpus); child != 0; 125*302acc2eSNathan Whitehorn child = OF_peer(child), maxcpu++) 126*302acc2eSNathan Whitehorn ; 127*302acc2eSNathan Whitehorn } else 128*302acc2eSNathan Whitehorn maxcpu = 1; 129*302acc2eSNathan Whitehorn 130*302acc2eSNathan Whitehorn /* 131*302acc2eSNathan Whitehorn * Clear local access windows. Skip DRAM entries, so we don't shoot 132*302acc2eSNathan Whitehorn * ourselves in the foot. 133*302acc2eSNathan Whitehorn */ 134*302acc2eSNathan Whitehorn law_max = law_getmax(); 135*302acc2eSNathan Whitehorn for (i = 0; i < law_max; i++) { 136*302acc2eSNathan Whitehorn sr = ccsr_read4(OCP85XX_LAWSR(i)); 137*302acc2eSNathan Whitehorn if ((sr & 0x80000000) == 0) 138*302acc2eSNathan Whitehorn continue; 139*302acc2eSNathan Whitehorn tgt = (sr & 0x01f00000) >> 20; 140*302acc2eSNathan Whitehorn if (tgt == OCP85XX_TGTIF_RAM1 || tgt == OCP85XX_TGTIF_RAM2 || 141*302acc2eSNathan Whitehorn tgt == OCP85XX_TGTIF_RAM_INTL) 142*302acc2eSNathan Whitehorn continue; 143*302acc2eSNathan Whitehorn 144*302acc2eSNathan Whitehorn ccsr_write4(OCP85XX_LAWSR(i), sr & 0x7fffffff); 145*302acc2eSNathan Whitehorn } 146*302acc2eSNathan Whitehorn 147*302acc2eSNathan Whitehorn return (0); 148*302acc2eSNathan Whitehorn } 149*302acc2eSNathan Whitehorn 150*302acc2eSNathan Whitehorn void 151*302acc2eSNathan Whitehorn mpc85xx_mem_regions(platform_t plat, struct mem_region **phys, int *physsz, 152*302acc2eSNathan Whitehorn struct mem_region **avail, int *availsz) 153*302acc2eSNathan Whitehorn { 154*302acc2eSNathan Whitehorn 155*302acc2eSNathan Whitehorn ofw_mem_regions(phys, physsz, avail, availsz); 156*302acc2eSNathan Whitehorn } 157*302acc2eSNathan Whitehorn 158*302acc2eSNathan Whitehorn static u_long 159*302acc2eSNathan Whitehorn mpc85xx_timebase_freq(platform_t plat, struct cpuref *cpuref) 160*302acc2eSNathan Whitehorn { 161*302acc2eSNathan Whitehorn u_long ticks; 162*302acc2eSNathan Whitehorn phandle_t cpus, child; 163*302acc2eSNathan Whitehorn pcell_t freq; 164*302acc2eSNathan Whitehorn 165*302acc2eSNathan Whitehorn if (bootinfo != NULL) { 166*302acc2eSNathan Whitehorn if (bootinfo[0] == 1) { 167*302acc2eSNathan Whitehorn /* Backward compatibility. See 8-STABLE. */ 168*302acc2eSNathan Whitehorn ticks = bootinfo[3] >> 3; 169*302acc2eSNathan Whitehorn } else { 170*302acc2eSNathan Whitehorn /* Compatibility with Juniper's loader. */ 171*302acc2eSNathan Whitehorn ticks = bootinfo[5] >> 3; 172*302acc2eSNathan Whitehorn } 173*302acc2eSNathan Whitehorn } else 174*302acc2eSNathan Whitehorn ticks = 0; 175*302acc2eSNathan Whitehorn 176*302acc2eSNathan Whitehorn if ((cpus = OF_finddevice("/cpus")) == -1) 177*302acc2eSNathan Whitehorn goto out; 178*302acc2eSNathan Whitehorn 179*302acc2eSNathan Whitehorn if ((child = OF_child(cpus)) == 0) 180*302acc2eSNathan Whitehorn goto out; 181*302acc2eSNathan Whitehorn 182*302acc2eSNathan Whitehorn switch (OF_getproplen(child, "timebase-frequency")) { 183*302acc2eSNathan Whitehorn case 4: 184*302acc2eSNathan Whitehorn { 185*302acc2eSNathan Whitehorn uint32_t tbase; 186*302acc2eSNathan Whitehorn OF_getprop(child, "timebase-frequency", &tbase, sizeof(tbase)); 187*302acc2eSNathan Whitehorn ticks = tbase; 188*302acc2eSNathan Whitehorn return (ticks); 189*302acc2eSNathan Whitehorn } 190*302acc2eSNathan Whitehorn case 8: 191*302acc2eSNathan Whitehorn { 192*302acc2eSNathan Whitehorn uint64_t tbase; 193*302acc2eSNathan Whitehorn OF_getprop(child, "timebase-frequency", &tbase, sizeof(tbase)); 194*302acc2eSNathan Whitehorn ticks = tbase; 195*302acc2eSNathan Whitehorn return (ticks); 196*302acc2eSNathan Whitehorn } 197*302acc2eSNathan Whitehorn default: 198*302acc2eSNathan Whitehorn break; 199*302acc2eSNathan Whitehorn } 200*302acc2eSNathan Whitehorn 201*302acc2eSNathan Whitehorn freq = 0; 202*302acc2eSNathan Whitehorn if (OF_getprop(child, "bus-frequency", (void *)&freq, 203*302acc2eSNathan Whitehorn sizeof(freq)) <= 0) 204*302acc2eSNathan Whitehorn goto out; 205*302acc2eSNathan Whitehorn 206*302acc2eSNathan Whitehorn /* 207*302acc2eSNathan Whitehorn * Time Base and Decrementer are updated every 8 CCB bus clocks. 208*302acc2eSNathan Whitehorn * HID0[SEL_TBCLK] = 0 209*302acc2eSNathan Whitehorn */ 210*302acc2eSNathan Whitehorn if (freq != 0) 211*302acc2eSNathan Whitehorn ticks = freq / 8; 212*302acc2eSNathan Whitehorn 213*302acc2eSNathan Whitehorn out: 214*302acc2eSNathan Whitehorn if (ticks <= 0) 215*302acc2eSNathan Whitehorn panic("Unable to determine timebase frequency!"); 216*302acc2eSNathan Whitehorn 217*302acc2eSNathan Whitehorn return (ticks); 218*302acc2eSNathan Whitehorn } 219*302acc2eSNathan Whitehorn 220*302acc2eSNathan Whitehorn static int 221*302acc2eSNathan Whitehorn mpc85xx_smp_first_cpu(platform_t plat, struct cpuref *cpuref) 222*302acc2eSNathan Whitehorn { 223*302acc2eSNathan Whitehorn 224*302acc2eSNathan Whitehorn cpu = 0; 225*302acc2eSNathan Whitehorn cpuref->cr_cpuid = cpu; 226*302acc2eSNathan Whitehorn cpuref->cr_hwref = cpuref->cr_cpuid; 227*302acc2eSNathan Whitehorn if (bootverbose) 228*302acc2eSNathan Whitehorn printf("powerpc_smp_first_cpu: cpuid %d\n", cpuref->cr_cpuid); 229*302acc2eSNathan Whitehorn cpu++; 230*302acc2eSNathan Whitehorn 231*302acc2eSNathan Whitehorn return (0); 232*302acc2eSNathan Whitehorn } 233*302acc2eSNathan Whitehorn 234*302acc2eSNathan Whitehorn static int 235*302acc2eSNathan Whitehorn mpc85xx_smp_next_cpu(platform_t plat, struct cpuref *cpuref) 236*302acc2eSNathan Whitehorn { 237*302acc2eSNathan Whitehorn 238*302acc2eSNathan Whitehorn if (cpu >= maxcpu) 239*302acc2eSNathan Whitehorn return (ENOENT); 240*302acc2eSNathan Whitehorn 241*302acc2eSNathan Whitehorn cpuref->cr_cpuid = cpu++; 242*302acc2eSNathan Whitehorn cpuref->cr_hwref = cpuref->cr_cpuid; 243*302acc2eSNathan Whitehorn if (bootverbose) 244*302acc2eSNathan Whitehorn printf("powerpc_smp_next_cpu: cpuid %d\n", cpuref->cr_cpuid); 245*302acc2eSNathan Whitehorn 246*302acc2eSNathan Whitehorn return (0); 247*302acc2eSNathan Whitehorn } 248*302acc2eSNathan Whitehorn 249*302acc2eSNathan Whitehorn static int 250*302acc2eSNathan Whitehorn mpc85xx_smp_get_bsp(platform_t plat, struct cpuref *cpuref) 251*302acc2eSNathan Whitehorn { 252*302acc2eSNathan Whitehorn 253*302acc2eSNathan Whitehorn cpuref->cr_cpuid = mfspr(SPR_PIR); 254*302acc2eSNathan Whitehorn cpuref->cr_hwref = cpuref->cr_cpuid; 255*302acc2eSNathan Whitehorn 256*302acc2eSNathan Whitehorn return (0); 257*302acc2eSNathan Whitehorn } 258*302acc2eSNathan Whitehorn 259*302acc2eSNathan Whitehorn static int 260*302acc2eSNathan Whitehorn mpc85xx_smp_start_cpu(platform_t plat, struct pcpu *pc) 261*302acc2eSNathan Whitehorn { 262*302acc2eSNathan Whitehorn #ifdef SMP 263*302acc2eSNathan Whitehorn uint32_t *tlb1; 264*302acc2eSNathan Whitehorn uint32_t bptr, eebpcr; 265*302acc2eSNathan Whitehorn int i, timeout; 266*302acc2eSNathan Whitehorn 267*302acc2eSNathan Whitehorn eebpcr = ccsr_read4(OCP85XX_EEBPCR); 268*302acc2eSNathan Whitehorn if ((eebpcr & (1 << (pc->pc_cpuid + 24))) != 0) { 269*302acc2eSNathan Whitehorn printf("SMP: CPU %d already out of hold-off state!\n", 270*302acc2eSNathan Whitehorn pc->pc_cpuid); 271*302acc2eSNathan Whitehorn return (ENXIO); 272*302acc2eSNathan Whitehorn } 273*302acc2eSNathan Whitehorn 274*302acc2eSNathan Whitehorn ap_pcpu = pc; 275*302acc2eSNathan Whitehorn 276*302acc2eSNathan Whitehorn i = 0; 277*302acc2eSNathan Whitehorn tlb1 = bp_tlb1; 278*302acc2eSNathan Whitehorn while (i < bp_ntlb1s && tlb1 < bp_tlb1_end) { 279*302acc2eSNathan Whitehorn mtspr(SPR_MAS0, MAS0_TLBSEL(1) | MAS0_ESEL(i)); 280*302acc2eSNathan Whitehorn __asm __volatile("isync; tlbre"); 281*302acc2eSNathan Whitehorn tlb1[0] = mfspr(SPR_MAS1); 282*302acc2eSNathan Whitehorn tlb1[1] = mfspr(SPR_MAS2); 283*302acc2eSNathan Whitehorn tlb1[2] = mfspr(SPR_MAS3); 284*302acc2eSNathan Whitehorn i++; 285*302acc2eSNathan Whitehorn tlb1 += 3; 286*302acc2eSNathan Whitehorn } 287*302acc2eSNathan Whitehorn if (i < bp_ntlb1s) 288*302acc2eSNathan Whitehorn bp_ntlb1s = i; 289*302acc2eSNathan Whitehorn 290*302acc2eSNathan Whitehorn /* 291*302acc2eSNathan Whitehorn * Set BPTR to the physical address of the boot page 292*302acc2eSNathan Whitehorn */ 293*302acc2eSNathan Whitehorn bptr = ((uint32_t)__boot_page - KERNBASE) + kernload; 294*302acc2eSNathan Whitehorn KASSERT((bptr & 0xfff) == 0, 295*302acc2eSNathan Whitehorn ("%s: boot page is not aligned (%#x)", __func__, bptr)); 296*302acc2eSNathan Whitehorn bptr = (bptr >> 12) | 0x80000000u; 297*302acc2eSNathan Whitehorn ccsr_write4(OCP85XX_BPTR, bptr); 298*302acc2eSNathan Whitehorn __asm __volatile("isync; msync"); 299*302acc2eSNathan Whitehorn 300*302acc2eSNathan Whitehorn /* Flush caches to have our changes hit DRAM. */ 301*302acc2eSNathan Whitehorn cpu_flush_dcache(__boot_page, 4096); 302*302acc2eSNathan Whitehorn 303*302acc2eSNathan Whitehorn /* 304*302acc2eSNathan Whitehorn * Release AP from hold-off state 305*302acc2eSNathan Whitehorn */ 306*302acc2eSNathan Whitehorn eebpcr |= (1 << (pc->pc_cpuid + 24)); 307*302acc2eSNathan Whitehorn ccsr_write4(OCP85XX_EEBPCR, eebpcr); 308*302acc2eSNathan Whitehorn __asm __volatile("isync; msync"); 309*302acc2eSNathan Whitehorn 310*302acc2eSNathan Whitehorn timeout = 500; 311*302acc2eSNathan Whitehorn while (!pc->pc_awake && timeout--) 312*302acc2eSNathan Whitehorn DELAY(1000); /* wait 1ms */ 313*302acc2eSNathan Whitehorn 314*302acc2eSNathan Whitehorn /* 315*302acc2eSNathan Whitehorn * Disable boot page translation so that the 4K page at the default 316*302acc2eSNathan Whitehorn * address (= 0xfffff000) isn't permanently remapped and thus not 317*302acc2eSNathan Whitehorn * usable otherwise. 318*302acc2eSNathan Whitehorn */ 319*302acc2eSNathan Whitehorn ccsr_write4(OCP85XX_BPTR, 0); 320*302acc2eSNathan Whitehorn __asm __volatile("isync; msync"); 321*302acc2eSNathan Whitehorn 322*302acc2eSNathan Whitehorn if (!pc->pc_awake) 323*302acc2eSNathan Whitehorn printf("SMP: CPU %d didn't wake up.\n", pc->pc_cpuid); 324*302acc2eSNathan Whitehorn return ((pc->pc_awake) ? 0 : EBUSY); 325*302acc2eSNathan Whitehorn #else 326*302acc2eSNathan Whitehorn /* No SMP support */ 327*302acc2eSNathan Whitehorn return (ENXIO); 328*302acc2eSNathan Whitehorn #endif 329*302acc2eSNathan Whitehorn } 330*302acc2eSNathan Whitehorn 331*302acc2eSNathan Whitehorn static void 332*302acc2eSNathan Whitehorn mpc85xx_reset(platform_t plat) 333*302acc2eSNathan Whitehorn { 334*302acc2eSNathan Whitehorn 335*302acc2eSNathan Whitehorn /* 336*302acc2eSNathan Whitehorn * Try the dedicated reset register first. 337*302acc2eSNathan Whitehorn * If the SoC doesn't have one, we'll fall 338*302acc2eSNathan Whitehorn * back to using the debug control register. 339*302acc2eSNathan Whitehorn */ 340*302acc2eSNathan Whitehorn ccsr_write4(OCP85XX_RSTCR, 2); 341*302acc2eSNathan Whitehorn 342*302acc2eSNathan Whitehorn /* Clear DBCR0, disables debug interrupts and events. */ 343*302acc2eSNathan Whitehorn mtspr(SPR_DBCR0, 0); 344*302acc2eSNathan Whitehorn __asm __volatile("isync"); 345*302acc2eSNathan Whitehorn 346*302acc2eSNathan Whitehorn /* Enable Debug Interrupts in MSR. */ 347*302acc2eSNathan Whitehorn mtmsr(mfmsr() | PSL_DE); 348*302acc2eSNathan Whitehorn 349*302acc2eSNathan Whitehorn /* Enable debug interrupts and issue reset. */ 350*302acc2eSNathan Whitehorn mtspr(SPR_DBCR0, mfspr(SPR_DBCR0) | DBCR0_IDM | DBCR0_RST_SYSTEM); 351*302acc2eSNathan Whitehorn 352*302acc2eSNathan Whitehorn printf("Reset failed...\n"); 353*302acc2eSNathan Whitehorn while (1) 354*302acc2eSNathan Whitehorn ; 355*302acc2eSNathan Whitehorn } 356*302acc2eSNathan Whitehorn 357