aboutsummaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorLandon J. Fuller <landonf@FreeBSD.org>2016-08-28 20:39:53 +0000
committerLandon J. Fuller <landonf@FreeBSD.org>2016-08-28 20:39:53 +0000
commitd851916ef2373be39838427fcdc5ea4ef097b120 (patch)
treed66b7640d2a612ebece1414b4cc9fb3acefee3ed /sys/dev
parent99cbd70f0b8da8e6547f63651c786efdd02081ab (diff)
Notes
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/bhnd/bhnd.h4
-rw-r--r--sys/dev/bhnd/bhnd_subr.c80
-rw-r--r--sys/dev/bhnd/siba/siba.c35
3 files changed, 90 insertions, 29 deletions
diff --git a/sys/dev/bhnd/bhnd.h b/sys/dev/bhnd/bhnd.h
index 95512629df78..9b5db371359a 100644
--- a/sys/dev/bhnd/bhnd.h
+++ b/sys/dev/bhnd/bhnd.h
@@ -317,6 +317,10 @@ void bhnd_release_resources(device_t dev,
struct bhnd_chipid bhnd_parse_chipid(uint32_t idreg,
bhnd_addr_t enum_addr);
+int bhnd_chipid_fixed_ncores(
+ const struct bhnd_chipid *cid,
+ uint16_t chipc_hwrev, uint8_t *ncores);
+
int bhnd_read_chipid(device_t dev,
struct resource_spec *rs,
bus_size_t chipc_offset,
diff --git a/sys/dev/bhnd/bhnd_subr.c b/sys/dev/bhnd/bhnd_subr.c
index 350d6d030bef..349bc27317c2 100644
--- a/sys/dev/bhnd/bhnd_subr.c
+++ b/sys/dev/bhnd/bhnd_subr.c
@@ -38,6 +38,8 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <machine/resource.h>
+#include <dev/bhnd/siba/sibareg.h>
+
#include <dev/bhnd/cores/chipc/chipcreg.h>
#include "nvram/bhnd_nvram.h"
@@ -840,6 +842,63 @@ bhnd_parse_chipid(uint32_t idreg, bhnd_addr_t enum_addr)
return (result);
}
+
+/**
+ * Determine the correct core count for a chip identification value that
+ * may contain an invalid core count.
+ *
+ * On some early siba(4) devices (see CHIPC_NCORES_MIN_HWREV()), the ChipCommon
+ * core does not provide a valid CHIPC_ID_NUMCORE field.
+ *
+ * @param cid The chip identification to be queried.
+ * @param chipc_hwrev The hardware revision of the ChipCommon core from which
+ * @p cid was parsed.
+ * @param[out] ncores On success, will be set to the correct core count.
+ *
+ * @retval 0 If the core count is already correct, or was mapped to a
+ * a correct value.
+ * @retval EINVAL If the core count is incorrect, but the chip was not
+ * recognized.
+ */
+int
+bhnd_chipid_fixed_ncores(const struct bhnd_chipid *cid, uint16_t chipc_hwrev,
+ uint8_t *ncores)
+{
+ /* bcma(4), and most siba(4) devices */
+ if (CHIPC_NCORES_MIN_HWREV(chipc_hwrev)) {
+ *ncores = cid->ncores;
+ return (0);
+ }
+
+ /* broken siba(4) chipsets */
+ switch (cid->chip_id) {
+ case BHND_CHIPID_BCM4306:
+ *ncores = 6;
+ break;
+ case BHND_CHIPID_BCM4704:
+ *ncores = 9;
+ break;
+ case BHND_CHIPID_BCM5365:
+ /*
+ * BCM5365 does support ID_NUMCORE in at least
+ * some of its revisions, but for unknown
+ * reasons, Broadcom's drivers always exclude
+ * the ChipCommon revision (0x5) used by BCM5365
+ * from the set of revisions supporting
+ * ID_NUMCORE, and instead supply a fixed value.
+ *
+ * Presumably, at least some of these devices
+ * shipped with a broken ID_NUMCORE value.
+ */
+ *ncores = 7;
+ break;
+ default:
+ return (EINVAL);
+ }
+
+ return (0);
+}
+
/**
* Allocate the resource defined by @p rs via @p dev, use it
* to read the ChipCommon ID register relative to @p chipc_offset,
@@ -894,6 +953,27 @@ bhnd_read_chipid(device_t dev, struct resource_spec *rs,
*result = bhnd_parse_chipid(reg, enum_addr);
+ /* Fix the core count on early siba(4) devices */
+ if (chip_type == BHND_CHIPTYPE_SIBA) {
+ uint32_t idh;
+ uint16_t chipc_hwrev;
+
+ /*
+ * We need the ChipCommon revision to determine whether
+ * the ncore field is valid.
+ *
+ * We can safely assume the siba IDHIGH register is mapped
+ * within the chipc register block.
+ */
+ idh = bus_read_4(res, SB0_REG_ABS(SIBA_CFG0_IDHIGH));
+ chipc_hwrev = SIBA_IDH_CORE_REV(idh);
+
+ error = bhnd_chipid_fixed_ncores(result, chipc_hwrev,
+ &result->ncores);
+ if (error)
+ goto cleanup;
+ }
+
cleanup:
/* Clean up */
bus_release_resource(dev, rtype, rid, res);
diff --git a/sys/dev/bhnd/siba/siba.c b/sys/dev/bhnd/siba/siba.c
index 6940cfda4c5c..a8b8bc458e46 100644
--- a/sys/dev/bhnd/siba/siba.c
+++ b/sys/dev/bhnd/siba/siba.c
@@ -635,35 +635,12 @@ siba_add_children(device_t dev, const struct bhnd_chipid *chipid)
ccreg = bus_read_4(r, CHIPC_ID);
ccid = bhnd_parse_chipid(ccreg, SIBA_ENUM_ADDR);
- if (!CHIPC_NCORES_MIN_HWREV(ccrev)) {
- switch (ccid.chip_id) {
- case BHND_CHIPID_BCM4306:
- ccid.ncores = 6;
- break;
- case BHND_CHIPID_BCM4704:
- ccid.ncores = 9;
- break;
- case BHND_CHIPID_BCM5365:
- /*
- * BCM5365 does support ID_NUMCORE in at least
- * some of its revisions, but for unknown
- * reasons, Broadcom's drivers always exclude
- * the ChipCommon revision (0x5) used by BCM5365
- * from the set of revisions supporting
- * ID_NUMCORE, and instead supply a fixed value.
- *
- * Presumably, at least some of these devices
- * shipped with a broken ID_NUMCORE value.
- */
- ccid.ncores = 7;
- break;
- default:
- device_printf(dev, "unable to determine core "
- "count for unrecognized chipset 0x%hx\n",
- ccid.chip_id);
- error = ENXIO;
- goto cleanup;
- }
+ /* Fix up the core count */
+ error = bhnd_chipid_fixed_ncores(&ccid, ccrev, &ccid.ncores);
+ if (error) {
+ device_printf(dev, "unable to determine core count for "
+ "chipset 0x%hx\n", ccid.chip_id);
+ goto cleanup;
}
chipid = &ccid;