1 /*- 2 * Copyright (c) 2015-2016 Landon Fuller <landonf@FreeBSD.org> 3 * Copyright (c) 2017 The FreeBSD Foundation 4 * All rights reserved. 5 * 6 * Portions of this software were developed by Landon Fuller 7 * under sponsorship from the FreeBSD Foundation. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer, 14 * without modification. 15 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 16 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 17 * redistribution must be conditioned upon including a substantially 18 * similar Disclaimer requirement for further binary redistribution. 19 * 20 * NO WARRANTY 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 24 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 25 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 26 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 29 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 31 * THE POSSIBILITY OF SUCH DAMAGES. 32 */ 33 34 #include <sys/cdefs.h> 35 __FBSDID("$FreeBSD$"); 36 37 /* 38 * Broadcom Home Networking Division (HND) Bus Driver. 39 * 40 * The Broadcom HND family of devices consists of both SoCs and host-connected 41 * networking chipsets containing a common family of Broadcom IP cores, 42 * including an integrated MIPS and/or ARM cores. 43 * 44 * HND devices expose a nearly identical interface whether accessible over a 45 * native SoC interconnect, or when connected via a host interface such as 46 * PCIe. As a result, the majority of hardware support code should be re-usable 47 * across host drivers for HND networking chipsets, as well as FreeBSD support 48 * for Broadcom MIPS/ARM HND SoCs. 49 * 50 * Earlier HND models used the siba(4) on-chip interconnect, while later models 51 * use bcma(4); the programming model is almost entirely independent 52 * of the actual underlying interconect. 53 */ 54 55 #include <sys/param.h> 56 #include <sys/kernel.h> 57 #include <sys/bus.h> 58 #include <sys/module.h> 59 #include <sys/systm.h> 60 61 #include <machine/bus.h> 62 #include <sys/rman.h> 63 #include <machine/resource.h> 64 65 #include <dev/bhnd/cores/pmu/bhnd_pmu.h> 66 67 #include "bhnd_chipc_if.h" 68 #include "bhnd_nvram_if.h" 69 70 #include "bhnd.h" 71 #include "bhndreg.h" 72 #include "bhndvar.h" 73 74 #include "bhnd_private.h" 75 76 MALLOC_DEFINE(M_BHND, "bhnd", "bhnd bus data structures"); 77 78 /** 79 * bhnd_generic_probe_nomatch() reporting configuration. 80 */ 81 static const struct bhnd_nomatch { 82 uint16_t vendor; /**< core designer */ 83 uint16_t device; /**< core id */ 84 bool if_verbose; /**< print when bootverbose is set. */ 85 } bhnd_nomatch_table[] = { 86 { BHND_MFGID_ARM, BHND_COREID_OOB_ROUTER, true }, 87 { BHND_MFGID_ARM, BHND_COREID_EROM, true }, 88 { BHND_MFGID_ARM, BHND_COREID_PL301, true }, 89 { BHND_MFGID_ARM, BHND_COREID_APB_BRIDGE, true }, 90 { BHND_MFGID_ARM, BHND_COREID_AXI_UNMAPPED, false }, 91 92 { BHND_MFGID_INVALID, BHND_COREID_INVALID, false } 93 }; 94 95 static int bhnd_delete_children(struct bhnd_softc *sc); 96 97 /** 98 * Default bhnd(4) bus driver implementation of DEVICE_ATTACH(). 99 * 100 * This implementation calls device_probe_and_attach() for each of the device's 101 * children, in bhnd probe order. 102 */ 103 int 104 bhnd_generic_attach(device_t dev) 105 { 106 struct bhnd_softc *sc; 107 int error; 108 109 if (device_is_attached(dev)) 110 return (EBUSY); 111 112 sc = device_get_softc(dev); 113 sc->dev = dev; 114 115 /* Probe and attach all children */ 116 if ((error = bhnd_bus_probe_children(dev))) { 117 bhnd_delete_children(sc); 118 return (error); 119 } 120 121 return (0); 122 } 123 124 /** 125 * Detach and delete all children, in reverse of their attach order. 126 */ 127 static int 128 bhnd_delete_children(struct bhnd_softc *sc) 129 { 130 device_t *devs; 131 int ndevs; 132 int error; 133 134 /* Fetch children in detach order */ 135 error = bhnd_bus_get_children(sc->dev, &devs, &ndevs, 136 BHND_DEVICE_ORDER_DETACH); 137 if (error) 138 return (error); 139 140 /* Perform detach */ 141 for (int i = 0; i < ndevs; i++) { 142 device_t child = devs[i]; 143 144 /* Terminate on first error */ 145 if ((error = device_delete_child(sc->dev, child))) 146 goto cleanup; 147 } 148 149 cleanup: 150 bhnd_bus_free_children(devs); 151 return (error); 152 } 153 154 /** 155 * Default bhnd(4) bus driver implementation of DEVICE_DETACH(). 156 * 157 * This implementation calls device_detach() for each of the device's 158 * children, in reverse bhnd probe order, terminating if any call to 159 * device_detach() fails. 160 */ 161 int 162 bhnd_generic_detach(device_t dev) 163 { 164 struct bhnd_softc *sc; 165 int error; 166 167 if (!device_is_attached(dev)) 168 return (EBUSY); 169 170 sc = device_get_softc(dev); 171 172 if ((error = bhnd_delete_children(sc))) 173 return (error); 174 175 return (0); 176 } 177 178 /** 179 * Default bhnd(4) bus driver implementation of DEVICE_SHUTDOWN(). 180 * 181 * This implementation calls device_shutdown() for each of the device's 182 * children, in reverse bhnd probe order, terminating if any call to 183 * device_shutdown() fails. 184 */ 185 int 186 bhnd_generic_shutdown(device_t dev) 187 { 188 device_t *devs; 189 int ndevs; 190 int error; 191 192 if (!device_is_attached(dev)) 193 return (EBUSY); 194 195 /* Fetch children in detach order */ 196 error = bhnd_bus_get_children(dev, &devs, &ndevs, 197 BHND_DEVICE_ORDER_DETACH); 198 if (error) 199 return (error); 200 201 /* Perform shutdown */ 202 for (int i = 0; i < ndevs; i++) { 203 device_t child = devs[i]; 204 205 /* Terminate on first error */ 206 if ((error = device_shutdown(child))) 207 goto cleanup; 208 } 209 210 cleanup: 211 bhnd_bus_free_children(devs); 212 return (error); 213 } 214 215 /** 216 * Default bhnd(4) bus driver implementation of DEVICE_RESUME(). 217 * 218 * This implementation calls BUS_RESUME_CHILD() for each of the device's 219 * children in bhnd probe order, terminating if any call to BUS_RESUME_CHILD() 220 * fails. 221 */ 222 int 223 bhnd_generic_resume(device_t dev) 224 { 225 device_t *devs; 226 int ndevs; 227 int error; 228 229 if (!device_is_attached(dev)) 230 return (EBUSY); 231 232 /* Fetch children in attach order */ 233 error = bhnd_bus_get_children(dev, &devs, &ndevs, 234 BHND_DEVICE_ORDER_ATTACH); 235 if (error) 236 return (error); 237 238 /* Perform resume */ 239 for (int i = 0; i < ndevs; i++) { 240 device_t child = devs[i]; 241 242 /* Terminate on first error */ 243 if ((error = BUS_RESUME_CHILD(device_get_parent(child), child))) 244 goto cleanup; 245 } 246 247 cleanup: 248 bhnd_bus_free_children(devs); 249 return (error); 250 } 251 252 /** 253 * Default bhnd(4) bus driver implementation of DEVICE_SUSPEND(). 254 * 255 * This implementation calls BUS_SUSPEND_CHILD() for each of the device's 256 * children in reverse bhnd probe order. If any call to BUS_SUSPEND_CHILD() 257 * fails, the suspend operation is terminated and any devices that were 258 * suspended are resumed immediately by calling their BUS_RESUME_CHILD() 259 * methods. 260 */ 261 int 262 bhnd_generic_suspend(device_t dev) 263 { 264 device_t *devs; 265 int ndevs; 266 int error; 267 268 if (!device_is_attached(dev)) 269 return (EBUSY); 270 271 /* Fetch children in detach order */ 272 error = bhnd_bus_get_children(dev, &devs, &ndevs, 273 BHND_DEVICE_ORDER_DETACH); 274 if (error) 275 return (error); 276 277 /* Perform suspend */ 278 for (int i = 0; i < ndevs; i++) { 279 device_t child = devs[i]; 280 error = BUS_SUSPEND_CHILD(device_get_parent(child), child); 281 282 /* On error, resume suspended devices and then terminate */ 283 if (error) { 284 for (int j = 0; j < i; j++) { 285 BUS_RESUME_CHILD(device_get_parent(devs[j]), 286 devs[j]); 287 } 288 289 goto cleanup; 290 } 291 } 292 293 cleanup: 294 bhnd_bus_free_children(devs); 295 return (error); 296 } 297 298 /** 299 * Default bhnd(4) bus driver implementation of BHND_BUS_GET_PROBE_ORDER(). 300 * 301 * This implementation determines probe ordering based on the device's class 302 * and other properties, including whether the device is serving as a host 303 * bridge. 304 */ 305 int 306 bhnd_generic_get_probe_order(device_t dev, device_t child) 307 { 308 switch (bhnd_get_class(child)) { 309 case BHND_DEVCLASS_CC: 310 /* Must be early enough to provide NVRAM access to the 311 * host bridge */ 312 return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_FIRST); 313 314 case BHND_DEVCLASS_CC_B: 315 /* fall through */ 316 case BHND_DEVCLASS_PMU: 317 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_EARLY); 318 319 case BHND_DEVCLASS_SOC_ROUTER: 320 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LATE); 321 322 case BHND_DEVCLASS_SOC_BRIDGE: 323 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LAST); 324 325 case BHND_DEVCLASS_CPU: 326 return (BHND_PROBE_CPU + BHND_PROBE_ORDER_FIRST); 327 328 case BHND_DEVCLASS_RAM: 329 /* fall through */ 330 case BHND_DEVCLASS_MEMC: 331 return (BHND_PROBE_CPU + BHND_PROBE_ORDER_EARLY); 332 333 case BHND_DEVCLASS_NVRAM: 334 return (BHND_PROBE_RESOURCE + BHND_PROBE_ORDER_EARLY); 335 336 case BHND_DEVCLASS_PCI: 337 case BHND_DEVCLASS_PCIE: 338 case BHND_DEVCLASS_PCCARD: 339 case BHND_DEVCLASS_ENET: 340 case BHND_DEVCLASS_ENET_MAC: 341 case BHND_DEVCLASS_ENET_PHY: 342 case BHND_DEVCLASS_WLAN: 343 case BHND_DEVCLASS_WLAN_MAC: 344 case BHND_DEVCLASS_WLAN_PHY: 345 case BHND_DEVCLASS_EROM: 346 case BHND_DEVCLASS_OTHER: 347 case BHND_DEVCLASS_INVALID: 348 if (bhnd_bus_find_hostb_device(dev) == child) 349 return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_EARLY); 350 351 return (BHND_PROBE_DEFAULT); 352 default: 353 return (BHND_PROBE_DEFAULT); 354 } 355 } 356 357 /** 358 * Default bhnd(4) bus driver implementation of BHND_BUS_ALLOC_PMU(). 359 */ 360 int 361 bhnd_generic_alloc_pmu(device_t dev, device_t child) 362 { 363 struct bhnd_softc *sc; 364 struct bhnd_resource *r; 365 struct bhnd_core_clkctl *clkctl; 366 struct resource_list *rl; 367 struct resource_list_entry *rle; 368 device_t pmu_dev; 369 bhnd_addr_t r_addr; 370 bhnd_size_t r_size; 371 bus_size_t pmu_regs; 372 u_int max_latency; 373 int error; 374 375 GIANT_REQUIRED; /* for newbus */ 376 377 if (device_get_parent(child) != dev) 378 return (EINVAL); 379 380 sc = device_get_softc(dev); 381 clkctl = bhnd_get_pmu_info(child); 382 pmu_regs = BHND_CLK_CTL_ST; 383 384 /* already allocated? */ 385 if (clkctl != NULL) { 386 panic("duplicate PMU allocation for %s", 387 device_get_nameunit(child)); 388 } 389 390 /* Determine address+size of the core's PMU register block */ 391 error = bhnd_get_region_addr(child, BHND_PORT_DEVICE, 0, 0, &r_addr, 392 &r_size); 393 if (error) { 394 device_printf(sc->dev, "error fetching register block info for " 395 "%s: %d\n", device_get_nameunit(child), error); 396 return (error); 397 } 398 399 if (r_size < (pmu_regs + sizeof(uint32_t))) { 400 device_printf(sc->dev, "pmu offset %#jx would overrun %s " 401 "register block\n", (uintmax_t)pmu_regs, 402 device_get_nameunit(child)); 403 return (ENODEV); 404 } 405 406 /* Locate actual resource containing the core's register block */ 407 if ((rl = BUS_GET_RESOURCE_LIST(dev, child)) == NULL) { 408 device_printf(dev, "NULL resource list returned for %s\n", 409 device_get_nameunit(child)); 410 return (ENXIO); 411 } 412 413 if ((rle = resource_list_find(rl, SYS_RES_MEMORY, 0)) == NULL) { 414 device_printf(dev, "cannot locate core register resource " 415 "for %s\n", device_get_nameunit(child)); 416 return (ENXIO); 417 } 418 419 if (rle->res == NULL) { 420 device_printf(dev, "core register resource unallocated for " 421 "%s\n", device_get_nameunit(child)); 422 return (ENXIO); 423 } 424 425 if (r_addr+pmu_regs < rman_get_start(rle->res) || 426 r_addr+pmu_regs >= rman_get_end(rle->res)) 427 { 428 device_printf(dev, "core register resource does not map PMU " 429 "registers at %#jx\n for %s\n", r_addr+pmu_regs, 430 device_get_nameunit(child)); 431 return (ENXIO); 432 } 433 434 /* Adjust PMU register offset relative to the actual start address 435 * of the core's register block allocation. 436 * 437 * XXX: The saved offset will be invalid if bus_adjust_resource is 438 * used to modify the resource's start address. 439 */ 440 if (rman_get_start(rle->res) > r_addr) 441 pmu_regs -= rman_get_start(rle->res) - r_addr; 442 else 443 pmu_regs -= r_addr - rman_get_start(rle->res); 444 445 /* Retain a PMU reference for the clkctl instance state */ 446 pmu_dev = bhnd_retain_provider(child, BHND_SERVICE_PMU); 447 if (pmu_dev == NULL) { 448 device_printf(sc->dev, "PMU not found\n"); 449 return (ENXIO); 450 } 451 452 /* Fetch the maximum transition latency from our PMU */ 453 max_latency = bhnd_pmu_get_max_transition_latency(pmu_dev); 454 455 /* Allocate a new bhnd_resource wrapping the standard resource we 456 * fetched from the resource list; we'll free this in 457 * bhnd_generic_release_pmu() */ 458 r = malloc(sizeof(struct bhnd_resource), M_BHND, M_NOWAIT); 459 if (r == NULL) { 460 bhnd_release_provider(child, pmu_dev, BHND_SERVICE_PMU); 461 return (ENOMEM); 462 } 463 464 r->res = rle->res; 465 r->direct = ((rman_get_flags(rle->res) & RF_ACTIVE) != 0); 466 467 /* Allocate the clkctl instance */ 468 clkctl = bhnd_alloc_core_clkctl(child, pmu_dev, r, pmu_regs, 469 max_latency); 470 if (clkctl == NULL) { 471 free(r, M_BHND); 472 bhnd_release_provider(child, pmu_dev, BHND_SERVICE_PMU); 473 return (ENOMEM); 474 } 475 476 bhnd_set_pmu_info(child, clkctl); 477 return (0); 478 } 479 480 /** 481 * Default bhnd(4) bus driver implementation of BHND_BUS_RELEASE_PMU(). 482 */ 483 int 484 bhnd_generic_release_pmu(device_t dev, device_t child) 485 { 486 struct bhnd_softc *sc; 487 struct bhnd_core_clkctl *clkctl; 488 struct bhnd_resource *r; 489 device_t pmu_dev; 490 491 GIANT_REQUIRED; /* for newbus */ 492 493 sc = device_get_softc(dev); 494 495 if (device_get_parent(child) != dev) 496 return (EINVAL); 497 498 clkctl = bhnd_get_pmu_info(child); 499 if (clkctl == NULL) 500 panic("pmu over-release for %s", device_get_nameunit(child)); 501 502 /* Clear all FORCE, AREQ, and ERSRC flags, unless we're already in 503 * RESET. Suspending a core clears clkctl automatically (and attempting 504 * to access the PMU registers in a suspended core will trigger a 505 * system livelock). */ 506 if (!bhnd_is_hw_suspended(clkctl->cc_dev)) { 507 BHND_CLKCTL_LOCK(clkctl); 508 509 /* Clear all FORCE, AREQ, and ERSRC flags */ 510 BHND_CLKCTL_SET_4(clkctl, 0x0, BHND_CCS_FORCE_MASK | 511 BHND_CCS_AREQ_MASK | BHND_CCS_ERSRC_REQ_MASK); 512 513 BHND_CLKCTL_UNLOCK(clkctl); 514 } 515 516 /* Clear child's PMU info reference */ 517 bhnd_set_pmu_info(child, NULL); 518 519 /* Before freeing the clkctl instance, save a pointer to resources we 520 * need to clean up manually */ 521 r = clkctl->cc_res; 522 pmu_dev = clkctl->cc_pmu_dev; 523 524 /* Free the clkctl instance */ 525 bhnd_free_core_clkctl(clkctl); 526 527 /* Free the child's bhnd resource wrapper */ 528 free(r, M_BHND); 529 530 /* Release the child's PMU provider reference */ 531 bhnd_release_provider(child, pmu_dev, BHND_SERVICE_PMU); 532 533 return (0); 534 } 535 536 /** 537 * Default bhnd(4) bus driver implementation of BHND_BUS_GET_CLOCK_LATENCY(). 538 */ 539 int 540 bhnd_generic_get_clock_latency(device_t dev, device_t child, bhnd_clock clock, 541 u_int *latency) 542 { 543 struct bhnd_core_clkctl *clkctl; 544 545 if (device_get_parent(child) != dev) 546 return (EINVAL); 547 548 if ((clkctl = bhnd_get_pmu_info(child)) == NULL) 549 panic("no active PMU allocation"); 550 551 return (bhnd_pmu_get_clock_latency(clkctl->cc_pmu_dev, clock, latency)); 552 } 553 554 /** 555 * Default bhnd(4) bus driver implementation of BHND_BUS_GET_CLOCK_FREQ(). 556 */ 557 int 558 bhnd_generic_get_clock_freq(device_t dev, device_t child, bhnd_clock clock, 559 u_int *freq) 560 { 561 struct bhnd_core_clkctl *clkctl; 562 563 if (device_get_parent(child) != dev) 564 return (EINVAL); 565 566 if ((clkctl = bhnd_get_pmu_info(child)) == NULL) 567 panic("no active PMU allocation"); 568 569 return (bhnd_pmu_get_clock_freq(clkctl->cc_pmu_dev, clock, freq)); 570 } 571 572 /** 573 * Default bhnd(4) bus driver implementation of BHND_BUS_REQUEST_CLOCK(). 574 */ 575 int 576 bhnd_generic_request_clock(device_t dev, device_t child, bhnd_clock clock) 577 { 578 struct bhnd_softc *sc; 579 struct bhnd_core_clkctl *clkctl; 580 uint32_t avail; 581 uint32_t req; 582 int error; 583 584 sc = device_get_softc(dev); 585 586 if (device_get_parent(child) != dev) 587 return (EINVAL); 588 589 if ((clkctl = bhnd_get_pmu_info(child)) == NULL) 590 panic("no active PMU allocation"); 591 592 BHND_ASSERT_CLKCTL_AVAIL(clkctl); 593 594 avail = 0x0; 595 req = 0x0; 596 597 switch (clock) { 598 case BHND_CLOCK_DYN: 599 break; 600 case BHND_CLOCK_ILP: 601 req |= BHND_CCS_FORCEILP; 602 break; 603 case BHND_CLOCK_ALP: 604 req |= BHND_CCS_FORCEALP; 605 avail |= BHND_CCS_ALPAVAIL; 606 break; 607 case BHND_CLOCK_HT: 608 req |= BHND_CCS_FORCEHT; 609 avail |= BHND_CCS_HTAVAIL; 610 break; 611 default: 612 device_printf(dev, "%s requested unknown clock: %#x\n", 613 device_get_nameunit(clkctl->cc_dev), clock); 614 return (ENODEV); 615 } 616 617 BHND_CLKCTL_LOCK(clkctl); 618 619 /* Issue request */ 620 BHND_CLKCTL_SET_4(clkctl, req, BHND_CCS_FORCE_MASK); 621 622 /* Wait for clock availability */ 623 error = bhnd_core_clkctl_wait(clkctl, avail, avail); 624 625 BHND_CLKCTL_UNLOCK(clkctl); 626 627 return (error); 628 } 629 630 /** 631 * Default bhnd(4) bus driver implementation of BHND_BUS_ENABLE_CLOCKS(). 632 */ 633 int 634 bhnd_generic_enable_clocks(device_t dev, device_t child, uint32_t clocks) 635 { 636 struct bhnd_softc *sc; 637 struct bhnd_core_clkctl *clkctl; 638 uint32_t avail; 639 uint32_t req; 640 int error; 641 642 sc = device_get_softc(dev); 643 644 if (device_get_parent(child) != dev) 645 return (EINVAL); 646 647 if ((clkctl = bhnd_get_pmu_info(child)) == NULL) 648 panic("no active PMU allocation"); 649 650 BHND_ASSERT_CLKCTL_AVAIL(clkctl); 651 652 sc = device_get_softc(dev); 653 654 avail = 0x0; 655 req = 0x0; 656 657 /* Build clock request flags */ 658 if (clocks & BHND_CLOCK_DYN) /* nothing to enable */ 659 clocks &= ~BHND_CLOCK_DYN; 660 661 if (clocks & BHND_CLOCK_ILP) /* nothing to enable */ 662 clocks &= ~BHND_CLOCK_ILP; 663 664 if (clocks & BHND_CLOCK_ALP) { 665 req |= BHND_CCS_ALPAREQ; 666 avail |= BHND_CCS_ALPAVAIL; 667 clocks &= ~BHND_CLOCK_ALP; 668 } 669 670 if (clocks & BHND_CLOCK_HT) { 671 req |= BHND_CCS_HTAREQ; 672 avail |= BHND_CCS_HTAVAIL; 673 clocks &= ~BHND_CLOCK_HT; 674 } 675 676 /* Check for unknown clock values */ 677 if (clocks != 0x0) { 678 device_printf(dev, "%s requested unknown clocks: %#x\n", 679 device_get_nameunit(clkctl->cc_dev), clocks); 680 return (ENODEV); 681 } 682 683 BHND_CLKCTL_LOCK(clkctl); 684 685 /* Issue request */ 686 BHND_CLKCTL_SET_4(clkctl, req, BHND_CCS_AREQ_MASK); 687 688 /* Wait for clock availability */ 689 error = bhnd_core_clkctl_wait(clkctl, avail, avail); 690 691 BHND_CLKCTL_UNLOCK(clkctl); 692 693 return (error); 694 } 695 696 /** 697 * Default bhnd(4) bus driver implementation of BHND_BUS_REQUEST_EXT_RSRC(). 698 */ 699 int 700 bhnd_generic_request_ext_rsrc(device_t dev, device_t child, u_int rsrc) 701 { 702 struct bhnd_softc *sc; 703 struct bhnd_core_clkctl *clkctl; 704 uint32_t req; 705 uint32_t avail; 706 int error; 707 708 sc = device_get_softc(dev); 709 710 if (device_get_parent(child) != dev) 711 return (EINVAL); 712 713 if ((clkctl = bhnd_get_pmu_info(child)) == NULL) 714 panic("no active PMU allocation"); 715 716 BHND_ASSERT_CLKCTL_AVAIL(clkctl); 717 718 sc = device_get_softc(dev); 719 720 if (rsrc > BHND_CCS_ERSRC_MAX) 721 return (EINVAL); 722 723 req = BHND_CCS_SET_BITS((1<<rsrc), BHND_CCS_ERSRC_REQ); 724 avail = BHND_CCS_SET_BITS((1<<rsrc), BHND_CCS_ERSRC_STS); 725 726 BHND_CLKCTL_LOCK(clkctl); 727 728 /* Write request */ 729 BHND_CLKCTL_SET_4(clkctl, req, req); 730 731 /* Wait for resource availability */ 732 error = bhnd_core_clkctl_wait(clkctl, avail, avail); 733 734 BHND_CLKCTL_UNLOCK(clkctl); 735 736 return (error); 737 } 738 739 /** 740 * Default bhnd(4) bus driver implementation of BHND_BUS_RELEASE_EXT_RSRC(). 741 */ 742 int 743 bhnd_generic_release_ext_rsrc(device_t dev, device_t child, u_int rsrc) 744 { 745 struct bhnd_softc *sc; 746 struct bhnd_core_clkctl *clkctl; 747 uint32_t mask; 748 749 sc = device_get_softc(dev); 750 751 if (device_get_parent(child) != dev) 752 return (EINVAL); 753 754 if ((clkctl = bhnd_get_pmu_info(child)) == NULL) 755 panic("no active PMU allocation"); 756 757 758 BHND_ASSERT_CLKCTL_AVAIL(clkctl); 759 760 sc = device_get_softc(dev); 761 762 if (rsrc > BHND_CCS_ERSRC_MAX) 763 return (EINVAL); 764 765 mask = BHND_CCS_SET_BITS((1<<rsrc), BHND_CCS_ERSRC_REQ); 766 767 /* Clear request */ 768 BHND_CLKCTL_LOCK(clkctl); 769 BHND_CLKCTL_SET_4(clkctl, 0x0, mask); 770 BHND_CLKCTL_UNLOCK(clkctl); 771 772 return (0); 773 } 774 775 /** 776 * Default bhnd(4) bus driver implementation of BHND_BUS_IS_REGION_VALID(). 777 * 778 * This implementation assumes that port and region numbers are 0-indexed and 779 * are allocated non-sparsely, using BHND_BUS_GET_PORT_COUNT() and 780 * BHND_BUS_GET_REGION_COUNT() to determine if @p port and @p region fall 781 * within the defined range. 782 */ 783 static bool 784 bhnd_generic_is_region_valid(device_t dev, device_t child, 785 bhnd_port_type type, u_int port, u_int region) 786 { 787 if (port >= bhnd_get_port_count(child, type)) 788 return (false); 789 790 if (region >= bhnd_get_region_count(child, type, port)) 791 return (false); 792 793 return (true); 794 } 795 796 /** 797 * Default bhnd(4) bus driver implementation of BHND_BUS_GET_NVRAM_VAR(). 798 * 799 * This implementation searches @p dev for a registered NVRAM child device. 800 * 801 * If no NVRAM device is registered with @p dev, the request is delegated to 802 * the BHND_BUS_GET_NVRAM_VAR() method on the parent of @p dev. 803 */ 804 int 805 bhnd_generic_get_nvram_var(device_t dev, device_t child, const char *name, 806 void *buf, size_t *size, bhnd_nvram_type type) 807 { 808 struct bhnd_softc *sc; 809 device_t nvram, parent; 810 int error; 811 812 sc = device_get_softc(dev); 813 814 /* If a NVRAM device is available, consult it first */ 815 nvram = bhnd_retain_provider(child, BHND_SERVICE_NVRAM); 816 if (nvram != NULL) { 817 error = BHND_NVRAM_GETVAR(nvram, name, buf, size, type); 818 bhnd_release_provider(child, nvram, BHND_SERVICE_NVRAM); 819 return (error); 820 } 821 822 /* Otherwise, try to delegate to parent */ 823 if ((parent = device_get_parent(dev)) == NULL) 824 return (ENODEV); 825 826 return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), child, 827 name, buf, size, type)); 828 } 829 830 /** 831 * Default bhnd(4) bus driver implementation of BUS_PRINT_CHILD(). 832 * 833 * This implementation requests the device's struct resource_list via 834 * BUS_GET_RESOURCE_LIST. 835 */ 836 int 837 bhnd_generic_print_child(device_t dev, device_t child) 838 { 839 struct resource_list *rl; 840 int retval = 0; 841 842 retval += bus_print_child_header(dev, child); 843 844 rl = BUS_GET_RESOURCE_LIST(dev, child); 845 846 847 if (rl != NULL) { 848 retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, 849 "%#jx"); 850 851 retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, 852 "%#jd"); 853 } 854 855 retval += printf(" at core %u", bhnd_get_core_index(child)); 856 857 retval += bus_print_child_domain(dev, child); 858 retval += bus_print_child_footer(dev, child); 859 860 return (retval); 861 } 862 863 /** 864 * Default bhnd(4) bus driver implementation of BUS_PROBE_NOMATCH(). 865 * 866 * This implementation requests the device's struct resource_list via 867 * BUS_GET_RESOURCE_LIST. 868 */ 869 void 870 bhnd_generic_probe_nomatch(device_t dev, device_t child) 871 { 872 struct resource_list *rl; 873 const struct bhnd_nomatch *nm; 874 bool report; 875 876 /* Fetch reporting configuration for this device */ 877 report = true; 878 for (nm = bhnd_nomatch_table; nm->device != BHND_COREID_INVALID; nm++) { 879 if (nm->vendor != bhnd_get_vendor(child)) 880 continue; 881 882 if (nm->device != bhnd_get_device(child)) 883 continue; 884 885 report = false; 886 if (bootverbose && nm->if_verbose) 887 report = true; 888 break; 889 } 890 891 if (!report) 892 return; 893 894 /* Print the non-matched device info */ 895 device_printf(dev, "<%s %s, rev %hhu>", bhnd_get_vendor_name(child), 896 bhnd_get_device_name(child), bhnd_get_hwrev(child)); 897 898 rl = BUS_GET_RESOURCE_LIST(dev, child); 899 if (rl != NULL) { 900 resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#jx"); 901 resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%#jd"); 902 } 903 904 printf(" at core %u (no driver attached)\n", 905 bhnd_get_core_index(child)); 906 } 907 908 /** 909 * Default implementation of BUS_CHILD_PNPINFO_STR(). 910 */ 911 static int 912 bhnd_child_pnpinfo_str(device_t dev, device_t child, char *buf, 913 size_t buflen) 914 { 915 if (device_get_parent(child) != dev) { 916 return (BUS_CHILD_PNPINFO_STR(device_get_parent(dev), child, 917 buf, buflen)); 918 } 919 920 snprintf(buf, buflen, "vendor=0x%hx device=0x%hx rev=0x%hhx", 921 bhnd_get_vendor(child), bhnd_get_device(child), 922 bhnd_get_hwrev(child)); 923 924 return (0); 925 } 926 927 /** 928 * Default implementation of BUS_CHILD_LOCATION_STR(). 929 */ 930 static int 931 bhnd_child_location_str(device_t dev, device_t child, char *buf, 932 size_t buflen) 933 { 934 bhnd_addr_t addr; 935 bhnd_size_t size; 936 937 if (device_get_parent(child) != dev) { 938 return (BUS_CHILD_LOCATION_STR(device_get_parent(dev), child, 939 buf, buflen)); 940 } 941 942 943 if (bhnd_get_region_addr(child, BHND_PORT_DEVICE, 0, 0, &addr, &size)) { 944 /* No device default port/region */ 945 if (buflen > 0) 946 *buf = '\0'; 947 return (0); 948 } 949 950 snprintf(buf, buflen, "port0.0=0x%llx", (unsigned long long) addr); 951 return (0); 952 } 953 954 /** 955 * Default bhnd(4) bus driver implementation of BUS_CHILD_DELETED(). 956 * 957 * This implementation manages internal bhnd(4) state, and must be called 958 * by subclassing drivers. 959 */ 960 void 961 bhnd_generic_child_deleted(device_t dev, device_t child) 962 { 963 struct bhnd_softc *sc; 964 965 sc = device_get_softc(dev); 966 967 /* Free device info */ 968 if (bhnd_get_pmu_info(child) != NULL) { 969 /* Releasing PMU requests automatically would be nice, 970 * but we can't reference per-core PMU register 971 * resource after driver detach */ 972 panic("%s leaked device pmu state\n", 973 device_get_nameunit(child)); 974 } 975 } 976 977 /** 978 * Helper function for implementing BUS_SUSPEND_CHILD(). 979 * 980 * TODO: Power management 981 * 982 * If @p child is not a direct child of @p dev, suspension is delegated to 983 * the @p dev parent. 984 */ 985 int 986 bhnd_generic_suspend_child(device_t dev, device_t child) 987 { 988 if (device_get_parent(child) != dev) 989 BUS_SUSPEND_CHILD(device_get_parent(dev), child); 990 991 return bus_generic_suspend_child(dev, child); 992 } 993 994 /** 995 * Helper function for implementing BUS_RESUME_CHILD(). 996 * 997 * TODO: Power management 998 * 999 * If @p child is not a direct child of @p dev, suspension is delegated to 1000 * the @p dev parent. 1001 */ 1002 int 1003 bhnd_generic_resume_child(device_t dev, device_t child) 1004 { 1005 if (device_get_parent(child) != dev) 1006 BUS_RESUME_CHILD(device_get_parent(dev), child); 1007 1008 return bus_generic_resume_child(dev, child); 1009 } 1010 1011 1012 /** 1013 * Default bhnd(4) bus driver implementation of BUS_SETUP_INTR(). 1014 * 1015 * This implementation of BUS_SETUP_INTR() will delegate interrupt setup 1016 * to the parent of @p dev, if any. 1017 */ 1018 int 1019 bhnd_generic_setup_intr(device_t dev, device_t child, struct resource *irq, 1020 int flags, driver_filter_t *filter, driver_intr_t *intr, void *arg, 1021 void **cookiep) 1022 { 1023 return (bus_generic_setup_intr(dev, child, irq, flags, filter, intr, 1024 arg, cookiep)); 1025 } 1026 1027 /* 1028 * Delegate all indirect I/O to the parent device. When inherited by 1029 * non-bridged bus implementations, resources will never be marked as 1030 * indirect, and these methods will never be called. 1031 */ 1032 #define BHND_IO_READ(_type, _name, _method) \ 1033 static _type \ 1034 bhnd_read_ ## _name (device_t dev, device_t child, \ 1035 struct bhnd_resource *r, bus_size_t offset) \ 1036 { \ 1037 return (BHND_BUS_READ_ ## _method( \ 1038 device_get_parent(dev), child, r, offset)); \ 1039 } 1040 1041 #define BHND_IO_WRITE(_type, _name, _method) \ 1042 static void \ 1043 bhnd_write_ ## _name (device_t dev, device_t child, \ 1044 struct bhnd_resource *r, bus_size_t offset, _type value) \ 1045 { \ 1046 return (BHND_BUS_WRITE_ ## _method( \ 1047 device_get_parent(dev), child, r, offset, \ 1048 value)); \ 1049 } 1050 1051 #define BHND_IO_MISC(_type, _op, _method) \ 1052 static void \ 1053 bhnd_ ## _op (device_t dev, device_t child, \ 1054 struct bhnd_resource *r, bus_size_t offset, _type datap, \ 1055 bus_size_t count) \ 1056 { \ 1057 BHND_BUS_ ## _method(device_get_parent(dev), child, r, \ 1058 offset, datap, count); \ 1059 } 1060 1061 #define BHND_IO_METHODS(_type, _size) \ 1062 BHND_IO_READ(_type, _size, _size) \ 1063 BHND_IO_WRITE(_type, _size, _size) \ 1064 \ 1065 BHND_IO_READ(_type, stream_ ## _size, STREAM_ ## _size) \ 1066 BHND_IO_WRITE(_type, stream_ ## _size, STREAM_ ## _size) \ 1067 \ 1068 BHND_IO_MISC(_type*, read_multi_ ## _size, \ 1069 READ_MULTI_ ## _size) \ 1070 BHND_IO_MISC(_type*, write_multi_ ## _size, \ 1071 WRITE_MULTI_ ## _size) \ 1072 \ 1073 BHND_IO_MISC(_type*, read_multi_stream_ ## _size, \ 1074 READ_MULTI_STREAM_ ## _size) \ 1075 BHND_IO_MISC(_type*, write_multi_stream_ ## _size, \ 1076 WRITE_MULTI_STREAM_ ## _size) \ 1077 \ 1078 BHND_IO_MISC(_type, set_multi_ ## _size, SET_MULTI_ ## _size) \ 1079 BHND_IO_MISC(_type, set_region_ ## _size, SET_REGION_ ## _size) \ 1080 \ 1081 BHND_IO_MISC(_type*, read_region_ ## _size, \ 1082 READ_REGION_ ## _size) \ 1083 BHND_IO_MISC(_type*, write_region_ ## _size, \ 1084 WRITE_REGION_ ## _size) \ 1085 \ 1086 BHND_IO_MISC(_type*, read_region_stream_ ## _size, \ 1087 READ_REGION_STREAM_ ## _size) \ 1088 BHND_IO_MISC(_type*, write_region_stream_ ## _size, \ 1089 WRITE_REGION_STREAM_ ## _size) \ 1090 1091 BHND_IO_METHODS(uint8_t, 1); 1092 BHND_IO_METHODS(uint16_t, 2); 1093 BHND_IO_METHODS(uint32_t, 4); 1094 1095 static void 1096 bhnd_barrier(device_t dev, device_t child, struct bhnd_resource *r, 1097 bus_size_t offset, bus_size_t length, int flags) 1098 { 1099 BHND_BUS_BARRIER(device_get_parent(dev), child, r, offset, length, 1100 flags); 1101 } 1102 1103 static device_method_t bhnd_methods[] = { 1104 /* Device interface */ \ 1105 DEVMETHOD(device_attach, bhnd_generic_attach), 1106 DEVMETHOD(device_detach, bhnd_generic_detach), 1107 DEVMETHOD(device_shutdown, bhnd_generic_shutdown), 1108 DEVMETHOD(device_suspend, bhnd_generic_suspend), 1109 DEVMETHOD(device_resume, bhnd_generic_resume), 1110 1111 /* Bus interface */ 1112 DEVMETHOD(bus_child_deleted, bhnd_generic_child_deleted), 1113 DEVMETHOD(bus_probe_nomatch, bhnd_generic_probe_nomatch), 1114 DEVMETHOD(bus_print_child, bhnd_generic_print_child), 1115 DEVMETHOD(bus_child_pnpinfo_str, bhnd_child_pnpinfo_str), 1116 DEVMETHOD(bus_child_location_str, bhnd_child_location_str), 1117 1118 DEVMETHOD(bus_suspend_child, bhnd_generic_suspend_child), 1119 DEVMETHOD(bus_resume_child, bhnd_generic_resume_child), 1120 1121 DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), 1122 DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), 1123 DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource), 1124 DEVMETHOD(bus_alloc_resource, bus_generic_rl_alloc_resource), 1125 DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource), 1126 DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource), 1127 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 1128 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 1129 1130 DEVMETHOD(bus_setup_intr, bhnd_generic_setup_intr), 1131 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 1132 DEVMETHOD(bus_config_intr, bus_generic_config_intr), 1133 DEVMETHOD(bus_bind_intr, bus_generic_bind_intr), 1134 DEVMETHOD(bus_describe_intr, bus_generic_describe_intr), 1135 1136 DEVMETHOD(bus_get_dma_tag, bus_generic_get_dma_tag), 1137 1138 /* BHND interface */ 1139 DEVMETHOD(bhnd_bus_get_chipid, bhnd_bus_generic_get_chipid), 1140 DEVMETHOD(bhnd_bus_is_hw_disabled, bhnd_bus_generic_is_hw_disabled), 1141 DEVMETHOD(bhnd_bus_read_board_info, bhnd_bus_generic_read_board_info), 1142 1143 DEVMETHOD(bhnd_bus_get_probe_order, bhnd_generic_get_probe_order), 1144 1145 DEVMETHOD(bhnd_bus_alloc_pmu, bhnd_generic_alloc_pmu), 1146 DEVMETHOD(bhnd_bus_release_pmu, bhnd_generic_release_pmu), 1147 DEVMETHOD(bhnd_bus_request_clock, bhnd_generic_request_clock), 1148 DEVMETHOD(bhnd_bus_enable_clocks, bhnd_generic_enable_clocks), 1149 DEVMETHOD(bhnd_bus_request_ext_rsrc, bhnd_generic_request_ext_rsrc), 1150 DEVMETHOD(bhnd_bus_release_ext_rsrc, bhnd_generic_release_ext_rsrc), 1151 DEVMETHOD(bhnd_bus_get_clock_latency, bhnd_generic_get_clock_latency), 1152 DEVMETHOD(bhnd_bus_get_clock_freq, bhnd_generic_get_clock_freq), 1153 1154 DEVMETHOD(bhnd_bus_is_region_valid, bhnd_generic_is_region_valid), 1155 DEVMETHOD(bhnd_bus_get_nvram_var, bhnd_generic_get_nvram_var), 1156 1157 /* BHND interface (bus I/O) */ 1158 DEVMETHOD(bhnd_bus_read_1, bhnd_read_1), 1159 DEVMETHOD(bhnd_bus_read_2, bhnd_read_2), 1160 DEVMETHOD(bhnd_bus_read_4, bhnd_read_4), 1161 DEVMETHOD(bhnd_bus_write_1, bhnd_write_1), 1162 DEVMETHOD(bhnd_bus_write_2, bhnd_write_2), 1163 DEVMETHOD(bhnd_bus_write_4, bhnd_write_4), 1164 1165 DEVMETHOD(bhnd_bus_read_stream_1, bhnd_read_stream_1), 1166 DEVMETHOD(bhnd_bus_read_stream_2, bhnd_read_stream_2), 1167 DEVMETHOD(bhnd_bus_read_stream_4, bhnd_read_stream_4), 1168 DEVMETHOD(bhnd_bus_write_stream_1, bhnd_write_stream_1), 1169 DEVMETHOD(bhnd_bus_write_stream_2, bhnd_write_stream_2), 1170 DEVMETHOD(bhnd_bus_write_stream_4, bhnd_write_stream_4), 1171 1172 DEVMETHOD(bhnd_bus_read_multi_1, bhnd_read_multi_1), 1173 DEVMETHOD(bhnd_bus_read_multi_2, bhnd_read_multi_2), 1174 DEVMETHOD(bhnd_bus_read_multi_4, bhnd_read_multi_4), 1175 DEVMETHOD(bhnd_bus_write_multi_1, bhnd_write_multi_1), 1176 DEVMETHOD(bhnd_bus_write_multi_2, bhnd_write_multi_2), 1177 DEVMETHOD(bhnd_bus_write_multi_4, bhnd_write_multi_4), 1178 1179 DEVMETHOD(bhnd_bus_read_multi_stream_1, bhnd_read_multi_stream_1), 1180 DEVMETHOD(bhnd_bus_read_multi_stream_2, bhnd_read_multi_stream_2), 1181 DEVMETHOD(bhnd_bus_read_multi_stream_4, bhnd_read_multi_stream_4), 1182 DEVMETHOD(bhnd_bus_write_multi_stream_1,bhnd_write_multi_stream_1), 1183 DEVMETHOD(bhnd_bus_write_multi_stream_2,bhnd_write_multi_stream_2), 1184 DEVMETHOD(bhnd_bus_write_multi_stream_4,bhnd_write_multi_stream_4), 1185 1186 DEVMETHOD(bhnd_bus_set_multi_1, bhnd_set_multi_1), 1187 DEVMETHOD(bhnd_bus_set_multi_2, bhnd_set_multi_2), 1188 DEVMETHOD(bhnd_bus_set_multi_4, bhnd_set_multi_4), 1189 1190 DEVMETHOD(bhnd_bus_set_region_1, bhnd_set_region_1), 1191 DEVMETHOD(bhnd_bus_set_region_2, bhnd_set_region_2), 1192 DEVMETHOD(bhnd_bus_set_region_4, bhnd_set_region_4), 1193 1194 DEVMETHOD(bhnd_bus_read_region_1, bhnd_read_region_1), 1195 DEVMETHOD(bhnd_bus_read_region_2, bhnd_read_region_2), 1196 DEVMETHOD(bhnd_bus_read_region_4, bhnd_read_region_4), 1197 DEVMETHOD(bhnd_bus_write_region_1, bhnd_write_region_1), 1198 DEVMETHOD(bhnd_bus_write_region_2, bhnd_write_region_2), 1199 DEVMETHOD(bhnd_bus_write_region_4, bhnd_write_region_4), 1200 1201 DEVMETHOD(bhnd_bus_read_region_stream_1,bhnd_read_region_stream_1), 1202 DEVMETHOD(bhnd_bus_read_region_stream_2,bhnd_read_region_stream_2), 1203 DEVMETHOD(bhnd_bus_read_region_stream_4,bhnd_read_region_stream_4), 1204 DEVMETHOD(bhnd_bus_write_region_stream_1, bhnd_write_region_stream_1), 1205 DEVMETHOD(bhnd_bus_write_region_stream_2, bhnd_write_region_stream_2), 1206 DEVMETHOD(bhnd_bus_write_region_stream_4, bhnd_write_region_stream_4), 1207 1208 DEVMETHOD(bhnd_bus_barrier, bhnd_barrier), 1209 1210 DEVMETHOD_END 1211 }; 1212 1213 devclass_t bhnd_devclass; /**< bhnd bus. */ 1214 devclass_t bhnd_hostb_devclass; /**< bhnd bus host bridge. */ 1215 devclass_t bhnd_nvram_devclass; /**< bhnd NVRAM device */ 1216 1217 DEFINE_CLASS_0(bhnd, bhnd_driver, bhnd_methods, sizeof(struct bhnd_softc)); 1218 MODULE_VERSION(bhnd, 1); 1219