1 /* SPDX-License-Identifier: GPL-2.0 */
3 /* Copyright (C) 2022-2024 Linaro Ltd. */
8 #include <linux/array_size.h>
9 #include <linux/bits.h>
10 #include <linux/bug.h>
11 #include <linux/log2.h>
12 #include <linux/types.h>
15 * struct reg - A register descriptor
16 * @offset: Register offset relative to base of register memory
17 * @stride: Distance between two instances, if parameterized
18 * @fcount: Number of entries in the @fmask array
19 * @fmask: Array of mask values defining position and width of fields
20 * @name: Upper-case name of the register
26 const u32
*fmask
; /* BIT(nr) or GENMASK(h, l) */
30 /* Helper macro for defining "simple" (non-parameterized) registers */
31 #define REG(__NAME, __reg_id, __offset) \
32 REG_STRIDE(__NAME, __reg_id, __offset, 0)
34 /* Helper macro for defining parameterized registers, specifying stride */
35 #define REG_STRIDE(__NAME, __reg_id, __offset, __stride) \
36 static const struct reg reg_ ## __reg_id = { \
42 #define REG_FIELDS(__NAME, __name, __offset) \
43 REG_STRIDE_FIELDS(__NAME, __name, __offset, 0)
45 #define REG_STRIDE_FIELDS(__NAME, __name, __offset, __stride) \
46 static const struct reg reg_ ## __name = { \
50 .fcount = ARRAY_SIZE(reg_ ## __name ## _fmask), \
51 .fmask = reg_ ## __name ## _fmask, \
55 * struct regs - Description of registers supported by hardware
56 * @reg_count: Number of registers in the @reg[] array
57 * @reg: Array of register descriptors
61 const struct reg
**reg
;
64 static inline const struct reg
*reg(const struct regs
*regs
, u32 reg_id
)
66 if (WARN(reg_id
>= regs
->reg_count
,
67 "reg out of range (%u > %u)\n", reg_id
, regs
->reg_count
- 1))
70 return regs
->reg
[reg_id
];
73 /* Return the field mask for a field in a register, or 0 on error */
74 static inline u32
reg_fmask(const struct reg
*reg
, u32 field_id
)
76 if (!reg
|| WARN_ON(field_id
>= reg
->fcount
))
79 return reg
->fmask
[field_id
];
82 /* Return the mask for a single-bit field in a register, or 0 on error */
83 static inline u32
reg_bit(const struct reg
*reg
, u32 field_id
)
85 u32 fmask
= reg_fmask(reg
, field_id
);
87 if (WARN_ON(!is_power_of_2(fmask
)))
93 /* Return the maximum value representable by the given field; always 2^n - 1 */
94 static inline u32
reg_field_max(const struct reg
*reg
, u32 field_id
)
96 u32 fmask
= reg_fmask(reg
, field_id
);
98 return fmask
? fmask
>> __ffs(fmask
) : 0;
101 /* Encode a value into the given field of a register */
102 static inline u32
reg_encode(const struct reg
*reg
, u32 field_id
, u32 val
)
104 u32 fmask
= reg_fmask(reg
, field_id
);
109 val
<<= __ffs(fmask
);
110 if (WARN_ON(val
& ~fmask
))
116 /* Given a register value, decode (extract) the value in the given field */
117 static inline u32
reg_decode(const struct reg
*reg
, u32 field_id
, u32 val
)
119 u32 fmask
= reg_fmask(reg
, field_id
);
121 return fmask
? (val
& fmask
) >> __ffs(fmask
) : 0;
124 /* Returns 0 for NULL reg; warning should have already been issued */
125 static inline u32
reg_offset(const struct reg
*reg
)
127 return reg
? reg
->offset
: 0;
130 /* Returns 0 for NULL reg; warning should have already been issued */
131 static inline u32
reg_n_offset(const struct reg
*reg
, u32 n
)
133 return reg
? reg
->offset
+ n
* reg
->stride
: 0;