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