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/log2.h> 10 #include <linux/bug.h> 11 12 /** 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 19 */ 20 struct reg { 21 u32 offset; 22 u32 stride; 23 u32 fcount; 24 const u32 *fmask; /* BIT(nr) or GENMASK(h, l) */ 25 const char *name; 26 }; 27 28 /* Helper macro for defining "simple" (non-parameterized) registers */ 29 #define REG(__NAME, __reg_id, __offset) \ 30 REG_STRIDE(__NAME, __reg_id, __offset, 0) 31 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 = { \ 35 .name = #__NAME, \ 36 .offset = __offset, \ 37 .stride = __stride, \ 38 } 39 40 #define REG_FIELDS(__NAME, __name, __offset) \ 41 REG_STRIDE_FIELDS(__NAME, __name, __offset, 0) 42 43 #define REG_STRIDE_FIELDS(__NAME, __name, __offset, __stride) \ 44 static const struct reg reg_ ## __name = { \ 45 .name = #__NAME, \ 46 .offset = __offset, \ 47 .stride = __stride, \ 48 .fcount = ARRAY_SIZE(reg_ ## __name ## _fmask), \ 49 .fmask = reg_ ## __name ## _fmask, \ 50 } 51 52 /** 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 56 */ 57 struct regs { 58 u32 reg_count; 59 const struct reg **reg; 60 }; 61 62 static inline const struct reg *reg(const struct regs *regs, u32 reg_id) 63 { 64 if (WARN(reg_id >= regs->reg_count, 65 "reg out of range (%u > %u)\n", reg_id, regs->reg_count - 1)) 66 return NULL; 67 68 return regs->reg[reg_id]; 69 } 70 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) 73 { 74 if (!reg || WARN_ON(field_id >= reg->fcount)) 75 return 0; 76 77 return reg->fmask[field_id]; 78 } 79 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) 82 { 83 u32 fmask = reg_fmask(reg, field_id); 84 85 if (WARN_ON(!is_power_of_2(fmask))) 86 return 0; 87 88 return fmask; 89 } 90 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) 93 { 94 u32 fmask = reg_fmask(reg, field_id); 95 96 return fmask ? fmask >> __ffs(fmask) : 0; 97 } 98 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) 101 { 102 u32 fmask = reg_fmask(reg, field_id); 103 104 if (!fmask) 105 return 0; 106 107 val <<= __ffs(fmask); 108 if (WARN_ON(val & ~fmask)) 109 return 0; 110 111 return val; 112 } 113 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) 116 { 117 u32 fmask = reg_fmask(reg, field_id); 118 119 return fmask ? (val & fmask) >> __ffs(fmask) : 0; 120 } 121 122 /* Returns 0 for NULL reg; warning should have already been issued */ 123 static inline u32 reg_offset(const struct reg *reg) 124 { 125 return reg ? reg->offset : 0; 126 } 127 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) 130 { 131 return reg ? reg->offset + n * reg->stride : 0; 132 } 133 134 #endif /* _REG_H_ */ 135