1 /* SPDX-License-Identifier: GPL-2.0 */ 2 3 /* *Copyright (C) 2022-2023 Linaro Ltd. */ 4 5 #ifndef _REG_H_ 6 #define _REG_H_ 7 8 #include <linux/types.h> 9 #include <linux/bits.h> 10 11 /** 12 * struct reg - A register descriptor 13 * @offset: Register offset relative to base of register memory 14 * @stride: Distance between two instances, if parameterized 15 * @fcount: Number of entries in the @fmask array 16 * @fmask: Array of mask values defining position and width of fields 17 * @name: Upper-case name of the register 18 */ 19 struct reg { 20 u32 offset; 21 u32 stride; 22 u32 fcount; 23 const u32 *fmask; /* BIT(nr) or GENMASK(h, l) */ 24 const char *name; 25 }; 26 27 /* Helper macro for defining "simple" (non-parameterized) registers */ 28 #define REG(__NAME, __reg_id, __offset) \ 29 REG_STRIDE(__NAME, __reg_id, __offset, 0) 30 31 /* Helper macro for defining parameterized registers, specifying stride */ 32 #define REG_STRIDE(__NAME, __reg_id, __offset, __stride) \ 33 static const struct reg reg_ ## __reg_id = { \ 34 .name = #__NAME, \ 35 .offset = __offset, \ 36 .stride = __stride, \ 37 } 38 39 #define REG_FIELDS(__NAME, __name, __offset) \ 40 REG_STRIDE_FIELDS(__NAME, __name, __offset, 0) 41 42 #define REG_STRIDE_FIELDS(__NAME, __name, __offset, __stride) \ 43 static const struct reg reg_ ## __name = { \ 44 .name = #__NAME, \ 45 .offset = __offset, \ 46 .stride = __stride, \ 47 .fcount = ARRAY_SIZE(reg_ ## __name ## _fmask), \ 48 .fmask = reg_ ## __name ## _fmask, \ 49 } 50 51 /** 52 * struct regs - Description of registers supported by hardware 53 * @reg_count: Number of registers in the @reg[] array 54 * @reg: Array of register descriptors 55 */ 56 struct regs { 57 u32 reg_count; 58 const struct reg **reg; 59 }; 60 61 static inline const struct reg *reg(const struct regs *regs, u32 reg_id) 62 { 63 if (WARN(reg_id >= regs->reg_count, 64 "reg out of range (%u > %u)\n", reg_id, regs->reg_count - 1)) 65 return NULL; 66 67 return regs->reg[reg_id]; 68 } 69 70 /* Return the field mask for a field in a register, or 0 on error */ 71 static inline u32 reg_fmask(const struct reg *reg, u32 field_id) 72 { 73 if (!reg || WARN_ON(field_id >= reg->fcount)) 74 return 0; 75 76 return reg->fmask[field_id]; 77 } 78 79 /* Return the mask for a single-bit field in a register, or 0 on error */ 80 static inline u32 reg_bit(const struct reg *reg, u32 field_id) 81 { 82 u32 fmask = reg_fmask(reg, field_id); 83 84 if (WARN_ON(!is_power_of_2(fmask))) 85 return 0; 86 87 return fmask; 88 } 89 90 /* Return the maximum value representable by the given field; always 2^n - 1 */ 91 static inline u32 reg_field_max(const struct reg *reg, u32 field_id) 92 { 93 u32 fmask = reg_fmask(reg, field_id); 94 95 return fmask ? fmask >> __ffs(fmask) : 0; 96 } 97 98 /* Encode a value into the given field of a register */ 99 static inline u32 reg_encode(const struct reg *reg, u32 field_id, u32 val) 100 { 101 u32 fmask = reg_fmask(reg, field_id); 102 103 if (!fmask) 104 return 0; 105 106 val <<= __ffs(fmask); 107 if (WARN_ON(val & ~fmask)) 108 return 0; 109 110 return val; 111 } 112 113 /* Given a register value, decode (extract) the value in the given field */ 114 static inline u32 reg_decode(const struct reg *reg, u32 field_id, u32 val) 115 { 116 u32 fmask = reg_fmask(reg, field_id); 117 118 return fmask ? (val & fmask) >> __ffs(fmask) : 0; 119 } 120 121 /* Returns 0 for NULL reg; warning should have already been issued */ 122 static inline u32 reg_offset(const struct reg *reg) 123 { 124 return reg ? reg->offset : 0; 125 } 126 127 /* Returns 0 for NULL reg; warning should have already been issued */ 128 static inline u32 reg_n_offset(const struct reg *reg, u32 n) 129 { 130 return reg ? reg->offset + n * reg->stride : 0; 131 } 132 133 #endif /* _REG_H_ */ 134