public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Alex Elder <elder@linaro.org>
To: davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
	pabeni@redhat.com
Cc: mka@chromium.org, evgreen@chromium.org, andersson@kernel.org,
	quic_cpratapa@quicinc.com, quic_avuyyuru@quicinc.com,
	quic_jponduru@quicinc.com, quic_subashab@quicinc.com,
	elder@kernel.org, netdev@vger.kernel.org,
	linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH net-next 06/15] net: ipa: introduce ipa_reg field masks
Date: Mon, 26 Sep 2022 17:09:22 -0500	[thread overview]
Message-ID: <20220926220931.3261749-7-elder@linaro.org> (raw)
In-Reply-To: <20220926220931.3261749-1-elder@linaro.org>

Add register field descriptors to the ipa_reg structure.  A field in
a register is defined by a field mask, which is a 32-bit mask having
a single contiguous range of bits set.

For each register that has at least one field defined, an enumerated
type will identify the register's fields.  The ipa_reg structure for
that register will include an array fmask[] of field masks, indexed
by that enumerated type.  Each field mask defines the position and
bit width of a field.  An additional "fcount" records how many
fields (masks) are defined for a given register.

Introduce two macros to be used to define registers that have at
least one field.

Introduce a few new functions related to field masks.  The first
simply returns a field mask, given an IPA register pointer and field
mask ID.  A variant of that is meant to be used for the special case
of single-bit field masks.

Next, ipa_reg_encode(), identifies a field with an IPA register
pointer and a field ID, and takes a value to represent in that
field.  The result encodes the value in the appropriate place to be
stored in the register.  This is roughly modeled after the bitmask
operations (like u32_encode_bits()).

Another function (ipa_reg_decode()) similarly identifies a register
field, but the value supplied to it represents a full register
value.  The value encoded in the field is extracted from the value
and returned.  This is also roughly modeled after bitmask operations
(such as u32_get_bits()).

Finally, ipa_reg_field_max() returns the maximum value representable
by a field.

Signed-off-by: Alex Elder <elder@linaro.org>
---
 drivers/net/ipa/ipa_reg.h | 68 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/drivers/net/ipa/ipa_reg.h b/drivers/net/ipa/ipa_reg.h
