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