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_core_clkctl *clkctl; 638 uint32_t avail; 639 uint32_t req; 640 int error; 641 642 if (device_get_parent(child) != dev) 643 return (EINVAL); 644 645 if ((clkctl = bhnd_get_pmu_info(child)) == NULL) 646 panic("no active PMU allocation"); 647 648 BHND_ASSERT_CLKCTL_AVAIL(clkctl); 649 650 avail = 0x0; 651 req = 0x0; 652 653 /* Build clock request flags */ 654 if (clocks & BHND_CLOCK_DYN) /* nothing to enable */ 655 clocks &= ~BHND_CLOCK_DYN; 656 657 if (clocks & BHND_CLOCK_ILP) /* nothing to enable */ 658 clocks &= ~BHND_CLOCK_ILP; 659 660 if (clocks & BHND_CLOCK_ALP) { 661 req |= BHND_CCS_ALPAREQ; 662 avail |= BHND_CCS_ALPAVAIL; 663 clocks &= ~BHND_CLOCK_ALP; 664 } 665 666 if (clocks & BHND_CLOCK_HT) { 667 req |= BHND_CCS_HTAREQ; 668 avail |= BHND_CCS_HTAVAIL; 669 clocks &= ~BHND_CLOCK_HT; 670 } 671 672 /* Check for unknown clock values */ 673 if (clocks != 0x0) { 674 device_printf(dev, "%s requested unknown clocks: %#x\n", 675 device_get_nameunit(clkctl->cc_dev), clocks); 676 return (ENODEV); 677 } 678 679 BHND_CLKCTL_LOCK(clkctl); 680 681 /* Issue request */ 682 BHND_CLKCTL_SET_4(clkctl, req, BHND_CCS_AREQ_MASK); 683 684 /* Wait for clock availability */ 685 error = bhnd_core_clkctl_wait(clkctl, avail, avail); 686 687 BHND_CLKCTL_UNLOCK(clkctl); 688 689 return (error); 690 } 691 692 /** 693 * Default bhnd(4) bus driver implementation of BHND_BUS_REQUEST_EXT_RSRC(). 694 */ 695 int 696 bhnd_generic_request_ext_rsrc(device_t dev, device_t child, u_int rsrc) 697 { 698 struct bhnd_softc *sc; 699 struct bhnd_core_clkctl *clkctl; 700 uint32_t req; 701 uint32_t avail; 702 int error; 703 704 sc = device_get_softc(dev); 705 706 if (device_get_parent(child) != dev) 707 return (EINVAL); 708 709 if ((clkctl = bhnd_get_pmu_info(child)) == NULL) 710 panic("no active PMU allocation"); 711 712 BHND_ASSERT_CLKCTL_AVAIL(clkctl); 713 714 sc = device_get_softc(dev); 715 716 if (rsrc > BHND_CCS_ERSRC_MAX) 717 return (EINVAL); 718 719 req = BHND_CCS_SET_BITS((1<<rsrc), BHND_CCS_ERSRC_REQ); 720 avail = BHND_CCS_SET_BITS((1<<rsrc), BHND_CCS_ERSRC_STS); 721 722 BHND_CLKCTL_LOCK(clkctl); 723 724 /* Write request */ 725 BHND_CLKCTL_SET_4(clkctl, req, req); 726 727 /* Wait for resource availability */ 728 error = bhnd_core_clkctl_wait(clkctl, avail, avail); 729 730 BHND_CLKCTL_UNLOCK(clkctl); 731 732 return (error); 733 } 734 735 /** 736 * Default bhnd(4) bus driver implementation of BHND_BUS_RELEASE_EXT_RSRC(). 737 */ 738 int 739 bhnd_generic_release_ext_rsrc(device_t dev, device_t child, u_int rsrc) 740 { 741 struct bhnd_softc *sc; 742 struct bhnd_core_clkctl *clkctl; 743 uint32_t mask; 744 745 sc = device_get_softc(dev); 746 747 if (device_get_parent(child) != dev) 748 return (EINVAL); 749 750 if ((clkctl = bhnd_get_pmu_info(child)) == NULL) 751 panic("no active PMU allocation"); 752 753 BHND_ASSERT_CLKCTL_AVAIL(clkctl); 754 755 sc = device_get_softc(dev); 756 757 if (rsrc > BHND_CCS_ERSRC_MAX) 758 return (EINVAL); 759 760 mask = BHND_CCS_SET_BITS((1<<rsrc), BHND_CCS_ERSRC_REQ); 761 762 /* Clear request */ 763 BHND_CLKCTL_LOCK(clkctl); 764 BHND_CLKCTL_SET_4(clkctl, 0x0, mask); 765 BHND_CLKCTL_UNLOCK(clkctl); 766 767 return (0); 768 } 769 770 /** 771 * Default bhnd(4) bus driver implementation of BHND_BUS_IS_REGION_VALID(). 772 * 773 * This implementation assumes that port and region numbers are 0-indexed and 774 * are allocated non-sparsely, using BHND_BUS_GET_PORT_COUNT() and 775 * BHND_BUS_GET_REGION_COUNT() to determine if @p port and @p region fall 776 * within the defined range. 777 */ 778 static bool 779 bhnd_generic_is_region_valid(device_t dev, device_t child, 780 bhnd_port_type type, u_int port, u_int region) 781 { 782 if (port >= bhnd_get_port_count(child, type)) 783 return (false); 784 785 if (region >= bhnd_get_region_count(child, type, port)) 786 return (false); 787 788 return (true); 789 } 790 791 /** 792 * Default bhnd(4) bus driver implementation of BHND_BUS_GET_NVRAM_VAR(). 793 * 794 * This implementation searches @p dev for a registered NVRAM child device. 795 * 796 * If no NVRAM device is registered with @p dev, the request is delegated to 797 * the BHND_BUS_GET_NVRAM_VAR() method on the parent of @p dev. 798 */ 799 int 800 bhnd_generic_get_nvram_var(device_t dev, device_t child, const char *name, 801 void *buf, size_t *size, bhnd_nvram_type type) 802 { 803 struct bhnd_softc *sc; 804 device_t nvram, parent; 805 int error; 806 807 sc = device_get_softc(dev); 808 809 /* If a NVRAM device is available, consult it first */ 810 nvram = bhnd_retain_provider(child, BHND_SERVICE_NVRAM); 811 if (nvram != NULL) { 812 error = BHND_NVRAM_GETVAR(nvram, name, buf, size, type); 813 bhnd_release_provider(child, nvram, BHND_SERVICE_NVRAM); 814 return (error); 815 } 816 817 /* Otherwise, try to delegate to parent */ 818 if ((parent = device_get_parent(dev)) == NULL) 819 return (ENODEV); 820 821 return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), child, 822 name, buf, size, type)); 823 } 824 825 /** 826 * Default bhnd(4) bus driver implementation of BUS_PRINT_CHILD(). 827 * 828 * This implementation requests the device's struct resource_list via 829 * BUS_GET_RESOURCE_LIST. 830 */ 831 int 832 bhnd_generic_print_child(device_t dev, device_t child) 833 { 834 struct resource_list *rl; 835 int retval = 0; 836 837 retval += bus_print_child_header(dev, child); 838 839 rl = BUS_GET_RESOURCE_LIST(dev, child); 840 841 if (rl != NULL) { 842 retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, 843 "%#jx"); 844 845 retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, 846 "%#jd"); 847 } 848 849 retval += printf(" at core %u", bhnd_get_core_index(child)); 850 851 retval += bus_print_child_domain(dev, child); 852 retval += bus_print_child_footer(dev, child); 853 854 return (retval); 855 } 856 857 /** 858 * Default bhnd(4) bus driver implementation of BUS_PROBE_NOMATCH(). 859 * 860 * This implementation requests the device's struct resource_list via 861 * BUS_GET_RESOURCE_LIST. 862 */ 863 void 864 bhnd_generic_probe_nomatch(device_t dev, device_t child) 865 { 866 struct resource_list *rl; 867 const struct bhnd_nomatch *nm; 868 bool report; 869 870 /* Fetch reporting configuration for this device */ 871 report = true; 872 for (nm = bhnd_nomatch_table; nm->device != BHND_COREID_INVALID; nm++) { 873 if (nm->vendor != bhnd_get_vendor(child)) 874 continue; 875 876 if (nm->device != bhnd_get_device(child)) 877 continue; 878 879 report = false; 880 if (bootverbose && nm->if_verbose) 881 report = true; 882 break; 883 } 884 885 if (!report) 886 return; 887 888 /* Print the non-matched device info */ 889 device_printf(dev, "<%s %s, rev %hhu>", bhnd_get_vendor_name(child), 890 bhnd_get_device_name(child), bhnd_get_hwrev(child)); 891 892 rl = BUS_GET_RESOURCE_LIST(dev, child); 893 if (rl != NULL) { 894 resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#jx"); 895 resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%#jd"); 896 } 897 898 printf(" at core %u (no driver attached)\n", 899 bhnd_get_core_index(child)); 900 } 901 902 /** 903 * Default implementation of BUS_CHILD_PNPINFO_STR(). 904 */ 905 static int 906 bhnd_child_pnpinfo_str(device_t dev, device_t child, char *buf, 907 size_t buflen) 908 { 909 if (device_get_parent(child) != dev) { 910 return (BUS_CHILD_PNPINFO_STR(device_get_parent(dev), child, 911 buf, buflen)); 912 } 913 914 snprintf(buf, buflen, "vendor=0x%hx device=0x%hx rev=0x%hhx", 915 bhnd_get_vendor(child), bhnd_get_device(child), 916 bhnd_get_hwrev(child)); 917 918 return (0); 919 } 920 921 /** 922 * Default implementation of BUS_CHILD_LOCATION_STR(). 923 */ 924 static int 925 bhnd_child_location_str(device_t dev, device_t child, char *buf, 926 size_t buflen) 927 { 928 bhnd_addr_t addr; 929 bhnd_size_t size; 930 931 if (device_get_parent(child) != dev) { 932 return (BUS_CHILD_LOCATION_STR(device_get_parent(dev), child, 933 buf, buflen)); 934 } 935 936 if (bhnd_get_region_addr(child, BHND_PORT_DEVICE, 0, 0, &addr, &size)) { 937 /* No device default port/region */ 938 if (buflen > 0) 939 *buf = '\0'; 940 return (0); 941 } 942 943 snprintf(buf, buflen, "port0.0=0x%llx", (unsigned long long) addr); 944 return (0); 945 } 946 947 /** 948 * Default bhnd(4) bus driver implementation of BUS_CHILD_DELETED(). 949 * 950 * This implementation manages internal bhnd(4) state, and must be called 951 * by subclassing drivers. 952 */ 953 void 954 bhnd_generic_child_deleted(device_t dev, device_t child) 955 { 956 struct bhnd_softc *sc; 957 958 sc = device_get_softc(dev); 959 960 /* Free device info */ 961 if (bhnd_get_pmu_info(child) != NULL) { 962 /* Releasing PMU requests automatically would be nice, 963 * but we can't reference per-core PMU register 964 * resource after driver detach */ 965 panic("%s leaked device pmu state\n", 966 device_get_nameunit(child)); 967 } 968 } 969 970 /** 971 * Helper function for implementing BUS_SUSPEND_CHILD(). 972 * 973 * TODO: Power management 974 * 975 * If @p child is not a direct child of @p dev, suspension is delegated to 976 * the @p dev parent. 977 */ 978 int 979 bhnd_generic_suspend_child(device_t dev, device_t child) 980 { 981 if (device_get_parent(child) != dev) 982 BUS_SUSPEND_CHILD(device_get_parent(dev), child); 983 984 return bus_generic_suspend_child(dev, child); 985 } 986 987 /** 988 * Helper function for implementing BUS_RESUME_CHILD(). 989 * 990 * TODO: Power management 991 * 992 * If @p child is not a direct child of @p dev, suspension is delegated to 993 * the @p dev parent. 994 */ 995 int 996 bhnd_generic_resume_child(device_t dev, device_t child) 997 { 998 if (device_get_parent(child) != dev) 999 BUS_RESUME_CHILD(device_get_parent(dev), child); 1000 1001 return bus_generic_resume_child(dev, child); 1002 } 1003 1004 /** 1005 * Default bhnd(4) bus driver implementation of BUS_SETUP_INTR(). 1006 * 1007 * This implementation of BUS_SETUP_INTR() will delegate interrupt setup 1008 * to the parent of @p dev, if any. 1009 */ 1010 int 1011 bhnd_generic_setup_intr(device_t dev, device_t child, struct resource *irq, 1012 int flags, driver_filter_t *filter, driver_intr_t *intr, void *arg, 1013 void **cookiep) 1014 { 1015 return (bus_generic_setup_intr(dev, child, irq, flags, filter, intr, 1016 arg, cookiep)); 1017 } 1018 1019 /* 1020 * Delegate all indirect I/O to the parent device. When inherited by 1021 * non-bridged bus implementations, resources will never be marked as 1022 * indirect, and these methods will never be called. 1023 */ 1024 #define BHND_IO_READ(_type, _name, _method) \ 1025 static _type \ 1026 bhnd_read_ ## _name (device_t dev, device_t child, \ 1027 struct bhnd_resource *r, bus_size_t offset) \ 1028 { \ 1029 return (BHND_BUS_READ_ ## _method( \ 1030 device_get_parent(dev), child, r, offset)); \ 1031 } 1032 1033 #define BHND_IO_WRITE(_type, _name, _method) \ 1034 static void \ 1035 bhnd_write_ ## _name (device_t dev, device_t child, \ 1036 struct bhnd_resource *r, bus_size_t offset, _type value) \ 1037 { \ 1038 return (BHND_BUS_WRITE_ ## _method( \ 1039 device_get_parent(dev), child, r, offset, \ 1040 value)); \ 1041 } 1042 1043 #define BHND_IO_MISC(_type, _op, _method) \ 1044 static void \ 1045 bhnd_ ## _op (device_t dev, device_t child, \ 1046 struct bhnd_resource *r, bus_size_t offset, _type datap, \ 1047 bus_size_t count) \ 1048 { \ 1049 BHND_BUS_ ## _method(device_get_parent(dev), child, r, \ 1050 offset, datap, count); \ 1051 } 1052 1053 #define BHND_IO_METHODS(_type, _size) \ 1054 BHND_IO_READ(_type, _size, _size) \ 1055 BHND_IO_WRITE(_type, _size, _size) \ 1056 \ 1057 BHND_IO_READ(_type, stream_ ## _size, STREAM_ ## _size) \ 1058 BHND_IO_WRITE(_type, stream_ ## _size, STREAM_ ## _size) \ 1059 \ 1060 BHND_IO_MISC(_type*, read_multi_ ## _size, \ 1061 READ_MULTI_ ## _size) \ 1062 BHND_IO_MISC(_type*, write_multi_ ## _size, \ 1063 WRITE_MULTI_ ## _size) \ 1064 \ 1065 BHND_IO_MISC(_type*, read_multi_stream_ ## _size, \ 1066 READ_MULTI_STREAM_ ## _size) \ 1067 BHND_IO_MISC(_type*, write_multi_stream_ ## _size, \ 1068 WRITE_MULTI_STREAM_ ## _size) \ 1069 \ 1070 BHND_IO_MISC(_type, set_multi_ ## _size, SET_MULTI_ ## _size) \ 1071 BHND_IO_MISC(_type, set_region_ ## _size, SET_REGION_ ## _size) \ 1072 \ 1073 BHND_IO_MISC(_type*, read_region_ ## _size, \ 1074 READ_REGION_ ## _size) \ 1075 BHND_IO_MISC(_type*, write_region_ ## _size, \ 1076 WRITE_REGION_ ## _size) \ 1077 \ 1078 BHND_IO_MISC(_type*, read_region_stream_ ## _size, \ 1079 READ_REGION_STREAM_ ## _size) \ 1080 BHND_IO_MISC(_type*, write_region_stream_ ## _size, \ 1081 WRITE_REGION_STREAM_ ## _size) \ 1082 1083 BHND_IO_METHODS(uint8_t, 1); 1084 BHND_IO_METHODS(uint16_t, 2); 1085 BHND_IO_METHODS(uint32_t, 4); 1086 1087 static void 1088 bhnd_barrier(device_t dev, device_t child, struct bhnd_resource *r, 1089 bus_size_t offset, bus_size_t length, int flags) 1090 { 1091 BHND_BUS_BARRIER(device_get_parent(dev), child, r, offset, length, 1092 flags); 1093 } 1094 1095 static device_method_t bhnd_methods[] = { 1096 /* Device interface */ \ 1097 DEVMETHOD(device_attach, bhnd_generic_attach), 1098 DEVMETHOD(device_detach, bhnd_generic_detach), 1099 DEVMETHOD(device_shutdown, bhnd_generic_shutdown), 1100 DEVMETHOD(device_suspend, bhnd_generic_suspend), 1101 DEVMETHOD(device_resume, bhnd_generic_resume), 1102 1103 /* Bus interface */ 1104 DEVMETHOD(bus_child_deleted, bhnd_generic_child_deleted), 1105 DEVMETHOD(bus_probe_nomatch, bhnd_generic_probe_nomatch), 1106 DEVMETHOD(bus_print_child, bhnd_generic_print_child), 1107 DEVMETHOD(bus_child_pnpinfo_str, bhnd_child_pnpinfo_str), 1108 DEVMETHOD(bus_child_location_str, bhnd_child_location_str), 1109 1110 DEVMETHOD(bus_suspend_child, bhnd_generic_suspend_child), 1111 DEVMETHOD(bus_resume_child, bhnd_generic_resume_child), 1112 1113 DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), 1114 DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), 1115 DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource), 1116 DEVMETHOD(bus_alloc_resource, bus_generic_rl_alloc_resource), 1117 DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource), 1118 DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource), 1119 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 1120 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 1121 1122 DEVMETHOD(bus_setup_intr, bhnd_generic_setup_intr), 1123 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 1124 DEVMETHOD(bus_config_intr, bus_generic_config_intr), 1125 DEVMETHOD(bus_bind_intr, bus_generic_bind_intr), 1126 DEVMETHOD(bus_describe_intr, bus_generic_describe_intr), 1127 1128 DEVMETHOD(bus_get_dma_tag, bus_generic_get_dma_tag), 1129 1130 /* BHND interface */ 1131 DEVMETHOD(bhnd_bus_get_chipid, bhnd_bus_generic_get_chipid), 1132 DEVMETHOD(bhnd_bus_is_hw_disabled, bhnd_bus_generic_is_hw_disabled), 1133 1134 DEVMETHOD(bhnd_bus_get_probe_order, bhnd_generic_get_probe_order), 1135 1136 DEVMETHOD(bhnd_bus_alloc_pmu, bhnd_generic_alloc_pmu), 1137 DEVMETHOD(bhnd_bus_release_pmu, bhnd_generic_release_pmu), 1138 DEVMETHOD(bhnd_bus_request_clock, bhnd_generic_request_clock), 1139 DEVMETHOD(bhnd_bus_enable_clocks, bhnd_generic_enable_clocks), 1140 DEVMETHOD(bhnd_bus_request_ext_rsrc, bhnd_generic_request_ext_rsrc), 1141 DEVMETHOD(bhnd_bus_release_ext_rsrc, bhnd_generic_release_ext_rsrc), 1142 DEVMETHOD(bhnd_bus_get_clock_latency, bhnd_generic_get_clock_latency), 1143 DEVMETHOD(bhnd_bus_get_clock_freq, bhnd_generic_get_clock_freq), 1144 1145 DEVMETHOD(bhnd_bus_is_region_valid, bhnd_generic_is_region_valid), 1146 DEVMETHOD(bhnd_bus_get_nvram_var, bhnd_generic_get_nvram_var), 1147 1148 /* BHND interface (bus I/O) */ 1149 DEVMETHOD(bhnd_bus_read_1, bhnd_read_1), 1150 DEVMETHOD(bhnd_bus_read_2, bhnd_read_2), 1151 DEVMETHOD(bhnd_bus_read_4, bhnd_read_4), 1152 DEVMETHOD(bhnd_bus_write_1, bhnd_write_1), 1153 DEVMETHOD(bhnd_bus_write_2, bhnd_write_2), 1154 DEVMETHOD(bhnd_bus_write_4, bhnd_write_4), 1155 1156 DEVMETHOD(bhnd_bus_read_stream_1, bhnd_read_stream_1), 1157 DEVMETHOD(bhnd_bus_read_stream_2, bhnd_read_stream_2), 1158 DEVMETHOD(bhnd_bus_read_stream_4, bhnd_read_stream_4), 1159 DEVMETHOD(bhnd_bus_write_stream_1, bhnd_write_stream_1), 1160 DEVMETHOD(bhnd_bus_write_stream_2, bhnd_write_stream_2), 1161 DEVMETHOD(bhnd_bus_write_stream_4, bhnd_write_stream_4), 1162 1163 DEVMETHOD(bhnd_bus_read_multi_1, bhnd_read_multi_1), 1164 DEVMETHOD(bhnd_bus_read_multi_2, bhnd_read_multi_2), 1165 DEVMETHOD(bhnd_bus_read_multi_4, bhnd_read_multi_4), 1166 DEVMETHOD(bhnd_bus_write_multi_1, bhnd_write_multi_1), 1167 DEVMETHOD(bhnd_bus_write_multi_2, bhnd_write_multi_2), 1168 DEVMETHOD(bhnd_bus_write_multi_4, bhnd_write_multi_4), 1169 1170 DEVMETHOD(bhnd_bus_read_multi_stream_1, bhnd_read_multi_stream_1), 1171 DEVMETHOD(bhnd_bus_read_multi_stream_2, bhnd_read_multi_stream_2), 1172 DEVMETHOD(bhnd_bus_read_multi_stream_4, bhnd_read_multi_stream_4), 1173 DEVMETHOD(bhnd_bus_write_multi_stream_1,bhnd_write_multi_stream_1), 1174 DEVMETHOD(bhnd_bus_write_multi_stream_2,bhnd_write_multi_stream_2), 1175 DEVMETHOD(bhnd_bus_write_multi_stream_4,bhnd_write_multi_stream_4), 1176 1177 DEVMETHOD(bhnd_bus_set_multi_1, bhnd_set_multi_1), 1178 DEVMETHOD(bhnd_bus_set_multi_2, bhnd_set_multi_2), 1179 DEVMETHOD(bhnd_bus_set_multi_4, bhnd_set_multi_4), 1180 1181 DEVMETHOD(bhnd_bus_set_region_1, bhnd_set_region_1), 1182 DEVMETHOD(bhnd_bus_set_region_2, bhnd_set_region_2), 1183 DEVMETHOD(bhnd_bus_set_region_4, bhnd_set_region_4), 1184 1185 DEVMETHOD(bhnd_bus_read_region_1, bhnd_read_region_1), 1186 DEVMETHOD(bhnd_bus_read_region_2, bhnd_read_region_2), 1187 DEVMETHOD(bhnd_bus_read_region_4, bhnd_read_region_4), 1188 DEVMETHOD(bhnd_bus_write_region_1, bhnd_write_region_1), 1189 DEVMETHOD(bhnd_bus_write_region_2, bhnd_write_region_2), 1190 DEVMETHOD(bhnd_bus_write_region_4, bhnd_write_region_4), 1191 1192 DEVMETHOD(bhnd_bus_read_region_stream_1,bhnd_read_region_stream_1), 1193 DEVMETHOD(bhnd_bus_read_region_stream_2,bhnd_read_region_stream_2), 1194 DEVMETHOD(bhnd_bus_read_region_stream_4,bhnd_read_region_stream_4), 1195 DEVMETHOD(bhnd_bus_write_region_stream_1, bhnd_write_region_stream_1), 1196 DEVMETHOD(bhnd_bus_write_region_stream_2, bhnd_write_region_stream_2), 1197 DEVMETHOD(bhnd_bus_write_region_stream_4, bhnd_write_region_stream_4), 1198 1199 DEVMETHOD(bhnd_bus_barrier, bhnd_barrier), 1200 1201 DEVMETHOD_END 1202 }; 1203 1204 devclass_t bhnd_devclass; /**< bhnd bus. */ 1205 devclass_t bhnd_hostb_devclass; /**< bhnd bus host bridge. */ 1206 devclass_t bhnd_nvram_devclass; /**< bhnd NVRAM device */ 1207 1208 DEFINE_CLASS_0(bhnd, bhnd_driver, bhnd_methods, sizeof(struct bhnd_softc)); 1209 MODULE_VERSION(bhnd, 1); 1210