1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2008-2012 Semihalf. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "opt_platform.h" 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/kernel.h> 36 #include <sys/module.h> 37 #include <sys/bus.h> 38 #include <sys/pcpu.h> 39 #include <sys/proc.h> 40 #include <sys/smp.h> 41 42 #include <machine/bus.h> 43 #include <machine/cpu.h> 44 #include <machine/hid.h> 45 #include <machine/_inttypes.h> 46 #include <machine/machdep.h> 47 #include <machine/md_var.h> 48 #include <machine/platform.h> 49 #include <machine/platformvar.h> 50 #include <machine/smp.h> 51 #include <machine/spr.h> 52 #include <machine/vmparam.h> 53 54 #include <dev/fdt/fdt_common.h> 55 #include <dev/ofw/ofw_bus.h> 56 #include <dev/ofw/ofw_bus_subr.h> 57 #include <dev/ofw/openfirm.h> 58 59 #include <vm/vm.h> 60 #include <vm/pmap.h> 61 #include <vm/vm_extern.h> 62 63 #include <powerpc/mpc85xx/mpc85xx.h> 64 65 #include "platform_if.h" 66 67 #ifdef SMP 68 extern void *ap_pcpu; 69 extern vm_paddr_t kernload; /* Kernel physical load address */ 70 extern uint8_t __boot_page[]; /* Boot page body */ 71 extern uint32_t bp_kernload; 72 extern vm_offset_t __startkernel; 73 74 struct cpu_release { 75 uint32_t entry_h; 76 uint32_t entry_l; 77 uint32_t r3_h; 78 uint32_t r3_l; 79 uint32_t reserved; 80 uint32_t pir; 81 }; 82 #endif 83 84 extern uint32_t *bootinfo; 85 vm_paddr_t ccsrbar_pa; 86 vm_offset_t ccsrbar_va; 87 vm_size_t ccsrbar_size; 88 89 static int cpu, maxcpu; 90 91 static device_t rcpm_dev; 92 static void dummy_freeze(device_t, bool); 93 94 static void (*freeze_timebase)(device_t, bool) = dummy_freeze; 95 96 static int mpc85xx_probe(platform_t); 97 static void mpc85xx_mem_regions(platform_t, struct mem_region *phys, 98 int *physsz, struct mem_region *avail, int *availsz); 99 static u_long mpc85xx_timebase_freq(platform_t, struct cpuref *cpuref); 100 static int mpc85xx_smp_first_cpu(platform_t, struct cpuref *cpuref); 101 static int mpc85xx_smp_next_cpu(platform_t, struct cpuref *cpuref); 102 static int mpc85xx_smp_get_bsp(platform_t, struct cpuref *cpuref); 103 static int mpc85xx_smp_start_cpu(platform_t, struct pcpu *cpu); 104 static void mpc85xx_smp_timebase_sync(platform_t, u_long tb, int ap); 105 106 static void mpc85xx_reset(platform_t); 107 108 static platform_method_t mpc85xx_methods[] = { 109 PLATFORMMETHOD(platform_probe, mpc85xx_probe), 110 PLATFORMMETHOD(platform_attach, mpc85xx_attach), 111 PLATFORMMETHOD(platform_mem_regions, mpc85xx_mem_regions), 112 PLATFORMMETHOD(platform_timebase_freq, mpc85xx_timebase_freq), 113 114 PLATFORMMETHOD(platform_smp_first_cpu, mpc85xx_smp_first_cpu), 115 PLATFORMMETHOD(platform_smp_next_cpu, mpc85xx_smp_next_cpu), 116 PLATFORMMETHOD(platform_smp_get_bsp, mpc85xx_smp_get_bsp), 117 PLATFORMMETHOD(platform_smp_start_cpu, mpc85xx_smp_start_cpu), 118 PLATFORMMETHOD(platform_smp_timebase_sync, mpc85xx_smp_timebase_sync), 119 120 PLATFORMMETHOD(platform_reset, mpc85xx_reset), 121 122 PLATFORMMETHOD_END 123 }; 124 125 DEFINE_CLASS_0(mpc85xx, mpc85xx_platform, mpc85xx_methods, 0); 126 127 PLATFORM_DEF(mpc85xx_platform); 128 129 static int 130 mpc85xx_probe(platform_t plat) 131 { 132 u_int pvr = (mfpvr() >> 16) & 0xFFFF; 133 134 switch (pvr) { 135 case FSL_E500v1: 136 case FSL_E500v2: 137 case FSL_E500mc: 138 case FSL_E5500: 139 case FSL_E6500: 140 return (BUS_PROBE_DEFAULT); 141 } 142 return (ENXIO); 143 } 144 145 int 146 mpc85xx_attach(platform_t plat) 147 { 148 phandle_t cpus, child, ccsr; 149 const char *soc_name_guesses[] = {"/soc", "soc", NULL}; 150 const char **name; 151 pcell_t ranges[6], acells, pacells, scells; 152 uint64_t ccsrbar, ccsrsize; 153 int i; 154 155 if ((cpus = OF_finddevice("/cpus")) != -1) { 156 for (maxcpu = 0, child = OF_child(cpus); child != 0; 157 child = OF_peer(child), maxcpu++) 158 ; 159 } else 160 maxcpu = 1; 161 162 /* 163 * Locate CCSR region. Irritatingly, there is no way to find it 164 * unless you already know where it is. Try to infer its location 165 * from the device tree. 166 */ 167 168 ccsr = -1; 169 for (name = soc_name_guesses; *name != NULL && ccsr == -1; name++) 170 ccsr = OF_finddevice(*name); 171 if (ccsr == -1) { 172 char type[64]; 173 174 /* That didn't work. Search for devices of type "soc" */ 175 child = OF_child(OF_peer(0)); 176 for (OF_child(child); child != 0; child = OF_peer(child)) { 177 if (OF_getprop(child, "device_type", type, sizeof(type)) 178 <= 0) 179 continue; 180 181 if (strcmp(type, "soc") == 0) { 182 ccsr = child; 183 break; 184 } 185 } 186 } 187 188 if (ccsr == -1) 189 panic("Could not locate CCSR window!"); 190 191 OF_getprop(ccsr, "#size-cells", &scells, sizeof(scells)); 192 OF_getprop(ccsr, "#address-cells", &acells, sizeof(acells)); 193 OF_searchprop(OF_parent(ccsr), "#address-cells", &pacells, 194 sizeof(pacells)); 195 OF_getprop(ccsr, "ranges", ranges, sizeof(ranges)); 196 ccsrbar = ccsrsize = 0; 197 for (i = acells; i < acells + pacells; i++) { 198 ccsrbar <<= 32; 199 ccsrbar |= ranges[i]; 200 } 201 for (i = acells + pacells; i < acells + pacells + scells; i++) { 202 ccsrsize <<= 32; 203 ccsrsize |= ranges[i]; 204 } 205 ccsrbar_va = pmap_early_io_map(ccsrbar, ccsrsize); 206 ccsrbar_pa = ccsrbar; 207 ccsrbar_size = ccsrsize; 208 209 mpc85xx_enable_l3_cache(); 210 211 return (0); 212 } 213 214 void 215 mpc85xx_mem_regions(platform_t plat, struct mem_region *phys, int *physsz, 216 struct mem_region *avail, int *availsz) 217 { 218 219 ofw_mem_regions(phys, physsz, avail, availsz); 220 } 221 222 static u_long 223 mpc85xx_timebase_freq(platform_t plat, struct cpuref *cpuref) 224 { 225 u_long ticks; 226 phandle_t cpus, child; 227 pcell_t freq; 228 229 if (bootinfo != NULL) { 230 if (bootinfo[0] == 1) { 231 /* Backward compatibility. See 8-STABLE. */ 232 ticks = bootinfo[3] >> 3; 233 } else { 234 /* Compatibility with Juniper's loader. */ 235 ticks = bootinfo[5] >> 3; 236 } 237 } else 238 ticks = 0; 239 240 if ((cpus = OF_finddevice("/cpus")) == -1) 241 goto out; 242 243 if ((child = OF_child(cpus)) == 0) 244 goto out; 245 246 switch (OF_getproplen(child, "timebase-frequency")) { 247 case 4: 248 { 249 uint32_t tbase; 250 OF_getprop(child, "timebase-frequency", &tbase, sizeof(tbase)); 251 ticks = tbase; 252 return (ticks); 253 } 254 case 8: 255 { 256 uint64_t tbase; 257 OF_getprop(child, "timebase-frequency", &tbase, sizeof(tbase)); 258 ticks = tbase; 259 return (ticks); 260 } 261 default: 262 break; 263 } 264 265 freq = 0; 266 if (OF_getprop(child, "bus-frequency", (void *)&freq, 267 sizeof(freq)) <= 0) 268 goto out; 269 270 if (freq == 0) 271 goto out; 272 273 /* 274 * Time Base and Decrementer are updated every 8 CCB bus clocks. 275 * HID0[SEL_TBCLK] = 0 276 */ 277 if (mpc85xx_is_qoriq()) 278 ticks = freq / 32; 279 else 280 ticks = freq / 8; 281 282 out: 283 if (ticks <= 0) 284 panic("Unable to determine timebase frequency!"); 285 286 return (ticks); 287 } 288 289 static int 290 mpc85xx_smp_first_cpu(platform_t plat, struct cpuref *cpuref) 291 { 292 293 cpu = 0; 294 cpuref->cr_cpuid = cpu; 295 cpuref->cr_hwref = cpuref->cr_cpuid; 296 if (bootverbose) 297 printf("powerpc_smp_first_cpu: cpuid %d\n", cpuref->cr_cpuid); 298 cpu++; 299 300 return (0); 301 } 302 303 static int 304 mpc85xx_smp_next_cpu(platform_t plat, struct cpuref *cpuref) 305 { 306 307 if (cpu >= maxcpu) 308 return (ENOENT); 309 310 cpuref->cr_cpuid = cpu++; 311 cpuref->cr_hwref = cpuref->cr_cpuid; 312 if (bootverbose) 313 printf("powerpc_smp_next_cpu: cpuid %d\n", cpuref->cr_cpuid); 314 315 return (0); 316 } 317 318 static int 319 mpc85xx_smp_get_bsp(platform_t plat, struct cpuref *cpuref) 320 { 321 322 cpuref->cr_cpuid = mfspr(SPR_PIR); 323 cpuref->cr_hwref = cpuref->cr_cpuid; 324 325 return (0); 326 } 327 328 #ifdef SMP 329 static int 330 mpc85xx_smp_start_cpu_epapr(platform_t plat, struct pcpu *pc) 331 { 332 vm_paddr_t rel_pa, bptr; 333 volatile struct cpu_release *rel; 334 vm_offset_t rel_va, rel_page; 335 phandle_t node; 336 int i; 337 338 /* If we're calling this, the node already exists. */ 339 node = OF_finddevice("/cpus"); 340 for (i = 0, node = OF_child(node); i < pc->pc_cpuid; 341 i++, node = OF_peer(node)) 342 ; 343 if (OF_getencprop(node, "cpu-release-addr", (pcell_t *)&rel_pa, 344 sizeof(rel_pa)) == -1) { 345 return (ENOENT); 346 } 347 348 rel_page = kva_alloc(PAGE_SIZE); 349 if (rel_page == 0) 350 return (ENOMEM); 351 352 critical_enter(); 353 rel_va = rel_page + (rel_pa & PAGE_MASK); 354 pmap_kenter(rel_page, rel_pa & ~PAGE_MASK); 355 rel = (struct cpu_release *)rel_va; 356 bptr = pmap_kextract((uintptr_t)__boot_page); 357 cpu_flush_dcache(__DEVOLATILE(struct cpu_release *,rel), sizeof(*rel)); 358 rel->pir = pc->pc_cpuid; __asm __volatile("sync"); 359 rel->entry_h = (bptr >> 32); 360 rel->entry_l = bptr; __asm __volatile("sync"); 361 cpu_flush_dcache(__DEVOLATILE(struct cpu_release *,rel), sizeof(*rel)); 362 if (bootverbose) 363 printf("Waking up CPU %d via CPU release page %p\n", 364 pc->pc_cpuid, rel); 365 critical_exit(); 366 pmap_kremove(rel_page); 367 kva_free(rel_page, PAGE_SIZE); 368 369 return (0); 370 } 371 #endif 372 373 static int 374 mpc85xx_smp_start_cpu(platform_t plat, struct pcpu *pc) 375 { 376 #ifdef SMP 377 vm_paddr_t bptr; 378 uint32_t reg; 379 int timeout; 380 uintptr_t brr; 381 int cpuid; 382 int epapr_boot = 0; 383 uint32_t tgt; 384 385 if (mpc85xx_is_qoriq()) { 386 reg = ccsr_read4(OCP85XX_COREDISR); 387 cpuid = pc->pc_cpuid; 388 389 if ((reg & (1 << cpuid)) != 0) { 390 printf("%s: CPU %d is disabled!\n", __func__, pc->pc_cpuid); 391 return (-1); 392 } 393 394 brr = OCP85XX_BRR; 395 } else { 396 brr = OCP85XX_EEBPCR; 397 cpuid = pc->pc_cpuid + 24; 398 } 399 bp_kernload = kernload; 400 /* 401 * bp_kernload is in the boot page. Sync the cache because ePAPR 402 * booting has the other core(s) already running. 403 */ 404 cpu_flush_dcache(&bp_kernload, sizeof(bp_kernload)); 405 406 ap_pcpu = pc; 407 __asm __volatile("msync; isync"); 408 409 /* First try the ePAPR way. */ 410 if (mpc85xx_smp_start_cpu_epapr(plat, pc) == 0) { 411 epapr_boot = 1; 412 goto spin_wait; 413 } 414 415 reg = ccsr_read4(brr); 416 if ((reg & (1 << cpuid)) != 0) { 417 printf("SMP: CPU %d already out of hold-off state!\n", 418 pc->pc_cpuid); 419 return (ENXIO); 420 } 421 422 /* Flush caches to have our changes hit DRAM. */ 423 cpu_flush_dcache(__boot_page, 4096); 424 425 bptr = pmap_kextract((uintptr_t)__boot_page); 426 KASSERT((bptr & 0xfff) == 0, 427 ("%s: boot page is not aligned (%#jx)", __func__, (uintmax_t)bptr)); 428 if (mpc85xx_is_qoriq()) { 429 /* 430 * Read DDR controller configuration to select proper BPTR target ID. 431 * 432 * On P5020 bit 29 of DDR1_CS0_CONFIG enables DDR controllers 433 * interleaving. If this bit is set, we have to use 434 * OCP85XX_TGTIF_RAM_INTL as BPTR target ID. On other QorIQ DPAA SoCs, 435 * this bit is reserved and always 0. 436 */ 437 438 reg = ccsr_read4(OCP85XX_DDR1_CS0_CONFIG); 439 if (reg & (1 << 29)) 440 tgt = OCP85XX_TGTIF_RAM_INTL; 441 else 442 tgt = OCP85XX_TGTIF_RAM1; 443 444 /* 445 * Set BSTR to the physical address of the boot page 446 */ 447 ccsr_write4(OCP85XX_BSTRH, bptr >> 32); 448 ccsr_write4(OCP85XX_BSTRL, bptr); 449 ccsr_write4(OCP85XX_BSTAR, OCP85XX_ENA_MASK | 450 (tgt << OCP85XX_TRGT_SHIFT_QORIQ) | (ffsl(PAGE_SIZE) - 2)); 451 452 /* Read back OCP85XX_BSTAR to synchronize write */ 453 ccsr_read4(OCP85XX_BSTAR); 454 455 /* 456 * Enable and configure time base on new CPU. 457 */ 458 459 /* Set TB clock source to platform clock / 32 */ 460 reg = ccsr_read4(CCSR_CTBCKSELR); 461 ccsr_write4(CCSR_CTBCKSELR, reg & ~(1 << pc->pc_cpuid)); 462 463 /* Enable TB */ 464 reg = ccsr_read4(CCSR_CTBENR); 465 ccsr_write4(CCSR_CTBENR, reg | (1 << pc->pc_cpuid)); 466 } else { 467 /* 468 * Set BPTR to the physical address of the boot page 469 */ 470 bptr = (bptr >> 12) | 0x80000000u; 471 ccsr_write4(OCP85XX_BPTR, bptr); 472 __asm __volatile("isync; msync"); 473 } 474 475 /* 476 * Release AP from hold-off state 477 */ 478 reg = ccsr_read4(brr); 479 ccsr_write4(brr, reg | (1 << cpuid)); 480 __asm __volatile("isync; msync"); 481 482 spin_wait: 483 timeout = 500; 484 while (!pc->pc_awake && timeout--) 485 DELAY(1000); /* wait 1ms */ 486 487 /* 488 * Disable boot page translation so that the 4K page at the default 489 * address (= 0xfffff000) isn't permanently remapped and thus not 490 * usable otherwise. 491 */ 492 if (!epapr_boot) { 493 if (mpc85xx_is_qoriq()) 494 ccsr_write4(OCP85XX_BSTAR, 0); 495 else 496 ccsr_write4(OCP85XX_BPTR, 0); 497 __asm __volatile("isync; msync"); 498 } 499 500 if (!pc->pc_awake) 501 panic("SMP: CPU %d didn't wake up.\n", pc->pc_cpuid); 502 return ((pc->pc_awake) ? 0 : EBUSY); 503 #else 504 /* No SMP support */ 505 return (ENXIO); 506 #endif 507 } 508 509 static void 510 mpc85xx_reset(platform_t plat) 511 { 512 513 /* 514 * Try the dedicated reset register first. 515 * If the SoC doesn't have one, we'll fall 516 * back to using the debug control register. 517 */ 518 ccsr_write4(OCP85XX_RSTCR, 2); 519 520 mtmsr(mfmsr() & ~PSL_DE); 521 522 /* Enable debug interrupts and issue reset. */ 523 mtspr(SPR_DBCR0, DBCR0_IDM | DBCR0_RST_SYSTEM); 524 __asm __volatile("isync"); 525 526 /* Enable Debug Interrupts in MSR. */ 527 mtmsr(mfmsr() | PSL_DE); 528 529 printf("Reset failed...\n"); 530 while (1) 531 ; 532 } 533 534 static void 535 mpc85xx_smp_timebase_sync(platform_t plat, u_long tb, int ap) 536 { 537 static volatile bool tb_ready; 538 static volatile int cpu_done; 539 540 if (ap) { 541 /* APs. Hold off until we get a stable timebase. */ 542 while (!tb_ready) 543 atomic_thread_fence_seq_cst(); 544 mttb(tb); 545 atomic_add_int(&cpu_done, 1); 546 while (cpu_done < mp_ncpus) 547 atomic_thread_fence_seq_cst(); 548 } else { 549 /* BSP */ 550 freeze_timebase(rcpm_dev, true); 551 tb_ready = true; 552 mttb(tb); 553 atomic_add_int(&cpu_done, 1); 554 while (cpu_done < mp_ncpus) 555 atomic_thread_fence_seq_cst(); 556 freeze_timebase(rcpm_dev, false); 557 } 558 } 559 560 /* Fallback freeze. In case no real handler is found in the device tree. */ 561 static void 562 dummy_freeze(device_t dev, bool freeze) 563 { 564 /* Nothing to do here, move along. */ 565 } 566 567 568 /* QorIQ Run control/power management timebase management. */ 569 570 #define RCPM_CTBENR 0x00000084 571 struct mpc85xx_rcpm_softc { 572 struct resource *sc_mem; 573 }; 574 575 static void 576 mpc85xx_rcpm_freeze_timebase(device_t dev, bool freeze) 577 { 578 struct mpc85xx_rcpm_softc *sc; 579 580 sc = device_get_softc(dev); 581 582 if (freeze) 583 bus_write_4(sc->sc_mem, RCPM_CTBENR, 0); 584 else 585 bus_write_4(sc->sc_mem, RCPM_CTBENR, (1 << maxcpu) - 1); 586 } 587 588 static int 589 mpc85xx_rcpm_probe(device_t dev) 590 { 591 if (!ofw_bus_is_compatible(dev, "fsl,qoriq-rcpm-1.0")) 592 return (ENXIO); 593 594 device_set_desc(dev, "QorIQ Run control and power management"); 595 return (BUS_PROBE_GENERIC); 596 } 597 598 static int 599 mpc85xx_rcpm_attach(device_t dev) 600 { 601 struct mpc85xx_rcpm_softc *sc; 602 int rid; 603 604 sc = device_get_softc(dev); 605 freeze_timebase = mpc85xx_rcpm_freeze_timebase; 606 rcpm_dev = dev; 607 608 rid = 0; 609 sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 610 RF_ACTIVE | RF_SHAREABLE); 611 612 return (0); 613 } 614 615 static device_method_t mpc85xx_rcpm_methods[] = { 616 DEVMETHOD(device_probe, mpc85xx_rcpm_probe), 617 DEVMETHOD(device_attach, mpc85xx_rcpm_attach), 618 DEVMETHOD_END 619 }; 620 621 static devclass_t mpc85xx_rcpm_devclass; 622 623 static driver_t mpc85xx_rcpm_driver = { 624 "rcpm", 625 mpc85xx_rcpm_methods, 626 sizeof(struct mpc85xx_rcpm_softc) 627 }; 628 629 EARLY_DRIVER_MODULE(mpc85xx_rcpm, simplebus, mpc85xx_rcpm_driver, 630 mpc85xx_rcpm_devclass, 0, 0, BUS_PASS_BUS); 631 632 633 /* "Global utilities" power management/Timebase management. */ 634 635 #define GUTS_DEVDISR 0x00000070 636 #define DEVDISR_TB0 0x00004000 637 #define DEVDISR_TB1 0x00001000 638 639 struct mpc85xx_guts_softc { 640 struct resource *sc_mem; 641 }; 642 643 static void 644 mpc85xx_guts_freeze_timebase(device_t dev, bool freeze) 645 { 646 struct mpc85xx_guts_softc *sc; 647 uint32_t devdisr; 648 649 sc = device_get_softc(dev); 650 651 devdisr = bus_read_4(sc->sc_mem, GUTS_DEVDISR); 652 if (freeze) 653 bus_write_4(sc->sc_mem, GUTS_DEVDISR, 654 devdisr | (DEVDISR_TB0 | DEVDISR_TB1)); 655 else 656 bus_write_4(sc->sc_mem, GUTS_DEVDISR, 657 devdisr & ~(DEVDISR_TB0 | DEVDISR_TB1)); 658 } 659 660 static int 661 mpc85xx_guts_probe(device_t dev) 662 { 663 if (!ofw_bus_is_compatible(dev, "fsl,mpc8572-guts") && 664 !ofw_bus_is_compatible(dev, "fsl,p1020-guts") && 665 !ofw_bus_is_compatible(dev, "fsl,p1021-guts") && 666 !ofw_bus_is_compatible(dev, "fsl,p1022-guts") && 667 !ofw_bus_is_compatible(dev, "fsl,p1023-guts") && 668 !ofw_bus_is_compatible(dev, "fsl,p2020-guts")) 669 return (ENXIO); 670 671 device_set_desc(dev, "MPC85xx Global Utilities"); 672 return (BUS_PROBE_GENERIC); 673 } 674 675 static int 676 mpc85xx_guts_attach(device_t dev) 677 { 678 struct mpc85xx_rcpm_softc *sc; 679 int rid; 680 681 sc = device_get_softc(dev); 682 freeze_timebase = mpc85xx_guts_freeze_timebase; 683 rcpm_dev = dev; 684 685 rid = 0; 686 sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 687 RF_ACTIVE | RF_SHAREABLE); 688 689 return (0); 690 } 691 692 static device_method_t mpc85xx_guts_methods[] = { 693 DEVMETHOD(device_probe, mpc85xx_guts_probe), 694 DEVMETHOD(device_attach, mpc85xx_guts_attach), 695 DEVMETHOD_END 696 }; 697 698 static driver_t mpc85xx_guts_driver = { 699 "guts", 700 mpc85xx_guts_methods, 701 sizeof(struct mpc85xx_guts_softc) 702 }; 703 704 static devclass_t mpc85xx_guts_devclass; 705 706 EARLY_DRIVER_MODULE(mpc85xx_guts, simplebus, mpc85xx_guts_driver, 707 mpc85xx_guts_devclass, 0, 0, BUS_PASS_BUS); 708