index 49eec53a375ec..a616b0c3d59a6 100644
--- a/drivers/net/ipa/ipa_reg.h
+++ b/drivers/net/ipa/ipa_reg.h
@@ -125,11 +125,15 @@ enum ipa_reg_id {
  * struct ipa_reg - An IPA register descriptor
  * @offset:	Register offset relative to base of the "ipa-reg" memory
  * @stride:	Distance between two instances, if parameterized
+ * @fcount:	Number of entries in the @fmask array
+ * @fmask:	Array of mask values defining position and width of fields
  * @name:	Upper-case name of the IPA register
  */
 struct ipa_reg {
 	u32 offset;
 	u32 stride;
+	u32 fcount;
+	const u32 *fmask;			/* BIT(nr) or GENMASK(h, l) */
 	const char *name;
 };
 
@@ -145,6 +149,18 @@ struct ipa_reg {
 		.stride	= __stride,					\
 	}
 
+#define IPA_REG_FIELDS(__NAME, __name, __offset)			\
+	IPA_REG_STRIDE_FIELDS(__NAME, __name, __offset, 0)
+
+#define IPA_REG_STRIDE_FIELDS(__NAME, __name, __offset, __stride)	\
+	static const struct ipa_reg ipa_reg_ ## __name = {		\
+		.name   = #__NAME,					\
+		.offset = __offset,					\
+		.stride = __stride,					\
+		.fcount = ARRAY_SIZE(ipa_reg_ ## __name ## _fmask),	\
+		.fmask  = ipa_reg_ ## __name ## _fmask,			\
+	}
+
 /**
  * struct ipa_regs - Description of registers supported by hardware
  * @reg_count:	Number of registers in the @reg[] array
@@ -746,6 +762,58 @@ extern const struct ipa_regs ipa_regs_v4_5;
 extern const struct ipa_regs ipa_regs_v4_9;
 extern const struct ipa_regs ipa_regs_v4_11;
 
+/* Return the field mask for a field in a register */
+static inline u32 ipa_reg_fmask(const struct ipa_reg *reg, u32 field_id)
+{
+	if (!reg || WARN_ON(field_id >= reg->fcount))
+		return 0;
+
+	return reg->fmask[field_id];
+}
+
+/* Return the mask for a single-bit field in a register */
+static inline u32 ipa_reg_bit(const struct ipa_reg *reg, u32 field_id)
+{
+	u32 fmask = ipa_reg_fmask(reg, field_id);
+
+	WARN_ON(!is_power_of_2(fmask));
+
+	return fmask;
+}
+
+/* Encode a value into the given field of a register */
+static inline u32
+ipa_reg_encode(const struct ipa_reg *reg, u32 field_id, u32 val)
+{
+	u32 fmask = ipa_reg_fmask(reg, field_id);
+
+	if (!fmask)
+		return 0;
+
+	val <<= __ffs(fmask);
+	if (WARN_ON(val & ~fmask))
+		return 0;
+
+	return val;
+}
+
+/* Given a register value, decode (extract) the value in the given field */
+static inline u32
+ipa_reg_decode(const struct ipa_reg *reg, u32 field_id, u32 val)
+{
+	u32 fmask = ipa_reg_fmask(reg, field_id);
+
+	return fmask ? (val & fmask) >> __ffs(fmask) : 0;
+}
+
+/* Return the maximum value representable by the given field; always 2^n - 1 */
+static inline u32 ipa_reg_field_max(const struct ipa_reg *reg, u32 field_id)
+{
+	u32 fmask = ipa_reg_fmask(reg, field_id);
+
+	return fmask ? fmask >> __ffs(fmask) : 0;
+}
+
 const struct ipa_reg *ipa_reg(struct ipa *ipa, enum ipa_reg_id reg_id);
 
 /* Returns 0 for NULL reg; warning will have already been issued */
-- 
2.34.1


  parent reply	other threads:[~2022-09-26 22:11 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-26 22:09 [PATCH net-next 00/15] net: ipa: generalized register definitions Alex Elder
2022-09-26 22:09 ` [PATCH net-next 01/15] net: ipa: introduce IPA register IDs Alex Elder
2022-09-26 22:09 ` [PATCH net-next 02/15] net: ipa: use IPA register IDs to determine offsets Alex Elder
2022-09-26 22:09 ` [PATCH net-next 03/15] net: ipa: add per-version IPA register definition files Alex Elder
2022-09-26 22:09 ` [PATCH net-next 04/15] net: ipa: use ipa_reg[] array for register offsets Alex Elder
2022-09-26 22:09 ` [PATCH net-next 05/15] net: ipa: introduce ipa_reg() Alex Elder
2022-09-26 22:09 ` Alex Elder [this message]
2022-09-26 22:09 ` [PATCH net-next 07/15] net: ipa: define COMP_CFG IPA register fields Alex Elder
2022-09-26 22:09 ` [PATCH net-next 08/15] net: ipa: define CLKON_CFG and ROUTE " Alex Elder
2022-09-26 22:09 ` [PATCH net-next 09/15] net: ipa: define some more " Alex Elder
2022-09-26 22:09 ` [PATCH net-next 10/15] net: ipa: define " Alex Elder
2022-09-26 22:09 ` [PATCH net-next 11/15] net: ipa: define even " Alex Elder
2022-09-26 22:09 ` [PATCH net-next 12/15] net: ipa: define resource group/type " Alex Elder
2022-09-26 22:09 ` [PATCH net-next 13/15] net: ipa: define some IPA endpoint " Alex Elder
2022-09-26 22:09 ` [PATCH net-next 14/15] net: ipa: define more " Alex Elder
2022-09-26 22:09 ` [PATCH net-next 15/15] net: ipa: define remaining IPA " Alex Elder
2022-09-28  2:00 ` [PATCH net-next 00/15] net: ipa: generalized register definitions patchwork-bot+netdevbpf
2022-09-28 14:04   ` Jakub Kicinski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220926220931.3261749-7-elder@linaro.org \
    --to=elder@linaro.org \
    --cc=andersson@kernel.org \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=elder@kernel.org \
    --cc=evgreen@chromium.org \
    --cc=kuba@kernel.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mka@chromium.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=quic_avuyyuru@quicinc.com \
    --cc=quic_cpratapa@quicinc.com \
    --cc=quic_jponduru@quicinc.com \
    --cc=quic_subashab@quicinc.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox