/ src / include / device / mmio.h
mmio.h
  1  /* SPDX-License-Identifier: GPL-2.0-only */
  2  
  3  #ifndef __DEVICE_MMIO_H__
  4  #define __DEVICE_MMIO_H__
  5  
  6  #include <arch/mmio.h> /* IWYU pragma: export */
  7  #include <commonlib/helpers.h>
  8  #include <endian.h>
  9  #include <types.h>
 10  
 11  #define __clrsetbits_impl(bits, addr, clear, set) write##bits(addr, \
 12  	(read##bits(addr) & ~((uint##bits##_t)(clear))) | (set))
 13  
 14  #define clrsetbits8(addr, clear, set)	__clrsetbits_impl(8, addr, clear, set)
 15  #define clrsetbits16(addr, clear, set)	__clrsetbits_impl(16, addr, clear, set)
 16  #define clrsetbits32(addr, clear, set)	__clrsetbits_impl(32, addr, clear, set)
 17  #define clrsetbits64(addr, clear, set)	__clrsetbits_impl(64, addr, clear, set)
 18  
 19  #define setbits8(addr, set)		clrsetbits8(addr, 0, set)
 20  #define setbits16(addr, set)		clrsetbits16(addr, 0, set)
 21  #define setbits32(addr, set)		clrsetbits32(addr, 0, set)
 22  #define setbits64(addr, set)		clrsetbits64(addr, 0, set)
 23  
 24  #define clrbits8(addr, clear)		clrsetbits8(addr, clear, 0)
 25  #define clrbits16(addr, clear)		clrsetbits16(addr, clear, 0)
 26  #define clrbits32(addr, clear)		clrsetbits32(addr, clear, 0)
 27  #define clrbits64(addr, clear)		clrsetbits64(addr, clear, 0)
 28  
 29  #define clrsetbits8p(addr, clear, set)	clrsetbits8((void *)((uintptr_t)addr), clear, set)
 30  #define clrsetbits16p(addr, clear, set)	clrsetbits16((void *)((uintptr_t)addr), clear, set)
 31  #define clrsetbits32p(addr, clear, set)	clrsetbits32((void *)((uintptr_t)addr), clear, set)
 32  #define clrsetbits64p(addr, clear, set)	clrsetbits64((void *)((uintptr_t)addr), clear, set)
 33  
 34  #define setbits8p(addr, set)		clrsetbits8((void *)((uintptr_t)addr), 0, set)
 35  #define setbits16p(addr, set)		clrsetbits16((void *)((uintptr_t)addr), 0, set)
 36  #define setbits32p(addr, set)		clrsetbits32((void *)((uintptr_t)addr), 0, set)
 37  #define setbits64p(addr, set)		clrsetbits64((void *)((uintptr_t)addr), 0, set)
 38  
 39  #define clrbits8p(addr, clear)		clrsetbits8((void *)((uintptr_t)addr), clear, 0)
 40  #define clrbits16p(addr, clear)		clrsetbits16((void *)((uintptr_t)addr), clear, 0)
 41  #define clrbits32p(addr, clear)		clrsetbits32((void *)((uintptr_t)addr), clear, 0)
 42  #define clrbits64p(addr, clear)		clrsetbits64((void *)((uintptr_t)addr), clear, 0)
 43  
 44  /*
 45   * Reads a transfer buffer from 32-bit FIFO registers. fifo_stride is the
 46   * distance in bytes between registers (e.g. pass 4 for a normal array of 32-bit
 47   * registers or 0 to read everything from the same register). fifo_width is
 48   * the amount of bytes read per register (can be 1 through 4).
 49   */
 50  void buffer_from_fifo32(void *buffer, size_t size, void *fifo,
 51  			int fifo_stride, int fifo_width);
 52  
 53  /*
 54   * Version of buffer_to_fifo32() that can prepend a prefix of up to fifo_width
 55   * size to the transfer. This is often useful for protocols where a command word
 56   * precedes the actual payload data. The prefix must be packed in the low-order
 57   * bytes of the 'prefix' u32 parameter and any high-order bytes exceeding prefsz
 58   * must be 0. Note that 'size' counts total bytes written, including 'prefsz'.
 59   */
 60  void buffer_to_fifo32_prefix(const void *buffer, u32 prefix, int prefsz, size_t size,
 61  			     void *fifo, int fifo_stride, int fifo_width);
 62  
 63  /*
 64   * Writes a transfer buffer into 32-bit FIFO registers. fifo_stride is the
 65   * distance in bytes between registers (e.g. pass 4 for a normal array of 32-bit
 66   * registers or 0 to write everything into the same register). fifo_width is
 67   * the amount of bytes written per register (can be 1 through 4).
 68   */
 69  static inline void buffer_to_fifo32(const void *buffer, size_t size, void *fifo,
 70  				    int fifo_stride, int fifo_width)
 71  {
 72  	buffer_to_fifo32_prefix(buffer, 0, 0, size, fifo,
 73  				fifo_stride, fifo_width);
 74  }
 75  
 76  /*
 77   * Utilities to help processing bit fields.
 78   *
 79   * To define a bit field (usually inside a register), do:
 80   *
 81   *  DEFINE_BITFIELD(name, high_bit, low_bit)
 82   *
 83   *  - name: Name of the field to access.
 84   *  - high_bit: highest bit that's part of the bit field.
 85   *  - low_bit: lowest bit in the bit field.
 86   *
 87   * To define a field with a single bit:
 88   *
 89   *  DEFINE_BIT(name, bit)
 90   *
 91   * To extract one field value from a raw reg value:
 92   *
 93   *  EXTRACT_BITFIELD(value, name);
 94   *
 95   * To read from an MMIO register and extract one field from it:
 96   *
 97   *  READ32_BITFIELD(&reg, name);
 98   *
 99   * To write into an MMIO register, set given fields (by names) to specified
100   * values, and all other bits to zero (usually used for resetting a register):
101   *
102   *  WRITE32_BITFIELDS(&reg, name, value, [name, value, ...])
103   *
104   * To write into an MMIO register, set given fields (by names) to specified
105   * values, and leaving all others "unchanged" (usually used for updating some
106   * settings):
107   *
108   *  SET32_BITFIELDS(&reg, name, value, [name, value, ...])
109   *
110   * Examples:
111   *
112   *  DEFINE_BITFIELD(DISP_TYPE, 2, 1)
113   *  DEFINE_BIT(DISP_EN, 0)
114   *
115   *  SET32_BITFIELDS(&disp_regs.ctrl, DISP_TYPE, 2);
116   *  SET32_BITFIELDS(&disp_regs.ctrl, DISP_EN, 0);
117   *
118   *  SET32_BITFIELDS(&disp_regs.ctrl, DISP_TYPE, 1, DISP_EN, 1);
119   *  WRITE32_BITFIELDS(&disp_regs.ctrl, DISP_TYPE, 1, DISP_EN, 1);
120   *
121   *  READ32_BITFIELD(&reg, DISP_TYPE)
122   *  EXTRACT_BITFIELD(value, DISP_TYPE)
123   *
124   * These will be translated to:
125   *
126   *  clrsetbits32(&disp_regs.ctrl, 0x6, 0x4);
127   *  clrsetbits32(&disp_regs.ctrl, 0x1, 0x0);
128   *
129   *  clrsetbits32(&disp_regs.ctrl, 0x7, 0x3);
130   *  write32(&disp_regs.ctrl, 0x3);
131   *
132   *  (read32(&reg) & 0x6) >> 1
133   *  (value & 0x6) >> 1
134   *
135   * The {WRITE,SET}32_BITFIELDS currently only allows setting up to 8 fields at
136   * one invocation.
137   */
138  
139  #define DEFINE_BITFIELD(name, high_bit, low_bit) \
140  	_Static_assert(high_bit >= low_bit, "invalid bit field range"); \
141  	enum { \
142  		name##_BITFIELD_SHIFT = (low_bit), \
143  		name##_BITFIELD_SIZE = (high_bit) - (low_bit) + 1, \
144  	};
145  
146  #define DEFINE_BIT(name, bit) DEFINE_BITFIELD(name, bit, bit)
147  
148  #define _BF_MASK(name, value) \
149  	((u32)GENMASK(name##_BITFIELD_SHIFT + name##_BITFIELD_SIZE - 1, \
150  		      name##_BITFIELD_SHIFT))
151  
152  #define _BF_VALUE(name, value) \
153  	(((u32)(value) << name##_BITFIELD_SHIFT) & _BF_MASK(name, 0))
154  
155  #define _BF_APPLY1(op, name, value, ...) (op(name, value))
156  #define _BF_APPLY2(op, name, value, ...) ((op(name, value)) | \
157  		_BF_APPLY1(op, __VA_ARGS__))
158  #define _BF_APPLY3(op, name, value, ...) ((op(name, value)) | \
159  		_BF_APPLY2(op, __VA_ARGS__))
160  #define _BF_APPLY4(op, name, value, ...) ((op(name, value)) | \
161  		_BF_APPLY3(op, __VA_ARGS__))
162  #define _BF_APPLY5(op, name, value, ...) ((op(name, value)) | \
163  		_BF_APPLY4(op, __VA_ARGS__))
164  #define _BF_APPLY6(op, name, value, ...) ((op(name, value)) | \
165  		_BF_APPLY5(op, __VA_ARGS__))
166  #define _BF_APPLY7(op, name, value, ...) ((op(name, value)) | \
167  		_BF_APPLY6(op, __VA_ARGS__))
168  #define _BF_APPLY8(op, name, value, ...) ((op(name, value)) | \
169  		_BF_APPLY7(op, __VA_ARGS__))
170  #define _BF_APPLY9(op, name, value, ...) ((op(name, value)) | \
171  		_BF_APPLY8(op, __VA_ARGS__))
172  #define _BF_APPLY10(op, name, value, ...) ((op(name, value)) | \
173  		_BF_APPLY9(op, __VA_ARGS__))
174  #define _BF_APPLY11(op, name, value, ...) ((op(name, value)) | \
175  		_BF_APPLY10(op, __VA_ARGS__))
176  #define _BF_APPLY12(op, name, value, ...) ((op(name, value)) | \
177  		_BF_APPLY11(op, __VA_ARGS__))
178  #define _BF_APPLY13(op, name, value, ...) ((op(name, value)) | \
179  		_BF_APPLY12(op, __VA_ARGS__))
180  #define _BF_APPLY14(op, name, value, ...) ((op(name, value)) | \
181  		_BF_APPLY13(op, __VA_ARGS__))
182  #define _BF_APPLY15(op, name, value, ...) ((op(name, value)) | \
183  		_BF_APPLY14(op, __VA_ARGS__))
184  #define _BF_APPLY16(op, name, value, ...) ((op(name, value)) | \
185  		_BF_APPLY15(op, __VA_ARGS__))
186  #define _BF_APPLYINVALID(...) \
187  		_Static_assert(0, "Invalid arguments for {WRITE,SET}*_BITFIELDS")
188  
189  #define _BF_IMPL2(op, addr, \
190  	n1, v1, n2, v2, n3, v3, n4, v4, n5, v5, n6, v6, n7, v7, n8, v8, \
191  	n9, v9, n10, v10, n11, v11, n12, v12, n13, v13, n14, v14, n15, v15, n16, v16, \
192  	NARGS, ...) \
193  	\
194  	op(addr, \
195  	   _BF_APPLY##NARGS(_BF_MASK, n1, v1, n2, v2, n3, v3, n4, v4, \
196  			    n5, v5, n6, v6, n7, v7, n8, v8, \
197  			    n9, v9, n10, v10, n11, v11, n12, v12, \
198  			    n13, v13, n14, v14, n15, v15, n16, v16), \
199  	   _BF_APPLY##NARGS(_BF_VALUE, n1, v1, n2, v2, n3, v3, n4, v4, \
200  			    n5, v5, n6, v6, n7, v7, n8, v8,\
201  			    n9, v9, n10, v10, n11, v11, n12, v12, \
202  			    n13, v13, n14, v14, n15, v15, n16, v16))
203  
204  #define _BF_IMPL(op, addr, ...) \
205  	_BF_IMPL2(op, addr, __VA_ARGS__, \
206  		16, INVALID, 15, INVALID, 14, INVALID, 13, INVALID, \
207  		12, INVALID, 11, INVALID, 10, INVALID, 9, INVALID, \
208  		  8, INVALID, 7, INVALID, 6, INVALID, 5, INVALID, \
209  		  4, INVALID, 3, INVALID, 2, INVALID, 1, INVALID)
210  
211  #define _WRITE32_BITFIELDS_IMPL(addr, masks, values) write32(addr, values)
212  
213  #define WRITE32_BITFIELDS(addr, ...)  \
214  	_BF_IMPL(_WRITE32_BITFIELDS_IMPL, addr, __VA_ARGS__)
215  
216  #define SET32_BITFIELDS(addr, ...) \
217  	_BF_IMPL(clrsetbits32, addr, __VA_ARGS__)
218  
219  #define EXTRACT_BITFIELD(value, name) \
220  	(((value) & _BF_MASK(name, 0)) >> name##_BITFIELD_SHIFT)
221  
222  #define READ32_BITFIELD(addr, name) \
223  	EXTRACT_BITFIELD(read32(addr), name)
224  
225  static __always_inline uint8_t read8p(const uintptr_t addr)
226  {
227  	return read8((void *)addr);
228  }
229  
230  static __always_inline uint16_t read16p(const uintptr_t addr)
231  {
232  	return read16((void *)addr);
233  }
234  
235  static __always_inline uint32_t read32p(const uintptr_t addr)
236  {
237  	return read32((void *)addr);
238  }
239  
240  static __always_inline uint64_t read64p(const uintptr_t addr)
241  {
242  	return read64((void *)addr);
243  }
244  
245  static __always_inline void write8p(const uintptr_t addr, const uint8_t value)
246  {
247  	write8((void *)addr, value);
248  }
249  
250  static __always_inline void write16p(const uintptr_t addr, const uint16_t value)
251  {
252  	write16((void *)addr, value);
253  }
254  
255  static __always_inline void write32p(const uintptr_t addr, const uint32_t value)
256  {
257  	write32((void *)addr, value);
258  }
259  
260  static __always_inline void write64p(const uintptr_t addr, const uint64_t value)
261  {
262  	write64((void *)addr, value);
263  }
264  
265  #endif	/* __DEVICE_MMIO_H__ */