Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F136746248
D6896.id17703.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
36 KB
Referenced Files
None
Subscribers
None
D6896.id17703.diff
View Options
Index: sys/dev/bhnd/bhnd_bus_if.m
===================================================================
--- sys/dev/bhnd/bhnd_bus_if.m
+++ sys/dev/bhnd/bhnd_bus_if.m
@@ -55,6 +55,12 @@
panic("bhnd_bus_get_chipid unimplemented");
}
+ static bhnd_attach_type
+ bhnd_bus_null_get_attach_type(device_t dev, device_t child)
+ {
+ panic("bhnd_bus_get_attach_type unimplemented");
+ }
+
static int
bhnd_bus_null_read_board_info(device_t dev, device_t child,
struct bhnd_board_info *info)
@@ -197,7 +203,7 @@
METHOD bhnd_attach_type get_attach_type {
device_t dev;
device_t child;
-} DEFAULT bhnd_bus_generic_get_attach_type;
+} DEFAULT bhnd_bus_null_get_attach_type;
/**
* Attempt to read the BHND board identification from the parent bus.
Index: sys/dev/bhnd/bhnd_subr.c
===================================================================
--- sys/dev/bhnd/bhnd_subr.c
+++ sys/dev/bhnd/bhnd_subr.c
@@ -1159,21 +1159,3 @@
return (EINVAL);
};
-/**
- * Helper function for implementing BHND_BUS_GET_ATTACH_TYPE().
- *
- * This implementation of BHND_BUS_GET_ATTACH_TYPE() simply calls the
- * BHND_BUS_GET_ATTACH_TYPE() method of the parent of @p dev.
- */
-bhnd_attach_type
-bhnd_bus_generic_get_attach_type(device_t dev, device_t child)
-{
- /* iterate from cores via bhnd to bridge or SoC */
- if (device_get_parent(dev) != NULL)
- return (BHND_BUS_GET_ATTACH_TYPE(device_get_parent(dev),
- child));
-
- panic("bhnd_bus_get_attach_type unimplemented");
- /* Unreachable */
- return (BHND_ATTACH_ADAPTER);
-}
Index: sys/dev/bhnd/cores/chipc/bhnd_chipc_if.m
===================================================================
--- sys/dev/bhnd/cores/chipc/bhnd_chipc_if.m
+++ sys/dev/bhnd/cores/chipc/bhnd_chipc_if.m
@@ -36,32 +36,16 @@
#
HEADER {
- #include <dev/bhnd/nvram/bhnd_nvram.h>
/* forward declarations */
struct chipc_caps;
- struct chipc_caps *bhnd_chipc_generic_get_caps(device_t dev);
}
CODE {
-
- /**
- * Helper function for implementing BHND_CHIPC_GET_CAPS().
- *
- * This implementation of BHND_CHIPC_GET_CAPS() simply calls the
- * BHND_CHIPC_GET_CAPS() method of the parent of @p dev.
- */
- struct chipc_caps*
- bhnd_chipc_generic_get_caps(device_t dev)
+ static struct chipc_caps *
+ bhnd_chipc_null_get_caps(device_t dev)
{
-
- if (device_get_parent(dev) != NULL)
- return (BHND_CHIPC_GET_CAPS(device_get_parent(dev)));
-
panic("bhnd_chipc_generic_get_caps unimplemented");
- /* Unreachable */
- return (NULL);
}
-
}
/**
@@ -91,7 +75,7 @@
*/
METHOD struct chipc_caps * get_caps {
device_t dev;
-} DEFAULT bhnd_chipc_generic_get_caps;
+} DEFAULT bhnd_chipc_null_get_caps;
/**
* Enable hardware access to the SPROM/OTP source.
@@ -114,12 +98,3 @@
METHOD void disable_sprom {
device_t dev;
}
-
-/**
- * Return the flash configuration register value
- *
- * @param dev A bhnd(4) ChipCommon device
- */
-METHOD uint32_t get_flash_cfg {
- device_t dev;
-}
Index: sys/dev/bhnd/cores/chipc/bhnd_sprom_chipc.c
===================================================================
--- sys/dev/bhnd/cores/chipc/bhnd_sprom_chipc.c
+++ sys/dev/bhnd/cores/chipc/bhnd_sprom_chipc.c
@@ -54,22 +54,6 @@
#define CHIPC_VALID_SPROM_SRC(_src) \
((_src) == BHND_NVRAM_SRC_SPROM || (_src) == BHND_NVRAM_SRC_OTP)
-static void
-chipc_sprom_identify(driver_t *driver, device_t parent)
-{
- struct chipc_caps *caps;
-
- caps = BHND_CHIPC_GET_CAPS(parent);
- if (!CHIPC_VALID_SPROM_SRC(caps->nvram_src))
- return;
-
- if (device_find_child(parent, "bhnd_nvram", 0) != NULL)
- return;
-
- if (BUS_ADD_CHILD(parent, 0, "bhnd_nvram", 0) == NULL)
- device_printf(parent, "add bhnd_nvram failed\n");
-}
-
static int
chipc_sprom_probe(device_t dev)
{
@@ -113,7 +97,6 @@
static device_method_t chipc_sprom_methods[] = {
/* Device interface */
- DEVMETHOD(device_identify, chipc_sprom_identify),
DEVMETHOD(device_probe, chipc_sprom_probe),
DEVMETHOD(device_attach, chipc_sprom_attach),
DEVMETHOD_END
Index: sys/dev/bhnd/cores/chipc/chipc.c
===================================================================
--- sys/dev/bhnd/cores/chipc/chipc.c
+++ sys/dev/bhnd/cores/chipc/chipc.c
@@ -37,25 +37,8 @@
* With the exception of some very early chipsets, the ChipCommon core
* has been included in all HND SoCs and chipsets based on the siba(4)
* and bcma(4) interconnects, providing a common interface to chipset
- * identification, bus enumeration, UARTs, clocks, watchdog interrupts, GPIO,
- * flash, etc.
- *
- * The purpose of this driver is memory resource management for ChipCommon drivers
- * like UART, PMU, flash. ChipCommon core has several memory regions.
- *
- * ChipCommon driver has memory resource manager. Driver
- * gets information about BHND core ports/regions and map them
- * into drivers' resources.
- *
- * Here is overview of mapping:
- *
- * ------------------------------------------------------
- * | Port.Region| Purpose |
- * ------------------------------------------------------
- * | 0.0 | PMU, SPI(0x40), UART(0x300) |
- * | 1.0 | ? |
- * | 1.1 | MMIO flash (SPI & CFI) |
- * ------------------------------------------------------
+ * identification, bus enumeration, UARTs, clocks, watchdog interrupts,
+ * GPIO, flash, etc.
*/
#include <sys/param.h>
@@ -123,49 +106,10 @@
BHND_DEVICE_QUIRK_END
};
+// FIXME: IRQ shouldn't be hard-coded
+#define CHIPC_MIPS_IRQ 2
-/*
- * Here is resource configuration hints for child devices
- *
- * [Flash] There are 2 flash resources:
- * - resource ID (rid) = 0: memory-mapped flash memory
- * - resource ID (rid) = 1: memory-mapped flash registers (i.e for SPI)
- *
- * [UART] Uses IRQ and memory resources:
- * - resource ID (rid) = 0: memory-mapped registers
- * - IRQ resource ID (rid) = 0: shared IRQ line for Tx/Rx.
- */
-
-static const struct chipc_hint {
- const char *name;
- int unit;
- int type;
- int rid;
- rman_res_t base; /* relative to parent resource */
- rman_res_t size;
- u_int port; /* ignored if SYS_RES_IRQ */
- u_int region;
-} chipc_hints[] = {
- // FIXME: cfg/spi port1.1 mapping on siba(4) SoCs
- // FIXME: IRQ shouldn't be hardcoded
- /* device unit type rid base size port,region */
- { "bhnd_nvram", 0, SYS_RES_MEMORY, 0, CHIPC_SPROM_OTP, CHIPC_SPROM_OTP_SIZE, 0,0 },
- { "uart", 0, SYS_RES_MEMORY, 0, CHIPC_UART0_BASE, CHIPC_UART_SIZE, 0,0 },
- { "uart", 0, SYS_RES_IRQ, 0, 2, 1 },
- { "uart", 1, SYS_RES_MEMORY, 0, CHIPC_UART1_BASE, CHIPC_UART_SIZE, 0,0 },
- { "uart", 1, SYS_RES_IRQ, 0, 2, 1 },
- { "spi", 0, SYS_RES_MEMORY, 0, 0, RM_MAX_END, 1,1 },
- { "spi", 0, SYS_RES_MEMORY, 1, CHIPC_SFLASH_BASE, CHIPC_SFLASH_SIZE, 0,0 },
- { "cfi", 0, SYS_RES_MEMORY, 0, 0, RM_MAX_END, 1,1},
- { "cfi", 0, SYS_RES_MEMORY, 1, CHIPC_SFLASH_BASE, CHIPC_SFLASH_SIZE, 0,0 },
- { NULL }
-};
-
-
-static int chipc_try_activate_resource(
- struct chipc_softc *sc, device_t child,
- int type, int rid, struct resource *r,
- bool req_direct);
+static int chipc_add_children(struct chipc_softc *sc);
static bhnd_nvram_src chipc_find_nvram_src(struct chipc_softc *sc,
struct chipc_caps *caps);
@@ -175,6 +119,11 @@
static bool chipc_should_enable_sprom(
struct chipc_softc *sc);
+static int chipc_try_activate_resource(
+ struct chipc_softc *sc, device_t child,
+ int type, int rid, struct resource *r,
+ bool req_direct);
+
static int chipc_init_rman(struct chipc_softc *sc);
static void chipc_free_rman(struct chipc_softc *sc);
static struct rman *chipc_get_rman(struct chipc_softc *sc,
@@ -210,9 +159,6 @@
chipc_attach(device_t dev)
{
struct chipc_softc *sc;
- bhnd_addr_t enum_addr;
- uint32_t ccid_reg;
- uint8_t chip_type;
int error;
sc = device_get_softc(dev);
@@ -231,7 +177,7 @@
goto failed;
}
- /* Allocate the region containing our core registers */
+ /* Allocate the region containing the chipc register block */
if ((sc->core_region = chipc_find_region_by_rid(sc, 0)) == NULL) {
error = ENXIO;
goto failed;
@@ -242,30 +188,10 @@
if (error) {
sc->core_region = NULL;
goto failed;
- } else {
- sc->core = sc->core_region->cr_res;
}
- /* Fetch our chipset identification data */
- ccid_reg = bhnd_bus_read_4(sc->core, CHIPC_ID);
- chip_type = CHIPC_GET_BITS(ccid_reg, CHIPC_ID_BUS);
-
- switch (chip_type) {
- case BHND_CHIPTYPE_SIBA:
- /* enumeration space starts at the ChipCommon register base. */
- enum_addr = rman_get_start(sc->core->res);
- break;
- case BHND_CHIPTYPE_BCMA:
- case BHND_CHIPTYPE_BCMA_ALT:
- enum_addr = bhnd_bus_read_4(sc->core, CHIPC_EROMPTR);
- break;
- default:
- device_printf(dev, "unsupported chip type %hhu\n", chip_type);
- error = ENODEV;
- goto failed;
- }
-
- sc->ccid = bhnd_parse_chipid(ccid_reg, enum_addr);
+ /* Save a direct reference to our chipc registers */
+ sc->core = sc->core_region->cr_res;
/* Fetch and parse capability register(s) */
if ((error = chipc_read_caps(sc, &sc->caps)))
@@ -274,8 +200,10 @@
if (bootverbose)
chipc_print_caps(sc->dev, &sc->caps);
- /* Probe and attach children */
- bus_generic_probe(dev);
+ /* Attach all supported child devices */
+ if ((error = chipc_add_children(sc)))
+ goto failed;
+
if ((error = bus_generic_attach(dev)))
goto failed;
@@ -313,6 +241,119 @@
return (0);
}
+static int
+chipc_add_children(struct chipc_softc *sc)
+{
+ device_t child;
+ const char *flash_bus;
+ int error;
+
+ /* SPROM/OTP */
+ if (sc->caps.nvram_src == BHND_NVRAM_SRC_SPROM ||
+ sc->caps.nvram_src == BHND_NVRAM_SRC_OTP)
+ {
+ child = BUS_ADD_CHILD(sc->dev, 0, "bhnd_nvram", -1);
+ if (child == NULL) {
+ device_printf(sc->dev, "failed to add nvram device\n");
+ return (ENXIO);
+ }
+
+ /* Both OTP and external SPROM are mapped at CHIPC_SPROM_OTP */
+ error = chipc_set_resource(sc, child, SYS_RES_MEMORY, 0,
+ CHIPC_SPROM_OTP, CHIPC_SPROM_OTP_SIZE, 0, 0);
+ if (error)
+ return (error);
+ }
+
+#ifdef notyet
+ /*
+ * PMU/SLOWCLK/INSTACLK
+ *
+ * On AOB ("Always on Bus") devices, a PMU core (if it exists) is
+ * enumerated directly by the bhnd(4) bus -- not chipc.
+ *
+ * Otherwise, we always add a PMU child device, and let the
+ * chipc bhnd_pmu drivers probe for it. If the core supports an
+ * earlier non-PMU clock/power register interface, one of the instaclk,
+ * powerctl, or null bhnd_pmu drivers will claim the device.
+ */
+ if (!sc->caps.aob || (sc->caps.aob && !sc->caps.pmu)) {
+ child = BUS_ADD_CHILD(sc->dev, 0, "bhnd_pmu", -1);
+ if (child == NULL) {
+ device_printf(sc->dev, "failed to add pmu\n");
+ return (ENXIO);
+ }
+
+ /* Associate the applicable register block */
+ error = 0;
+ if (sc->caps.pmu) {
+ error = chipc_set_resource(sc, child, SYS_RES_MEMORY, 0,
+ CHIPC_PMU, CHIPC_PMU_SIZE, 0, 0);
+ } else if (sc->caps.power_control) {
+ error = chipc_set_resource(sc, child, SYS_RES_MEMORY, 0,
+ CHIPC_PWRCTL, CHIPC_PWRCTL_SIZE, 0, 0);
+ }
+
+ if (error)
+ return (error);
+
+ }
+#endif /* notyet */
+
+ /* All remaining devices are SoC-only */
+ if (bhnd_get_attach_type(sc->dev) != BHND_ATTACH_NATIVE)
+ return (0);
+
+ /* UARTs */
+ for (u_int i = 0; i < min(sc->caps.num_uarts, CHIPC_UART_MAX); i++) {
+ child = BUS_ADD_CHILD(sc->dev, 0, "uart", -1);
+ if (child == NULL) {
+ device_printf(sc->dev, "failed to add uart%u\n", i);
+ return (ENXIO);
+ }
+
+ /* Shared IRQ */
+ error = bus_set_resource(child, SYS_RES_IRQ, 0, CHIPC_MIPS_IRQ,
+ 1);
+ if (error) {
+ device_printf(sc->dev, "failed to set uart%u irq %u\n",
+ i, CHIPC_MIPS_IRQ);
+ return (error);
+ }
+
+ /* UART registers are mapped sequentially */
+ error = chipc_set_resource(sc, child, SYS_RES_MEMORY, 0,
+ CHIPC_UART(i), CHIPC_UART_SIZE, 0, 0);
+ if (error)
+ return (error);
+ }
+
+ /* Flash */
+ flash_bus = chipc_flash_bus_name(sc->caps.flash_type);
+ if (flash_bus != NULL) {
+ child = BUS_ADD_CHILD(sc->dev, 0, flash_bus, -1);
+ if (child == NULL) {
+ device_printf(sc->dev, "failed to add %s device\n",
+ flash_bus);
+ return (ENXIO);
+ }
+
+ /* flash memory mapping */
+ error = chipc_set_resource(sc, child, SYS_RES_MEMORY, 0,
+ 0, RM_MAX_END, 1, 1);
+ if (error)
+ return (error);
+
+ /* flashctrl registers */
+ error = chipc_set_resource(sc, child, SYS_RES_MEMORY, 1,
+ CHIPC_SFLASH_BASE, CHIPC_SFLASH_SIZE, 0, 0);
+ if (error)
+ return (error);
+ }
+
+ return (0);
+}
+
/**
* Determine the NVRAM data source for this device.
*
@@ -411,7 +452,6 @@
/* Determine flash type and parameters */
caps->cfi_width = 0;
-
switch (CHIPC_GET_BITS(cap_reg, CHIPC_CAP_FLASH)) {
case CHIPC_CAP_SFLASH_ST:
caps->flash_type = CHIPC_SFLASH_ST;
@@ -420,6 +460,7 @@
caps->flash_type = CHIPC_SFLASH_AT;
break;
case CHIPC_CAP_NFLASH:
+ /* unimplemented */
caps->flash_type = CHIPC_NFLASH;
break;
case CHIPC_CAP_PFLASH:
@@ -548,33 +589,16 @@
static device_t
chipc_add_child(device_t dev, u_int order, const char *name, int unit)
{
+ struct chipc_softc *sc;
struct chipc_devinfo *dinfo;
- const struct chipc_hint *hint;
device_t child;
- devclass_t child_dc;
- int error;
- int busrel_unit;
+
+ sc = device_get_softc(dev);
child = device_add_child_ordered(dev, order, name, unit);
if (child == NULL)
return (NULL);
- /* system-wide device unit */
- unit = device_get_unit(child);
- child_dc = device_get_devclass(child);
-
- busrel_unit = 0;
- for (int i = 0; i < unit; i++) {
- device_t tmp;
-
- tmp = devclass_get_device(child_dc, i);
- if (tmp != NULL && (device_get_parent(tmp) == dev))
- busrel_unit++;
- }
-
- /* bus-wide device unit (override unit for further hint matching) */
- unit = busrel_unit;
-
dinfo = malloc(sizeof(struct chipc_devinfo), M_BHND, M_NOWAIT);
if (dinfo == NULL) {
device_delete_child(dev, child);
@@ -584,93 +608,7 @@
resource_list_init(&dinfo->resources);
device_set_ivars(child, dinfo);
- /* Hint matching requires a device name */
- if (name == NULL)
- return (child);
-
- /* Use hint table to set child resources */
- for (hint = chipc_hints; hint->name != NULL; hint++) {
- bhnd_addr_t region_addr;
- bhnd_size_t region_size;
-
- /* Check device name */
- if (strcmp(hint->name, name) != 0)
- continue;
-
- /* Check device unit */
- if (hint->unit >= 0 && unit != hint->unit)
- continue;
-
- switch (hint->type) {
- case SYS_RES_IRQ:
- /* Add child resource */
- error = bus_set_resource(child, hint->type, hint->rid,
- hint->base, hint->size);
- if (error) {
- device_printf(dev,
- "bus_set_resource() failed for %s: %d\n",
- device_get_nameunit(child), error);
- goto failed;
- }
- break;
-
- case SYS_RES_MEMORY:
- /* Fetch region address and size */
- error = bhnd_get_region_addr(dev, BHND_PORT_DEVICE,
- hint->port, hint->region, ®ion_addr,
- ®ion_size);
- if (error) {
- device_printf(dev,
- "lookup of %s%u.%u failed: %d\n",
- bhnd_port_type_name(BHND_PORT_DEVICE),
- hint->port, hint->region, error);
- goto failed;
- }
-
- /* Verify requested range is mappable */
- if (hint->base > region_size ||
- (hint->size != RM_MAX_END &&
- (hint->size > region_size ||
- region_size - hint->base < hint->size )))
- {
- device_printf(dev,
- "%s%u.%u region cannot map requested range "
- "%#jx+%#jx\n",
- bhnd_port_type_name(BHND_PORT_DEVICE),
- hint->port, hint->region, hint->base,
- hint->size);
- }
-
- /*
- * Add child resource. If hint doesn't define the end
- * of resource window (RX_MAX_END), use end of region.
- */
-
- error = bus_set_resource(child,
- hint->type,
- hint->rid, region_addr + hint->base,
- (hint->size == RM_MAX_END) ?
- region_size - hint->base :
- hint->size);
- if (error) {
- device_printf(dev,
- "bus_set_resource() failed for %s: %d\n",
- device_get_nameunit(child), error);
- goto failed;
- }
- break;
- default:
- device_printf(child, "unknown hint resource type: %d\n",
- hint->type);
- break;
- }
- }
-
return (child);
-
-failed:
- device_delete_child(dev, child);
- return (NULL);
}
static void
@@ -705,7 +643,7 @@
u_int num_regions;
int error;
- num_regions = bhnd_get_region_count(sc->dev, port, port);
+ num_regions = bhnd_get_region_count(sc->dev, type, port);
for (u_int region = 0; region < num_regions; region++) {
/* Allocate new region record */
cr = chipc_alloc_region(sc, type, port, region);
@@ -1349,15 +1287,6 @@
return (&sc->caps);
}
-static uint32_t
-chipc_get_flash_cfg(device_t dev)
-{
- struct chipc_softc *sc;
-
- sc = device_get_softc(dev);
- return (bhnd_bus_read_4(sc->core, CHIPC_FLASH_CFG));
-}
-
static device_method_t chipc_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, chipc_probe),
@@ -1399,7 +1328,6 @@
DEVMETHOD(bhnd_chipc_enable_sprom, chipc_enable_sprom_pins),
DEVMETHOD(bhnd_chipc_disable_sprom, chipc_disable_sprom_pins),
DEVMETHOD(bhnd_chipc_get_caps, chipc_get_caps),
- DEVMETHOD(bhnd_chipc_get_flash_cfg, chipc_get_flash_cfg),
DEVMETHOD_END
};
Index: sys/dev/bhnd/cores/chipc/chipc_cfi.c
===================================================================
--- sys/dev/bhnd/cores/chipc/chipc_cfi.c
+++ sys/dev/bhnd/cores/chipc/chipc_cfi.c
@@ -40,92 +40,32 @@
#include <machine/bus.h>
-#include <dev/bhnd/bhnd_debug.h>
#include <dev/cfi/cfi_var.h>
#include "bhnd_chipc_if.h"
-#include "chipc_slicer.h"
#include "chipcreg.h"
#include "chipcvar.h"
-/*
- * **************************** PROTOTYPES ****************************
- */
-
-static void chipc_cfi_identify(driver_t *driver, device_t parent);
-static int chipc_cfi_probe(device_t dev);
-static int chipc_cfi_attach(device_t dev);
-
-/*
- * **************************** IMPLEMENTATION ************************
- */
-
-static void
-chipc_cfi_identify(driver_t *driver, device_t parent)
-{
- struct chipc_caps *caps;
-
- if (device_find_child(parent, cfi_driver_name, -1) != NULL)
- return;
-
- caps = BHND_CHIPC_GET_CAPS(parent);
- if (caps == NULL)
- return;
-
- if (caps->flash_type != CHIPC_PFLASH_CFI)
- return;
-
- BUS_ADD_CHILD(parent, 0, cfi_driver_name, -1);
- return;
-}
-
static int
chipc_cfi_probe(device_t dev)
{
- int error;
- int enabled;
- int byteswap;
- uint32_t flash_config;
struct cfi_softc *sc;
+ int error;
sc = device_get_softc(dev);
- flash_config = BHND_CHIPC_GET_FLASH_CFG(device_get_parent(dev));
-
- enabled = (flash_config & CHIPC_CF_EN);
- byteswap = (flash_config & CHIPC_CF_BS);
-
- if (enabled == 0)
- device_disable(dev);
-
- BHND_DEBUG_DEV(dev, "trying attach flash enabled=%d swapbytes=%d",
- enabled, byteswap);
-
sc->sc_width = 0;
- error = cfi_probe(dev);
- if (error == 0)
- device_set_desc(dev, "ChipCommon CFI");
- return (error);
-}
-
-static int
-chipc_cfi_attach(device_t dev)
-{
- int error;
-
- error = cfi_attach(dev);
- if (error)
+ if ((error = cfi_probe(dev)) > 0)
return (error);
- flash_register_slicer(chipc_slicer_cfi);
- return (0);
+ device_set_desc(dev, "Broadcom ChipCommon CFI");
+ return (error);
}
static device_method_t chipc_cfi_methods[] = {
/* device interface */
- DEVMETHOD(device_identify, chipc_cfi_identify),
DEVMETHOD(device_probe, chipc_cfi_probe),
- DEVMETHOD(device_attach, chipc_cfi_attach),
+ DEVMETHOD(device_attach, cfi_attach),
DEVMETHOD(device_detach, cfi_detach),
{0, 0}
@@ -138,4 +78,3 @@
};
DRIVER_MODULE(cfi, bhnd_chipc, chipc_cfi_driver, cfi_devclass, 0, 0);
-
Index: sys/dev/bhnd/cores/chipc/chipc_private.h
===================================================================
--- sys/dev/bhnd/cores/chipc/chipc_private.h
+++ sys/dev/bhnd/cores/chipc/chipc_private.h
@@ -55,6 +55,11 @@
struct resource *parent,
bhnd_size_t offset, bhnd_size_t size);
+int chipc_set_resource(struct chipc_softc *sc,
+ device_t child, int type, int rid,
+ rman_res_t start, rman_res_t count, u_int port,
+ u_int region);
+
struct chipc_region *chipc_alloc_region(struct chipc_softc *sc,
bhnd_port_type type, u_int port,
u_int region);
Index: sys/dev/bhnd/cores/chipc/chipc_spi.h
===================================================================
--- sys/dev/bhnd/cores/chipc/chipc_spi.h
+++ sys/dev/bhnd/cores/chipc/chipc_spi.h
@@ -62,28 +62,23 @@
#define CHIPC_SPI_FLASHDATA 0x08
struct chipc_spi_softc {
- device_t dev;
-
- /* SPI registers */
- struct resource *sc_mem_res;
-
- /* MMIO flash */
- struct resource *sc_res;
+ device_t sc_dev;
+ struct resource *sc_res; /**< SPI registers */
+ int sc_rid;
};
/* register space access macros */
-#define SPI_BARRIER_WRITE(sc) bus_barrier((sc)->sc_mem_res, 0, 0, \
+#define SPI_BARRIER_WRITE(sc) bus_barrier((sc)->sc_res, 0, 0, \
BUS_SPACE_BARRIER_WRITE)
-#define SPI_BARRIER_READ(sc) bus_barrier((sc)->sc_mem_res, 0, 0, \
+#define SPI_BARRIER_READ(sc) bus_barrier((sc)->sc_res, 0, 0, \
BUS_SPACE_BARRIER_READ)
-#define SPI_BARRIER_RW(sc) bus_barrier((sc)->sc_mem_res, 0, 0, \
- BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE)
+#define SPI_BARRIER_RW(sc) bus_barrier((sc)->sc_res, 0, 0, \
+ BUS_SPACE_BARRIER_READ | \
+ BUS_SPACE_BARRIER_WRITE)
-#define SPI_WRITE(sc, reg, val) do { \
- bus_write_4(sc->sc_mem_res, (reg), (val)); \
- } while (0)
+#define SPI_WRITE(sc, reg, val) bus_write_4(sc->sc_res, (reg), (val));
-#define SPI_READ(sc, reg) bus_read_4(sc->sc_mem_res, (reg))
+#define SPI_READ(sc, reg) bus_read_4(sc->sc_res, (reg))
#define SPI_SET_BITS(sc, reg, bits) \
SPI_WRITE(sc, reg, SPI_READ(sc, (reg)) | (bits))
Index: sys/dev/bhnd/cores/chipc/chipc_spi.c
===================================================================
--- sys/dev/bhnd/cores/chipc/chipc_spi.c
+++ sys/dev/bhnd/cores/chipc/chipc_spi.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2016 Michael Zhilin <mizhka@gmail.com>
+ * Copyright (c) 2016 Landon Fuller <landonf@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -41,135 +42,111 @@
#include <machine/bus.h>
#include <dev/bhnd/bhndvar.h>
-/*
- * SPI BUS interface
- */
+
#include <dev/spibus/spi.h>
+#include "bhnd_chipc_if.h"
+
#include "spibus_if.h"
#include "chipcreg.h"
#include "chipcvar.h"
-#include "chipc_spi.h"
-#include "bhnd_chipc_if.h"
-
-/*
- * Flash slicer
- */
-#include "chipc_slicer.h"
-/*
- * **************************** PROTOTYPES ****************************
- */
+#include "chipc_spi.h"
-static void chipc_spi_identify(driver_t *driver, device_t parent);
static int chipc_spi_probe(device_t dev);
static int chipc_spi_attach(device_t dev);
+static int chipc_spi_detach(device_t dev);
static int chipc_spi_transfer(device_t dev, device_t child,
struct spi_command *cmd);
static int chipc_spi_txrx(struct chipc_spi_softc *sc, uint8_t in,
uint8_t* out);
static int chipc_spi_wait(struct chipc_spi_softc *sc);
-/*
- * **************************** IMPLEMENTATION ************************
- */
-
-static void
-chipc_spi_identify(driver_t *driver, device_t parent)
+static int
+chipc_spi_probe(device_t dev)
{
- struct chipc_caps *caps;
- device_t spidev;
- device_t spibus;
- device_t flash;
- char* flash_name;
- int err;
-
- flash_name = NULL;
-
- if (device_find_child(parent, "spi", -1) != NULL)
- return;
-
- caps = BHND_CHIPC_GET_CAPS(parent);
- if (caps == NULL) {
- BHND_ERROR_DEV(parent, "can't retrieve ChipCommon capabilities");
- return;
- }
+ device_set_desc(dev, "Broadcom ChipCommon SPI");
+ return (BUS_PROBE_NOWILDCARD);
+}
- switch (caps->flash_type) {
- case CHIPC_SFLASH_AT:
- flash_name = "at45d";
- break;
- case CHIPC_SFLASH_ST:
- flash_name = "mx25l";
- break;
- default:
- return;
- }
+static int
+chipc_spi_attach(device_t dev)
+{
+ struct chipc_spi_softc *sc;
+ struct chipc_caps *ccaps;
+ device_t flash_dev;
+ device_t spibus;
+ const char *flash_name;
+ int error;
- spidev = BUS_ADD_CHILD(parent, 0, "spi", -1);
- if (spidev == NULL) {
- BHND_ERROR_DEV(parent, "can't add chipc_spi to ChipCommon");
- return;
- }
+ sc = device_get_softc(dev);
- err = device_probe_and_attach(spidev);
- if (err) {
- BHND_ERROR_DEV(spidev, "failed attach chipc_spi: %d", err);
- return;
+ /* Allocate SPI controller registers */
+ sc->sc_rid = 1;
+ sc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rid,
+ RF_ACTIVE);
+ if (sc->sc_res == NULL) {
+ device_printf(dev, "failed to allocate device registers\n");
+ return (ENXIO);
}
- spibus = device_find_child(spidev, "spibus", -1);
- if (spibus == NULL) {
- BHND_ERROR_DEV(spidev, "can't find spibus under chipc_spi");
- return;
+ /*
+ * Add flash device
+ *
+ * XXX: This should be replaced with a DEVICE_IDENTIFY implementation
+ * in chipc-specific subclasses of the mx25l and at45d drivers.
+ */
+ if ((spibus = device_add_child(dev, "spibus", -1)) == NULL) {
+ device_printf(dev, "failed to add spibus\n");
+ error = ENXIO;
+ goto failed;
}
- flash = BUS_ADD_CHILD(spibus, 0, flash_name, -1);
- if (flash == NULL) {
- BHND_ERROR_DEV(spibus, "can't add %s to spibus", flash_name);
- return;
+ /* Let spibus perform full attach before we try to call
+ * BUS_ADD_CHILD() */
+ if ((error = bus_generic_attach(dev)))
+ goto failed;
+
+ /* Determine flash type and add the flash child */
+ ccaps = BHND_CHIPC_GET_CAPS(device_get_parent(dev));
+ flash_name = chipc_sflash_device_name(ccaps->flash_type);
+ if (flash_name != NULL) {
+ flash_dev = BUS_ADD_CHILD(spibus, 0, flash_name, -1);
+ if (flash_dev == NULL) {
+ device_printf(dev, "failed to add %s\n", flash_name);
+ error = ENXIO;
+ goto failed;
+ }
+
+ if ((error = device_probe_and_attach(flash_dev))) {
+ device_printf(dev, "failed to attach %s: %d\n",
+ flash_name, error);
+ goto failed;
+ }
}
- err = device_probe_and_attach(flash);
- if (err)
- BHND_ERROR_DEV(flash, "failed attach flash %s: %d", flash_name,
- err);
-
- return;
-}
+ return (0);
-static int
-chipc_spi_probe(device_t dev)
-{
- device_set_desc(dev, "ChipCommon SPI");
- return (BUS_PROBE_DEFAULT);
+failed:
+ device_delete_children(dev);
+ bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rid, sc->sc_res);
+ return (error);
}
-struct resource_spec spec_mem[] = {
- {SYS_RES_MEMORY, 0, RF_ACTIVE},
- {SYS_RES_MEMORY, 1, RF_ACTIVE},
- { -1, -1, 0 }
- };
-
static int
-chipc_spi_attach(device_t dev)
+chipc_spi_detach(device_t dev)
{
- int err;
struct chipc_spi_softc *sc;
- struct resource *mem[2];
+ int error;
sc = device_get_softc(dev);
- err = bus_alloc_resources(dev, spec_mem, mem);
- if (err != 0)
- return (ENXIO);
- sc->sc_res = mem[0];
- sc->sc_mem_res = mem[1];
+ if ((error = bus_generic_detach(dev)))
+ return (error);
- flash_register_slicer(chipc_slicer_spi);
- device_add_child(dev, "spibus", 0);
- return (bus_generic_attach(dev));
+ bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rid, sc->sc_res);
+ return (0);
}
static int
@@ -256,13 +233,11 @@
return (0);
}
-/*
- * **************************** METADATA ************************
- */
static device_method_t chipc_spi_methods[] = {
- DEVMETHOD(device_identify, chipc_spi_identify),
DEVMETHOD(device_probe, chipc_spi_probe),
DEVMETHOD(device_attach, chipc_spi_attach),
+ DEVMETHOD(device_detach, chipc_spi_detach),
+
/* SPI */
DEVMETHOD(spibus_transfer, chipc_spi_transfer),
DEVMETHOD_END
@@ -277,4 +252,4 @@
static devclass_t chipc_spi_devclass;
DRIVER_MODULE(chipc_spi, bhnd_chipc, chipc_spi_driver, chipc_spi_devclass,
- 0, 0);
+ 0, 0);
Index: sys/dev/bhnd/cores/chipc/chipc_subr.c
===================================================================
--- sys/dev/bhnd/cores/chipc/chipc_subr.c
+++ sys/dev/bhnd/cores/chipc/chipc_subr.c
@@ -38,6 +38,93 @@
#include "chipcvar.h"
/**
+ * Return a human-readable name for the given flash @p type.
+ */
+const char *
+chipc_flash_name(chipc_flash type)
+{
+ switch (type) {
+ case CHIPC_PFLASH_CFI:
+ return ("CFI Flash");
+
+ case CHIPC_SFLASH_ST:
+ case CHIPC_SFLASH_AT:
+ return ("SPI Flash");
+
+ case CHIPC_QSFLASH_ST:
+ case CHIPC_QSFLASH_AT:
+ return ("QSPI Flash");
+
+ case CHIPC_NFLASH:
+ case CHIPC_NFLASH_4706:
+ return ("NAND");
+
+ case CHIPC_FLASH_NONE:
+ default:
+ return ("unknown");
+ }
+}
+
+/**
+ * Return the name of the bus device class used by flash @p type,
+ * or NULL if @p type is unsupported.
+ */
+const char *
+chipc_flash_bus_name(chipc_flash type)
+{
+ switch (type) {
+ case CHIPC_PFLASH_CFI:
+ return ("cfi");
+
+ case CHIPC_SFLASH_ST:
+ case CHIPC_SFLASH_AT:
+ return ("spi");
+
+ case CHIPC_QSFLASH_ST:
+ case CHIPC_QSFLASH_AT:
+ /* unimplemented; spi? */
+ return (NULL);
+
+ case CHIPC_NFLASH:
+ case CHIPC_NFLASH_4706:
+ /* unimplemented; nandbus? */
+ return (NULL);
+
+ case CHIPC_FLASH_NONE:
+ default:
+ return (NULL);
+ }
+}
+
+/**
+ * Return the name of the flash device class for SPI flash @p type,
+ * or NULL if @p type does not use SPI, or is unsupported.
+ */
+const char *
+chipc_sflash_device_name(chipc_flash type)
+{
+ switch (type) {
+ case CHIPC_SFLASH_ST:
+ return ("mx25l");
+
+ case CHIPC_SFLASH_AT:
+ return ("at45d");
+
+ case CHIPC_QSFLASH_ST:
+ case CHIPC_QSFLASH_AT:
+ /* unimplemented */
+ return (NULL);
+
+ case CHIPC_PFLASH_CFI:
+ case CHIPC_NFLASH:
+ case CHIPC_NFLASH_4706:
+ case CHIPC_FLASH_NONE:
+ default:
+ return (NULL);
+ }
+}
+
+/**
* Initialize child resource @p r with a virtual address, tag, and handle
* copied from @p parent, adjusted to contain only the range defined by
* @p offsize and @p size.
@@ -74,6 +161,72 @@
return (0);
}
+/**
+ * Associate a resource with a given resource ID, relative to the given
+ * port and region.
+ *
+ * This function behaves identically to bus_set_resource() for all resource
+ * types other than SYS_RES_MEMORY.
+ *
+ * For SYS_RES_MEMORY resources, the specified @p region's address and size
+ * will be fetched from the bhnd(4) bus, and bus_set_resource() will be called
+ * with @p start added the region's actual base address.
+ *
+ * To use the default region values for @p start and @p count, specify
+ * a @p start value of 0ul, and an end value of RMAN_MAX_END
+ *
+ * @param sc chipc driver state.
+ * @param child The device to set the resource on.
+ * @param type The resource type.
+ * @param rid The resource ID.
+ * @param start The resource start address (if SYS_RES_MEMORY, this is
+ * relative to @p region's base address).
+ * @param count The length of the resource.
+ * @param port The mapping port number (ignored if not SYS_RES_MEMORY).
+ * @param region The mapping region number (ignored if not SYS_RES_MEMORY).
+ */
+int
+chipc_set_resource(struct chipc_softc *sc, device_t child, int type, int rid,
+ rman_res_t start, rman_res_t count, u_int port, u_int region)
+{
+ bhnd_addr_t region_addr;
+ bhnd_size_t region_size;
+ bool isdefault;
+ int error;
+
+ if (type != SYS_RES_MEMORY)
+ return (bus_set_resource(child, type, rid, start, count));
+
+ isdefault = RMAN_IS_DEFAULT_RANGE(start, count);
+
+ /* Fetch region address and size */
+ error = bhnd_get_region_addr(sc->dev, BHND_PORT_DEVICE, port,
+ region, ®ion_addr, ®ion_size);
+ if (error) {
+ device_printf(sc->dev,
+ "lookup of %s%u.%u failed: %d\n",
+ bhnd_port_type_name(BHND_PORT_DEVICE), port, region, error);
+ return (error);
+ }
+
+ /* Populate defaults */
+ if (isdefault) {
+ start = 0;
+ count = region_size;
+ }
+
+ /* Verify requested range is mappable */
+ if (start > region_size || region_size - start < count) {
+ device_printf(sc->dev,
+ "%s%u.%u region cannot map requested range %#jx+%#jx\n",
+ bhnd_port_type_name(BHND_PORT_DEVICE), port, region, start,
+ count);
+ return (ERANGE);
+ }
+
+ return (bus_set_resource(child, type, rid, region_addr + start, count));
+}
+
/*
* Print a capability structure.
Index: sys/dev/bhnd/cores/chipc/chipcreg.h
===================================================================
--- sys/dev/bhnd/cores/chipc/chipcreg.h
+++ sys/dev/bhnd/cores/chipc/chipcreg.h
@@ -175,8 +175,8 @@
#define CHIPC_UART_BASE 0x300
#define CHIPC_UART_SIZE 0x100
-#define CHIPC_UART0_BASE CHIPC_UART_BASE
-#define CHIPC_UART1_BASE (CHIPC_UART_BASE + CHIPC_UART_SIZE)
+#define CHIPC_UART_MAX 3 /**< max UART blocks */
+#define CHIPC_UART(_n) (CHIPC_UART_BASE + (CHIPC_UART_SIZE*_n))
/* PMU registers (rev >= 20) */
#define CHIPC_PMU_BASE 0x600
Index: sys/dev/bhnd/cores/chipc/chipcvar.h
===================================================================
--- sys/dev/bhnd/cores/chipc/chipcvar.h
+++ sys/dev/bhnd/cores/chipc/chipcvar.h
@@ -59,6 +59,10 @@
CHIPC_NFLASH_4706 = 7 /**< BCM4706 NAND flash */
} chipc_flash;
+const char *chipc_flash_name(chipc_flash type);
+const char *chipc_flash_bus_name(chipc_flash type);
+const char *chipc_sflash_device_name(chipc_flash type);
+
/**
* ChipCommon capability flags;
*/
@@ -69,15 +73,16 @@
uint8_t uart_gpio; /**< UARTs own GPIO pins 12-15 */
uint8_t extbus_type; /**< ExtBus type (CHIPC_CAP_EXTBUS_*) */
- chipc_flash flash_type; /**< Flash type */
- bhnd_nvram_src nvram_src; /**< identified NVRAM source */
+ chipc_flash flash_type; /**< flash type */
+ uint8_t cfi_width; /**< CFI bus width, 0 if unknown or CFI
+ not present */
+
+ bhnd_nvram_src nvram_src; /**< identified NVRAM source */
bus_size_t sprom_offset; /**< Offset to SPROM data within
SPROM/OTP, 0 if unknown or not
present */
uint8_t otp_size; /**< OTP (row?) size, 0 if not present */
- uint8_t cfi_width; /**< CFI bus width, 0 if unknown or CFI
- not present */
uint8_t pll_type; /**< PLL type */
bool power_control; /**< Power control available */
@@ -200,7 +205,6 @@
struct bhnd_resource *core; /**< core registers. */
struct chipc_region *core_region; /**< region containing core registers */
- struct bhnd_chipid ccid; /**< chip identification */
uint32_t quirks; /**< chipc quirk flags */
struct chipc_caps caps; /**< chipc capabilities */
Index: sys/mips/broadcom/uart_bus_chipc.c
===================================================================
--- sys/mips/broadcom/uart_bus_chipc.c
+++ sys/mips/broadcom/uart_bus_chipc.c
@@ -45,84 +45,29 @@
#include <dev/uart/uart_bus.h>
#include <dev/uart/uart_cpu.h>
-#include <dev/bhnd/cores/chipc/chipcvar.h>
-
#include "uart_if.h"
#include "bhnd_chipc_if.h"
+#include "bcm_socinfo.h"
-static int uart_chipc_probe(device_t dev);
-
-extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
-
-static void
-uart_chipc_identify(driver_t *driver, device_t parent)
-{
- struct chipc_caps *caps;
-
- if (device_find_child(parent, "uart", -1) != NULL)
- return;
-
- caps = BHND_CHIPC_GET_CAPS(parent);
-
- if (caps == NULL) {
- device_printf(parent, "error: can't retrieve ChipCommon "
- "capabilities\n");
- return;
- }
-
- if (caps->num_uarts == 0)
- return;
-
- /*
- * TODO: add more than one UART
- */
- BUS_ADD_CHILD(parent, 0, "uart", -1);
-}
static int
uart_chipc_probe(device_t dev)
{
struct uart_softc *sc;
- struct resource *res;
- int rid;
- int err;
-
- rid = 0;
- res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
- if (res == NULL) {
- device_printf(dev, "can't allocate main resource\n");
- return (ENXIO);
- }
+ struct bcm_socinfo *socinfo;
sc = device_get_softc(dev);
sc->sc_class = &uart_ns8250_class;
- sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs);
- if (sc->sc_sysdev == NULL) {
- device_printf(dev, "missing sysdev\n");
- return (EINVAL);
- }
-
- bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas));
-
- sc->sc_sysdev->bas.bst = rman_get_bustag(res);
- sc->sc_sysdev->bas.bsh = rman_get_bushandle(res);
- sc->sc_bas.bst = sc->sc_sysdev->bas.bst;
- sc->sc_bas.bsh = sc->sc_sysdev->bas.bsh;
-
- err = bus_release_resource(dev, SYS_RES_MEMORY, rid, res);
- if (err) {
- device_printf(dev, "can't release resource [%d]\n", rid);
- return (ENXIO);
- }
- /* We use internal SoC clock generator with non-standart freq MHz */
- return (uart_bus_probe(dev, 0, sc->sc_sysdev->bas.rclk, 0, 0));
+ /* TODO: UART rate should be calculated from CPU clock speed
+ * as fetched from bhnd bus */
+ socinfo = bcm_get_socinfo();
+ return (uart_bus_probe(dev, 0, socinfo->uartrate, 0, 0));
}
static device_method_t uart_chipc_methods[] = {
/* Device interface */
- DEVMETHOD(device_identify, uart_chipc_identify),
DEVMETHOD(device_probe, uart_chipc_probe),
DEVMETHOD(device_attach, uart_bus_attach),
DEVMETHOD(device_detach, uart_bus_detach),
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Nov 20, 5:46 AM (7 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25710340
Default Alt Text
D6896.id17703.diff (36 KB)
Attached To
Mode
D6896: bhnd(4) chipc child enumeration using the chipc capabilities.
Attached
Detach File
Event Timeline
Log In to Comment