svn commit: r299241 - in head/sys: conf dev/bhnd dev/bhnd/bhndb dev/bhnd/cores/chipc dev/bhnd/nvram dev/bhnd/tools dev/bwn modules/bhnd modules/bhnd/bhndb modules/bhnd/bhndb_pci modules/bhnd/cores/...
Adrian Chadd
adrian at FreeBSD.org
Sun May 8 19:14:07 UTC 2016
Author: adrian
Date: Sun May 8 19:14:05 2016
New Revision: 299241
URL: https://svnweb.freebsd.org/changeset/base/299241
Log:
[bhnd] Initial bhnd(4) SPROM/NVRAM support.
This adds support for the NVRAM handling and the basic SPROM
hardware used on siba(4) and bcma(4) devices, including:
* SPROM directly attached to the PCI core, accessible via PCI configuration
space.
* SPROM attached to later ChipCommon cores.
* SPROM variables vended from the parent SoC bus (e.g. via a directly-attached
flash device).
Additional improvements to the NVRAM/SPROM interface will
be required, but this changeset stands alone as working
checkpoint.
Submitted by: Landon Fuller <landonf at landonf.org>
Reviewed by: Michael Zhilin <mizkha at gmail.com> (Broadcom MIPS support)
Differential Revision: https://reviews.freebsd.org/D6196
Added:
head/sys/dev/bhnd/bhndb/bhndb_pci_sprom.c (contents, props changed)
head/sys/dev/bhnd/nvram/bhnd_sprom.c (contents, props changed)
head/sys/dev/bhnd/nvram/bhnd_spromreg.h
- copied, changed from r299234, head/sys/dev/bhnd/bhndb/bhndb_pcivar.h
head/sys/dev/bhnd/nvram/bhnd_spromvar.h
- copied, changed from r299234, head/sys/dev/bhnd/bhndb/bhndb_pcivar.h
head/sys/dev/bhnd/nvram/nvram_map (contents, props changed)
head/sys/dev/bhnd/nvram/nvram_subr.c (contents, props changed)
head/sys/dev/bhnd/nvram/nvramvar.h (contents, props changed)
head/sys/dev/bhnd/tools/nvram_map_gen.awk (contents, props changed)
head/sys/dev/bhnd/tools/nvram_map_gen.sh (contents, props changed)
Deleted:
head/sys/dev/bhnd/bcmsrom_fmt.h
head/sys/dev/bhnd/bcmsrom_tbl.h
head/sys/modules/bhnd/nvram/Makefile
Modified:
head/sys/conf/files
head/sys/conf/kmod.mk
head/sys/dev/bhnd/bhnd.c
head/sys/dev/bhnd/bhnd.h
head/sys/dev/bhnd/bhnd_bus_if.m
head/sys/dev/bhnd/bhnd_ids.h
head/sys/dev/bhnd/bhndb/bhndb.c
head/sys/dev/bhnd/bhndb/bhndb_pci.c
head/sys/dev/bhnd/bhndb/bhndb_pcireg.h
head/sys/dev/bhnd/bhndb/bhndb_pcivar.h
head/sys/dev/bhnd/cores/chipc/chipc.c
head/sys/dev/bhnd/cores/chipc/chipcreg.h
head/sys/dev/bhnd/cores/chipc/chipcvar.h
head/sys/dev/bhnd/nvram/bhnd_nvram.h
head/sys/dev/bhnd/nvram/bhnd_nvram_if.m
head/sys/dev/bwn/bwn_mac.c
head/sys/modules/bhnd/Makefile
head/sys/modules/bhnd/bhndb/Makefile
head/sys/modules/bhnd/bhndb_pci/Makefile
head/sys/modules/bhnd/cores/bhnd_chipc/Makefile
head/sys/modules/bwn_pci/Makefile
Directory Properties:
head/sys/dev/bhnd/tools/bus_macro.sh (props changed)
Modified: head/sys/conf/files
==============================================================================
--- head/sys/conf/files Sun May 8 18:30:08 2016 (r299240)
+++ head/sys/conf/files Sun May 8 19:14:05 2016 (r299241)
@@ -9,6 +9,16 @@ acpi_quirks.h optional acpi \
compile-with "${AWK} -f $S/tools/acpi_quirks2h.awk $S/dev/acpica/acpi_quirks" \
no-obj no-implicit-rule before-depend \
clean "acpi_quirks.h"
+bhnd_nvram_map.h optional bhndbus | bhnd \
+ dependency "$S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/tools/nvram_map_gen.awk $S/dev/bhnd/nvram/nvram_map" \
+ compile-with "$S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/nvram/nvram_map -h" \
+ no-obj no-implicit-rule before-depend \
+ clean "bhnd_nvram_map.h"
+bhnd_nvram_map_data.h optional bhndbus | bhnd \
+ dependency "$S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/tools/nvram_map_gen.awk $S/dev/bhnd/nvram/nvram_map" \
+ compile-with "$S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/nvram/nvram_map -d" \
+ no-obj no-implicit-rule before-depend \
+ clean "bhnd_nvram_map_data.h"
#
# The 'fdt_dtb_file' target covers an actual DTB file name, which is derived
# from the specified source (DTS) file: <platform>.dts -> <platform>.dtb
@@ -1121,6 +1131,7 @@ dev/bhnd/bhndb/bhndb_hwdata.c optional
dev/bhnd/bhndb/bhndb_if.m optional bhndbus | bhndb
dev/bhnd/bhndb/bhndb_pci.c optional bhndbus pci | bhndb pci
dev/bhnd/bhndb/bhndb_pci_hwdata.c optional bhndbus pci | bhndb pci
+dev/bhnd/bhndb/bhndb_pci_sprom.c optional bhndbus pci | bhndb pci
dev/bhnd/bhndb/bhndb_subr.c optional bhndbus pci | bhndb
dev/bhnd/bcma/bcma.c optional bhndbus | bcma
dev/bhnd/bcma/bcma_bhndb.c optional bhndbus | bcma bhndb
@@ -1132,6 +1143,8 @@ dev/bhnd/cores/pci/bhnd_pci.c optional
dev/bhnd/cores/pci/bhnd_pci_hostb.c optional bhndbus pci | bhndb pci
dev/bhnd/cores/pci/bhnd_pcib.c optional bhnd_pcib bhnd pci
dev/bhnd/nvram/bhnd_nvram_if.m optional bhndbus | bhnd
+dev/bhnd/nvram/bhnd_sprom.c optional bhndbus | bhnd
+dev/bhnd/nvram/nvram_subr.c optional bhndbus | bhnd
dev/bhnd/siba/siba.c optional bhndbus | siba
dev/bhnd/siba/siba_bhndb.c optional bhndbus | siba bhndb
dev/bhnd/siba/siba_nexus.c optional siba_nexus siba
Modified: head/sys/conf/kmod.mk
==============================================================================
--- head/sys/conf/kmod.mk Sun May 8 18:30:08 2016 (r299240)
+++ head/sys/conf/kmod.mk Sun May 8 19:14:05 2016 (r299241)
@@ -411,6 +411,26 @@ ${_i}devs.h: ${SYSDIR}/tools/${_i}devs2h
.endif
.endfor # _i
+.if !empty(SRCS:Mbhnd_nvram_map.h)
+CLEANFILES+= bhnd_nvram_map.h
+bhnd_nvram_map.h: ${SYSDIR}/dev/bhnd/tools/nvram_map_gen.awk \
+ ${SYSDIR}/dev/bhnd/tools/nvram_map_gen.sh \
+ ${SYSDIR}/dev/bhnd/nvram/nvram_map
+bhnd_nvram_map.h:
+ ${SYSDIR}/dev/bhnd/tools/nvram_map_gen.sh \
+ ${SYSDIR}/dev/bhnd/nvram/nvram_map -h
+.endif
+
+.if !empty(SRCS:Mbhnd_nvram_map_data.h)
+CLEANFILES+= bhnd_nvram_map_data.h
+bhnd_nvram_map_data.h: ${SYSDIR}/dev/bhnd/tools/nvram_map_gen.awk \
+ ${SYSDIR}/dev/bhnd/tools/nvram_map_gen.sh \
+ ${SYSDIR}/dev/bhnd/nvram/nvram_map
+bhnd_nvram_map_data.h:
+ ${SYSDIR}/dev/bhnd/tools/nvram_map_gen.sh \
+ ${SYSDIR}/dev/bhnd/nvram/nvram_map -d
+.endif
+
.if !empty(SRCS:Musbdevs.h)
CLEANFILES+= usbdevs.h
usbdevs.h: ${SYSDIR}/tools/usbdevs2h.awk ${SYSDIR}/dev/usb/usbdevs
Modified: head/sys/dev/bhnd/bhnd.c
==============================================================================
--- head/sys/dev/bhnd/bhnd.c Sun May 8 18:30:08 2016 (r299240)
+++ head/sys/dev/bhnd/bhnd.c Sun May 8 19:14:05 2016 (r299241)
@@ -58,11 +58,14 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <machine/resource.h>
-#include "bhnd.h"
-#include "bhndvar.h"
+#include "nvram/bhnd_nvram.h"
+#include "bhnd_chipc_if.h"
#include "bhnd_nvram_if.h"
+#include "bhnd.h"
+#include "bhndvar.h"
+
MALLOC_DEFINE(M_BHND, "bhnd", "bhnd bus data structures");
/**
@@ -386,23 +389,27 @@ bhnd_generic_is_region_valid(device_t de
static device_t
find_nvram_child(device_t dev)
{
- device_t chipc, nvram;
+ device_t chipc, nvram;
/* Look for a directly-attached NVRAM child */
- nvram = device_find_child(dev, devclass_get_name(bhnd_nvram_devclass),
- -1);
- if (nvram == NULL)
- return (NULL);
+ nvram = device_find_child(dev, "bhnd_nvram", 0);
+ if (nvram != NULL)
+ return (nvram);
- /* Further checks require a bhnd(4) bus */
+ /* Remaining checks are only applicable when searching a bhnd(4)
+ * bus. */
if (device_get_devclass(dev) != bhnd_devclass)
return (NULL);
- /* Look for a ChipCommon-attached OTP device */
+ /* Look for a ChipCommon device */
if ((chipc = bhnd_find_child(dev, BHND_DEVCLASS_CC, -1)) != NULL) {
- /* Recursively search the ChipCommon device */
- if ((nvram = find_nvram_child(chipc)) != NULL)
- return (nvram);
+ bhnd_nvram_src_t src;
+
+ /* Query the NVRAM source and determine whether it's
+ * accessible via the ChipCommon device */
+ src = BHND_CHIPC_NVRAM_SRC(chipc);
+ if (BHND_NVRAM_SRC_CC(src))
+ return (chipc);
}
/* Not found */
@@ -410,22 +417,26 @@ find_nvram_child(device_t dev)
}
/**
- * Default bhnd(4) bus driver implementation of BHND_BUS_READ_NVRAM_VAR().
+ * Default bhnd(4) bus driver implementation of BHND_BUS_GET_NVRAM_VAR().
+ *
+ * This implementation searches @p dev for a usable NVRAM child device:
+ * - The first child device implementing the bhnd_nvram devclass is
+ * returned, otherwise
+ * - If @p dev is a bhnd(4) bus, a ChipCommon core that advertises an
+ * attached NVRAM source.
*
- * This implementation searches @p dev for a valid NVRAM device. If no NVRAM
- * child device is found on @p dev, the request is delegated to the
- * BHND_BUS_READ_NVRAM_VAR() method on the parent
- * of @p dev.
+ * If no usable child device is found on @p dev, the request is delegated to
+ * the BHND_BUS_GET_NVRAM_VAR() method on the parent of @p dev.
*/
static int
-bhnd_generic_read_nvram_var(device_t dev, device_t child, const char *name,
+bhnd_generic_get_nvram_var(device_t dev, device_t child, const char *name,
void *buf, size_t *size)
{
device_t nvram;
/* Try to find an NVRAM device applicable to @p child */
if ((nvram = find_nvram_child(dev)) == NULL)
- return (BHND_BUS_READ_NVRAM_VAR(device_get_parent(dev), child,
+ return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), child,
name, buf, size));
return BHND_NVRAM_GETVAR(nvram, name, buf, size);
@@ -682,7 +693,7 @@ static device_method_t bhnd_methods[] =
DEVMETHOD(bhnd_bus_get_probe_order, bhnd_generic_get_probe_order),
DEVMETHOD(bhnd_bus_is_region_valid, bhnd_generic_is_region_valid),
DEVMETHOD(bhnd_bus_is_hw_disabled, bhnd_bus_generic_is_hw_disabled),
- DEVMETHOD(bhnd_bus_read_nvram_var, bhnd_generic_read_nvram_var),
+ DEVMETHOD(bhnd_bus_get_nvram_var, bhnd_generic_get_nvram_var),
DEVMETHOD(bhnd_bus_read_1, bhnd_read_1),
DEVMETHOD(bhnd_bus_read_2, bhnd_read_2),
DEVMETHOD(bhnd_bus_read_4, bhnd_read_4),
Modified: head/sys/dev/bhnd/bhnd.h
==============================================================================
--- head/sys/dev/bhnd/bhnd.h Sun May 8 18:30:08 2016 (r299240)
+++ head/sys/dev/bhnd/bhnd.h Sun May 8 19:14:05 2016 (r299241)
@@ -464,6 +464,55 @@ bhnd_get_chipid(device_t dev) {
return (BHND_BUS_GET_CHIPID(device_get_parent(dev), dev));
};
+/**
+ * Determine an NVRAM variable's expected size.
+ *
+ * @param dev A bhnd bus child device.
+ * @param name The variable name.
+ * @param[out] len On success, the variable's size, in bytes.
+ *
+ * @retval 0 success
+ * @retval ENOENT The requested variable was not found.
+ * @retval non-zero If reading @p name otherwise fails, a regular unix
+ * error code will be returned.
+ */
+static inline int
+bhnd_nvram_getvarlen(device_t dev, const char *name, size_t *len)
+{
+ return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), dev, name, NULL,
+ len));
+}
+
+/**
+ * Read an NVRAM variable.
+ *
+ * @param dev A bhnd bus child device.
+ * @param name The NVRAM variable name.
+ * @param buf A buffer large enough to hold @p len bytes. On success,
+ * the requested value will be written to this buffer.
+ * @param len The required variable length.
+ *
+ * @retval 0 success
+ * @retval ENOENT The requested variable was not found.
+ * @retval EINVAL If @p len does not match the actual variable size.
+ * @retval non-zero If reading @p name otherwise fails, a regular unix
+ * error code will be returned.
+ */
+static inline int
+bhnd_nvram_getvar(device_t dev, const char *name, void *buf, size_t len)
+{
+ size_t var_len;
+ int error;
+
+ if ((error = bhnd_nvram_getvarlen(dev, name, &var_len)))
+ return (error);
+
+ if (len != var_len)
+ return (EINVAL);
+
+ return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), dev, name, buf,
+ &len));
+}
/**
* Allocate a resource from a device's parent bhnd(4) bus.
Modified: head/sys/dev/bhnd/bhnd_bus_if.m
==============================================================================
--- head/sys/dev/bhnd/bhnd_bus_if.m Sun May 8 18:30:08 2016 (r299240)
+++ head/sys/dev/bhnd/bhnd_bus_if.m Sun May 8 19:14:05 2016 (r299241)
@@ -96,7 +96,7 @@ CODE {
}
static int
- bhnd_bus_null_read_nvram_var(device_t dev, device_t child,
+ bhnd_bus_null_get_nvram_var(device_t dev, device_t child,
const char *name, void *buf, size_t *size)
{
return (ENOENT);
@@ -403,13 +403,13 @@ METHOD int get_region_addr {
* @retval non-zero If reading @p name otherwise fails, a regular unix
* error code will be returned.
*/
-METHOD int read_nvram_var {
+METHOD int get_nvram_var {
device_t dev;
device_t child;
const char *name;
void *buf;
size_t *size;
-} DEFAULT bhnd_bus_null_read_nvram_var;
+} DEFAULT bhnd_bus_null_get_nvram_var;
/** An implementation of bus_read_1() compatible with bhnd_resource */
Modified: head/sys/dev/bhnd/bhnd_ids.h
==============================================================================
--- head/sys/dev/bhnd/bhnd_ids.h Sun May 8 18:30:08 2016 (r299240)
+++ head/sys/dev/bhnd/bhnd_ids.h Sun May 8 19:14:05 2016 (r299241)
@@ -328,6 +328,7 @@
#define BHND_CHIPID_BCM43428 43428 /* 43228 chipcommon chipid (OTP, RBBU) */
#define BHND_CHIPID_BCM43431 43431 /* 4331 chipcommon chipid (OTP, RBBU) */
#define BHND_CHIPID_BCM43460 43460 /* 4360 chipcommon chipid (OTP, RBBU) */
+#define BHND_CHIPID_BCM43462 0xA9C6 /* 43462 chipcommon chipid */
#define BHND_CHIPID_BCM4325 0x4325 /* 4325 chip id */
#define BHND_CHIPID_BCM4328 0x4328 /* 4328 chip id */
#define BHND_CHIPID_BCM4329 0x4329 /* 4329 chipcommon chipid */
@@ -345,6 +346,7 @@
#define BHND_CHIPID_BCM4334 0x4334 /* 4334 chipcommon chipid */
#define BHND_CHIPID_BCM4335 0x4335 /* 4335 chipcommon chipid */
#define BHND_CHIPID_BCM4360 0x4360 /* 4360 chipcommon chipid */
+#define BHND_CHIPID_BCM43602 0xaa52 /* 43602 chipcommon chipid */
#define BHND_CHIPID_BCM4352 0x4352 /* 4352 chipcommon chipid */
#define BHND_CHIPID_BCM43526 0xAA06
#define BHND_CHIPID_BCM43341 43341 /* 43341 chipcommon chipid */
@@ -433,7 +435,6 @@
#define BHND_PKGID_BCM4335_FCBGAD (0x3) /* FCBGA Debug Debug/Dev All if's. */
#define BHND_PKGID_PKG_MASK_BCM4335 (0x3)
-
/* Broadcom Core IDs */
#define BHND_COREID_INVALID 0x700 /* Invalid coreid */
#define BHND_COREID_CC 0x800 /* chipcommon core */
Modified: head/sys/dev/bhnd/bhndb/bhndb.c
==============================================================================
--- head/sys/dev/bhnd/bhndb/bhndb.c Sun May 8 18:30:08 2016 (r299240)
+++ head/sys/dev/bhnd/bhndb/bhndb.c Sun May 8 19:14:05 2016 (r299241)
@@ -51,6 +51,10 @@ __FBSDID("$FreeBSD$");
#include <dev/bhnd/bhndreg.h>
#include <dev/bhnd/cores/chipc/chipcreg.h>
+#include <dev/bhnd/nvram/bhnd_nvram.h>
+
+#include "bhnd_chipc_if.h"
+#include "bhnd_nvram_if.h"
#include "bhndbvar.h"
#include "bhndb_bus_if.h"
@@ -609,7 +613,7 @@ bhndb_generic_init_full_config(device_t
goto cleanup;
}
- if (bootverbose)
+ if (bootverbose || BHNDB_DEBUG(PRIO))
device_printf(sc->dev, "%s resource configuration\n", hw->name);
/* Release existing resource state */
@@ -1298,9 +1302,10 @@ bhndb_retain_dynamic_window(struct bhndb
rman_get_size(r));
if (error) {
device_printf(sc->dev, "dynamic window initialization "
- "for 0x%llx-0x%llx failed\n",
+ "for 0x%llx-0x%llx failed: %d\n",
(unsigned long long) r_start,
- (unsigned long long) r_start + r_size - 1);
+ (unsigned long long) r_start + r_size - 1,
+ error);
return (NULL);
}
@@ -1709,6 +1714,26 @@ bhndb_io_resource(struct bhndb_softc *sc
return (dwa);
}
+/**
+ * Default bhndb(4) implementation of BHND_BUS_GET_NVRAM_VAR().
+ */
+static int
+bhndb_get_nvram_var(device_t dev, device_t child, const char *name,
+ void *buf, size_t *size)
+{
+ device_t nvram;
+
+ /* Look for a directly-attached NVRAM child */
+ nvram = device_find_child(dev, devclass_get_name(bhnd_nvram_devclass),
+ 0);
+ if (nvram != NULL)
+ return (BHND_NVRAM_GETVAR(nvram, name, buf, size));
+
+ /* Otherwise, delegate to our parent */
+ return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), child,
+ name, buf, size));
+}
+
/*
* BHND_BUS_(READ|WRITE_* implementations
*/
@@ -1936,6 +1961,7 @@ static device_method_t bhndb_methods[] =
DEVMETHOD(bhnd_bus_get_chipid, bhndb_get_chipid),
DEVMETHOD(bhnd_bus_activate_resource, bhndb_activate_bhnd_resource),
DEVMETHOD(bhnd_bus_deactivate_resource, bhndb_deactivate_bhnd_resource),
+ DEVMETHOD(bhnd_bus_get_nvram_var, bhndb_get_nvram_var),
DEVMETHOD(bhnd_bus_read_1, bhndb_bus_read_1),
DEVMETHOD(bhnd_bus_read_2, bhndb_bus_read_2),
DEVMETHOD(bhnd_bus_read_4, bhndb_bus_read_4),
Modified: head/sys/dev/bhnd/bhndb/bhndb_pci.c
==============================================================================
--- head/sys/dev/bhnd/bhndb/bhndb_pci.c Sun May 8 18:30:08 2016 (r299240)
+++ head/sys/dev/bhnd/bhndb/bhndb_pci.c Sun May 8 19:14:05 2016 (r299241)
@@ -61,15 +61,19 @@ __FBSDID("$FreeBSD$");
#include "bhndb_pcivar.h"
#include "bhndb_private.h"
-static int bhndb_enable_pci_clocks(struct bhndb_pci_softc *sc);
-static int bhndb_disable_pci_clocks(struct bhndb_pci_softc *sc);
+static int bhndb_enable_pci_clocks(struct bhndb_pci_softc *sc);
+static int bhndb_disable_pci_clocks(struct bhndb_pci_softc *sc);
-static int bhndb_pci_compat_setregwin(struct bhndb_pci_softc *,
- const struct bhndb_regwin *, bhnd_addr_t);
-static int bhndb_pci_fast_setregwin(struct bhndb_pci_softc *,
- const struct bhndb_regwin *, bhnd_addr_t);
+static int bhndb_pci_compat_setregwin(struct bhndb_pci_softc *,
+ const struct bhndb_regwin *, bhnd_addr_t);
+static int bhndb_pci_fast_setregwin(struct bhndb_pci_softc *,
+ const struct bhndb_regwin *, bhnd_addr_t);
-static void bhndb_init_sromless_pci_config(struct bhndb_pci_softc *sc);
+static void bhndb_init_sromless_pci_config(
+ struct bhndb_pci_softc *sc);
+
+static bus_addr_t bhndb_pci_sprom_addr(struct bhndb_pci_softc *sc);
+static size_t bhndb_pci_sprom_size(struct bhndb_pci_softc *sc);
/**
* Default bhndb_pci implementation of device_probe().
@@ -104,13 +108,14 @@ bhndb_pci_attach(device_t dev)
sc = device_get_softc(dev);
sc->dev = dev;
+ sc->parent = device_get_parent(dev);
/* Enable PCI bus mastering */
- pci_enable_busmaster(device_get_parent(dev));
+ pci_enable_busmaster(sc->parent);
/* Determine our bridge device class */
sc->pci_devclass = BHND_DEVCLASS_PCI;
- if (pci_find_cap(device_get_parent(dev), PCIY_EXPRESS, ®) == 0)
+ if (pci_find_cap(sc->parent, PCIY_EXPRESS, ®) == 0)
sc->pci_devclass = BHND_DEVCLASS_PCIE;
/* Enable clocks (if supported by this hardware) */
@@ -142,6 +147,8 @@ bhndb_pci_init_full_config(device_t dev,
const struct bhndb_hw_priority *hw_prio_table)
{
struct bhndb_pci_softc *sc;
+ device_t nv_dev;
+ bus_size_t nv_sz;
int error;
sc = device_get_softc(dev);
@@ -153,9 +160,126 @@ bhndb_pci_init_full_config(device_t dev,
/* Fix-up power on defaults for SROM-less devices. */
bhndb_init_sromless_pci_config(sc);
+ /* If SPROM is mapped directly into BAR0, add NVRAM device. */
+ nv_sz = bhndb_pci_sprom_size(sc);
+ if (nv_sz > 0) {
+ struct bhndb_devinfo *dinfo;
+ const char *dname;
+
+ if (bootverbose) {
+ device_printf(dev, "found SPROM (%zu bytes)\n", nv_sz);
+ }
+
+ /* Add sprom device */
+ dname = "bhnd_nvram";
+ if ((nv_dev = BUS_ADD_CHILD(dev, 0, dname, -1)) == NULL) {
+ device_printf(dev, "failed to add sprom device\n");
+ return (ENXIO);
+ }
+
+ /* Initialize device address space and resource covering the
+ * BAR0 SPROM shadow. */
+ dinfo = device_get_ivars(nv_dev);
+ dinfo->addrspace = BHNDB_ADDRSPACE_NATIVE;
+ error = bus_set_resource(nv_dev, SYS_RES_MEMORY, 0,
+ bhndb_pci_sprom_addr(sc), nv_sz);
+
+ if (error) {
+ device_printf(dev,
+ "failed to register sprom resources\n");
+ return (error);
+ }
+
+ /* Attach the device */
+ if ((error = device_probe_and_attach(nv_dev))) {
+ device_printf(dev, "sprom attach failed\n");
+ return (error);
+ }
+ }
+
return (0);
}
+static const struct bhndb_regwin *
+bhndb_pci_sprom_regwin(struct bhndb_pci_softc *sc)
+{
+ struct bhndb_resources *bres;
+ const struct bhndb_hwcfg *cfg;
+ const struct bhndb_regwin *sprom_win;
+
+ bres = sc->bhndb.bus_res;
+ cfg = bres->cfg;
+
+ sprom_win = bhndb_regwin_find_type(cfg->register_windows,
+ BHNDB_REGWIN_T_SPROM, BHNDB_PCI_V0_BAR0_SPROM_SIZE);
+
+ return (sprom_win);
+}
+
+static bus_addr_t
+bhndb_pci_sprom_addr(struct bhndb_pci_softc *sc)
+{
+ const struct bhndb_regwin *sprom_win;
+ struct resource *r;
+
+ /* Fetch the SPROM register window */
+ sprom_win = bhndb_pci_sprom_regwin(sc);
+ KASSERT(sprom_win != NULL, ("requested sprom address on PCI_V2+"));
+
+ /* Fetch the associated resource */
+ r = bhndb_find_regwin_resource(sc->bhndb.bus_res, sprom_win);
+ KASSERT(r != NULL, ("missing resource for sprom window\n"));
+
+ return (rman_get_start(r) + sprom_win->win_offset);
+}
+
+static bus_size_t
+bhndb_pci_sprom_size(struct bhndb_pci_softc *sc)
+{
+ const struct bhndb_regwin *sprom_win;
+ uint32_t sctl;
+ bus_size_t sprom_sz;
+
+ sprom_win = bhndb_pci_sprom_regwin(sc);
+
+ /* PCI_V2 and later devices map SPROM/OTP via ChipCommon */
+ if (sprom_win == NULL)
+ return (0);
+
+ /* Determine SPROM size */
+ sctl = pci_read_config(sc->parent, BHNDB_PCI_SPROM_CONTROL, 4);
+ if (sctl & BHNDB_PCI_SPROM_BLANK)
+ return (0);
+
+ switch (sctl & BHNDB_PCI_SPROM_SZ_MASK) {
+ case BHNDB_PCI_SPROM_SZ_1KB:
+ sprom_sz = (1 * 1024);
+ break;
+
+ case BHNDB_PCI_SPROM_SZ_4KB:
+ sprom_sz = (4 * 1024);
+ break;
+
+ case BHNDB_PCI_SPROM_SZ_16KB:
+ sprom_sz = (16 * 1024);
+ break;
+
+ case BHNDB_PCI_SPROM_SZ_RESERVED:
+ default:
+ device_printf(sc->dev, "invalid PCI sprom size 0x%x\n", sctl);
+ return (0);
+ }
+
+ if (sprom_sz > sprom_win->win_size) {
+ device_printf(sc->dev,
+ "PCI sprom size (0x%x) overruns defined register window\n",
+ sctl);
+ return (0);
+ }
+
+ return (sprom_sz);
+}
+
/*
* On devices without a SROM, the PCI(e) cores will be initialized with
* their Power-on-Reset defaults; this can leave two of the BAR0 PCI windows
@@ -274,7 +398,7 @@ bhndb_pci_detach(device_t dev)
return (error);
/* Disable PCI bus mastering */
- pci_disable_busmaster(device_get_parent(dev));
+ pci_disable_busmaster(sc->parent);
return (0);
}
@@ -301,19 +425,18 @@ static int
bhndb_pci_compat_setregwin(struct bhndb_pci_softc *sc,
const struct bhndb_regwin *rw, bhnd_addr_t addr)
{
- device_t parent;
int error;
-
- parent = sc->bhndb.parent_dev;
+ int reg;
if (rw->win_type != BHNDB_REGWIN_T_DYN)
return (ENODEV);
+ reg = rw->d.dyn.cfg_offset;
for (u_int i = 0; i < BHNDB_PCI_BARCTRL_WRITE_RETRY; i++) {
if ((error = bhndb_pci_fast_setregwin(sc, rw, addr)))
return (error);
- if (pci_read_config(parent, rw->d.dyn.cfg_offset, 4) == addr)
+ if (pci_read_config(sc->parent, reg, 4) == addr)
return (0);
DELAY(10);
@@ -330,8 +453,6 @@ static int
bhndb_pci_fast_setregwin(struct bhndb_pci_softc *sc,
const struct bhndb_regwin *rw, bhnd_addr_t addr)
{
- device_t parent = sc->bhndb.parent_dev;
-
/* The PCI bridge core only supports 32-bit addressing, regardless
* of the bus' support for 64-bit addressing */
if (addr > UINT32_MAX)
@@ -343,7 +464,7 @@ bhndb_pci_fast_setregwin(struct bhndb_pc
if (addr % rw->win_size != 0)
return (EINVAL);
- pci_write_config(parent, rw->d.dyn.cfg_offset, addr, 4);
+ pci_write_config(sc->parent, rw->d.dyn.cfg_offset, addr, 4);
break;
default:
return (ENODEV);
@@ -366,7 +487,6 @@ bhndb_pci_fast_setregwin(struct bhndb_pc
static int
bhndb_enable_pci_clocks(struct bhndb_pci_softc *sc)
{
- device_t pci_parent;
uint32_t gpio_in, gpio_out, gpio_en;
uint32_t gpio_flags;
uint16_t pci_status;
@@ -375,35 +495,33 @@ bhndb_enable_pci_clocks(struct bhndb_pci
if (sc->pci_devclass != BHND_DEVCLASS_PCI)
return (0);
- pci_parent = device_get_parent(sc->dev);
-
/* Read state of XTAL pin */
- gpio_in = pci_read_config(pci_parent, BHNDB_PCI_GPIO_IN, 4);
+ gpio_in = pci_read_config(sc->parent, BHNDB_PCI_GPIO_IN, 4);
if (gpio_in & BHNDB_PCI_GPIO_XTAL_ON)
return (0); /* already enabled */
/* Fetch current config */
- gpio_out = pci_read_config(pci_parent, BHNDB_PCI_GPIO_OUT, 4);
- gpio_en = pci_read_config(pci_parent, BHNDB_PCI_GPIO_OUTEN, 4);
+ gpio_out = pci_read_config(sc->parent, BHNDB_PCI_GPIO_OUT, 4);
+ gpio_en = pci_read_config(sc->parent, BHNDB_PCI_GPIO_OUTEN, 4);
/* Set PLL_OFF/XTAL_ON pins to HIGH and enable both pins */
gpio_flags = (BHNDB_PCI_GPIO_PLL_OFF|BHNDB_PCI_GPIO_XTAL_ON);
gpio_out |= gpio_flags;
gpio_en |= gpio_flags;
- pci_write_config(pci_parent, BHNDB_PCI_GPIO_OUT, gpio_out, 4);
- pci_write_config(pci_parent, BHNDB_PCI_GPIO_OUTEN, gpio_en, 4);
+ pci_write_config(sc->parent, BHNDB_PCI_GPIO_OUT, gpio_out, 4);
+ pci_write_config(sc->parent, BHNDB_PCI_GPIO_OUTEN, gpio_en, 4);
DELAY(1000);
/* Reset PLL_OFF */
gpio_out &= ~BHNDB_PCI_GPIO_PLL_OFF;
- pci_write_config(pci_parent, BHNDB_PCI_GPIO_OUT, gpio_out, 4);
+ pci_write_config(sc->parent, BHNDB_PCI_GPIO_OUT, gpio_out, 4);
DELAY(5000);
/* Clear any PCI 'sent target-abort' flag. */
- pci_status = pci_read_config(pci_parent, PCIR_STATUS, 2);
+ pci_status = pci_read_config(sc->parent, PCIR_STATUS, 2);
pci_status &= ~PCIM_STATUS_STABORT;
- pci_write_config(pci_parent, PCIR_STATUS, pci_status, 2);
+ pci_write_config(sc->parent, PCIR_STATUS, pci_status, 2);
return (0);
}
@@ -416,31 +534,28 @@ bhndb_enable_pci_clocks(struct bhndb_pci
static int
bhndb_disable_pci_clocks(struct bhndb_pci_softc *sc)
{
- device_t parent_dev;
uint32_t gpio_out, gpio_en;
/* Only supported and required on PCI devices */
if (sc->pci_devclass != BHND_DEVCLASS_PCI)
return (0);
- parent_dev = device_get_parent(sc->dev);
-
// TODO: Check board flags for BFL2_XTALBUFOUTEN?
// TODO: Check PCI core revision?
// TODO: Switch to 'slow' clock?
/* Fetch current config */
- gpio_out = pci_read_config(parent_dev, BHNDB_PCI_GPIO_OUT, 4);
- gpio_en = pci_read_config(parent_dev, BHNDB_PCI_GPIO_OUTEN, 4);
+ gpio_out = pci_read_config(sc->parent, BHNDB_PCI_GPIO_OUT, 4);
+ gpio_en = pci_read_config(sc->parent, BHNDB_PCI_GPIO_OUTEN, 4);
/* Set PLL_OFF to HIGH, XTAL_ON to LOW. */
gpio_out &= ~BHNDB_PCI_GPIO_XTAL_ON;
gpio_out |= BHNDB_PCI_GPIO_PLL_OFF;
- pci_write_config(parent_dev, BHNDB_PCI_GPIO_OUT, gpio_out, 4);
+ pci_write_config(sc->parent, BHNDB_PCI_GPIO_OUT, gpio_out, 4);
/* Enable both output pins */
gpio_en |= (BHNDB_PCI_GPIO_PLL_OFF|BHNDB_PCI_GPIO_XTAL_ON);
- pci_write_config(parent_dev, BHNDB_PCI_GPIO_OUTEN, gpio_en, 4);
+ pci_write_config(sc->parent, BHNDB_PCI_GPIO_OUTEN, gpio_en, 4);
return (0);
}
Added: head/sys/dev/bhnd/bhndb/bhndb_pci_sprom.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/sys/dev/bhnd/bhndb/bhndb_pci_sprom.c Sun May 8 19:14:05 2016 (r299241)
@@ -0,0 +1,210 @@
+/*-
+ * Copyright (c) 2015-2016 Landon Fuller <landon at landonf.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * BHNDB PCI SPROM driver.
+ *
+ * Provides support for early PCI bridge cores that vend SPROM CSRs
+ * via PCI configuration space.
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/limits.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/systm.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
+#include <dev/bhnd/bhnd.h>
+#include <dev/bhnd/cores/pci/bhnd_pci_hostbvar.h>
+#include <dev/bhnd/nvram/bhnd_spromvar.h>
+
+#include "bhnd_nvram_if.h"
+#include "bhndb_pcireg.h"
+#include "bhndb_pcivar.h"
+
+struct bhndb_pci_sprom_softc {
+ device_t dev;
+ struct bhnd_resource *sprom_res; /**< SPROM resource */
+ int sprom_rid; /**< SPROM RID */
+ struct bhnd_sprom shadow; /**< SPROM shadow */
+ struct mtx mtx; /**< SPROM shadow mutex */
+};
+
+#define SPROM_LOCK_INIT(sc) \
+ mtx_init(&(sc)->mtx, device_get_nameunit((sc)->dev), \
+ "BHND PCI SPROM lock", MTX_DEF)
+#define SPROM_LOCK(sc) mtx_lock(&(sc)->mtx)
+#define SPROM_UNLOCK(sc) mtx_unlock(&(sc)->mtx)
+#define SPROM_LOCK_ASSERT(sc, what) mtx_assert(&(sc)->mtx, what)
+#define SPROM_LOCK_DESTROY(sc) mtx_destroy(&(sc)->mtx)
+
+static int
+bhndb_pci_sprom_probe(device_t dev)
+{
+ device_t bridge, bus;
+
+ /* Our parent must be a PCI-BHND bridge with an attached bhnd bus */
+ bridge = device_get_parent(dev);
+ if (device_get_driver(bridge) != &bhndb_pci_driver)
+ return (ENXIO);
+
+ bus = device_find_child(bridge, devclass_get_name(bhnd_devclass), 0);
+ if (bus == NULL)
+ return (ENXIO);
+
+ /* Found */
+ device_set_desc(dev, "PCI-BHNDB SPROM/OTP");
+ if (!bootverbose)
+ device_quiet(dev);
+
+ /* Refuse wildcard attachments */
+ return (BUS_PROBE_NOWILDCARD);
+}
+
+static int
+bhndb_pci_sprom_attach(device_t dev)
+{
+ struct bhndb_pci_sprom_softc *sc;
+ int error;
+
+ sc = device_get_softc(dev);
+ sc->dev = dev;
+
+ /* Allocate SPROM resource */
+ sc->sprom_rid = 0;
+ sc->sprom_res = bhnd_alloc_resource_any(dev, SYS_RES_MEMORY,
+ &sc->sprom_rid, RF_ACTIVE);
+ if (sc->sprom_res == NULL) {
+ device_printf(dev, "failed to allocate resources\n");
+ return (ENXIO);
+ }
+
+ /* Initialize SPROM shadow */
+ if ((error = bhnd_sprom_init(&sc->shadow, sc->sprom_res, 0))) {
+ device_printf(dev, "unrecognized SPROM format\n");
+ goto failed;
+ }
+
+ /* Initialize mutex */
+ SPROM_LOCK_INIT(sc);
+
+ return (0);
+
+failed:
+ bhnd_release_resource(dev, SYS_RES_MEMORY, sc->sprom_rid,
+ sc->sprom_res);
+ return (error);
+}
+
+static int
+bhndb_pci_sprom_resume(device_t dev)
+{
+ return (0);
+}
+
+static int
+bhndb_pci_sprom_suspend(device_t dev)
+{
+ return (0);
+}
+
+static int
+bhndb_pci_sprom_detach(device_t dev)
+{
+ struct bhndb_pci_sprom_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ bhnd_release_resource(dev, SYS_RES_MEMORY, sc->sprom_rid,
+ sc->sprom_res);
+ bhnd_sprom_fini(&sc->shadow);
+ SPROM_LOCK_DESTROY(sc);
+
+ return (0);
+}
+
+static int
+bhndb_pci_sprom_getvar(device_t dev, const char *name, void *buf, size_t *len)
+{
+ struct bhndb_pci_sprom_softc *sc;
+ int error;
+
+ sc = device_get_softc(dev);
+
+ SPROM_LOCK(sc);
+ error = bhnd_sprom_getvar(&sc->shadow, name, buf, len);
+ SPROM_UNLOCK(sc);
+
+ return (error);
+}
+
+static int
+bhndb_pci_sprom_setvar(device_t dev, const char *name, const void *buf,
+ size_t len)
+{
+ struct bhndb_pci_sprom_softc *sc;
+ int error;
+
+ sc = device_get_softc(dev);
+
+ SPROM_LOCK(sc);
+ error = bhnd_sprom_setvar(&sc->shadow, name, buf, len);
+ SPROM_UNLOCK(sc);
+
+ return (error);
+}
+
+static device_method_t bhndb_pci_sprom_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, bhndb_pci_sprom_probe),
+ DEVMETHOD(device_attach, bhndb_pci_sprom_attach),
+ DEVMETHOD(device_resume, bhndb_pci_sprom_resume),
+ DEVMETHOD(device_suspend, bhndb_pci_sprom_suspend),
+ DEVMETHOD(device_detach, bhndb_pci_sprom_detach),
+
+ /* NVRAM interface */
+ DEVMETHOD(bhnd_nvram_getvar, bhndb_pci_sprom_getvar),
+ DEVMETHOD(bhnd_nvram_setvar, bhndb_pci_sprom_setvar),
+
+ DEVMETHOD_END
+};
+
+DEFINE_CLASS_0(bhnd_nvram, bhndb_pci_sprom_driver, bhndb_pci_sprom_methods, sizeof(struct bhndb_pci_sprom_softc));
+
+DRIVER_MODULE(bhndb_pci_sprom, bhndb, bhndb_pci_sprom_driver, bhnd_nvram_devclass, NULL, NULL);
+MODULE_DEPEND(bhndb_pci_sprom, bhnd, 1, 1, 1);
+MODULE_VERSION(bhndb_pci_sprom, 1);
Modified: head/sys/dev/bhnd/bhndb/bhndb_pcireg.h
==============================================================================
--- head/sys/dev/bhnd/bhndb/bhndb_pcireg.h Sun May 8 18:30:08 2016 (r299240)
+++ head/sys/dev/bhnd/bhndb/bhndb_pcireg.h Sun May 8 19:14:05 2016 (r299241)
@@ -205,13 +205,17 @@
#define BHNDB_PCI_SBIM_MASK_SERR 0x4 /* backplane SBErr interrupt mask */
/* BHNDB_PCI_SPROM_CONTROL */
-#define BHNDB_PCI_SPROM_SZ_MSK 0x02 /* SPROM Size Mask */
-#define BHNDB_PCI_SPROM_LOCKED 0x08 /* SPROM Locked */
-#define BHNDB_PCI_SPROM_BLANK 0x04 /* indicating a blank SPROM */
-#define BHNDB_PCI_SPROM_WRITEEN 0x10 /* SPROM write enable */
-#define BHNDB_PCI_SPROM_BOOTROM_WE 0x20 /* external bootrom write enable */
-#define BHNDB_PCI_SPROM_BACKPLANE_EN 0x40 /* Enable indirect backplane access */
-#define BHNDB_PCI_SPROM_OTPIN_USE 0x80 /* device OTP In use */
+#define BHNDB_PCI_SPROM_SZ_MASK 0x03 /**< sprom size mask */
+#define BHNDB_PCI_SPROM_SZ_1KB 0x00 /**< 1KB sprom size */
+#define BHNDB_PCI_SPROM_SZ_4KB 0x01 /**< 4KB sprom size */
+#define BHNDB_PCI_SPROM_SZ_16KB 0x02 /**< 16KB sprom size */
+#define BHNDB_PCI_SPROM_SZ_RESERVED 0x03 /**< unsupported sprom size */
+#define BHNDB_PCI_SPROM_LOCKED 0x08 /**< sprom locked */
+#define BHNDB_PCI_SPROM_BLANK 0x04 /**< sprom blank */
+#define BHNDB_PCI_SPROM_WRITEEN 0x10 /**< sprom write enable */
+#define BHNDB_PCI_SPROM_BOOTROM_WE 0x20 /**< external bootrom write enable */
+#define BHNDB_PCI_SPROM_BACKPLANE_EN 0x40 /**< enable indirect backplane access (BHNDB_PCI_BACKPLANE_*) */
+#define BHNDB_PCI_SPROM_OTPIN_USE 0x80 /**< device OTP in use */
/* PCI (non-PCIe) BHNDB_PCI_GPIO_OUTEN */
Modified: head/sys/dev/bhnd/bhndb/bhndb_pcivar.h
==============================================================================
--- head/sys/dev/bhnd/bhndb/bhndb_pcivar.h Sun May 8 18:30:08 2016 (r299240)
+++ head/sys/dev/bhnd/bhndb/bhndb_pcivar.h Sun May 8 19:14:05 2016 (r299241)
@@ -51,6 +51,7 @@ typedef int (*bhndb_pci_set_regwin_t)(st
struct bhndb_pci_softc {
struct bhndb_softc bhndb; /**< parent softc */
device_t dev; /**< bridge device */
+ device_t parent; /**< parent PCI device */
bhnd_devclass_t pci_devclass; /**< PCI core's devclass */
bhndb_pci_set_regwin_t set_regwin; /**< regwin handler */
};
Modified: head/sys/dev/bhnd/cores/chipc/chipc.c
==============================================================================
--- head/sys/dev/bhnd/cores/chipc/chipc.c Sun May 8 18:30:08 2016 (r299240)
+++ head/sys/dev/bhnd/cores/chipc/chipc.c Sun May 8 19:14:05 2016 (r299241)
@@ -52,6 +52,8 @@ __FBSDID("$FreeBSD$");
#include <dev/bhnd/bhnd.h>
+#include "bhnd_nvram_if.h"
+
#include "chipcreg.h"
#include "chipcvar.h"
@@ -73,13 +75,44 @@ static const struct bhnd_device chipc_de
/* Device quirks table */
static struct bhnd_device_quirk chipc_quirks[] = {
- { BHND_HWREV_RANGE (0, 21), CHIPC_QUIRK_ALWAYS_HAS_SPROM },
- { BHND_HWREV_EQ (22), CHIPC_QUIRK_SPROM_CHECK_CST_R22 },
- { BHND_HWREV_RANGE (23, 31), CHIPC_QUIRK_SPROM_CHECK_CST_R23 },
- { BHND_HWREV_GTE (35), CHIPC_QUIRK_SUPPORTS_NFLASH },
+ { BHND_HWREV_GTE (32), CHIPC_QUIRK_SUPPORTS_SPROM },
+ { BHND_HWREV_GTE (35), CHIPC_QUIRK_SUPPORTS_NFLASH },
BHND_DEVICE_QUIRK_END
};
+/* Chip-specific quirks table */
+static struct bhnd_chip_quirk chipc_chip_quirks[] = {
+ /* 4331 12x9 packages */
+ {{ BHND_CHIP_IP(4331, 4331TN) },
+ CHIPC_QUIRK_4331_GPIO2_5_MUX_SPROM
+ },
+ {{ BHND_CHIP_IP(4331, 4331TNA0) },
+ CHIPC_QUIRK_4331_GPIO2_5_MUX_SPROM
+ },
+
+ /* 4331 12x12 packages */
+ {{ BHND_CHIP_IPR(4331, 4331TT, HWREV_GTE(1)) },
+ CHIPC_QUIRK_4331_EXTPA2_MUX_SPROM
+ },
+
+ /* 4331 (all packages/revisions) */
+ {{ BHND_CHIP_ID(4331) },
+ CHIPC_QUIRK_4331_EXTPA_MUX_SPROM
+ },
+
+ /* 4360 family (all revs <= 2) */
+ {{ BHND_CHIP_IR(4352, HWREV_LTE(2)) },
+ CHIPC_QUIRK_4360_FEM_MUX_SPROM },
+ {{ BHND_CHIP_IR(43460, HWREV_LTE(2)) },
+ CHIPC_QUIRK_4360_FEM_MUX_SPROM },
+ {{ BHND_CHIP_IR(43462, HWREV_LTE(2)) },
+ CHIPC_QUIRK_4360_FEM_MUX_SPROM },
+ {{ BHND_CHIP_IR(43602, HWREV_LTE(2)) },
+ CHIPC_QUIRK_4360_FEM_MUX_SPROM },
+
+ BHND_CHIP_QUIRK_END
+};
+
/* quirk and capability flag convenience macros */
#define CHIPC_QUIRK(_sc, _name) \
((_sc)->quirks & CHIPC_QUIRK_ ## _name)
@@ -91,7 +124,13 @@ static struct bhnd_device_quirk chipc_qu
KASSERT(CHIPC_QUIRK((_sc), name), ("quirk " __STRING(_name) " not set"))
#define CHIPC_ASSERT_CAP(_sc, name) \
- KASSERT(CHIPC_CAP((_sc), name), ("capability " __STRING(_name) " not set"))
+ KASSERT(CHIPC_CAP((_sc), name), ("capability " __STRING(_name) " not set"))
+
+static bhnd_nvram_src_t chipc_nvram_identify(struct chipc_softc *sc);
+static int chipc_sprom_init(struct chipc_softc *);
+static int chipc_enable_sprom_pins(struct chipc_softc *);
+static int chipc_disable_sprom_pins(struct chipc_softc *);
+
static int
chipc_probe(device_t dev)
@@ -119,6 +158,9 @@ chipc_attach(device_t dev)
sc->dev = dev;
sc->quirks = bhnd_device_quirks(dev, chipc_devices,
sizeof(chipc_devices[0]));
+ sc->quirks |= bhnd_chip_quirks(dev, chipc_chip_quirks);
+
+ CHIPC_LOCK_INIT(sc);
/* Allocate bus resources */
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-all
mailing list