2 * Copyright (c) 2015-2016 Landon Fuller <landonf@FreeBSD.org>
3 * Copyright (c) 2017 The FreeBSD Foundation
6 * Portions of this software were developed by Landon Fuller
7 * under sponsorship from the FreeBSD Foundation.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer,
14 * without modification.
15 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
16 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
17 * redistribution must be conditioned upon including a substantially
18 * similar Disclaimer requirement for further binary redistribution.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
24 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
25 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
26 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
29 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGES.
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
38 * Broadcom Home Networking Division (HND) Bus Driver.
40 * The Broadcom HND family of devices consists of both SoCs and host-connected
41 * networking chipsets containing a common family of Broadcom IP cores,
42 * including an integrated MIPS and/or ARM cores.
44 * HND devices expose a nearly identical interface whether accessible over a
45 * native SoC interconnect, or when connected via a host interface such as
46 * PCIe. As a result, the majority of hardware support code should be re-usable
47 * across host drivers for HND networking chipsets, as well as FreeBSD support
48 * for Broadcom MIPS/ARM HND SoCs.
50 * Earlier HND models used the siba(4) on-chip interconnect, while later models
51 * use bcma(4); the programming model is almost entirely independent
52 * of the actual underlying interconect.
55 #include <sys/param.h>
56 #include <sys/kernel.h>
58 #include <sys/module.h>
59 #include <sys/systm.h>
61 #include <machine/bus.h>
63 #include <machine/resource.h>
65 #include <dev/bhnd/cores/pmu/bhnd_pmu.h>
67 #include "bhnd_chipc_if.h"
68 #include "bhnd_nvram_if.h"
74 #include "bhnd_private.h"
76 MALLOC_DEFINE(M_BHND, "bhnd", "bhnd bus data structures");
79 * bhnd_generic_probe_nomatch() reporting configuration.
81 static const struct bhnd_nomatch {
82 uint16_t vendor; /**< core designer */
83 uint16_t device; /**< core id */
84 bool if_verbose; /**< print when bootverbose is set. */
85 } bhnd_nomatch_table[] = {
86 { BHND_MFGID_ARM, BHND_COREID_OOB_ROUTER, true },
87 { BHND_MFGID_ARM, BHND_COREID_EROM, true },
88 { BHND_MFGID_ARM, BHND_COREID_PL301, true },
89 { BHND_MFGID_ARM, BHND_COREID_APB_BRIDGE, true },
90 { BHND_MFGID_ARM, BHND_COREID_AXI_UNMAPPED, false },
92 { BHND_MFGID_INVALID, BHND_COREID_INVALID, false }
95 static int bhnd_delete_children(struct bhnd_softc *sc);
98 * Default bhnd(4) bus driver implementation of DEVICE_ATTACH().
100 * This implementation calls device_probe_and_attach() for each of the device's
101 * children, in bhnd probe order.
104 bhnd_generic_attach(device_t dev)
106 struct bhnd_softc *sc;
109 if (device_is_attached(dev))
112 sc = device_get_softc(dev);
115 /* Probe and attach all children */
116 if ((error = bhnd_bus_probe_children(dev))) {
117 bhnd_delete_children(sc);
125 * Detach and delete all children, in reverse of their attach order.
128 bhnd_delete_children(struct bhnd_softc *sc)
134 /* Fetch children in detach order */
135 error = bhnd_bus_get_children(sc->dev, &devs, &ndevs,
136 BHND_DEVICE_ORDER_DETACH);
141 for (int i = 0; i < ndevs; i++) {
142 device_t child = devs[i];
144 /* Terminate on first error */
145 if ((error = device_delete_child(sc->dev, child)))
150 bhnd_bus_free_children(devs);
155 * Default bhnd(4) bus driver implementation of DEVICE_DETACH().
157 * This implementation calls device_detach() for each of the device's
158 * children, in reverse bhnd probe order, terminating if any call to
159 * device_detach() fails.
162 bhnd_generic_detach(device_t dev)
164 struct bhnd_softc *sc;
167 if (!device_is_attached(dev))
170 sc = device_get_softc(dev);
172 if ((error = bhnd_delete_children(sc)))
179 * Default bhnd(4) bus driver implementation of DEVICE_SHUTDOWN().
181 * This implementation calls device_shutdown() for each of the device's
182 * children, in reverse bhnd probe order, terminating if any call to
183 * device_shutdown() fails.
186 bhnd_generic_shutdown(device_t dev)
192 if (!device_is_attached(dev))
195 /* Fetch children in detach order */
196 error = bhnd_bus_get_children(dev, &devs, &ndevs,
197 BHND_DEVICE_ORDER_DETACH);
201 /* Perform shutdown */
202 for (int i = 0; i < ndevs; i++) {
203 device_t child = devs[i];
205 /* Terminate on first error */
206 if ((error = device_shutdown(child)))
211 bhnd_bus_free_children(devs);
216 * Default bhnd(4) bus driver implementation of DEVICE_RESUME().
218 * This implementation calls BUS_RESUME_CHILD() for each of the device's
219 * children in bhnd probe order, terminating if any call to BUS_RESUME_CHILD()
223 bhnd_generic_resume(device_t dev)
229 if (!device_is_attached(dev))
232 /* Fetch children in attach order */
233 error = bhnd_bus_get_children(dev, &devs, &ndevs,
234 BHND_DEVICE_ORDER_ATTACH);
239 for (int i = 0; i < ndevs; i++) {
240 device_t child = devs[i];
242 /* Terminate on first error */
243 if ((error = BUS_RESUME_CHILD(device_get_parent(child), child)))
248 bhnd_bus_free_children(devs);
253 * Default bhnd(4) bus driver implementation of DEVICE_SUSPEND().
255 * This implementation calls BUS_SUSPEND_CHILD() for each of the device's
256 * children in reverse bhnd probe order. If any call to BUS_SUSPEND_CHILD()
257 * fails, the suspend operation is terminated and any devices that were
258 * suspended are resumed immediately by calling their BUS_RESUME_CHILD()
262 bhnd_generic_suspend(device_t dev)
268 if (!device_is_attached(dev))
271 /* Fetch children in detach order */
272 error = bhnd_bus_get_children(dev, &devs, &ndevs,
273 BHND_DEVICE_ORDER_DETACH);
277 /* Perform suspend */
278 for (int i = 0; i < ndevs; i++) {
279 device_t child = devs[i];
280 error = BUS_SUSPEND_CHILD(device_get_parent(child), child);
282 /* On error, resume suspended devices and then terminate */
284 for (int j = 0; j < i; j++) {
285 BUS_RESUME_CHILD(device_get_parent(devs[j]),
294 bhnd_bus_free_children(devs);
299 * Default bhnd(4) bus driver implementation of BHND_BUS_GET_PROBE_ORDER().
301 * This implementation determines probe ordering based on the device's class
302 * and other properties, including whether the device is serving as a host
306 bhnd_generic_get_probe_order(device_t dev, device_t child)
308 switch (bhnd_get_class(child)) {
309 case BHND_DEVCLASS_CC:
310 /* Must be early enough to provide NVRAM access to the
312 return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_FIRST);
314 case BHND_DEVCLASS_CC_B:
316 case BHND_DEVCLASS_PMU:
317 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_EARLY);
319 case BHND_DEVCLASS_SOC_ROUTER:
320 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LATE);
322 case BHND_DEVCLASS_SOC_BRIDGE:
323 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LAST);
325 case BHND_DEVCLASS_CPU:
326 return (BHND_PROBE_CPU + BHND_PROBE_ORDER_FIRST);
328 case BHND_DEVCLASS_RAM:
330 case BHND_DEVCLASS_MEMC:
331 return (BHND_PROBE_CPU + BHND_PROBE_ORDER_EARLY);
333 case BHND_DEVCLASS_NVRAM:
334 return (BHND_PROBE_RESOURCE + BHND_PROBE_ORDER_EARLY);
336 case BHND_DEVCLASS_PCI:
337 case BHND_DEVCLASS_PCIE:
338 case BHND_DEVCLASS_PCCARD:
339 case BHND_DEVCLASS_ENET:
340 case BHND_DEVCLASS_ENET_MAC:
341 case BHND_DEVCLASS_ENET_PHY:
342 case BHND_DEVCLASS_WLAN:
343 case BHND_DEVCLASS_WLAN_MAC:
344 case BHND_DEVCLASS_WLAN_PHY:
345 case BHND_DEVCLASS_EROM:
346 case BHND_DEVCLASS_OTHER:
347 case BHND_DEVCLASS_INVALID:
348 if (bhnd_bus_find_hostb_device(dev) == child)
349 return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_EARLY);
351 return (BHND_PROBE_DEFAULT);
353 return (BHND_PROBE_DEFAULT);
358 * Default bhnd(4) bus driver implementation of BHND_BUS_ALLOC_PMU().
361 bhnd_generic_alloc_pmu(device_t dev, device_t child)
363 struct bhnd_softc *sc;
364 struct bhnd_resource *r;
365 struct bhnd_core_clkctl *clkctl;
366 struct resource_list *rl;
367 struct resource_list_entry *rle;
375 GIANT_REQUIRED; /* for newbus */
377 if (device_get_parent(child) != dev)
380 sc = device_get_softc(dev);
381 clkctl = bhnd_get_pmu_info(child);
382 pmu_regs = BHND_CLK_CTL_ST;
384 /* already allocated? */
385 if (clkctl != NULL) {
386 panic("duplicate PMU allocation for %s",
387 device_get_nameunit(child));
390 /* Determine address+size of the core's PMU register block */
391 error = bhnd_get_region_addr(child, BHND_PORT_DEVICE, 0, 0, &r_addr,
394 device_printf(sc->dev, "error fetching register block info for "
395 "%s: %d\n", device_get_nameunit(child), error);
399 if (r_size < (pmu_regs + sizeof(uint32_t))) {
400 device_printf(sc->dev, "pmu offset %#jx would overrun %s "
401 "register block\n", (uintmax_t)pmu_regs,
402 device_get_nameunit(child));
406 /* Locate actual resource containing the core's register block */
407 if ((rl = BUS_GET_RESOURCE_LIST(dev, child)) == NULL) {
408 device_printf(dev, "NULL resource list returned for %s\n",
409 device_get_nameunit(child));
413 if ((rle = resource_list_find(rl, SYS_RES_MEMORY, 0)) == NULL) {
414 device_printf(dev, "cannot locate core register resource "
415 "for %s\n", device_get_nameunit(child));
419 if (rle->res == NULL) {
420 device_printf(dev, "core register resource unallocated for "
421 "%s\n", device_get_nameunit(child));
425 if (r_addr+pmu_regs < rman_get_start(rle->res) ||
426 r_addr+pmu_regs >= rman_get_end(rle->res))
428 device_printf(dev, "core register resource does not map PMU "
429 "registers at %#jx\n for %s\n", r_addr+pmu_regs,
430 device_get_nameunit(child));
434 /* Adjust PMU register offset relative to the actual start address
435 * of the core's register block allocation.
437 * XXX: The saved offset will be invalid if bus_adjust_resource is
438 * used to modify the resource's start address.
440 if (rman_get_start(rle->res) > r_addr)
441 pmu_regs -= rman_get_start(rle->res) - r_addr;
443 pmu_regs -= r_addr - rman_get_start(rle->res);
445 /* Retain a PMU reference for the clkctl instance state */
446 pmu_dev = bhnd_retain_provider(child, BHND_SERVICE_PMU);
447 if (pmu_dev == NULL) {
448 device_printf(sc->dev, "PMU not found\n");
452 /* Fetch the maximum transition latency from our PMU */
453 max_latency = bhnd_pmu_get_max_transition_latency(pmu_dev);
455 /* Allocate a new bhnd_resource wrapping the standard resource we
456 * fetched from the resource list; we'll free this in
457 * bhnd_generic_release_pmu() */
458 r = malloc(sizeof(struct bhnd_resource), M_BHND, M_NOWAIT);
460 bhnd_release_provider(child, pmu_dev, BHND_SERVICE_PMU);
465 r->direct = ((rman_get_flags(rle->res) & RF_ACTIVE) != 0);
467 /* Allocate the clkctl instance */
468 clkctl = bhnd_alloc_core_clkctl(child, pmu_dev, r, pmu_regs,
470 if (clkctl == NULL) {
472 bhnd_release_provider(child, pmu_dev, BHND_SERVICE_PMU);
476 bhnd_set_pmu_info(child, clkctl);
481 * Default bhnd(4) bus driver implementation of BHND_BUS_RELEASE_PMU().
484 bhnd_generic_release_pmu(device_t dev, device_t child)
486 struct bhnd_softc *sc;
487 struct bhnd_core_clkctl *clkctl;
488 struct bhnd_resource *r;
491 GIANT_REQUIRED; /* for newbus */
493 sc = device_get_softc(dev);
495 if (device_get_parent(child) != dev)
498 clkctl = bhnd_get_pmu_info(child);
500 panic("pmu over-release for %s", device_get_nameunit(child));
502 /* Clear all FORCE, AREQ, and ERSRC flags, unless we're already in
503 * RESET. Suspending a core clears clkctl automatically (and attempting
504 * to access the PMU registers in a suspended core will trigger a
505 * system livelock). */
506 if (!bhnd_is_hw_suspended(clkctl->cc_dev)) {
507 BHND_CLKCTL_LOCK(clkctl);
509 /* Clear all FORCE, AREQ, and ERSRC flags */
510 BHND_CLKCTL_SET_4(clkctl, 0x0, BHND_CCS_FORCE_MASK |
511 BHND_CCS_AREQ_MASK | BHND_CCS_ERSRC_REQ_MASK);
513 BHND_CLKCTL_UNLOCK(clkctl);
516 /* Clear child's PMU info reference */
517 bhnd_set_pmu_info(child, NULL);
519 /* Before freeing the clkctl instance, save a pointer to resources we
520 * need to clean up manually */
522 pmu_dev = clkctl->cc_pmu_dev;
524 /* Free the clkctl instance */
525 bhnd_free_core_clkctl(clkctl);
527 /* Free the child's bhnd resource wrapper */
530 /* Release the child's PMU provider reference */
531 bhnd_release_provider(child, pmu_dev, BHND_SERVICE_PMU);
537 * Default bhnd(4) bus driver implementation of BHND_BUS_GET_CLOCK_LATENCY().
540 bhnd_generic_get_clock_latency(device_t dev, device_t child, bhnd_clock clock,
543 struct bhnd_core_clkctl *clkctl;
545 if (device_get_parent(child) != dev)
548 if ((clkctl = bhnd_get_pmu_info(child)) == NULL)
549 panic("no active PMU allocation");
551 return (bhnd_pmu_get_clock_latency(clkctl->cc_pmu_dev, clock, latency));
555 * Default bhnd(4) bus driver implementation of BHND_BUS_GET_CLOCK_FREQ().
558 bhnd_generic_get_clock_freq(device_t dev, device_t child, bhnd_clock clock,
561 struct bhnd_core_clkctl *clkctl;
563 if (device_get_parent(child) != dev)
566 if ((clkctl = bhnd_get_pmu_info(child)) == NULL)
567 panic("no active PMU allocation");
569 return (bhnd_pmu_get_clock_freq(clkctl->cc_pmu_dev, clock, freq));
573 * Default bhnd(4) bus driver implementation of BHND_BUS_REQUEST_CLOCK().
576 bhnd_generic_request_clock(device_t dev, device_t child, bhnd_clock clock)
578 struct bhnd_softc *sc;
579 struct bhnd_core_clkctl *clkctl;
584 sc = device_get_softc(dev);
586 if (device_get_parent(child) != dev)
589 if ((clkctl = bhnd_get_pmu_info(child)) == NULL)
590 panic("no active PMU allocation");
592 BHND_ASSERT_CLKCTL_AVAIL(clkctl);
601 req |= BHND_CCS_FORCEILP;
604 req |= BHND_CCS_FORCEALP;
605 avail |= BHND_CCS_ALPAVAIL;
608 req |= BHND_CCS_FORCEHT;
609 avail |= BHND_CCS_HTAVAIL;
612 device_printf(dev, "%s requested unknown clock: %#x\n",
613 device_get_nameunit(clkctl->cc_dev), clock);
617 BHND_CLKCTL_LOCK(clkctl);
620 BHND_CLKCTL_SET_4(clkctl, req, BHND_CCS_FORCE_MASK);
622 /* Wait for clock availability */
623 error = bhnd_core_clkctl_wait(clkctl, avail, avail);
625 BHND_CLKCTL_UNLOCK(clkctl);
631 * Default bhnd(4) bus driver implementation of BHND_BUS_ENABLE_CLOCKS().
634 bhnd_generic_enable_clocks(device_t dev, device_t child, uint32_t clocks)
636 struct bhnd_softc *sc;
637 struct bhnd_core_clkctl *clkctl;
642 sc = device_get_softc(dev);
644 if (device_get_parent(child) != dev)
647 if ((clkctl = bhnd_get_pmu_info(child)) == NULL)
648 panic("no active PMU allocation");
650 BHND_ASSERT_CLKCTL_AVAIL(clkctl);
652 sc = device_get_softc(dev);
657 /* Build clock request flags */
658 if (clocks & BHND_CLOCK_DYN) /* nothing to enable */
659 clocks &= ~BHND_CLOCK_DYN;
661 if (clocks & BHND_CLOCK_ILP) /* nothing to enable */
662 clocks &= ~BHND_CLOCK_ILP;
664 if (clocks & BHND_CLOCK_ALP) {
665 req |= BHND_CCS_ALPAREQ;
666 avail |= BHND_CCS_ALPAVAIL;
667 clocks &= ~BHND_CLOCK_ALP;
670 if (clocks & BHND_CLOCK_HT) {
671 req |= BHND_CCS_HTAREQ;
672 avail |= BHND_CCS_HTAVAIL;
673 clocks &= ~BHND_CLOCK_HT;
676 /* Check for unknown clock values */
678 device_printf(dev, "%s requested unknown clocks: %#x\n",
679 device_get_nameunit(clkctl->cc_dev), clocks);
683 BHND_CLKCTL_LOCK(clkctl);
686 BHND_CLKCTL_SET_4(clkctl, req, BHND_CCS_AREQ_MASK);
688 /* Wait for clock availability */
689 error = bhnd_core_clkctl_wait(clkctl, avail, avail);
691 BHND_CLKCTL_UNLOCK(clkctl);
697 * Default bhnd(4) bus driver implementation of BHND_BUS_REQUEST_EXT_RSRC().
700 bhnd_generic_request_ext_rsrc(device_t dev, device_t child, u_int rsrc)
702 struct bhnd_softc *sc;
703 struct bhnd_core_clkctl *clkctl;
708 sc = device_get_softc(dev);
710 if (device_get_parent(child) != dev)
713 if ((clkctl = bhnd_get_pmu_info(child)) == NULL)
714 panic("no active PMU allocation");
716 BHND_ASSERT_CLKCTL_AVAIL(clkctl);
718 sc = device_get_softc(dev);
720 if (rsrc > BHND_CCS_ERSRC_MAX)
723 req = BHND_CCS_SET_BITS((1<<rsrc), BHND_CCS_ERSRC_REQ);
724 avail = BHND_CCS_SET_BITS((1<<rsrc), BHND_CCS_ERSRC_STS);
726 BHND_CLKCTL_LOCK(clkctl);
729 BHND_CLKCTL_SET_4(clkctl, req, req);
731 /* Wait for resource availability */
732 error = bhnd_core_clkctl_wait(clkctl, avail, avail);
734 BHND_CLKCTL_UNLOCK(clkctl);
740 * Default bhnd(4) bus driver implementation of BHND_BUS_RELEASE_EXT_RSRC().
743 bhnd_generic_release_ext_rsrc(device_t dev, device_t child, u_int rsrc)
745 struct bhnd_softc *sc;
746 struct bhnd_core_clkctl *clkctl;
749 sc = device_get_softc(dev);
751 if (device_get_parent(child) != dev)
754 if ((clkctl = bhnd_get_pmu_info(child)) == NULL)
755 panic("no active PMU allocation");
758 BHND_ASSERT_CLKCTL_AVAIL(clkctl);
760 sc = device_get_softc(dev);
762 if (rsrc > BHND_CCS_ERSRC_MAX)
765 mask = BHND_CCS_SET_BITS((1<<rsrc), BHND_CCS_ERSRC_REQ);
768 BHND_CLKCTL_LOCK(clkctl);
769 BHND_CLKCTL_SET_4(clkctl, 0x0, mask);
770 BHND_CLKCTL_UNLOCK(clkctl);
776 * Default bhnd(4) bus driver implementation of BHND_BUS_IS_REGION_VALID().
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.
784 bhnd_generic_is_region_valid(device_t dev, device_t child,
785 bhnd_port_type type, u_int port, u_int region)
787 if (port >= bhnd_get_port_count(child, type))
790 if (region >= bhnd_get_region_count(child, type, port))
797 * Default bhnd(4) bus driver implementation of BHND_BUS_GET_NVRAM_VAR().
799 * This implementation searches @p dev for a registered NVRAM child device.
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.
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)
808 struct bhnd_softc *sc;
809 device_t nvram, parent;
812 sc = device_get_softc(dev);
814 /* If a NVRAM device is available, consult it first */
815 nvram = bhnd_retain_provider(child, BHND_SERVICE_NVRAM);
817 error = BHND_NVRAM_GETVAR(nvram, name, buf, size, type);
818 bhnd_release_provider(child, nvram, BHND_SERVICE_NVRAM);
822 /* Otherwise, try to delegate to parent */
823 if ((parent = device_get_parent(dev)) == NULL)
826 return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), child,
827 name, buf, size, type));
831 * Default bhnd(4) bus driver implementation of BUS_PRINT_CHILD().
833 * This implementation requests the device's struct resource_list via
834 * BUS_GET_RESOURCE_LIST.
837 bhnd_generic_print_child(device_t dev, device_t child)
839 struct resource_list *rl;
842 retval += bus_print_child_header(dev, child);
844 rl = BUS_GET_RESOURCE_LIST(dev, child);
848 retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY,
851 retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ,
855 retval += printf(" at core %u", bhnd_get_core_index(child));
857 retval += bus_print_child_domain(dev, child);
858 retval += bus_print_child_footer(dev, child);
864 * Default bhnd(4) bus driver implementation of BUS_PROBE_NOMATCH().
866 * This implementation requests the device's struct resource_list via
867 * BUS_GET_RESOURCE_LIST.
870 bhnd_generic_probe_nomatch(device_t dev, device_t child)
872 struct resource_list *rl;
873 const struct bhnd_nomatch *nm;
876 /* Fetch reporting configuration for this device */
878 for (nm = bhnd_nomatch_table; nm->device != BHND_COREID_INVALID; nm++) {
879 if (nm->vendor != bhnd_get_vendor(child))
882 if (nm->device != bhnd_get_device(child))
886 if (bootverbose && nm->if_verbose)
894 /* Print the non-matched device info */
895 device_printf(dev, "<%s %s, rev %hhu>", bhnd_get_vendor_name(child),
896 bhnd_get_device_name(child), bhnd_get_hwrev(child));
898 rl = BUS_GET_RESOURCE_LIST(dev, child);
900 resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#jx");
901 resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%#jd");
904 printf(" at core %u (no driver attached)\n",
905 bhnd_get_core_index(child));
909 * Default implementation of BUS_CHILD_PNPINFO_STR().
912 bhnd_child_pnpinfo_str(device_t dev, device_t child, char *buf,
915 if (device_get_parent(child) != dev) {
916 return (BUS_CHILD_PNPINFO_STR(device_get_parent(dev), child,
920 snprintf(buf, buflen, "vendor=0x%hx device=0x%hx rev=0x%hhx",
921 bhnd_get_vendor(child), bhnd_get_device(child),
922 bhnd_get_hwrev(child));
928 * Default implementation of BUS_CHILD_LOCATION_STR().
931 bhnd_child_location_str(device_t dev, device_t child, char *buf,
937 if (device_get_parent(child) != dev) {
938 return (BUS_CHILD_LOCATION_STR(device_get_parent(dev), child,
943 if (bhnd_get_region_addr(child, BHND_PORT_DEVICE, 0, 0, &addr, &size)) {
944 /* No device default port/region */
950 snprintf(buf, buflen, "port0.0=0x%llx", (unsigned long long) addr);
955 * Default bhnd(4) bus driver implementation of BUS_CHILD_DELETED().
957 * This implementation manages internal bhnd(4) state, and must be called
958 * by subclassing drivers.
961 bhnd_generic_child_deleted(device_t dev, device_t child)
963 struct bhnd_softc *sc;
965 sc = device_get_softc(dev);
967 /* Free device info */
968 if (bhnd_get_pmu_info(child) != NULL) {
969 /* Releasing PMU requests automatically would be nice,
970 * but we can't reference per-core PMU register
971 * resource after driver detach */
972 panic("%s leaked device pmu state\n",
973 device_get_nameunit(child));
978 * Helper function for implementing BUS_SUSPEND_CHILD().
980 * TODO: Power management
982 * If @p child is not a direct child of @p dev, suspension is delegated to
986 bhnd_generic_suspend_child(device_t dev, device_t child)
988 if (device_get_parent(child) != dev)
989 BUS_SUSPEND_CHILD(device_get_parent(dev), child);
991 return bus_generic_suspend_child(dev, child);
995 * Helper function for implementing BUS_RESUME_CHILD().
997 * TODO: Power management
999 * If @p child is not a direct child of @p dev, suspension is delegated to
1000 * the @p dev parent.
1003 bhnd_generic_resume_child(device_t dev, device_t child)
1005 if (device_get_parent(child) != dev)
1006 BUS_RESUME_CHILD(device_get_parent(dev), child);
1008 return bus_generic_resume_child(dev, child);
1013 * Default bhnd(4) bus driver implementation of BUS_SETUP_INTR().
1015 * This implementation of BUS_SETUP_INTR() will delegate interrupt setup
1016 * to the parent of @p dev, if any.
1019 bhnd_generic_setup_intr(device_t dev, device_t child, struct resource *irq,
1020 int flags, driver_filter_t *filter, driver_intr_t *intr, void *arg,
1023 return (bus_generic_setup_intr(dev, child, irq, flags, filter, intr,
1028 * Delegate all indirect I/O to the parent device. When inherited by
1029 * non-bridged bus implementations, resources will never be marked as
1030 * indirect, and these methods will never be called.
1032 #define BHND_IO_READ(_type, _name, _method) \
1034 bhnd_read_ ## _name (device_t dev, device_t child, \
1035 struct bhnd_resource *r, bus_size_t offset) \
1037 return (BHND_BUS_READ_ ## _method( \
1038 device_get_parent(dev), child, r, offset)); \
1041 #define BHND_IO_WRITE(_type, _name, _method) \
1043 bhnd_write_ ## _name (device_t dev, device_t child, \
1044 struct bhnd_resource *r, bus_size_t offset, _type value) \
1046 return (BHND_BUS_WRITE_ ## _method( \
1047 device_get_parent(dev), child, r, offset, \
1051 #define BHND_IO_MISC(_type, _op, _method) \
1053 bhnd_ ## _op (device_t dev, device_t child, \
1054 struct bhnd_resource *r, bus_size_t offset, _type datap, \
1057 BHND_BUS_ ## _method(device_get_parent(dev), child, r, \
1058 offset, datap, count); \
1061 #define BHND_IO_METHODS(_type, _size) \
1062 BHND_IO_READ(_type, _size, _size) \
1063 BHND_IO_WRITE(_type, _size, _size) \
1065 BHND_IO_READ(_type, stream_ ## _size, STREAM_ ## _size) \
1066 BHND_IO_WRITE(_type, stream_ ## _size, STREAM_ ## _size) \
1068 BHND_IO_MISC(_type*, read_multi_ ## _size, \
1069 READ_MULTI_ ## _size) \
1070 BHND_IO_MISC(_type*, write_multi_ ## _size, \
1071 WRITE_MULTI_ ## _size) \
1073 BHND_IO_MISC(_type*, read_multi_stream_ ## _size, \
1074 READ_MULTI_STREAM_ ## _size) \
1075 BHND_IO_MISC(_type*, write_multi_stream_ ## _size, \
1076 WRITE_MULTI_STREAM_ ## _size) \
1078 BHND_IO_MISC(_type, set_multi_ ## _size, SET_MULTI_ ## _size) \
1079 BHND_IO_MISC(_type, set_region_ ## _size, SET_REGION_ ## _size) \
1081 BHND_IO_MISC(_type*, read_region_ ## _size, \
1082 READ_REGION_ ## _size) \
1083 BHND_IO_MISC(_type*, write_region_ ## _size, \
1084 WRITE_REGION_ ## _size) \
1086 BHND_IO_MISC(_type*, read_region_stream_ ## _size, \
1087 READ_REGION_STREAM_ ## _size) \
1088 BHND_IO_MISC(_type*, write_region_stream_ ## _size, \
1089 WRITE_REGION_STREAM_ ## _size) \
1091 BHND_IO_METHODS(uint8_t, 1);
1092 BHND_IO_METHODS(uint16_t, 2);
1093 BHND_IO_METHODS(uint32_t, 4);
1096 bhnd_barrier(device_t dev, device_t child, struct bhnd_resource *r,
1097 bus_size_t offset, bus_size_t length, int flags)
1099 BHND_BUS_BARRIER(device_get_parent(dev), child, r, offset, length,
1103 static device_method_t bhnd_methods[] = {
1104 /* Device interface */ \
1105 DEVMETHOD(device_attach, bhnd_generic_attach),
1106 DEVMETHOD(device_detach, bhnd_generic_detach),
1107 DEVMETHOD(device_shutdown, bhnd_generic_shutdown),
1108 DEVMETHOD(device_suspend, bhnd_generic_suspend),
1109 DEVMETHOD(device_resume, bhnd_generic_resume),
1112 DEVMETHOD(bus_child_deleted, bhnd_generic_child_deleted),
1113 DEVMETHOD(bus_probe_nomatch, bhnd_generic_probe_nomatch),
1114 DEVMETHOD(bus_print_child, bhnd_generic_print_child),
1115 DEVMETHOD(bus_child_pnpinfo_str, bhnd_child_pnpinfo_str),
1116 DEVMETHOD(bus_child_location_str, bhnd_child_location_str),
1118 DEVMETHOD(bus_suspend_child, bhnd_generic_suspend_child),
1119 DEVMETHOD(bus_resume_child, bhnd_generic_resume_child),
1121 DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource),
1122 DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
1123 DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource),
1124 DEVMETHOD(bus_alloc_resource, bus_generic_rl_alloc_resource),
1125 DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource),
1126 DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource),
1127 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
1128 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
1130 DEVMETHOD(bus_setup_intr, bhnd_generic_setup_intr),
1131 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
1132 DEVMETHOD(bus_config_intr, bus_generic_config_intr),
1133 DEVMETHOD(bus_bind_intr, bus_generic_bind_intr),
1134 DEVMETHOD(bus_describe_intr, bus_generic_describe_intr),
1136 DEVMETHOD(bus_get_dma_tag, bus_generic_get_dma_tag),
1138 /* BHND interface */
1139 DEVMETHOD(bhnd_bus_get_chipid, bhnd_bus_generic_get_chipid),
1140 DEVMETHOD(bhnd_bus_is_hw_disabled, bhnd_bus_generic_is_hw_disabled),
1141 DEVMETHOD(bhnd_bus_read_board_info, bhnd_bus_generic_read_board_info),
1143 DEVMETHOD(bhnd_bus_get_probe_order, bhnd_generic_get_probe_order),
1145 DEVMETHOD(bhnd_bus_alloc_pmu, bhnd_generic_alloc_pmu),
1146 DEVMETHOD(bhnd_bus_release_pmu, bhnd_generic_release_pmu),
1147 DEVMETHOD(bhnd_bus_request_clock, bhnd_generic_request_clock),
1148 DEVMETHOD(bhnd_bus_enable_clocks, bhnd_generic_enable_clocks),
1149 DEVMETHOD(bhnd_bus_request_ext_rsrc, bhnd_generic_request_ext_rsrc),
1150 DEVMETHOD(bhnd_bus_release_ext_rsrc, bhnd_generic_release_ext_rsrc),
1151 DEVMETHOD(bhnd_bus_get_clock_latency, bhnd_generic_get_clock_latency),
1152 DEVMETHOD(bhnd_bus_get_clock_freq, bhnd_generic_get_clock_freq),
1154 DEVMETHOD(bhnd_bus_is_region_valid, bhnd_generic_is_region_valid),
1155 DEVMETHOD(bhnd_bus_get_nvram_var, bhnd_generic_get_nvram_var),
1157 /* BHND interface (bus I/O) */
1158 DEVMETHOD(bhnd_bus_read_1, bhnd_read_1),
1159 DEVMETHOD(bhnd_bus_read_2, bhnd_read_2),
1160 DEVMETHOD(bhnd_bus_read_4, bhnd_read_4),
1161 DEVMETHOD(bhnd_bus_write_1, bhnd_write_1),
1162 DEVMETHOD(bhnd_bus_write_2, bhnd_write_2),
1163 DEVMETHOD(bhnd_bus_write_4, bhnd_write_4),
1165 DEVMETHOD(bhnd_bus_read_stream_1, bhnd_read_stream_1),
1166 DEVMETHOD(bhnd_bus_read_stream_2, bhnd_read_stream_2),
1167 DEVMETHOD(bhnd_bus_read_stream_4, bhnd_read_stream_4),
1168 DEVMETHOD(bhnd_bus_write_stream_1, bhnd_write_stream_1),
1169 DEVMETHOD(bhnd_bus_write_stream_2, bhnd_write_stream_2),
1170 DEVMETHOD(bhnd_bus_write_stream_4, bhnd_write_stream_4),
1172 DEVMETHOD(bhnd_bus_read_multi_1, bhnd_read_multi_1),
1173 DEVMETHOD(bhnd_bus_read_multi_2, bhnd_read_multi_2),
1174 DEVMETHOD(bhnd_bus_read_multi_4, bhnd_read_multi_4),
1175 DEVMETHOD(bhnd_bus_write_multi_1, bhnd_write_multi_1),
1176 DEVMETHOD(bhnd_bus_write_multi_2, bhnd_write_multi_2),
1177 DEVMETHOD(bhnd_bus_write_multi_4, bhnd_write_multi_4),
1179 DEVMETHOD(bhnd_bus_read_multi_stream_1, bhnd_read_multi_stream_1),
1180 DEVMETHOD(bhnd_bus_read_multi_stream_2, bhnd_read_multi_stream_2),
1181 DEVMETHOD(bhnd_bus_read_multi_stream_4, bhnd_read_multi_stream_4),
1182 DEVMETHOD(bhnd_bus_write_multi_stream_1,bhnd_write_multi_stream_1),
1183 DEVMETHOD(bhnd_bus_write_multi_stream_2,bhnd_write_multi_stream_2),
1184 DEVMETHOD(bhnd_bus_write_multi_stream_4,bhnd_write_multi_stream_4),
1186 DEVMETHOD(bhnd_bus_set_multi_1, bhnd_set_multi_1),
1187 DEVMETHOD(bhnd_bus_set_multi_2, bhnd_set_multi_2),
1188 DEVMETHOD(bhnd_bus_set_multi_4, bhnd_set_multi_4),
1190 DEVMETHOD(bhnd_bus_set_region_1, bhnd_set_region_1),
1191 DEVMETHOD(bhnd_bus_set_region_2, bhnd_set_region_2),
1192 DEVMETHOD(bhnd_bus_set_region_4, bhnd_set_region_4),
1194 DEVMETHOD(bhnd_bus_read_region_1, bhnd_read_region_1),
1195 DEVMETHOD(bhnd_bus_read_region_2, bhnd_read_region_2),
1196 DEVMETHOD(bhnd_bus_read_region_4, bhnd_read_region_4),
1197 DEVMETHOD(bhnd_bus_write_region_1, bhnd_write_region_1),
1198 DEVMETHOD(bhnd_bus_write_region_2, bhnd_write_region_2),
1199 DEVMETHOD(bhnd_bus_write_region_4, bhnd_write_region_4),
1201 DEVMETHOD(bhnd_bus_read_region_stream_1,bhnd_read_region_stream_1),
1202 DEVMETHOD(bhnd_bus_read_region_stream_2,bhnd_read_region_stream_2),
1203 DEVMETHOD(bhnd_bus_read_region_stream_4,bhnd_read_region_stream_4),
1204 DEVMETHOD(bhnd_bus_write_region_stream_1, bhnd_write_region_stream_1),
1205 DEVMETHOD(bhnd_bus_write_region_stream_2, bhnd_write_region_stream_2),
1206 DEVMETHOD(bhnd_bus_write_region_stream_4, bhnd_write_region_stream_4),
1208 DEVMETHOD(bhnd_bus_barrier, bhnd_barrier),
1213 devclass_t bhnd_devclass; /**< bhnd bus. */
1214 devclass_t bhnd_hostb_devclass; /**< bhnd bus host bridge. */
1215 devclass_t bhnd_nvram_devclass; /**< bhnd NVRAM device */
1217 DEFINE_CLASS_0(bhnd, bhnd_driver, bhnd_methods, sizeof(struct bhnd_softc));
1218 MODULE_VERSION(bhnd, 1);