1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2020 Marvell International Ltd.
4  *
5  * Interface to the hardware Fetch and Add Unit.
6  */
7 
8 /**
9  * @file
10  *
11  * Interface to the hardware Fetch and Add Unit.
12  *
13  */
14 
15 #ifndef __CVMX_HWFAU_H__
16 #define __CVMX_HWFAU_H__
17 
18 typedef int cvmx_fau_reg64_t;
19 typedef int cvmx_fau_reg32_t;
20 typedef int cvmx_fau_reg16_t;
21 typedef int cvmx_fau_reg8_t;
22 
23 #define CVMX_FAU_REG_ANY -1
24 
25 /*
26  * Octeon Fetch and Add Unit (FAU)
27  */
28 
29 #define CVMX_FAU_LOAD_IO_ADDRESS cvmx_build_io_address(0x1e, 0)
30 #define CVMX_FAU_BITS_SCRADDR	 63, 56
31 #define CVMX_FAU_BITS_LEN	 55, 48
32 #define CVMX_FAU_BITS_INEVAL	 35, 14
33 #define CVMX_FAU_BITS_TAGWAIT	 13, 13
34 #define CVMX_FAU_BITS_NOADD	 13, 13
35 #define CVMX_FAU_BITS_SIZE	 12, 11
36 #define CVMX_FAU_BITS_REGISTER	 10, 0
37 
38 #define CVMX_FAU_MAX_REGISTERS_8 (2048)
39 
40 typedef enum {
41 	CVMX_FAU_OP_SIZE_8 = 0,
42 	CVMX_FAU_OP_SIZE_16 = 1,
43 	CVMX_FAU_OP_SIZE_32 = 2,
44 	CVMX_FAU_OP_SIZE_64 = 3
45 } cvmx_fau_op_size_t;
46 
47 /**
48  * Tagwait return definition. If a timeout occurs, the error
49  * bit will be set. Otherwise the value of the register before
50  * the update will be returned.
51  */
52 typedef struct {
53 	u64 error : 1;
54 	s64 value : 63;
55 } cvmx_fau_tagwait64_t;
56 
57 /**
58  * Tagwait return definition. If a timeout occurs, the error
59  * bit will be set. Otherwise the value of the register before
60  * the update will be returned.
61  */
62 typedef struct {
63 	u64 error : 1;
64 	s32 value : 31;
65 } cvmx_fau_tagwait32_t;
66 
67 /**
68  * Tagwait return definition. If a timeout occurs, the error
69  * bit will be set. Otherwise the value of the register before
70  * the update will be returned.
71  */
72 typedef struct {
73 	u64 error : 1;
74 	s16 value : 15;
75 } cvmx_fau_tagwait16_t;
76 
77 /**
78  * Tagwait return definition. If a timeout occurs, the error
79  * bit will be set. Otherwise the value of the register before
80  * the update will be returned.
81  */
82 typedef struct {
83 	u64 error : 1;
84 	int8_t value : 7;
85 } cvmx_fau_tagwait8_t;
86 
87 /**
88  * Asynchronous tagwait return definition. If a timeout occurs,
89  * the error bit will be set. Otherwise the value of the
90  * register before the update will be returned.
91  */
92 typedef union {
93 	u64 u64;
94 	struct {
95 		u64 invalid : 1;
96 		u64 data : 63; /* unpredictable if invalid is set */
97 	} s;
98 } cvmx_fau_async_tagwait_result_t;
99 
100 #define SWIZZLE_8  0
101 #define SWIZZLE_16 0
102 #define SWIZZLE_32 0
103 
104 /**
105  * @INTERNAL
106  * Builds a store I/O address for writing to the FAU
107  *
108  * @param noadd  0 = Store value is atomically added to the current value
109  *               1 = Store value is atomically written over the current value
110  * @param reg    FAU atomic register to access. 0 <= reg < 2048.
111  *               - Step by 2 for 16 bit access.
112  *               - Step by 4 for 32 bit access.
113  *               - Step by 8 for 64 bit access.
114  * @return Address to store for atomic update
115  */
__cvmx_hwfau_store_address(u64 noadd,u64 reg)116 static inline u64 __cvmx_hwfau_store_address(u64 noadd, u64 reg)
117 {
118 	return (CVMX_ADD_IO_SEG(CVMX_FAU_LOAD_IO_ADDRESS) |
119 		cvmx_build_bits(CVMX_FAU_BITS_NOADD, noadd) |
120 		cvmx_build_bits(CVMX_FAU_BITS_REGISTER, reg));
121 }
122 
123 /**
124  * @INTERNAL
125  * Builds a I/O address for accessing the FAU
126  *
127  * @param tagwait Should the atomic add wait for the current tag switch
128  *                operation to complete.
129  *                - 0 = Don't wait
130  *                - 1 = Wait for tag switch to complete
131  * @param reg     FAU atomic register to access. 0 <= reg < 2048.
132  *                - Step by 2 for 16 bit access.
133  *                - Step by 4 for 32 bit access.
134  *                - Step by 8 for 64 bit access.
135  * @param value   Signed value to add.
136  *                Note: When performing 32 and 64 bit access, only the low
137  *                22 bits are available.
138  * @return Address to read from for atomic update
139  */
__cvmx_hwfau_atomic_address(u64 tagwait,u64 reg,s64 value)140 static inline u64 __cvmx_hwfau_atomic_address(u64 tagwait, u64 reg, s64 value)
141 {
142 	return (CVMX_ADD_IO_SEG(CVMX_FAU_LOAD_IO_ADDRESS) |
143 		cvmx_build_bits(CVMX_FAU_BITS_INEVAL, value) |
144 		cvmx_build_bits(CVMX_FAU_BITS_TAGWAIT, tagwait) |
145 		cvmx_build_bits(CVMX_FAU_BITS_REGISTER, reg));
146 }
147 
148 /**
149  * Perform an atomic 64 bit add
150  *
151  * @param reg     FAU atomic register to access. 0 <= reg < 2048.
152  *                - Step by 8 for 64 bit access.
153  * @param value   Signed value to add.
154  *                Note: Only the low 22 bits are available.
155  * @return Value of the register before the update
156  */
cvmx_hwfau_fetch_and_add64(cvmx_fau_reg64_t reg,s64 value)157 static inline s64 cvmx_hwfau_fetch_and_add64(cvmx_fau_reg64_t reg, s64 value)
158 {
159 	return cvmx_read64_int64(__cvmx_hwfau_atomic_address(0, reg, value));
160 }
161 
162 /**
163  * Perform an atomic 32 bit add
164  *
165  * @param reg     FAU atomic register to access. 0 <= reg < 2048.
166  *                - Step by 4 for 32 bit access.
167  * @param value   Signed value to add.
168  *                Note: Only the low 22 bits are available.
169  * @return Value of the register before the update
170  */
cvmx_hwfau_fetch_and_add32(cvmx_fau_reg32_t reg,s32 value)171 static inline s32 cvmx_hwfau_fetch_and_add32(cvmx_fau_reg32_t reg, s32 value)
172 {
173 	reg ^= SWIZZLE_32;
174 	return cvmx_read64_int32(__cvmx_hwfau_atomic_address(0, reg, value));
175 }
176 
177 /**
178  * Perform an atomic 16 bit add
179  *
180  * @param reg     FAU atomic register to access. 0 <= reg < 2048.
181  *                - Step by 2 for 16 bit access.
182  * @param value   Signed value to add.
183  * @return Value of the register before the update
184  */
cvmx_hwfau_fetch_and_add16(cvmx_fau_reg16_t reg,s16 value)185 static inline s16 cvmx_hwfau_fetch_and_add16(cvmx_fau_reg16_t reg, s16 value)
186 {
187 	reg ^= SWIZZLE_16;
188 	return cvmx_read64_int16(__cvmx_hwfau_atomic_address(0, reg, value));
189 }
190 
191 /**
192  * Perform an atomic 8 bit add
193  *
194  * @param reg     FAU atomic register to access. 0 <= reg < 2048.
195  * @param value   Signed value to add.
196  * @return Value of the register before the update
197  */
cvmx_hwfau_fetch_and_add8(cvmx_fau_reg8_t reg,int8_t value)198 static inline int8_t cvmx_hwfau_fetch_and_add8(cvmx_fau_reg8_t reg, int8_t value)
199 {
200 	reg ^= SWIZZLE_8;
201 	return cvmx_read64_int8(__cvmx_hwfau_atomic_address(0, reg, value));
202 }
203 
204 /**
205  * Perform an atomic 64 bit add after the current tag switch
206  * completes
207  *
208  * @param reg    FAU atomic register to access. 0 <= reg < 2048.
209  *               - Step by 8 for 64 bit access.
210  * @param value  Signed value to add.
211  *               Note: Only the low 22 bits are available.
212  * @return If a timeout occurs, the error bit will be set. Otherwise
213  *         the value of the register before the update will be
214  *         returned
215  */
cvmx_hwfau_tagwait_fetch_and_add64(cvmx_fau_reg64_t reg,s64 value)216 static inline cvmx_fau_tagwait64_t cvmx_hwfau_tagwait_fetch_and_add64(cvmx_fau_reg64_t reg,
217 								      s64 value)
218 {
219 	union {
220 		u64 i64;
221 		cvmx_fau_tagwait64_t t;
222 	} result;
223 	result.i64 = cvmx_read64_int64(__cvmx_hwfau_atomic_address(1, reg, value));
224 	return result.t;
225 }
226 
227 /**
228  * Perform an atomic 32 bit add after the current tag switch
229  * completes
230  *
231  * @param reg    FAU atomic register to access. 0 <= reg < 2048.
232  *               - Step by 4 for 32 bit access.
233  * @param value  Signed value to add.
234  *               Note: Only the low 22 bits are available.
235  * @return If a timeout occurs, the error bit will be set. Otherwise
236  *         the value of the register before the update will be
237  *         returned
238  */
cvmx_hwfau_tagwait_fetch_and_add32(cvmx_fau_reg32_t reg,s32 value)239 static inline cvmx_fau_tagwait32_t cvmx_hwfau_tagwait_fetch_and_add32(cvmx_fau_reg32_t reg,
240 								      s32 value)
241 {
242 	union {
243 		u64 i32;
244 		cvmx_fau_tagwait32_t t;
245 	} result;
246 	reg ^= SWIZZLE_32;
247 	result.i32 = cvmx_read64_int32(__cvmx_hwfau_atomic_address(1, reg, value));
248 	return result.t;
249 }
250 
251 /**
252  * Perform an atomic 16 bit add after the current tag switch
253  * completes
254  *
255  * @param reg    FAU atomic register to access. 0 <= reg < 2048.
256  *               - Step by 2 for 16 bit access.
257  * @param value  Signed value to add.
258  * @return If a timeout occurs, the error bit will be set. Otherwise
259  *         the value of the register before the update will be
260  *         returned
261  */
cvmx_hwfau_tagwait_fetch_and_add16(cvmx_fau_reg16_t reg,s16 value)262 static inline cvmx_fau_tagwait16_t cvmx_hwfau_tagwait_fetch_and_add16(cvmx_fau_reg16_t reg,
263 								      s16 value)
264 {
265 	union {
266 		u64 i16;
267 		cvmx_fau_tagwait16_t t;
268 	} result;
269 	reg ^= SWIZZLE_16;
270 	result.i16 = cvmx_read64_int16(__cvmx_hwfau_atomic_address(1, reg, value));
271 	return result.t;
272 }
273 
274 /**
275  * Perform an atomic 8 bit add after the current tag switch
276  * completes
277  *
278  * @param reg    FAU atomic register to access. 0 <= reg < 2048.
279  * @param value  Signed value to add.
280  * @return If a timeout occurs, the error bit will be set. Otherwise
281  *         the value of the register before the update will be
282  *         returned
283  */
cvmx_hwfau_tagwait_fetch_and_add8(cvmx_fau_reg8_t reg,int8_t value)284 static inline cvmx_fau_tagwait8_t cvmx_hwfau_tagwait_fetch_and_add8(cvmx_fau_reg8_t reg,
285 								    int8_t value)
286 {
287 	union {
288 		u64 i8;
289 		cvmx_fau_tagwait8_t t;
290 	} result;
291 	reg ^= SWIZZLE_8;
292 	result.i8 = cvmx_read64_int8(__cvmx_hwfau_atomic_address(1, reg, value));
293 	return result.t;
294 }
295 
296 /**
297  * @INTERNAL
298  * Builds I/O data for async operations
299  *
300  * @param scraddr Scratch pad byte address to write to.  Must be 8 byte aligned
301  * @param value   Signed value to add.
302  *                Note: When performing 32 and 64 bit access, only the low
303  *                22 bits are available.
304  * @param tagwait Should the atomic add wait for the current tag switch
305  *                operation to complete.
306  *                - 0 = Don't wait
307  *                - 1 = Wait for tag switch to complete
308  * @param size    The size of the operation:
309  *                - CVMX_FAU_OP_SIZE_8  (0) = 8 bits
310  *                - CVMX_FAU_OP_SIZE_16 (1) = 16 bits
311  *                - CVMX_FAU_OP_SIZE_32 (2) = 32 bits
312  *                - CVMX_FAU_OP_SIZE_64 (3) = 64 bits
313  * @param reg     FAU atomic register to access. 0 <= reg < 2048.
314  *                - Step by 2 for 16 bit access.
315  *                - Step by 4 for 32 bit access.
316  *                - Step by 8 for 64 bit access.
317  * @return Data to write using cvmx_send_single
318  */
__cvmx_fau_iobdma_data(u64 scraddr,s64 value,u64 tagwait,cvmx_fau_op_size_t size,u64 reg)319 static inline u64 __cvmx_fau_iobdma_data(u64 scraddr, s64 value, u64 tagwait,
320 					 cvmx_fau_op_size_t size, u64 reg)
321 {
322 	return (CVMX_FAU_LOAD_IO_ADDRESS | cvmx_build_bits(CVMX_FAU_BITS_SCRADDR, scraddr >> 3) |
323 		cvmx_build_bits(CVMX_FAU_BITS_LEN, 1) |
324 		cvmx_build_bits(CVMX_FAU_BITS_INEVAL, value) |
325 		cvmx_build_bits(CVMX_FAU_BITS_TAGWAIT, tagwait) |
326 		cvmx_build_bits(CVMX_FAU_BITS_SIZE, size) |
327 		cvmx_build_bits(CVMX_FAU_BITS_REGISTER, reg));
328 }
329 
330 /**
331  * Perform an async atomic 64 bit add. The old value is
332  * placed in the scratch memory at byte address scraddr.
333  *
334  * @param scraddr Scratch memory byte address to put response in.
335  *                Must be 8 byte aligned.
336  * @param reg     FAU atomic register to access. 0 <= reg < 2048.
337  *                - Step by 8 for 64 bit access.
338  * @param value   Signed value to add.
339  *                Note: Only the low 22 bits are available.
340  * @return Placed in the scratch pad register
341  */
cvmx_hwfau_async_fetch_and_add64(u64 scraddr,cvmx_fau_reg64_t reg,s64 value)342 static inline void cvmx_hwfau_async_fetch_and_add64(u64 scraddr, cvmx_fau_reg64_t reg, s64 value)
343 {
344 	cvmx_send_single(__cvmx_fau_iobdma_data(scraddr, value, 0, CVMX_FAU_OP_SIZE_64, reg));
345 }
346 
347 /**
348  * Perform an async atomic 32 bit add. The old value is
349  * placed in the scratch memory at byte address scraddr.
350  *
351  * @param scraddr Scratch memory byte address to put response in.
352  *                Must be 8 byte aligned.
353  * @param reg     FAU atomic register to access. 0 <= reg < 2048.
354  *                - Step by 4 for 32 bit access.
355  * @param value   Signed value to add.
356  *                Note: Only the low 22 bits are available.
357  * @return Placed in the scratch pad register
358  */
cvmx_hwfau_async_fetch_and_add32(u64 scraddr,cvmx_fau_reg32_t reg,s32 value)359 static inline void cvmx_hwfau_async_fetch_and_add32(u64 scraddr, cvmx_fau_reg32_t reg, s32 value)
360 {
361 	cvmx_send_single(__cvmx_fau_iobdma_data(scraddr, value, 0, CVMX_FAU_OP_SIZE_32, reg));
362 }
363 
364 /**
365  * Perform an async atomic 16 bit add. The old value is
366  * placed in the scratch memory at byte address scraddr.
367  *
368  * @param scraddr Scratch memory byte address to put response in.
369  *                Must be 8 byte aligned.
370  * @param reg     FAU atomic register to access. 0 <= reg < 2048.
371  *                - Step by 2 for 16 bit access.
372  * @param value   Signed value to add.
373  * @return Placed in the scratch pad register
374  */
cvmx_hwfau_async_fetch_and_add16(u64 scraddr,cvmx_fau_reg16_t reg,s16 value)375 static inline void cvmx_hwfau_async_fetch_and_add16(u64 scraddr, cvmx_fau_reg16_t reg, s16 value)
376 {
377 	cvmx_send_single(__cvmx_fau_iobdma_data(scraddr, value, 0, CVMX_FAU_OP_SIZE_16, reg));
378 }
379 
380 /**
381  * Perform an async atomic 8 bit add. The old value is
382  * placed in the scratch memory at byte address scraddr.
383  *
384  * @param scraddr Scratch memory byte address to put response in.
385  *                Must be 8 byte aligned.
386  * @param reg     FAU atomic register to access. 0 <= reg < 2048.
387  * @param value   Signed value to add.
388  * @return Placed in the scratch pad register
389  */
cvmx_hwfau_async_fetch_and_add8(u64 scraddr,cvmx_fau_reg8_t reg,int8_t value)390 static inline void cvmx_hwfau_async_fetch_and_add8(u64 scraddr, cvmx_fau_reg8_t reg, int8_t value)
391 {
392 	cvmx_send_single(__cvmx_fau_iobdma_data(scraddr, value, 0, CVMX_FAU_OP_SIZE_8, reg));
393 }
394 
395 /**
396  * Perform an async atomic 64 bit add after the current tag
397  * switch completes.
398  *
399  * @param scraddr Scratch memory byte address to put response in.
400  *                Must be 8 byte aligned.
401  *                If a timeout occurs, the error bit (63) will be set. Otherwise
402  *                the value of the register before the update will be
403  *                returned
404  * @param reg     FAU atomic register to access. 0 <= reg < 2048.
405  *                - Step by 8 for 64 bit access.
406  * @param value   Signed value to add.
407  *                Note: Only the low 22 bits are available.
408  * @return Placed in the scratch pad register
409  */
cvmx_hwfau_async_tagwait_fetch_and_add64(u64 scraddr,cvmx_fau_reg64_t reg,s64 value)410 static inline void cvmx_hwfau_async_tagwait_fetch_and_add64(u64 scraddr, cvmx_fau_reg64_t reg,
411 							    s64 value)
412 {
413 	cvmx_send_single(__cvmx_fau_iobdma_data(scraddr, value, 1, CVMX_FAU_OP_SIZE_64, reg));
414 }
415 
416 /**
417  * Perform an async atomic 32 bit add after the current tag
418  * switch completes.
419  *
420  * @param scraddr Scratch memory byte address to put response in.
421  *                Must be 8 byte aligned.
422  *                If a timeout occurs, the error bit (63) will be set. Otherwise
423  *                the value of the register before the update will be
424  *                returned
425  * @param reg     FAU atomic register to access. 0 <= reg < 2048.
426  *                - Step by 4 for 32 bit access.
427  * @param value   Signed value to add.
428  *                Note: Only the low 22 bits are available.
429  * @return Placed in the scratch pad register
430  */
cvmx_hwfau_async_tagwait_fetch_and_add32(u64 scraddr,cvmx_fau_reg32_t reg,s32 value)431 static inline void cvmx_hwfau_async_tagwait_fetch_and_add32(u64 scraddr, cvmx_fau_reg32_t reg,
432 							    s32 value)
433 {
434 	cvmx_send_single(__cvmx_fau_iobdma_data(scraddr, value, 1, CVMX_FAU_OP_SIZE_32, reg));
435 }
436 
437 /**
438  * Perform an async atomic 16 bit add after the current tag
439  * switch completes.
440  *
441  * @param scraddr Scratch memory byte address to put response in.
442  *                Must be 8 byte aligned.
443  *                If a timeout occurs, the error bit (63) will be set. Otherwise
444  *                the value of the register before the update will be
445  *                returned
446  * @param reg     FAU atomic register to access. 0 <= reg < 2048.
447  *                - Step by 2 for 16 bit access.
448  * @param value   Signed value to add.
449  * @return Placed in the scratch pad register
450  */
cvmx_hwfau_async_tagwait_fetch_and_add16(u64 scraddr,cvmx_fau_reg16_t reg,s16 value)451 static inline void cvmx_hwfau_async_tagwait_fetch_and_add16(u64 scraddr, cvmx_fau_reg16_t reg,
452 							    s16 value)
453 {
454 	cvmx_send_single(__cvmx_fau_iobdma_data(scraddr, value, 1, CVMX_FAU_OP_SIZE_16, reg));
455 }
456 
457 /**
458  * Perform an async atomic 8 bit add after the current tag
459  * switch completes.
460  *
461  * @param scraddr Scratch memory byte address to put response in.
462  *                Must be 8 byte aligned.
463  *                If a timeout occurs, the error bit (63) will be set. Otherwise
464  *                the value of the register before the update will be
465  *                returned
466  * @param reg     FAU atomic register to access. 0 <= reg < 2048.
467  * @param value   Signed value to add.
468  * @return Placed in the scratch pad register
469  */
cvmx_hwfau_async_tagwait_fetch_and_add8(u64 scraddr,cvmx_fau_reg8_t reg,int8_t value)470 static inline void cvmx_hwfau_async_tagwait_fetch_and_add8(u64 scraddr, cvmx_fau_reg8_t reg,
471 							   int8_t value)
472 {
473 	cvmx_send_single(__cvmx_fau_iobdma_data(scraddr, value, 1, CVMX_FAU_OP_SIZE_8, reg));
474 }
475 
476 /**
477  * Perform an atomic 64 bit add
478  *
479  * @param reg     FAU atomic register to access. 0 <= reg < 2048.
480  *                - Step by 8 for 64 bit access.
481  * @param value   Signed value to add.
482  */
cvmx_hwfau_atomic_add64(cvmx_fau_reg64_t reg,s64 value)483 static inline void cvmx_hwfau_atomic_add64(cvmx_fau_reg64_t reg, s64 value)
484 {
485 	cvmx_write64_int64(__cvmx_hwfau_store_address(0, reg), value);
486 }
487 
488 /**
489  * Perform an atomic 32 bit add
490  *
491  * @param reg     FAU atomic register to access. 0 <= reg < 2048.
492  *                - Step by 4 for 32 bit access.
493  * @param value   Signed value to add.
494  */
cvmx_hwfau_atomic_add32(cvmx_fau_reg32_t reg,s32 value)495 static inline void cvmx_hwfau_atomic_add32(cvmx_fau_reg32_t reg, s32 value)
496 {
497 	reg ^= SWIZZLE_32;
498 	cvmx_write64_int32(__cvmx_hwfau_store_address(0, reg), value);
499 }
500 
501 /**
502  * Perform an atomic 16 bit add
503  *
504  * @param reg     FAU atomic register to access. 0 <= reg < 2048.
505  *                - Step by 2 for 16 bit access.
506  * @param value   Signed value to add.
507  */
cvmx_hwfau_atomic_add16(cvmx_fau_reg16_t reg,s16 value)508 static inline void cvmx_hwfau_atomic_add16(cvmx_fau_reg16_t reg, s16 value)
509 {
510 	reg ^= SWIZZLE_16;
511 	cvmx_write64_int16(__cvmx_hwfau_store_address(0, reg), value);
512 }
513 
514 /**
515  * Perform an atomic 8 bit add
516  *
517  * @param reg     FAU atomic register to access. 0 <= reg < 2048.
518  * @param value   Signed value to add.
519  */
cvmx_hwfau_atomic_add8(cvmx_fau_reg8_t reg,int8_t value)520 static inline void cvmx_hwfau_atomic_add8(cvmx_fau_reg8_t reg, int8_t value)
521 {
522 	reg ^= SWIZZLE_8;
523 	cvmx_write64_int8(__cvmx_hwfau_store_address(0, reg), value);
524 }
525 
526 /**
527  * Perform an atomic 64 bit write
528  *
529  * @param reg     FAU atomic register to access. 0 <= reg < 2048.
530  *                - Step by 8 for 64 bit access.
531  * @param value   Signed value to write.
532  */
cvmx_hwfau_atomic_write64(cvmx_fau_reg64_t reg,s64 value)533 static inline void cvmx_hwfau_atomic_write64(cvmx_fau_reg64_t reg, s64 value)
534 {
535 	cvmx_write64_int64(__cvmx_hwfau_store_address(1, reg), value);
536 }
537 
538 /**
539  * Perform an atomic 32 bit write
540  *
541  * @param reg     FAU atomic register to access. 0 <= reg < 2048.
542  *                - Step by 4 for 32 bit access.
543  * @param value   Signed value to write.
544  */
cvmx_hwfau_atomic_write32(cvmx_fau_reg32_t reg,s32 value)545 static inline void cvmx_hwfau_atomic_write32(cvmx_fau_reg32_t reg, s32 value)
546 {
547 	reg ^= SWIZZLE_32;
548 	cvmx_write64_int32(__cvmx_hwfau_store_address(1, reg), value);
549 }
550 
551 /**
552  * Perform an atomic 16 bit write
553  *
554  * @param reg     FAU atomic register to access. 0 <= reg < 2048.
555  *                - Step by 2 for 16 bit access.
556  * @param value   Signed value to write.
557  */
cvmx_hwfau_atomic_write16(cvmx_fau_reg16_t reg,s16 value)558 static inline void cvmx_hwfau_atomic_write16(cvmx_fau_reg16_t reg, s16 value)
559 {
560 	reg ^= SWIZZLE_16;
561 	cvmx_write64_int16(__cvmx_hwfau_store_address(1, reg), value);
562 }
563 
564 /**
565  * Perform an atomic 8 bit write
566  *
567  * @param reg     FAU atomic register to access. 0 <= reg < 2048.
568  * @param value   Signed value to write.
569  */
cvmx_hwfau_atomic_write8(cvmx_fau_reg8_t reg,int8_t value)570 static inline void cvmx_hwfau_atomic_write8(cvmx_fau_reg8_t reg, int8_t value)
571 {
572 	reg ^= SWIZZLE_8;
573 	cvmx_write64_int8(__cvmx_hwfau_store_address(1, reg), value);
574 }
575 
576 /** Allocates 64bit FAU register.
577  *  @return value is the base address of allocated FAU register
578  */
579 int cvmx_fau64_alloc(int reserve);
580 
581 /** Allocates 32bit FAU register.
582  *  @return value is the base address of allocated FAU register
583  */
584 int cvmx_fau32_alloc(int reserve);
585 
586 /** Allocates 16bit FAU register.
587  *  @return value is the base address of allocated FAU register
588  */
589 int cvmx_fau16_alloc(int reserve);
590 
591 /** Allocates 8bit FAU register.
592  *  @return value is the base address of allocated FAU register
593  */
594 int cvmx_fau8_alloc(int reserve);
595 
596 /** Frees the specified FAU register.
597  *  @param address Base address of register to release.
598  *  @return 0 on success; -1 on failure
599  */
600 int cvmx_fau_free(int address);
601 
602 /** Display the fau registers array
603  */
604 void cvmx_fau_show(void);
605 
606 #endif /* __CVMX_HWFAU_H__ */
607