From f74f1a68d55de465fe0736d2507d658614566843 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sun, 8 May 2016 18:30:08 +0000 Subject: [PATCH] [bhnd] Add support for matching on chip identifiers. This is used by the upcoming SPROM code to match on chipsets that require special handling of muxed SPROM pins. Submitted by: Landon Fuller Differential Revision: https://reviews.freebsd.org/D6195 --- sys/dev/bhnd/bhnd.h | 77 ++++++++++++++++++++++++++++++++++++++++ sys/dev/bhnd/bhnd_subr.c | 57 ++++++++++++++++++++++++++--- 2 files changed, 130 insertions(+), 4 deletions(-) diff --git a/sys/dev/bhnd/bhnd.h b/sys/dev/bhnd/bhnd.h index fdfe51055c6..55d2081dc6b 100644 --- a/sys/dev/bhnd/bhnd.h +++ b/sys/dev/bhnd/bhnd.h @@ -232,6 +232,65 @@ struct bhnd_core_match { .unit = -1 \ } +/** A chipset match descriptor. */ +struct bhnd_chip_match { + /** Select fields to be matched */ + uint8_t + match_id:1, + match_rev:1, + match_pkg:1, + match_flags_unused:5; + + uint16_t chip_id; /**< required chip id */ + struct bhnd_hwrev_match chip_rev; /**< matching chip revisions */ + uint8_t chip_pkg; /**< required package */ +}; + +#define BHND_CHIP_MATCH_ANY \ + { .match_id = 0, .match_rev = 0, .match_pkg = 0 } + +#define BHND_CHIP_MATCH_IS_ANY(_m) \ + ((_m)->match_id == 0 && (_m)->match_rev == 0 && (_m)->match_pkg == 0) + +/** Set the required chip ID within a bhnd_chip_match instance */ +#define BHND_CHIP_ID(_cid) \ + .match_id = 1, .chip_id = BHND_CHIPID_BCM ## _cid + +/** Set the required revision range within a bhnd_chip_match instance */ +#define BHND_CHIP_REV(_rev) \ + .match_rev = 1, .chip_rev = BHND_ ## _rev + +/** Set the required package ID within a bhnd_chip_match instance */ +#define BHND_CHIP_PKG(_pkg) \ + .match_pkg = 1, .chip_pkg = BHND_PKGID_BCM ## _pkg + +/** Set the required chip and package ID within a bhnd_chip_match instance */ +#define BHND_CHIP_IP(_cid, _pkg) \ + BHND_CHIP_ID(_cid), BHND_CHIP_PKG(_pkg) + +/** Set the required chip ID, package ID, and revision within a bhnd_chip_match + * instance */ +#define BHND_CHIP_IPR(_cid, _pkg, _rev) \ + BHND_CHIP_ID(_cid), BHND_CHIP_PKG(_pkg), BHND_CHIP_REV(_rev) + +/** Set the required chip ID and revision within a bhnd_chip_match + * instance */ +#define BHND_CHIP_IR(_cid, _rev) \ + BHND_CHIP_ID(_cid), BHND_CHIP_REV(_rev) + +/** + * Chipset quirk table descriptor. + */ +struct bhnd_chip_quirk { + const struct bhnd_chip_match chip; /**< chip match descriptor */ + uint32_t quirks; /**< quirk flags */ +}; + +#define BHND_CHIP_QUIRK_END { BHND_CHIP_MATCH_ANY, 0 } + +#define BHND_CHIP_QUIRK_IS_END(_q) \ + (BHND_CHIP_MATCH_IS_ANY(&(_q)->chip) && (_q)->quirks == 0) + /** * Device quirk table descriptor. */ @@ -297,9 +356,16 @@ bool bhnd_core_matches( const struct bhnd_core_info *core, const struct bhnd_core_match *desc); +bool bhnd_chip_matches( + const struct bhnd_chipid *chipid, + const struct bhnd_chip_match *desc); + bool bhnd_hwrev_matches(uint16_t hwrev, const struct bhnd_hwrev_match *desc); +uint32_t bhnd_chip_quirks(device_t dev, + const struct bhnd_chip_quirk *table); + bool bhnd_device_matches(device_t dev, const struct bhnd_core_match *desc); @@ -388,6 +454,17 @@ bhnd_is_hw_disabled(device_t dev) { return (BHND_BUS_IS_HW_DISABLED(device_get_parent(dev), dev)); } +/** + * Return the BHND chip identification info for the bhnd bus. + * + * @param dev A bhnd bus child device. + */ +static inline const struct bhnd_chipid * +bhnd_get_chipid(device_t dev) { + return (BHND_BUS_GET_CHIPID(device_get_parent(dev), dev)); +}; + + /** * Allocate a resource from a device's parent bhnd(4) bus. * diff --git a/sys/dev/bhnd/bhnd_subr.c b/sys/dev/bhnd/bhnd_subr.c index e9bad4fee1c..ac8fb0db91a 100644 --- a/sys/dev/bhnd/bhnd_subr.c +++ b/sys/dev/bhnd/bhnd_subr.c @@ -415,10 +415,6 @@ bhnd_core_matches(const struct bhnd_core_info *core, if (!bhnd_hwrev_matches(core->hwrev, &desc->hwrev)) return (false); - - if (desc->hwrev.end != BHND_HWREV_INVALID && - desc->hwrev.end < core->hwrev) - return (false); if (desc->class != BHND_DEVCLASS_INVALID && desc->class != bhnd_core_class(core)) @@ -427,6 +423,32 @@ bhnd_core_matches(const struct bhnd_core_info *core, return true; } +/** + * Return true if the @p chip matches @p desc. + * + * @param chip A bhnd chip identifier. + * @param desc A match descriptor to compare against @p chip. + * + * @retval true if @p chip matches @p match + * @retval false if @p chip does not match @p match. + */ +bool +bhnd_chip_matches(const struct bhnd_chipid *chip, + const struct bhnd_chip_match *desc) +{ + if (desc->match_id && chip->chip_id != desc->chip_id) + return (false); + + if (desc->match_pkg && chip->chip_pkg != desc->chip_pkg) + return (false); + + if (desc->match_rev && + !bhnd_hwrev_matches(chip->chip_rev, &desc->chip_rev)) + return (false); + + return (true); +} + /** * Return true if the @p hwrev matches @p desc. * @@ -513,6 +535,33 @@ bhnd_device_lookup(device_t dev, const struct bhnd_device *table, return (NULL); } +/** + * Scan @p table for all quirk flags applicable to @p dev's chip identifier + * (as returned by bhnd_get_chipid). + * + * @param dev A bhnd device. + * @param table The chip quirk table to search. + * + * @return returns all matching quirk flags. + */ +uint32_t +bhnd_chip_quirks(device_t dev, const struct bhnd_chip_quirk *table) +{ + const struct bhnd_chipid *cid; + const struct bhnd_chip_quirk *qent; + uint32_t quirks; + + cid = bhnd_get_chipid(dev); + quirks = 0; + + for (qent = table; !BHND_CHIP_QUIRK_IS_END(qent); qent++) { + if (bhnd_chip_matches(cid, &qent->chip)) + quirks |= qent->quirks; + } + + return (quirks); +} + /** * Scan @p table for all quirk flags applicable to @p dev. * -- 2.45.2