svn commit: r302189 - in head/sys: dev/bhnd dev/bhnd/cores/chipc mips/broadcom
Landon J. Fuller
landonf at FreeBSD.org
Sat Jun 25 04:33:03 UTC 2016
Author: landonf
Date: Sat Jun 25 04:33:00 2016
New Revision: 302189
URL: https://svnweb.freebsd.org/changeset/base/302189
Log:
bhnd(4): Perform explicit chipc child enumeration.
Replaces use of DEVICE_IDENTIFY with explicit enumeration of chipc
child devices using the chipc capability structure.
This is a precursor to PMU support, which requires more complex resource
assignment handling than achievable with the static device name-based
hints table.
Reviewed by: Michael Zhilin <mizkha at gmail.com> (Broadcom MIPS support)
Approved by: re (gjb), adrian (mentor)
Differential Revision: https://reviews.freebsd.org/D6896
Modified:
head/sys/dev/bhnd/bhnd_bus_if.m
head/sys/dev/bhnd/bhnd_subr.c
head/sys/dev/bhnd/cores/chipc/bhnd_chipc_if.m
head/sys/dev/bhnd/cores/chipc/bhnd_sprom_chipc.c
head/sys/dev/bhnd/cores/chipc/chipc.c
head/sys/dev/bhnd/cores/chipc/chipc_cfi.c
head/sys/dev/bhnd/cores/chipc/chipc_private.h
head/sys/dev/bhnd/cores/chipc/chipc_slicer.c
head/sys/dev/bhnd/cores/chipc/chipc_slicer.h
head/sys/dev/bhnd/cores/chipc/chipc_spi.c
head/sys/dev/bhnd/cores/chipc/chipc_spi.h
head/sys/dev/bhnd/cores/chipc/chipc_subr.c
head/sys/dev/bhnd/cores/chipc/chipcreg.h
head/sys/dev/bhnd/cores/chipc/chipcvar.h
head/sys/mips/broadcom/uart_bus_chipc.c
Modified: head/sys/dev/bhnd/bhnd_bus_if.m
==============================================================================
--- head/sys/dev/bhnd/bhnd_bus_if.m Sat Jun 25 02:09:49 2016 (r302188)
+++ head/sys/dev/bhnd/bhnd_bus_if.m Sat Jun 25 04:33:00 2016 (r302189)
@@ -55,6 +55,12 @@ CODE {
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 const struct bhnd_chipid * get_ch
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.
Modified: head/sys/dev/bhnd/bhnd_subr.c
==============================================================================
--- head/sys/dev/bhnd/bhnd_subr.c Sat Jun 25 02:09:49 2016 (r302188)
+++ head/sys/dev/bhnd/bhnd_subr.c Sat Jun 25 04:33:00 2016 (r302189)
@@ -1159,21 +1159,3 @@ bhnd_bus_generic_deactivate_resource(dev
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);
-}
Modified: head/sys/dev/bhnd/cores/chipc/bhnd_chipc_if.m
==============================================================================
--- head/sys/dev/bhnd/cores/chipc/bhnd_chipc_if.m Sat Jun 25 02:09:49 2016 (r302188)
+++ head/sys/dev/bhnd/cores/chipc/bhnd_chipc_if.m Sat Jun 25 04:33:00 2016 (r302189)
@@ -36,32 +36,16 @@ INTERFACE bhnd_chipc;
#
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 void write_chipctrl {
*/
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 int enable_sprom {
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;
-}
Modified: head/sys/dev/bhnd/cores/chipc/bhnd_sprom_chipc.c
==============================================================================
--- head/sys/dev/bhnd/cores/chipc/bhnd_sprom_chipc.c Sat Jun 25 02:09:49 2016 (r302188)
+++ head/sys/dev/bhnd/cores/chipc/bhnd_sprom_chipc.c Sat Jun 25 04:33:00 2016 (r302189)
@@ -54,22 +54,6 @@ __FBSDID("$FreeBSD$");
#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 @@ chipc_sprom_attach(device_t dev)
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
Modified: head/sys/dev/bhnd/cores/chipc/chipc.c
==============================================================================
--- head/sys/dev/bhnd/cores/chipc/chipc.c Sat Jun 25 02:09:49 2016 (r302188)
+++ head/sys/dev/bhnd/cores/chipc/chipc.c Sat Jun 25 04:33:00 2016 (r302189)
@@ -37,25 +37,8 @@ __FBSDID("$FreeBSD$");
* 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>
@@ -76,6 +59,7 @@ __FBSDID("$FreeBSD$");
#include "chipcreg.h"
#include "chipcvar.h"
+
#include "chipc_private.h"
devclass_t bhnd_chipc_devclass; /**< bhnd(4) chipcommon device class */
@@ -123,49 +107,10 @@ static struct bhnd_device_quirk chipc_qu
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 +120,11 @@ static int chipc_read_caps(struct chi
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 +160,6 @@ static int
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 +178,7 @@ chipc_attach(device_t dev)
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 +189,10 @@ chipc_attach(device_t dev)
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 +201,10 @@ chipc_attach(device_t dev)
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 +242,119 @@ chipc_detach(device_t dev)
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 +453,6 @@ chipc_read_caps(struct chipc_softc *sc,
/* 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 +461,7 @@ chipc_read_caps(struct chipc_softc *sc,
caps->flash_type = CHIPC_SFLASH_AT;
break;
case CHIPC_CAP_NFLASH:
+ /* unimplemented */
caps->flash_type = CHIPC_NFLASH;
break;
case CHIPC_CAP_PFLASH:
@@ -548,33 +590,16 @@ chipc_child_location_str(device_t dev, d
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 +609,7 @@ chipc_add_child(device_t dev, u_int orde
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 +644,7 @@ chipc_rman_init_regions (struct chipc_so
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 +1288,6 @@ chipc_get_caps(device_t dev)
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 +1329,6 @@ static device_method_t chipc_methods[] =
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
};
Modified: head/sys/dev/bhnd/cores/chipc/chipc_cfi.c
==============================================================================
--- head/sys/dev/bhnd/cores/chipc/chipc_cfi.c Sat Jun 25 02:09:49 2016 (r302188)
+++ head/sys/dev/bhnd/cores/chipc/chipc_cfi.c Sat Jun 25 04:33:00 2016 (r302189)
@@ -40,90 +40,39 @@ __FBSDID("$FreeBSD$");
#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;
-}
+#include "chipc_slicer.h"
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");
+ if ((error = cfi_probe(dev)) > 0)
+ return (error);
+
+ device_set_desc(dev, "Broadcom ChipCommon CFI");
return (error);
}
static int
chipc_cfi_attach(device_t dev)
{
- int error;
-
- error = cfi_attach(dev);
- if (error)
- return (error);
-
- flash_register_slicer(chipc_slicer_cfi);
- return (0);
+ chipc_register_slicer(CHIPC_PFLASH_CFI);
+ return (cfi_attach(dev));
}
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_detach, cfi_detach),
@@ -138,4 +87,3 @@ static driver_t chipc_cfi_driver = {
};
DRIVER_MODULE(cfi, bhnd_chipc, chipc_cfi_driver, cfi_devclass, 0, 0);
-
Modified: head/sys/dev/bhnd/cores/chipc/chipc_private.h
==============================================================================
--- head/sys/dev/bhnd/cores/chipc/chipc_private.h Sat Jun 25 02:09:49 2016 (r302188)
+++ head/sys/dev/bhnd/cores/chipc/chipc_private.h Sat Jun 25 04:33:00 2016 (r302189)
@@ -55,6 +55,11 @@ int chipc_init_child_resource(struct
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);
Modified: head/sys/dev/bhnd/cores/chipc/chipc_slicer.c
==============================================================================
--- head/sys/dev/bhnd/cores/chipc/chipc_slicer.c Sat Jun 25 02:09:49 2016 (r302188)
+++ head/sys/dev/bhnd/cores/chipc/chipc_slicer.c Sat Jun 25 04:33:00 2016 (r302189)
@@ -54,58 +54,88 @@ __FBSDID("$FreeBSD$");
#include <dev/cfi/cfi_var.h>
#include "chipc_spi.h"
-static int chipc_slicer_walk(device_t dev, struct resource* res,
+static int chipc_slicer_walk(device_t dev, struct resource *res,
struct flash_slice *slices, int *nslices);
+void
+chipc_register_slicer(chipc_flash flash_type)
+{
+ switch (flash_type) {
+ case CHIPC_SFLASH_AT:
+ case CHIPC_SFLASH_ST:
+ flash_register_slicer(chipc_slicer_spi);
+ break;
+ case CHIPC_PFLASH_CFI:
+ flash_register_slicer(chipc_slicer_cfi);
+ break;
+ default:
+ /* Unsupported */
+ break;
+ }
+}
+
int
chipc_slicer_cfi(device_t dev, struct flash_slice *slices, int *nslices)
{
struct cfi_softc *sc;
+ device_t parent;
- if (strcmp("cfi", device_get_name(dev)) != 0)
- return (0);
+ /* must be CFI flash */
+ if (device_get_devclass(dev) != devclass_find("cfi"))
+ return (ENXIO);
+
+ /* must be attached to chipc */
+ if ((parent = device_get_parent(dev)) == NULL) {
+ BHND_ERROR_DEV(dev, "no found ChipCommon device");
+ return (ENXIO);
+ }
- sc = device_get_softc(dev);
+ if (device_get_devclass(parent) != devclass_find("bhnd_chipc")) {
+ BHND_ERROR_DEV(dev, "no found ChipCommon device");
+ return (ENXIO);
+ }
+ sc = device_get_softc(dev);
return (chipc_slicer_walk(dev, sc->sc_res, slices, nslices));
}
int
chipc_slicer_spi(device_t dev, struct flash_slice *slices, int *nslices)
{
- /* flash(mx25l) <- spibus <- chipc_spi */
- device_t spibus;
- device_t chipc_spi;
struct chipc_spi_softc *sc;
+ device_t chipc, spi, spibus;
BHND_DEBUG_DEV(dev, "initting SPI slicer: %s", device_get_name(dev));
- if (strcmp("mx25l", device_get_name(dev)) != 0)
- return (EINVAL);
-
+ /* must be SPI-attached flash */
spibus = device_get_parent(dev);
if (spibus == NULL) {
BHND_ERROR_DEV(dev, "no found ChipCommon SPI BUS device");
- return (EINVAL);
+ return (ENXIO);
}
- chipc_spi = device_get_parent(spibus);
- if (chipc_spi == NULL) {
- BHND_ERROR_DEV(spibus, "no found ChipCommon SPI device");
- return (EINVAL);
+ spi = device_get_parent(spibus);
+ if (spi == NULL) {
+ BHND_ERROR_DEV(dev, "no found ChipCommon SPI device");
+ return (ENXIO);
}
- sc = device_get_softc(chipc_spi);
+ chipc = device_get_parent(spi);
+ if (device_get_devclass(chipc) != devclass_find("bhnd_chipc")) {
+ BHND_ERROR_DEV(dev, "no found ChipCommon device");
+ return (ENXIO);
+ }
- return (chipc_slicer_walk(dev, sc->sc_res, slices, nslices));
+ sc = device_get_softc(spi);
+ return (chipc_slicer_walk(dev, sc->sc_flash_res, slices, nslices));
}
/*
* Main processing part
*/
static int
-chipc_slicer_walk(device_t dev, struct resource* res,
- struct flash_slice *slices, int *nslices)
+chipc_slicer_walk(device_t dev, struct resource *res,
+ struct flash_slice *slices, int *nslices)
{
uint32_t fw_len;
uint32_t fs_ofs;
Modified: head/sys/dev/bhnd/cores/chipc/chipc_slicer.h
==============================================================================
--- head/sys/dev/bhnd/cores/chipc/chipc_slicer.h Sat Jun 25 02:09:49 2016 (r302188)
+++ head/sys/dev/bhnd/cores/chipc/chipc_slicer.h Sat Jun 25 04:33:00 2016 (r302189)
@@ -34,10 +34,13 @@
#include <sys/slicer.h>
+#include "chipcvar.h"
+
#define TRX_MAGIC 0x30524448
#define CFE_MAGIC 0x43464531
#define NVRAM_MAGIC 0x48534C46
+void chipc_register_slicer(chipc_flash flash_type);
int chipc_slicer_spi(device_t dev, struct flash_slice *slices,
int *nslices);
int chipc_slicer_cfi(device_t dev, struct flash_slice *slices,
Modified: head/sys/dev/bhnd/cores/chipc/chipc_spi.c
==============================================================================
--- head/sys/dev/bhnd/cores/chipc/chipc_spi.c Sat Jun 25 02:09:49 2016 (r302188)
+++ head/sys/dev/bhnd/cores/chipc/chipc_spi.c Sat Jun 25 04:33:00 2016 (r302189)
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2016 Michael Zhilin <mizhka at gmail.com>
+ * Copyright (c) 2016 Landon Fuller <landonf at FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -41,135 +42,134 @@ __FBSDID("$FreeBSD$");
#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 int
+chipc_spi_probe(device_t dev)
+{
+ device_set_desc(dev, "Broadcom ChipCommon SPI");
+ return (BUS_PROBE_NOWILDCARD);
+}
-static void
-chipc_spi_identify(driver_t *driver, device_t parent)
+static int
+chipc_spi_attach(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;
- }
+ struct chipc_spi_softc *sc;
+ struct chipc_caps *ccaps;
+ device_t flash_dev;
+ device_t spibus;
+ const char *flash_name;
+ int error;
- switch (caps->flash_type) {
- case CHIPC_SFLASH_AT:
- flash_name = "at45d";
- break;
- case CHIPC_SFLASH_ST:
- flash_name = "mx25l";
- break;
- default:
- return;
- }
+ sc = device_get_softc(dev);
- spidev = BUS_ADD_CHILD(parent, 0, "spi", -1);
- if (spidev == NULL) {
- BHND_ERROR_DEV(parent, "can't add chipc_spi to ChipCommon");
- 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);
}
- err = device_probe_and_attach(spidev);
- if (err) {
- BHND_ERROR_DEV(spidev, "failed attach chipc_spi: %d", err);
- return;
+ /* Allocate flash shadow region */
+ sc->sc_flash_rid = 0;
+ sc->sc_flash_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+ &sc->sc_flash_rid, RF_ACTIVE);
+ if (sc->sc_flash_res == NULL) {
+ device_printf(dev, "failed to allocate flash region\n");
+ error = ENXIO;
+ goto failed;
}
- 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);
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-head
mailing list