svn commit: r296077 - in head/sys/dev/bhnd: . bcma bhndb cores cores/chipc cores/pci nvram siba tools
Adrian Chadd
adrian at FreeBSD.org
Fri Feb 26 03:34:10 UTC 2016
Author: adrian
Date: Fri Feb 26 03:34:08 2016
New Revision: 296077
URL: https://svnweb.freebsd.org/changeset/base/296077
Log:
Bring over the initial rewrite of the broadcom bus support found in their
SoCs and various chips (including, famously, their wifi chips.)
This is "just" (all 20,000 lines of it) code to enumerate the various
versions of busses inside these devices, including the PCI bridge and
the direct SIBA bridge found in MIPS chips.
It also includes shared code for some bus operations (suspend, resume, etc);
EEPROM/SROM/etc parsing and other things that are shared between chips.
Eventually this'll replace the code that bwi/bwn uses for the internal
bus, as well as some apparently upcoming mips74k broadcom SoC support
which uses bwn!
Thanks to Landon Fuller <landonf at landonf.org> for all this work!
Obtained from: https://github.com/landonf/freebsd/compare/user/landonf/bcm4331-CURRENT
Added:
head/sys/dev/bhnd/
head/sys/dev/bhnd/bcma/
head/sys/dev/bhnd/bcma/bcma.c (contents, props changed)
head/sys/dev/bhnd/bcma/bcma.h (contents, props changed)
head/sys/dev/bhnd/bcma/bcma_bhndb.c (contents, props changed)
head/sys/dev/bhnd/bcma/bcma_dmp.h (contents, props changed)
head/sys/dev/bhnd/bcma/bcma_erom.c (contents, props changed)
head/sys/dev/bhnd/bcma/bcma_eromreg.h (contents, props changed)
head/sys/dev/bhnd/bcma/bcma_eromvar.h (contents, props changed)
head/sys/dev/bhnd/bcma/bcma_subr.c (contents, props changed)
head/sys/dev/bhnd/bcma/bcmavar.h (contents, props changed)
head/sys/dev/bhnd/bcmsrom_fmt.h (contents, props changed)
head/sys/dev/bhnd/bcmsrom_tbl.h (contents, props changed)
head/sys/dev/bhnd/bhnd.c (contents, props changed)
head/sys/dev/bhnd/bhnd.h (contents, props changed)
head/sys/dev/bhnd/bhnd_bus_if.m (contents, props changed)
head/sys/dev/bhnd/bhnd_core.h (contents, props changed)
head/sys/dev/bhnd/bhnd_ids.h (contents, props changed)
head/sys/dev/bhnd/bhnd_subr.c (contents, props changed)
head/sys/dev/bhnd/bhnd_types.h (contents, props changed)
head/sys/dev/bhnd/bhndb/
head/sys/dev/bhnd/bhndb/bhndb.c (contents, props changed)
head/sys/dev/bhnd/bhndb/bhndb.h (contents, props changed)
head/sys/dev/bhnd/bhndb/bhndb_bus_if.m (contents, props changed)
head/sys/dev/bhnd/bhndb/bhndb_hwdata.c (contents, props changed)
head/sys/dev/bhnd/bhndb/bhndb_hwdata.h (contents, props changed)
head/sys/dev/bhnd/bhndb/bhndb_if.m (contents, props changed)
head/sys/dev/bhnd/bhndb/bhndb_pci.c (contents, props changed)
head/sys/dev/bhnd/bhndb/bhndb_pci_hwdata.c (contents, props changed)
head/sys/dev/bhnd/bhndb/bhndb_pci_hwdata.h (contents, props changed)
head/sys/dev/bhnd/bhndb/bhndb_pcireg.h (contents, props changed)
head/sys/dev/bhnd/bhndb/bhndb_pcivar.h (contents, props changed)
head/sys/dev/bhnd/bhndb/bhndb_private.h (contents, props changed)
head/sys/dev/bhnd/bhndb/bhndb_subr.c (contents, props changed)
head/sys/dev/bhnd/bhndb/bhndbvar.h (contents, props changed)
head/sys/dev/bhnd/bhndreg.h (contents, props changed)
head/sys/dev/bhnd/bhndvar.h (contents, props changed)
head/sys/dev/bhnd/cores/
head/sys/dev/bhnd/cores/chipc/
head/sys/dev/bhnd/cores/chipc/bhnd_chipc_if.m (contents, props changed)
head/sys/dev/bhnd/cores/chipc/chipc.c (contents, props changed)
head/sys/dev/bhnd/cores/chipc/chipc.h (contents, props changed)
head/sys/dev/bhnd/cores/chipc/chipcreg.h (contents, props changed)
head/sys/dev/bhnd/cores/chipc/chipcvar.h (contents, props changed)
head/sys/dev/bhnd/cores/pci/
head/sys/dev/bhnd/cores/pci/bhnd_pci.c (contents, props changed)
head/sys/dev/bhnd/cores/pci/bhnd_pci_hostb.c (contents, props changed)
head/sys/dev/bhnd/cores/pci/bhnd_pcib.c (contents, props changed)
head/sys/dev/bhnd/cores/pci/bhnd_pcibvar.h (contents, props changed)
head/sys/dev/bhnd/cores/pci/bhnd_pcireg.h (contents, props changed)
head/sys/dev/bhnd/cores/pci/bhnd_pcivar.h (contents, props changed)
head/sys/dev/bhnd/cores/pci/mdio_pcie.c (contents, props changed)
head/sys/dev/bhnd/cores/pci/mdio_pciereg.h (contents, props changed)
head/sys/dev/bhnd/cores/pci/mdio_pcievar.h (contents, props changed)
head/sys/dev/bhnd/nvram/
head/sys/dev/bhnd/nvram/bhnd_nvram.h (contents, props changed)
head/sys/dev/bhnd/nvram/bhnd_nvram_if.m (contents, props changed)
head/sys/dev/bhnd/siba/
head/sys/dev/bhnd/siba/siba.c (contents, props changed)
head/sys/dev/bhnd/siba/siba.h (contents, props changed)
head/sys/dev/bhnd/siba/siba_bhndb.c (contents, props changed)
head/sys/dev/bhnd/siba/siba_nexus.c (contents, props changed)
head/sys/dev/bhnd/siba/siba_subr.c (contents, props changed)
head/sys/dev/bhnd/siba/sibareg.h (contents, props changed)
head/sys/dev/bhnd/siba/sibavar.h (contents, props changed)
head/sys/dev/bhnd/tools/
head/sys/dev/bhnd/tools/bus_macro.sh (contents, props changed)
Added: head/sys/dev/bhnd/bcma/bcma.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/sys/dev/bhnd/bcma/bcma.c Fri Feb 26 03:34:08 2016 (r296077)
@@ -0,0 +1,482 @@
+/*-
+ * Copyright (c) 2015 Landon Fuller <landon at landonf.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/systm.h>
+
+#include <machine/bus.h>
+
+#include "bcmavar.h"
+
+#include "bcma_eromreg.h"
+#include "bcma_eromvar.h"
+
+int
+bcma_probe(device_t dev)
+{
+ device_set_desc(dev, "BCMA BHND bus");
+ return (BUS_PROBE_DEFAULT);
+}
+
+int
+bcma_attach(device_t dev)
+{
+ struct bcma_devinfo *dinfo;
+ device_t *devs, child;
+ int ndevs;
+ int error;
+
+
+ if ((error = device_get_children(dev, &devs, &ndevs)))
+ return (error);
+
+ /*
+ * Map our children's agent register block.
+ */
+ for (int i = 0; i < ndevs; i++) {
+ bhnd_addr_t addr;
+ bhnd_size_t size;
+ rman_res_t r_start, r_count, r_end;
+
+ child = devs[i];
+ dinfo = device_get_ivars(child);
+
+ KASSERT(!device_is_suspended(child),
+ ("bcma(4) stateful suspend handling requires that devices "
+ "not be suspended before bcma_attach()"));
+
+ /* Verify that the agent register block exists and is
+ * mappable */
+ if (bhnd_get_port_rid(child, BHND_PORT_AGENT, 0, 0) == -1)
+ continue;
+
+ /* Fetch the address of the agent register block */
+ error = bhnd_get_region_addr(child, BHND_PORT_AGENT, 0, 0,
+ &addr, &size);
+ if (error) {
+ device_printf(dev, "failed fetching agent register "
+ "block address for core %d\n", i);
+ goto cleanup;
+ }
+
+ /* Allocate the resource */
+ r_start = addr;
+ r_count = size;
+ r_end = r_start + r_count - 1;
+
+ dinfo->rid_agent = 0;
+ dinfo->res_agent = bhnd_alloc_resource(dev, SYS_RES_MEMORY,
+ &dinfo->rid_agent, r_start, r_end, r_count, RF_ACTIVE);
+ if (dinfo->res_agent == NULL) {
+ device_printf(dev, "failed allocating agent register "
+ "block for core %d\n", i);
+ error = ENXIO;
+ goto cleanup;
+ }
+ }
+
+cleanup:
+ free(devs, M_BHND);
+ if (error)
+ return (error);
+
+ return (bhnd_generic_attach(dev));
+}
+
+int
+bcma_detach(device_t dev)
+{
+ return (bhnd_generic_detach(dev));
+}
+
+static int
+bcma_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
+{
+ const struct bcma_devinfo *dinfo;
+ const struct bhnd_core_info *ci;
+
+ dinfo = device_get_ivars(child);
+ ci = &dinfo->corecfg->core_info;
+
+ switch (index) {
+ case BHND_IVAR_VENDOR:
+ *result = ci->vendor;
+ return (0);
+ case BHND_IVAR_DEVICE:
+ *result = ci->device;
+ return (0);
+ case BHND_IVAR_HWREV:
+ *result = ci->hwrev;
+ return (0);
+ case BHND_IVAR_DEVICE_CLASS:
+ *result = bhnd_core_class(ci);
+ return (0);
+ case BHND_IVAR_VENDOR_NAME:
+ *result = (uintptr_t) bhnd_vendor_name(ci->vendor);
+ return (0);
+ case BHND_IVAR_DEVICE_NAME:
+ *result = (uintptr_t) bhnd_core_name(ci);
+ return (0);
+ case BHND_IVAR_CORE_INDEX:
+ *result = ci->core_idx;
+ return (0);
+ case BHND_IVAR_CORE_UNIT:
+ *result = ci->unit;
+ return (0);
+ default:
+ return (ENOENT);
+ }
+}
+
+static int
+bcma_write_ivar(device_t dev, device_t child, int index, uintptr_t value)
+{
+ switch (index) {
+ case BHND_IVAR_VENDOR:
+ case BHND_IVAR_DEVICE:
+ case BHND_IVAR_HWREV:
+ case BHND_IVAR_DEVICE_CLASS:
+ case BHND_IVAR_VENDOR_NAME:
+ case BHND_IVAR_DEVICE_NAME:
+ case BHND_IVAR_CORE_INDEX:
+ case BHND_IVAR_CORE_UNIT:
+ return (EINVAL);
+ default:
+ return (ENOENT);
+ }
+}
+
+static void
+bcma_child_deleted(device_t dev, device_t child)
+{
+ struct bcma_devinfo *dinfo = device_get_ivars(child);
+ if (dinfo != NULL)
+ bcma_free_dinfo(dev, dinfo);
+}
+
+static struct resource_list *
+bcma_get_resource_list(device_t dev, device_t child)
+{
+ struct bcma_devinfo *dinfo = device_get_ivars(child);
+ return (&dinfo->resources);
+}
+
+
+static int
+bcma_reset_core(device_t dev, device_t child, uint16_t flags)
+{
+ struct bcma_devinfo *dinfo;
+
+ if (device_get_parent(child) != dev)
+ BHND_BUS_RESET_CORE(device_get_parent(dev), child, flags);
+
+ dinfo = device_get_ivars(child);
+
+ /* Can't reset the core without access to the agent registers */
+ if (dinfo->res_agent == NULL)
+ return (ENODEV);
+
+ // TODO - perform reset
+
+ return (ENXIO);
+}
+
+static int
+bcma_suspend_core(device_t dev, device_t child)
+{
+ struct bcma_devinfo *dinfo;
+
+ if (device_get_parent(child) != dev)
+ BHND_BUS_SUSPEND_CORE(device_get_parent(dev), child);
+
+ dinfo = device_get_ivars(child);
+
+ /* Can't suspend the core without access to the agent registers */
+ if (dinfo->res_agent == NULL)
+ return (ENODEV);
+
+ // TODO - perform suspend
+
+ return (ENXIO);
+}
+
+static u_int
+bcma_get_port_count(device_t dev, device_t child, bhnd_port_type type)
+{
+ struct bcma_devinfo *dinfo;
+
+ /* delegate non-bus-attached devices to our parent */
+ if (device_get_parent(child) != dev)
+ return (BHND_BUS_GET_PORT_COUNT(device_get_parent(dev), child,
+ type));
+
+ dinfo = device_get_ivars(child);
+ switch (type) {
+ case BHND_PORT_DEVICE:
+ return (dinfo->corecfg->num_dev_ports);
+ case BHND_PORT_BRIDGE:
+ return (dinfo->corecfg->num_bridge_ports);
+ case BHND_PORT_AGENT:
+ return (dinfo->corecfg->num_wrapper_ports);
+ }
+}
+
+static u_int
+bcma_get_region_count(device_t dev, device_t child, bhnd_port_type type,
+ u_int port_num)
+{
+ struct bcma_devinfo *dinfo;
+ struct bcma_sport_list *ports;
+ struct bcma_sport *port;
+
+ /* delegate non-bus-attached devices to our parent */
+ if (device_get_parent(child) != dev)
+ return (BHND_BUS_GET_REGION_COUNT(device_get_parent(dev), child,
+ type, port_num));
+
+ dinfo = device_get_ivars(child);
+ ports = bcma_corecfg_get_port_list(dinfo->corecfg, type);
+
+ STAILQ_FOREACH(port, ports, sp_link) {
+ if (port->sp_num == port_num)
+ return (port->sp_num_maps);
+ }
+
+ /* not found */
+ return (0);
+}
+
+static int
+bcma_get_port_rid(device_t dev, device_t child, bhnd_port_type port_type,
+ u_int port_num, u_int region_num)
+{
+ struct bcma_devinfo *dinfo;
+ struct bcma_map *map;
+ struct bcma_sport_list *ports;
+ struct bcma_sport *port;
+
+ dinfo = device_get_ivars(child);
+ ports = bcma_corecfg_get_port_list(dinfo->corecfg, port_type);
+
+ STAILQ_FOREACH(port, ports, sp_link) {
+ if (port->sp_num != port_num)
+ continue;
+
+ STAILQ_FOREACH(map, &port->sp_maps, m_link)
+ if (map->m_region_num == region_num)
+ return map->m_rid;
+ }
+
+ return -1;
+}
+
+static int
+bcma_decode_port_rid(device_t dev, device_t child, int type, int rid,
+ bhnd_port_type *port_type, u_int *port_num, u_int *region_num)
+{
+ struct bcma_devinfo *dinfo;
+ struct bcma_map *map;
+ struct bcma_sport_list *ports;
+ struct bcma_sport *port;
+
+ dinfo = device_get_ivars(child);
+
+ /* Ports are always memory mapped */
+ if (type != SYS_RES_MEMORY)
+ return (EINVAL);
+
+ /* Starting with the most likely device list, search all three port
+ * lists */
+ bhnd_port_type types[] = {
+ BHND_PORT_DEVICE,
+ BHND_PORT_AGENT,
+ BHND_PORT_BRIDGE
+ };
+
+ for (int i = 0; i < nitems(types); i++) {
+ ports = bcma_corecfg_get_port_list(dinfo->corecfg, types[i]);
+
+ STAILQ_FOREACH(port, ports, sp_link) {
+ STAILQ_FOREACH(map, &port->sp_maps, m_link) {
+ if (map->m_rid != rid)
+ continue;
+
+ *port_type = port->sp_type;
+ *port_num = port->sp_num;
+ *region_num = map->m_region_num;
+ return (0);
+ }
+ }
+ }
+
+ return (ENOENT);
+}
+
+static int
+bcma_get_region_addr(device_t dev, device_t child, bhnd_port_type port_type,
+ u_int port_num, u_int region_num, bhnd_addr_t *addr, bhnd_size_t *size)
+{
+ struct bcma_devinfo *dinfo;
+ struct bcma_map *map;
+ struct bcma_sport_list *ports;
+ struct bcma_sport *port;
+
+ dinfo = device_get_ivars(child);
+ ports = bcma_corecfg_get_port_list(dinfo->corecfg, port_type);
+
+ /* Search the port list */
+ STAILQ_FOREACH(port, ports, sp_link) {
+ if (port->sp_num != port_num)
+ continue;
+
+ STAILQ_FOREACH(map, &port->sp_maps, m_link) {
+ if (map->m_region_num != region_num)
+ continue;
+
+ /* Found! */
+ *addr = map->m_base;
+ *size = map->m_size;
+ return (0);
+ }
+ }
+
+ return (ENOENT);
+}
+
+/**
+ * Scan a device enumeration ROM table, adding all valid discovered cores to
+ * the bus.
+ *
+ * @param bus The bcma bus.
+ * @param erom_res An active resource mapping the EROM core.
+ * @param erom_offset Base offset of the EROM core's register mapping.
+ */
+int
+bcma_add_children(device_t bus, struct resource *erom_res, bus_size_t erom_offset)
+{
+ struct bcma_erom erom;
+ struct bcma_corecfg *corecfg;
+ struct bcma_devinfo *dinfo;
+ device_t child;
+ int error;
+
+ dinfo = NULL;
+ corecfg = NULL;
+
+ /* Initialize our reader */
+ error = bcma_erom_open(&erom, erom_res, erom_offset);
+ if (error)
+ return (error);
+
+ /* Add all cores. */
+ while (!error) {
+ /* Parse next core */
+ error = bcma_erom_parse_corecfg(&erom, &corecfg);
+ if (error && error == ENOENT) {
+ return (0);
+ } else if (error) {
+ goto failed;
+ }
+
+ /* Allocate per-device bus info */
+ dinfo = bcma_alloc_dinfo(bus, corecfg);
+ if (dinfo == NULL) {
+ error = ENXIO;
+ goto failed;
+ }
+
+ /* The dinfo instance now owns the corecfg value */
+ corecfg = NULL;
+
+ /* Add the child device */
+ child = device_add_child(bus, NULL, -1);
+ if (child == NULL) {
+ error = ENXIO;
+ goto failed;
+ }
+
+ /* The child device now owns the dinfo pointer */
+ device_set_ivars(child, dinfo);
+ dinfo = NULL;
+
+ /* If pins are floating or the hardware is otherwise
+ * unpopulated, the device shouldn't be used. */
+ if (bhnd_is_hw_disabled(child))
+ device_disable(child);
+ }
+
+ /* Hit EOF parsing cores? */
+ if (error == ENOENT)
+ return (0);
+
+failed:
+ if (dinfo != NULL)
+ bcma_free_dinfo(bus, dinfo);
+
+ if (corecfg != NULL)
+ bcma_free_corecfg(corecfg);
+
+ return (error);
+}
+
+
+static device_method_t bcma_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, bcma_probe),
+ DEVMETHOD(device_attach, bcma_attach),
+ DEVMETHOD(device_detach, bcma_detach),
+
+ /* Bus interface */
+ DEVMETHOD(bus_child_deleted, bcma_child_deleted),
+ DEVMETHOD(bus_read_ivar, bcma_read_ivar),
+ DEVMETHOD(bus_write_ivar, bcma_write_ivar),
+ DEVMETHOD(bus_get_resource_list, bcma_get_resource_list),
+
+ /* BHND interface */
+ DEVMETHOD(bhnd_bus_reset_core, bcma_reset_core),
+ DEVMETHOD(bhnd_bus_suspend_core, bcma_suspend_core),
+ DEVMETHOD(bhnd_bus_get_port_count, bcma_get_port_count),
+ DEVMETHOD(bhnd_bus_get_region_count, bcma_get_region_count),
+ DEVMETHOD(bhnd_bus_get_port_rid, bcma_get_port_rid),
+ DEVMETHOD(bhnd_bus_decode_port_rid, bcma_decode_port_rid),
+ DEVMETHOD(bhnd_bus_get_region_addr, bcma_get_region_addr),
+
+ DEVMETHOD_END
+};
+
+DEFINE_CLASS_1(bhnd, bcma_driver, bcma_methods, sizeof(struct bcma_softc), bhnd_driver);
+MODULE_VERSION(bcma, 1);
+MODULE_DEPEND(bcma, bhnd, 1, 1, 1);
Added: head/sys/dev/bhnd/bcma/bcma.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/sys/dev/bhnd/bcma/bcma.h Fri Feb 26 03:34:08 2016 (r296077)
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 2015 Landon Fuller <landon at landonf.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _BCMA_BCMA_H_
+#define _BCMA_BCMA_H_
+
+#include <sys/types.h>
+#include <sys/bus.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+#include <sys/rman.h>
+
+#include <dev/bhnd/bhndvar.h>
+
+/*
+ * Broadcom AMBA backplane types and data structures.
+ */
+
+DECLARE_CLASS(bcma_driver);
+
+#endif /* _BCMA_BCMA_H_ */
\ No newline at end of file
Added: head/sys/dev/bhnd/bcma/bcma_bhndb.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/sys/dev/bhnd/bcma/bcma_bhndb.c Fri Feb 26 03:34:08 2016 (r296077)
@@ -0,0 +1,183 @@
+/*-
+ * Copyright (c) 2015 Landon Fuller <landon at landonf.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/module.h>
+
+#include <dev/bhnd/bhnd_ids.h>
+#include <dev/bhnd/bhndb/bhndbvar.h>
+#include <dev/bhnd/bhndb/bhndb_hwdata.h>
+
+#include "bcmavar.h"
+
+#include "bcma_eromreg.h"
+#include "bcma_eromvar.h"
+
+/*
+ * Supports attachment of bcma(4) bus devices via a bhndb bridge.
+ */
+
+static int
+bcma_bhndb_probe(device_t dev)
+{
+ const struct bhnd_chipid *cid;
+
+ /* Check bus type */
+ cid = BHNDB_GET_CHIPID(device_get_parent(dev), dev);
+ if (cid->chip_type != BHND_CHIPTYPE_BCMA)
+ return (ENXIO);
+
+ /* Delegate to default probe implementation */
+ return (bcma_probe(dev));
+}
+
+static int
+bcma_bhndb_attach(device_t dev)
+{
+ const struct bhnd_chipid *cid;
+ struct resource *erom_res;
+ int error;
+ int rid;
+
+ cid = BHNDB_GET_CHIPID(device_get_parent(dev), dev);
+
+ /* Map the EROM resource and enumerate our children. */
+ rid = 0;
+ erom_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, cid->enum_addr,
+ cid->enum_addr + BCMA_EROM_TABLE_SIZE, BCMA_EROM_TABLE_SIZE,
+ RF_ACTIVE);
+ if (erom_res == NULL) {
+ device_printf(dev, "failed to allocate EROM resource\n");
+ return (ENXIO);
+ }
+
+ error = bcma_add_children(dev, erom_res, BCMA_EROM_TABLE_START);
+
+ /* Clean up */
+ bus_release_resource(dev, SYS_RES_MEMORY, rid, erom_res);
+ if (error)
+ return (error);
+
+ /* Initialize full bridge configuration */
+ error = BHNDB_INIT_FULL_CONFIG(device_get_parent(dev), dev,
+ bhndb_bcma_priority_table);
+ if (error)
+ return (error);
+
+ /* Call our superclass' implementation */
+ return (bcma_attach(dev));
+}
+
+static int
+bcma_bhndb_suspend_child(device_t dev, device_t child)
+{
+ struct bcma_devinfo *dinfo;
+ int error;
+
+ if (device_get_parent(child) != dev)
+ BUS_SUSPEND_CHILD(device_get_parent(dev), child);
+
+ if (device_is_suspended(child))
+ return (EBUSY);
+
+ dinfo = device_get_ivars(child);
+
+ /* Suspend the child */
+ if ((error = bhnd_generic_br_suspend_child(dev, child)))
+ return (error);
+
+ /* Suspend child's agent resource */
+ if (dinfo->res_agent != NULL)
+ BHNDB_SUSPEND_RESOURCE(device_get_parent(dev), dev,
+ SYS_RES_MEMORY, dinfo->res_agent->res);
+
+ return (0);
+}
+
+static int
+bcma_bhndb_resume_child(device_t dev, device_t child)
+{
+ struct bcma_devinfo *dinfo;
+ int error;
+
+ if (device_get_parent(child) != dev)
+ BUS_SUSPEND_CHILD(device_get_parent(dev), child);
+
+ if (!device_is_suspended(child))
+ return (EBUSY);
+
+ dinfo = device_get_ivars(child);
+
+ /* Resume child's agent resource */
+ if (dinfo->res_agent != NULL) {
+ error = BHNDB_RESUME_RESOURCE(device_get_parent(dev), dev,
+ SYS_RES_MEMORY, dinfo->res_agent->res);
+ if (error)
+ return (error);
+ }
+
+ /* Resume the child */
+ if ((error = bhnd_generic_br_resume_child(dev, child))) {
+ /* On failure, re-suspend the agent resource */
+ if (dinfo->res_agent != NULL) {
+ BHNDB_SUSPEND_RESOURCE(device_get_parent(dev), dev,
+ SYS_RES_MEMORY, dinfo->res_agent->res);
+ }
+
+ return (error);
+ }
+
+ return (0);
+}
+
+static device_method_t bcma_bhndb_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, bcma_bhndb_probe),
+ DEVMETHOD(device_attach, bcma_bhndb_attach),
+
+ /* Bus interface */
+ DEVMETHOD(bus_suspend_child, bcma_bhndb_suspend_child),
+ DEVMETHOD(bus_resume_child, bcma_bhndb_resume_child),
+
+ DEVMETHOD_END
+};
+
+DEFINE_CLASS_1(bhnd, bcma_bhndb_driver, bcma_bhndb_methods,
+ sizeof(struct bcma_softc), bcma_driver);
+
+DRIVER_MODULE(bcma_bhndb, bhndb, bcma_bhndb_driver, bhnd_devclass, NULL, NULL);
+
+MODULE_VERSION(bcma_bhndb, 1);
+MODULE_DEPEND(bcma_bhndb, bcma, 1, 1, 1);
+MODULE_DEPEND(bcma_bhndb, bhndb, 1, 1, 1);
Added: head/sys/dev/bhnd/bcma/bcma_dmp.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/sys/dev/bhnd/bcma/bcma_dmp.h Fri Feb 26 03:34:08 2016 (r296077)
@@ -0,0 +1,193 @@
+/*-
+ * Copyright (c) 2015 Landon Fuller <landon at landonf.org>
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * Portions of this file were derived from the aidmp.h header
+ * distributed with Broadcom's initial brcm80211 Linux driver release, as
+ * contributed to the Linux staging repository.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _BCMA_BCMA_DMP_H_
+#define _BCMA_BCMA_DMP_H_
+
+/*
+ * PL-368 Device Management Plugin (DMP) Registers & Constants
+ *
+ * The "DMP" core used in Broadcom HND devices has been described
+ * by Broadcom engineers (and in published header files) as being
+ * ARM's PL-368 "Device Management Plugin" system IP, included with
+ * the CoreLink AMBA Designer tooling.
+ *
+ * Documentation for the PL-368 is not publicly available, however,
+ * and the only public reference by ARM to its existence appears to be
+ * in the proprietary "NIC-301 Interconnect Device Management (PL368)"
+ * errata publication, available to licensees as part of ARM's
+ * CoreLink Controllers and Peripherals Engineering Errata.
+ */
+
+/* Out-of-band Router registers */
+#define BCMA_OOB_BUSCONFIG 0x020
+#define BCMA_OOB_STATUSA 0x100
+#define BCMA_OOB_STATUSB 0x104
+#define BCMA_OOB_STATUSC 0x108
+#define BCMA_OOB_STATUSD 0x10c
+#define BCMA_OOB_ENABLEA0 0x200
+#define BCMA_OOB_ENABLEA1 0x204
+#define BCMA_OOB_ENABLEA2 0x208
+#define BCMA_OOB_ENABLEA3 0x20c
+#define BCMA_OOB_ENABLEB0 0x280
+#define BCMA_OOB_ENABLEB1 0x284
+#define BCMA_OOB_ENABLEB2 0x288
+#define BCMA_OOB_ENABLEB3 0x28c
+#define BCMA_OOB_ENABLEC0 0x300
+#define BCMA_OOB_ENABLEC1 0x304
+#define BCMA_OOB_ENABLEC2 0x308
+#define BCMA_OOB_ENABLEC3 0x30c
+#define BCMA_OOB_ENABLED0 0x380
+#define BCMA_OOB_ENABLED1 0x384
+#define BCMA_OOB_ENABLED2 0x388
+#define BCMA_OOB_ENABLED3 0x38c
+#define BCMA_OOB_ITCR 0xf00
+#define BCMA_OOB_ITIPOOBA 0xf10
+#define BCMA_OOB_ITIPOOBB 0xf14
+#define BCMA_OOB_ITIPOOBC 0xf18
+#define BCMA_OOB_ITIPOOBD 0xf1c
+#define BCMA_OOB_ITOPOOBA 0xf30
+#define BCMA_OOB_ITOPOOBB 0xf34
+#define BCMA_OOB_ITOPOOBC 0xf38
+#define BCMA_OOB_ITOPOOBD 0xf3c
+
+/* DMP wrapper registers */
+#define BCMA_DMP_OOBSELINA30 0x000
+#define BCMA_DMP_OOBSELINA74 0x004
+#define BCMA_DMP_OOBSELINB30 0x020
+#define BCMA_DMP_OOBSELINB74 0x024
+#define BCMA_DMP_OOBSELINC30 0x040
+#define BCMA_DMP_OOBSELINC74 0x044
+#define BCMA_DMP_OOBSELIND30 0x060
+#define BCMA_DMP_OOBSELIND74 0x064
+#define BCMA_DMP_OOBSELOUTA30 0x100
+#define BCMA_DMP_OOBSELOUTA74 0x104
+#define BCMA_DMP_OOBSELOUTB30 0x120
+#define BCMA_DMP_OOBSELOUTB74 0x124
+#define BCMA_DMP_OOBSELOUTC30 0x140
+#define BCMA_DMP_OOBSELOUTC74 0x144
+#define BCMA_DMP_OOBSELOUTD30 0x160
+#define BCMA_DMP_OOBSELOUTD74 0x164
+#define BCMA_DMP_OOBSYNCA 0x200
+#define BCMA_DMP_OOBSELOUTAEN 0x204
+#define BCMA_DMP_OOBSYNCB 0x220
+#define BCMA_DMP_OOBSELOUTBEN 0x224
+#define BCMA_DMP_OOBSYNCC 0x240
+#define BCMA_DMP_OOBSELOUTCEN 0x244
+#define BCMA_DMP_OOBSYNCD 0x260
+#define BCMA_DMP_OOBSELOUTDEN 0x264
+#define BCMA_DMP_OOBAEXTWIDTH 0x300
+#define BCMA_DMP_OOBAINWIDTH 0x304
+#define BCMA_DMP_OOBAOUTWIDTH 0x308
+#define BCMA_DMP_OOBBEXTWIDTH 0x320
+#define BCMA_DMP_OOBBINWIDTH 0x324
+#define BCMA_DMP_OOBBOUTWIDTH 0x328
+#define BCMA_DMP_OOBCEXTWIDTH 0x340
+#define BCMA_DMP_OOBCINWIDTH 0x344
+#define BCMA_DMP_OOBCOUTWIDTH 0x348
+#define BCMA_DMP_OOBDEXTWIDTH 0x360
+#define BCMA_DMP_OOBDINWIDTH 0x364
+#define BCMA_DMP_OOBDOUTWIDTH 0x368
+
+// This was inherited from Broadcom's aidmp.h header
+// Is it required for any of our use-cases?
+#if 0 /* defined(IL_BIGENDIAN) && defined(BCMHND74K) */
+/* Selective swapped defines for those registers we need in
+ * big-endian code.
+ */
+#define BCMA_DMP_IOCTRLSET 0x404
+#define BCMA_DMP_IOCTRLCLEAR 0x400
+#define BCMA_DMP_IOCTRL 0x40c
+#define BCMA_DMP_IOSTATUS 0x504
+#define BCMA_DMP_RESETCTRL 0x804
+#define BCMA_DMP_RESETSTATUS 0x800
+
+#else /* !IL_BIGENDIAN || !BCMHND74K */
+
+#define BCMA_DMP_IOCTRLSET 0x400
+#define BCMA_DMP_IOCTRLCLEAR 0x404
+#define BCMA_DMP_IOCTRL 0x408
+#define BCMA_DMP_IOSTATUS 0x500
+#define BCMA_DMP_RESETCTRL 0x800
+#define BCMA_DMP_RESETSTATUS 0x804
+
+#endif /* IL_BIGENDIAN && BCMHND74K */
+
+#define BCMA_DMP_IOCTRLWIDTH 0x700
+#define BCMA_DMP_IOSTATUSWIDTH 0x704
+
+#define BCMA_DMP_RESETREADID 0x808
+#define BCMA_DMP_RESETWRITEID 0x80c
+#define BCMA_DMP_ERRLOGCTRL 0xa00
+#define BCMA_DMP_ERRLOGDONE 0xa04
+#define BCMA_DMP_ERRLOGSTATUS 0xa08
+#define BCMA_DMP_ERRLOGADDRLO 0xa0c
+#define BCMA_DMP_ERRLOGADDRHI 0xa10
+#define BCMA_DMP_ERRLOGID 0xa14
+#define BCMA_DMP_ERRLOGUSER 0xa18
+#define BCMA_DMP_ERRLOGFLAGS 0xa1c
+#define BCMA_DMP_INTSTATUS 0xa00
+#define BCMA_DMP_CONFIG 0xe00
+#define BCMA_DMP_ITCR 0xf00
+#define BCMA_DMP_ITIPOOBA 0xf10
+#define BCMA_DMP_ITIPOOBB 0xf14
+#define BCMA_DMP_ITIPOOBC 0xf18
+#define BCMA_DMP_ITIPOOBD 0xf1c
+#define BCMA_DMP_ITIPOOBAOUT 0xf30
+#define BCMA_DMP_ITIPOOBBOUT 0xf34
+#define BCMA_DMP_ITIPOOBCOUT 0xf38
+#define BCMA_DMP_ITIPOOBDOUT 0xf3c
+#define BCMA_DMP_ITOPOOBA 0xf50
+#define BCMA_DMP_ITOPOOBB 0xf54
+#define BCMA_DMP_ITOPOOBC 0xf58
+#define BCMA_DMP_ITOPOOBD 0xf5c
+#define BCMA_DMP_ITOPOOBAIN 0xf70
+#define BCMA_DMP_ITOPOOBBIN 0xf74
+#define BCMA_DMP_ITOPOOBCIN 0xf78
+#define BCMA_DMP_ITOPOOBDIN 0xf7c
+#define BCMA_DMP_ITOPRESET 0xf90
+#define BCMA_DMP_PERIPHERIALID4 0xfd0
+#define BCMA_DMP_PERIPHERIALID5 0xfd4
+#define BCMA_DMP_PERIPHERIALID6 0xfd8
+#define BCMA_DMP_PERIPHERIALID7 0xfdc
+#define BCMA_DMP_PERIPHERIALID0 0xfe0
+#define BCMA_DMP_PERIPHERIALID1 0xfe4
+#define BCMA_DMP_PERIPHERIALID2 0xfe8
+#define BCMA_DMP_PERIPHERIALID3 0xfec
+#define BCMA_DMP_COMPONENTID0 0xff0
+#define BCMA_DMP_COMPONENTID1 0xff4
+#define BCMA_DMP_COMPONENTID2 0xff8
+#define BCMA_DMP_COMPONENTID3 0xffc
+
+/* resetctrl */
+#define BMCA_DMP_RC_RESET 1
+
+/* config */
+#define BCMA_DMP_CFG_OOB 0x00000020
+#define BCMA_DMP_CFG_IOS 0x00000010
+#define BCMA_DMP_CFGIOC 0x00000008
+#define BCMA_DMP_CFGTO 0x00000004
+#define BCMA_DMP_CFGERRL 0x00000002
+#define BCMA_DMP_CFGRST 0x00000001
+
+#endif /* _BCMA_BCMA_DMP_H_ */
Added: head/sys/dev/bhnd/bcma/bcma_erom.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/sys/dev/bhnd/bcma/bcma_erom.c Fri Feb 26 03:34:08 2016 (r296077)
@@ -0,0 +1,897 @@
+/*-
+ * Copyright (c) 2015 Landon Fuller <landon at landonf.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/limits.h>
+#include <sys/systm.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include "bcma_eromreg.h"
+#include "bcma_eromvar.h"
+
+/*
+ * BCMA Enumeration ROM (EROM) Table
+ *
+ * Provides auto-discovery of BCMA cores on Broadcom's HND SoC.
+ *
+ * The EROM core address can be found at BCMA_CC_EROM_ADDR within the
+ * ChipCommon registers. The table itself is comprised of 32-bit
+ * type-tagged entries, organized into an array of variable-length
+ * core descriptor records.
+ *
+ * The final core descriptor is followed by a 32-bit BCMA_EROM_TABLE_EOF (0xF)
+ * marker.
+ */
+
+static const char *erom_entry_type_name (uint8_t entry);
+static int erom_read32(struct bcma_erom *erom, uint32_t *entry);
+static int erom_skip32(struct bcma_erom *erom);
+
+static int erom_skip_core(struct bcma_erom *erom);
+static int erom_skip_mport(struct bcma_erom *erom);
+static int erom_skip_sport_region(struct bcma_erom *erom);
+
+static int erom_seek_next(struct bcma_erom *erom, uint8_t etype);
+
+#define EROM_LOG(erom, fmt, ...) \
+ device_printf(erom->dev, "erom[0x%llx]: " fmt, \
+ (unsigned long long) (erom->offset), ##__VA_ARGS__);
+
+/**
+ * Open an EROM table for reading.
+ *
+ * @param[out] erom On success, will be populated with a valid EROM
+ * read state.
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-all
mailing list