Index: head/sys/dev/bhnd/bcma/bcma.c =================================================================== --- head/sys/dev/bhnd/bcma/bcma.c (revision 308694) +++ head/sys/dev/bhnd/bcma/bcma.c (revision 308695) @@ -1,800 +1,800 @@ /*- * Copyright (c) 2015 Landon Fuller * 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 __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include "bcma_dmp.h" #include "bcma_eromreg.h" #include "bcma_eromvar.h" #include "bcmavar.h" /* RID used when allocating EROM table */ #define BCMA_EROM_RID 0 static bhnd_erom_class_t * bcma_get_erom_class(driver_t *driver) { return (&bcma_erom_parser); } int bcma_probe(device_t dev) { device_set_desc(dev, "BCMA BHND bus"); return (BUS_PROBE_DEFAULT); } /** * Default bcma(4) bus driver implementation of DEVICE_ATTACH(). * * This implementation initializes internal bcma(4) state and performs * bus enumeration, and must be called by subclassing drivers in * DEVICE_ATTACH() before any other bus methods. */ int bcma_attach(device_t dev) { int error; /* Enumerate children */ if ((error = bcma_add_children(dev))) { device_delete_children(dev); return (error); } return (0); } int bcma_detach(device_t dev) { return (bhnd_generic_detach(dev)); } static device_t bcma_add_child(device_t dev, u_int order, const char *name, int unit) { struct bcma_devinfo *dinfo; device_t child; child = device_add_child_ordered(dev, order, name, unit); if (child == NULL) return (NULL); if ((dinfo = bcma_alloc_dinfo(dev)) == NULL) { device_delete_child(dev, child); return (NULL); } device_set_ivars(child, dinfo); return (child); } static void bcma_child_deleted(device_t dev, device_t child) { struct bhnd_softc *sc; struct bcma_devinfo *dinfo; sc = device_get_softc(dev); /* Call required bhnd(4) implementation */ bhnd_generic_child_deleted(dev, child); /* Free bcma device info */ if ((dinfo = device_get_ivars(child)) != NULL) bcma_free_dinfo(dev, dinfo); device_set_ivars(child, NULL); } 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); case BHND_IVAR_PMU_INFO: *result = (uintptr_t) dinfo->pmu_info; return (0); default: return (ENOENT); } } static int bcma_write_ivar(device_t dev, device_t child, int index, uintptr_t value) { struct bcma_devinfo *dinfo; dinfo = device_get_ivars(child); 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); case BHND_IVAR_PMU_INFO: dinfo->pmu_info = (struct bhnd_core_pmu_info *) value; return (0); default: return (ENOENT); } } 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_read_iost(device_t dev, device_t child, uint16_t *iost) { uint32_t value; int error; if ((error = bhnd_read_config(child, BCMA_DMP_IOSTATUS, &value, 4))) return (error); /* Return only the bottom 16 bits */ *iost = (value & BCMA_DMP_IOST_MASK); return (0); } static int bcma_read_ioctl(device_t dev, device_t child, uint16_t *ioctl) { uint32_t value; int error; if ((error = bhnd_read_config(child, BCMA_DMP_IOCTRL, &value, 4))) return (error); /* Return only the bottom 16 bits */ *ioctl = (value & BCMA_DMP_IOCTRL_MASK); return (0); } static int bcma_write_ioctl(device_t dev, device_t child, uint16_t value, uint16_t mask) { struct bcma_devinfo *dinfo; struct bhnd_resource *r; uint32_t ioctl; if (device_get_parent(child) != dev) return (EINVAL); dinfo = device_get_ivars(child); if ((r = dinfo->res_agent) == NULL) return (ENODEV); /* Write new value */ ioctl = bhnd_bus_read_4(r, BCMA_DMP_IOCTRL); ioctl &= ~(BCMA_DMP_IOCTRL_MASK & mask); ioctl |= (value & mask); bhnd_bus_write_4(r, BCMA_DMP_IOCTRL, ioctl); /* Perform read-back and wait for completion */ bhnd_bus_read_4(r, BCMA_DMP_IOCTRL); DELAY(10); return (0); } static bool bcma_is_hw_suspended(device_t dev, device_t child) { uint32_t rst; uint16_t ioctl; int error; /* Is core held in RESET? */ error = bhnd_read_config(child, BCMA_DMP_RESETCTRL, &rst, 4); if (error) { device_printf(child, "error reading HW reset state: %d\n", error); return (true); } - if (rst & BMCA_DMP_RC_RESET) + if (rst & BCMA_DMP_RC_RESET) return (true); /* Is core clocked? */ error = bhnd_read_ioctl(child, &ioctl); if (error) { device_printf(child, "error reading HW ioctl register: %d\n", error); return (true); } if (!(ioctl & BHND_IOCTL_CLK_EN)) return (true); return (false); } static int bcma_reset_hw(device_t dev, device_t child, uint16_t ioctl) { struct bcma_devinfo *dinfo; struct bhnd_core_pmu_info *pm; struct bhnd_resource *r; int error; if (device_get_parent(child) != dev) return (EINVAL); dinfo = device_get_ivars(child); pm = dinfo->pmu_info; /* We require exclusive control over BHND_IOCTL_CLK_EN and * BHND_IOCTL_CLK_FORCE. */ if (ioctl & (BHND_IOCTL_CLK_EN | BHND_IOCTL_CLK_FORCE)) return (EINVAL); /* Can't suspend the core without access to the agent registers */ if ((r = dinfo->res_agent) == NULL) return (ENODEV); /* Place core into known RESET state */ if ((error = BHND_BUS_SUSPEND_HW(dev, child))) return (error); /* * Leaving the core in reset: * - Set the caller's IOCTL flags * - Enable clocks * - Force clock distribution to ensure propagation throughout the * core. */ error = bhnd_write_ioctl(child, ioctl | BHND_IOCTL_CLK_EN | BHND_IOCTL_CLK_FORCE, UINT16_MAX); if (error) return (error); /* Bring the core out of reset */ if ((error = bcma_dmp_write_reset(child, dinfo, 0x0))) return (error); /* Disable forced clock gating (leaving clock enabled) */ error = bhnd_write_ioctl(child, 0x0, BHND_IOCTL_CLK_FORCE); if (error) return (error); return (0); } static int bcma_suspend_hw(device_t dev, device_t child) { struct bcma_devinfo *dinfo; struct bhnd_core_pmu_info *pm; struct bhnd_resource *r; uint32_t rst; int error; if (device_get_parent(child) != dev) return (EINVAL); dinfo = device_get_ivars(child); pm = dinfo->pmu_info; /* Can't suspend the core without access to the agent registers */ if ((r = dinfo->res_agent) == NULL) return (ENODEV); /* Wait for any pending reset operations to clear */ if ((error = bcma_dmp_wait_reset(child, dinfo))) return (error); /* Already in reset? */ rst = bhnd_bus_read_4(r, BCMA_DMP_RESETCTRL); - if (rst & BMCA_DMP_RC_RESET) + if (rst & BCMA_DMP_RC_RESET) return (0); /* Put core into reset */ - if ((error = bcma_dmp_write_reset(child, dinfo, BMCA_DMP_RC_RESET))) + if ((error = bcma_dmp_write_reset(child, dinfo, BCMA_DMP_RC_RESET))) return (error); /* Clear core flags */ if ((error = bhnd_write_ioctl(child, 0x0, UINT16_MAX))) return (error); /* Inform PMU that all outstanding request state should be discarded */ if (pm != NULL) { if ((error = BHND_PMU_CORE_RELEASE(pm->pm_pmu, pm))) return (error); } return (0); } static int bcma_read_config(device_t dev, device_t child, bus_size_t offset, void *value, u_int width) { struct bcma_devinfo *dinfo; struct bhnd_resource *r; /* Must be a directly attached child core */ if (device_get_parent(child) != dev) return (EINVAL); /* Fetch the agent registers */ dinfo = device_get_ivars(child); if ((r = dinfo->res_agent) == NULL) return (ENODEV); /* Verify bounds */ if (offset > rman_get_size(r->res)) return (EFAULT); if (rman_get_size(r->res) - offset < width) return (EFAULT); switch (width) { case 1: *((uint8_t *)value) = bhnd_bus_read_1(r, offset); return (0); case 2: *((uint16_t *)value) = bhnd_bus_read_2(r, offset); return (0); case 4: *((uint32_t *)value) = bhnd_bus_read_4(r, offset); return (0); default: return (EINVAL); } } static int bcma_write_config(device_t dev, device_t child, bus_size_t offset, const void *value, u_int width) { struct bcma_devinfo *dinfo; struct bhnd_resource *r; /* Must be a directly attached child core */ if (device_get_parent(child) != dev) return (EINVAL); /* Fetch the agent registers */ dinfo = device_get_ivars(child); if ((r = dinfo->res_agent) == NULL) return (ENODEV); /* Verify bounds */ if (offset > rman_get_size(r->res)) return (EFAULT); if (rman_get_size(r->res) - offset < width) return (EFAULT); switch (width) { case 1: bhnd_bus_write_1(r, offset, *(const uint8_t *)value); return (0); case 2: bhnd_bus_write_2(r, offset, *(const uint16_t *)value); return (0); case 4: bhnd_bus_write_4(r, offset, *(const uint32_t *)value); return (0); default: return (EINVAL); } } 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); default: device_printf(dev, "%s: unknown type (%d)\n", __func__, type); return (0); } } 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); } /** * Default bcma(4) bus driver implementation of BHND_BUS_GET_INTR_COUNT(). * * This implementation consults @p child's agent register block, * returning the number of interrupt output lines routed to @p child. */ int bcma_get_intr_count(device_t dev, device_t child) { struct bcma_devinfo *dinfo; uint32_t dmpcfg, oobw; dinfo = device_get_ivars(child); /* Agent block must be mapped */ if (dinfo->res_agent == NULL) return (0); /* Agent must support OOB */ dmpcfg = bhnd_bus_read_4(dinfo->res_agent, BCMA_DMP_CONFIG); if (!BCMA_DMP_GET_FLAG(dmpcfg, BCMA_DMP_CFG_OOB)) return (0); /* Return OOB width as interrupt count */ oobw = bhnd_bus_read_4(dinfo->res_agent, BCMA_DMP_OOB_OUTWIDTH(BCMA_OOB_BANK_INTR)); if (oobw > BCMA_OOB_NUM_SEL) { device_printf(dev, "ignoring invalid OOBOUTWIDTH for core %u: " "%#x\n", BCMA_DINFO_COREIDX(dinfo), oobw); return (0); } return (oobw); } /** * Default bcma(4) bus driver implementation of BHND_BUS_GET_CORE_IVEC(). * * This implementation consults @p child's agent register block, * returning the interrupt output line routed to @p child, at OOB selector * @p intr. */ int bcma_get_core_ivec(device_t dev, device_t child, u_int intr, uint32_t *ivec) { struct bcma_devinfo *dinfo; uint32_t oobsel; dinfo = device_get_ivars(child); /* Interrupt ID must be valid. */ if (intr >= bcma_get_intr_count(dev, child)) return (ENXIO); /* Fetch OOBSEL busline value */ KASSERT(dinfo->res_agent != NULL, ("missing agent registers")); oobsel = bhnd_bus_read_4(dinfo->res_agent, BCMA_DMP_OOBSELOUT( BCMA_OOB_BANK_INTR, intr)); *ivec = (oobsel >> BCMA_DMP_OOBSEL_SHIFT(intr)) & BCMA_DMP_OOBSEL_BUSLINE_MASK; return (0); } /** * Scan the device enumeration ROM table, adding all valid discovered cores to * the bus. * * @param bus The bcma bus. */ int bcma_add_children(device_t bus) { bhnd_erom_t *erom; struct bcma_erom *bcma_erom; const struct bhnd_chipid *cid; struct bcma_corecfg *corecfg; struct bcma_devinfo *dinfo; device_t child; int error; cid = BHND_BUS_GET_CHIPID(bus, bus); corecfg = NULL; /* Allocate our EROM parser */ erom = bhnd_erom_alloc(&bcma_erom_parser, cid, bus, BCMA_EROM_RID); if (erom == NULL) return (ENODEV); /* Add all cores. */ bcma_erom = (struct bcma_erom *)erom; while ((error = bcma_erom_next_corecfg(bcma_erom, &corecfg)) == 0) { int nintr; /* Add the child device */ child = BUS_ADD_CHILD(bus, 0, NULL, -1); if (child == NULL) { error = ENXIO; goto cleanup; } /* Initialize device ivars */ dinfo = device_get_ivars(child); if ((error = bcma_init_dinfo(bus, dinfo, corecfg))) goto cleanup; /* The dinfo instance now owns the corecfg value */ corecfg = NULL; /* Allocate device's agent registers, if any */ if ((error = bcma_dinfo_alloc_agent(bus, child, dinfo))) goto cleanup; /* Assign interrupts */ nintr = bhnd_get_intr_count(child); for (int rid = 0; rid < nintr; rid++) { error = BHND_BUS_ASSIGN_INTR(bus, child, rid); if (error) { device_printf(bus, "failed to assign interrupt " "%d to core %u: %d\n", rid, BCMA_DINFO_COREIDX(dinfo), error); } } /* 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); /* Issue bus callback for fully initialized child. */ BHND_BUS_CHILD_ADDED(bus, child); } /* EOF while parsing cores is expected */ if (error == ENOENT) error = 0; cleanup: bhnd_erom_free(erom); if (corecfg != NULL) bcma_free_corecfg(corecfg); if (error) device_delete_children(bus); 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_add_child, bcma_add_child), 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_get_erom_class, bcma_get_erom_class), DEVMETHOD(bhnd_bus_read_ioctl, bcma_read_ioctl), DEVMETHOD(bhnd_bus_write_ioctl, bcma_write_ioctl), DEVMETHOD(bhnd_bus_read_iost, bcma_read_iost), DEVMETHOD(bhnd_bus_is_hw_suspended, bcma_is_hw_suspended), DEVMETHOD(bhnd_bus_reset_hw, bcma_reset_hw), DEVMETHOD(bhnd_bus_suspend_hw, bcma_suspend_hw), DEVMETHOD(bhnd_bus_read_config, bcma_read_config), DEVMETHOD(bhnd_bus_write_config, bcma_write_config), 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(bhnd_bus_get_intr_count, bcma_get_intr_count), DEVMETHOD(bhnd_bus_get_core_ivec, bcma_get_core_ivec), 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); Index: head/sys/dev/bhnd/bcma/bcma_dmp.h =================================================================== --- head/sys/dev/bhnd/bcma/bcma_dmp.h (revision 308694) +++ head/sys/dev/bhnd/bcma/bcma_dmp.h (revision 308695) @@ -1,265 +1,265 @@ /*- * Copyright (c) 2015 Landon Fuller * 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. * * As such, the exact interpretation of these register definitions is * unconfirmed, and may be incorrect. */ #define BCMA_DMP_GET_FLAG(_value, _flag) \ (((_value) & _flag) != 0) #define BCMA_DMP_GET_BITS(_value, _field) \ ((_value & _field ## _MASK) >> _field ## _SHIFT) #define BHND_DMP_SET_BITS(_value, _field) \ (((_value) << _field ## _SHIFT) & _field ## _MASK) /* 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 /* Common definitions */ #define BCMA_OOB_NUM_BANKS 4 /**< number of OOB banks (A, B, C, D) */ #define BCMA_OOB_NUM_SEL 8 /**< number of OOB selectors per bank */ #define BCMA_OOB_NUM_BUSLINES 32 /**< number of bus lines managed by OOB core */ #define BCMA_OOB_BANKA 0 /**< bank A index */ #define BCMA_OOB_BANKB 1 /**< bank B index */ #define BCMA_OOB_BANKC 2 /**< bank C index */ #define BCMA_OOB_BANKD 3 /**< bank D index */ /** OOB bank used for interrupt lines */ #define BCMA_OOB_BANK_INTR BCMA_OOB_BANKA /* DMP agent registers */ #define BCMA_DMP_OOBSELINA30 0x000 /**< A0-A3 input selectors */ #define BCMA_DMP_OOBSELINA74 0x004 /**< A4-A7 input selectors */ #define BCMA_DMP_OOBSELINB30 0x020 /**< B0-B3 input selectors */ #define BCMA_DMP_OOBSELINB74 0x024 /**< B4-B7 input selectors */ #define BCMA_DMP_OOBSELINC30 0x040 /**< C0-C3 input selectors */ #define BCMA_DMP_OOBSELINC74 0x044 /**< C4-C7 input selectors */ #define BCMA_DMP_OOBSELIND30 0x060 /**< D0-D3 input selectors */ #define BCMA_DMP_OOBSELIND74 0x064 /**< D4-D7 input selectors */ #define BCMA_DMP_OOBSELOUTA30 0x100 /**< A0-A3 output selectors */ #define BCMA_DMP_OOBSELOUTA74 0x104 /**< A4-A7 output selectors */ #define BCMA_DMP_OOBSELOUTB30 0x120 /**< B0-B3 output selectors */ #define BCMA_DMP_OOBSELOUTB74 0x124 /**< B4-B7 output selectors */ #define BCMA_DMP_OOBSELOUTC30 0x140 /**< C0-C3 output selectors */ #define BCMA_DMP_OOBSELOUTC74 0x144 /**< C4-C7 output selectors */ #define BCMA_DMP_OOBSELOUTD30 0x160 /**< D0-D3 output selectors */ #define BCMA_DMP_OOBSELOUTD74 0x164 /**< D4-D7 output selectors */ #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 #define BCMA_DMP_OOBSEL(_base, _bank, _sel) \ (_base + (_bank * 8) + (_sel >= 4 ? 4 : 0)) #define BCMA_DMP_OOBSELIN(_bank, _sel) \ BCMA_DMP_OOBSEL(BCMA_DMP_OOBSELINA30, _bank, _sel) #define BCMA_DMP_OOBSELOUT(_bank, _sel) \ BCMA_DMP_OOBSEL(BCMA_DMP_OOBSELOUTA30, _bank, _sel) #define BCMA_DMP_OOBSYNC(_bank) (BCMA_DMP_OOBSYNCA + (_bank * 8)) #define BCMA_DMP_OOBSELOUT_EN(_bank) (BCMA_DMP_OOBSELOUTAEN + (_bank * 8)) #define BCMA_DMP_OOB_EXTWIDTH(_bank) (BCMA_DMP_OOBAEXTWIDTH + (_bank * 12)) #define BCMA_DMP_OOB_INWIDTH(_bank) (BCMA_DMP_OOBAINWIDTH + (_bank * 12)) #define BCMA_DMP_OOB_OUTWIDTH(_bank) (BCMA_DMP_OOBAOUTWIDTH + (_bank * 12)) // 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 /* OOBSEL(IN|OUT) */ #define BCMA_DMP_OOBSEL_MASK 0xFF /**< OOB selector mask */ #define BCMA_DMP_OOBSEL_EN (1<<7) /**< OOB selector enable bit */ #define BCMA_DMP_OOBSEL_SHIFT(_sel) ((_sel % BCMA_OOB_NUM_SEL) * 8) #define BCMA_DMP_OOBSEL_BUSLINE_MASK 0x7F /**< OOB selector bus line mask */ #define BCMA_DMP_OOBSEL_BUSLINE_SHIFT 0 #define BCMA_DMP_OOBSEL_0_MASK BCMA_DMP_OOBSEL_MASK #define BCMA_DMP_OOBSEL_1_MASK BCMA_DMP_OOBSEL_MASK #define BCMA_DMP_OOBSEL_2_MASK BCMA_DMP_OOBSEL_MASK #define BCMA_DMP_OOBSEL_3_MASK BCMA_DMP_OOBSEL_MASK #define BCMA_DMP_OOBSEL_4_MASK BCMA_DMP_OOBSEL_MASK #define BCMA_DMP_OOBSEL_5_MASK BCMA_DMP_OOBSEL_MASK #define BCMA_DMP_OOBSEL_6_MASK BCMA_DMP_OOBSEL_MASK #define BCMA_DMP_OOBSEL_7_MASK BCMA_DMP_OOBSEL_MASK #define BCMA_DMP_OOBSEL_0_SHIFT BCMA_DMP_OOBSEL_SHIFT(0) #define BCMA_DMP_OOBSEL_1_SHIFT BCMA_DMP_OOBSEL_SHIFT(1) #define BCMA_DMP_OOBSEL_2_SHIFT BCMA_DMP_OOBSEL_SHIFT(2) #define BCMA_DMP_OOBSEL_3_SHIFT BCMA_DMP_OOBSEL_SHIFT(3) #define BCMA_DMP_OOBSEL_4_SHIFT BCMA_DMP_OOBSEL_0_SHIFT #define BCMA_DMP_OOBSEL_5_SHIFT BCMA_DMP_OOBSEL_1_SHIFT #define BCMA_DMP_OOBSEL_6_SHIFT BCMA_DMP_OOBSEL_2_SHIFT #define BCMA_DMP_OOBSEL_7_SHIFT BCMA_DMP_OOBSEL_3_SHIFT /* ioctrl */ #define BCMA_DMP_IOCTRL_MASK 0x0000FFFF /* iostatus */ #define BCMA_DMP_IOST_MASK 0x0000FFFF /* resetctrl */ -#define BMCA_DMP_RC_RESET 0x00000001 +#define BCMA_DMP_RC_RESET 0x00000001 /* 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_ */