1 /* SPDX-License-Identifier: GPL-2.0 */
3 /* *Copyright (C) 2022-2023 Linaro Ltd. */
8 #include <linux/types.h>
9 #include <linux/log2.h>
10 #include <linux/bug.h>
13 * struct reg - A register descriptor
14 * @offset: Register offset relative to base of register memory
15 * @stride: Distance between two instances, if parameterized
16 * @fcount: Number of entries in the @fmask array
17 * @fmask: Array of mask values defining position and width of fields
18 * @name: Upper-case name of the register
24 const u32 *fmask; /* BIT(nr) or GENMASK(h, l) */
28 /* Helper macro for defining "simple" (non-parameterized) registers */
29 #define REG(__NAME, __reg_id, __offset) \
30 REG_STRIDE(__NAME, __reg_id, __offset, 0)
32 /* Helper macro for defining parameterized registers, specifying stride */
33 #define REG_STRIDE(__NAME, __reg_id, __offset, __stride) \
34 static const struct reg reg_ ## __reg_id = { \
40 #define REG_FIELDS(__NAME, __name, __offset) \
41 REG_STRIDE_FIELDS(__NAME, __name, __offset, 0)
43 #define REG_STRIDE_FIELDS(__NAME, __name, __offset, __stride) \
44 static const struct reg reg_ ## __name = { \
48 .fcount = ARRAY_SIZE(reg_ ## __name ## _fmask), \
49 .fmask = reg_ ## __name ## _fmask, \
53 * struct regs - Description of registers supported by hardware
54 * @reg_count: Number of registers in the @reg[] array
55 * @reg: Array of register descriptors
59 const struct reg **reg;
62 static inline const struct reg *reg(const struct regs *regs, u32 reg_id)
64 if (WARN(reg_id >= regs->reg_count,
65 "reg out of range (%u > %u)\n", reg_id, regs->reg_count - 1))
68 return regs->reg[reg_id];
71 /* Return the field mask for a field in a register, or 0 on error */
72 static inline u32 reg_fmask(const struct reg *reg, u32 field_id)
74 if (!reg || WARN_ON(field_id >= reg->fcount))
77 return reg->fmask[field_id];
80 /* Return the mask for a single-bit field in a register, or 0 on error */
81 static inline u32 reg_bit(const struct reg *reg, u32 field_id)
83 u32 fmask = reg_fmask(reg, field_id);
85 if (WARN_ON(!is_power_of_2(fmask)))
91 /* Return the maximum value representable by the given field; always 2^n - 1 */
92 static inline u32 reg_field_max(const struct reg *reg, u32 field_id)
94 u32 fmask = reg_fmask(reg, field_id);
96 return fmask ? fmask >> __ffs(fmask) : 0;
99 /* Encode a value into the given field of a register */
100 static inline u32 reg_encode(const struct reg *reg, u32 field_id, u32 val)
102 u32 fmask = reg_fmask(reg, field_id);
107 val <<= __ffs(fmask);
108 if (WARN_ON(val & ~fmask))
114 /* Given a register value, decode (extract) the value in the given field */
115 static inline u32 reg_decode(const struct reg *reg, u32 field_id, u32 val)
117 u32 fmask = reg_fmask(reg, field_id);
119 return fmask ? (val & fmask) >> __ffs(fmask) : 0;
122 /* Returns 0 for NULL reg; warning should have already been issued */
123 static inline u32 reg_offset(const struct reg *reg)
125 return reg ? reg->offset : 0;
128 /* Returns 0 for NULL reg; warning should have already been issued */
129 static inline u32 reg_n_offset(const struct reg *reg, u32 n)
131 return reg ? reg->offset + n * reg->stride : 0;