1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2020 Marvell International Ltd.
4  *
5  * Interface to the hardware Free Pool Allocator.
6  */
7 
8 #ifndef __CVMX_FPA_H__
9 #define __CVMX_FPA_H__
10 
11 #include "cvmx-scratch.h"
12 #include "cvmx-fpa-defs.h"
13 #include "cvmx-fpa1.h"
14 #include "cvmx-fpa3.h"
15 
16 #define CVMX_FPA_MIN_BLOCK_SIZE 128
17 #define CVMX_FPA_ALIGNMENT	128
18 #define CVMX_FPA_POOL_NAME_LEN	16
19 
20 /* On CN78XX in backward-compatible mode, pool is mapped to AURA */
21 #define CVMX_FPA_NUM_POOLS                                                                         \
22 	(octeon_has_feature(OCTEON_FEATURE_FPA3) ? cvmx_fpa3_num_auras() : CVMX_FPA1_NUM_POOLS)
23 
24 /**
25  * Structure to store FPA pool configuration parameters.
26  */
27 struct cvmx_fpa_pool_config {
28 	s64 pool_num;
29 	u64 buffer_size;
30 	u64 buffer_count;
31 };
32 
33 typedef struct cvmx_fpa_pool_config cvmx_fpa_pool_config_t;
34 
35 /**
36  * Return the name of the pool
37  *
38  * @param pool_num   Pool to get the name of
39  * @return The name
40  */
41 const char *cvmx_fpa_get_name(int pool_num);
42 
43 /**
44  * Initialize FPA per node
45  */
46 int cvmx_fpa_global_init_node(int node);
47 
48 /**
49  * Enable the FPA
50  */
cvmx_fpa_enable(void)51 static inline void cvmx_fpa_enable(void)
52 {
53 	if (!octeon_has_feature(OCTEON_FEATURE_FPA3))
54 		cvmx_fpa1_enable();
55 	else
56 		cvmx_fpa_global_init_node(cvmx_get_node_num());
57 }
58 
59 /**
60  * Disable the FPA
61  */
cvmx_fpa_disable(void)62 static inline void cvmx_fpa_disable(void)
63 {
64 	if (!octeon_has_feature(OCTEON_FEATURE_FPA3))
65 		cvmx_fpa1_disable();
66 	/* FPA3 does not have a disable function */
67 }
68 
69 /**
70  * @INTERNAL
71  * @deprecated OBSOLETE
72  *
73  * Kept for transition assistance only
74  */
cvmx_fpa_global_initialize(void)75 static inline void cvmx_fpa_global_initialize(void)
76 {
77 	cvmx_fpa_global_init_node(cvmx_get_node_num());
78 }
79 
80 /**
81  * @INTERNAL
82  *
83  * Convert FPA1 style POOL into FPA3 AURA in
84  * backward compatibility mode.
85  */
cvmx_fpa1_pool_to_fpa3_aura(cvmx_fpa1_pool_t pool)86 static inline cvmx_fpa3_gaura_t cvmx_fpa1_pool_to_fpa3_aura(cvmx_fpa1_pool_t pool)
87 {
88 	if ((octeon_has_feature(OCTEON_FEATURE_FPA3))) {
89 		unsigned int node = cvmx_get_node_num();
90 		cvmx_fpa3_gaura_t aura = __cvmx_fpa3_gaura(node, pool);
91 		return aura;
92 	}
93 	return CVMX_FPA3_INVALID_GAURA;
94 }
95 
96 /**
97  * Get a new block from the FPA
98  *
99  * @param pool   Pool to get the block from
100  * @return Pointer to the block or NULL on failure
101  */
cvmx_fpa_alloc(u64 pool)102 static inline void *cvmx_fpa_alloc(u64 pool)
103 {
104 	/* FPA3 is handled differently */
105 	if ((octeon_has_feature(OCTEON_FEATURE_FPA3))) {
106 		return cvmx_fpa3_alloc(cvmx_fpa1_pool_to_fpa3_aura(pool));
107 	} else
108 		return cvmx_fpa1_alloc(pool);
109 }
110 
111 /**
112  * Asynchronously get a new block from the FPA
113  *
114  * The result of cvmx_fpa_async_alloc() may be retrieved using
115  * cvmx_fpa_async_alloc_finish().
116  *
117  * @param scr_addr Local scratch address to put response in.  This is a byte
118  *		   address but must be 8 byte aligned.
119  * @param pool      Pool to get the block from
120  */
cvmx_fpa_async_alloc(u64 scr_addr,u64 pool)121 static inline void cvmx_fpa_async_alloc(u64 scr_addr, u64 pool)
122 {
123 	if ((octeon_has_feature(OCTEON_FEATURE_FPA3))) {
124 		return cvmx_fpa3_async_alloc(scr_addr, cvmx_fpa1_pool_to_fpa3_aura(pool));
125 	} else
126 		return cvmx_fpa1_async_alloc(scr_addr, pool);
127 }
128 
129 /**
130  * Retrieve the result of cvmx_fpa_async_alloc
131  *
132  * @param scr_addr The Local scratch address.  Must be the same value
133  * passed to cvmx_fpa_async_alloc().
134  *
135  * @param pool Pool the block came from.  Must be the same value
136  * passed to cvmx_fpa_async_alloc.
137  *
138  * @return Pointer to the block or NULL on failure
139  */
cvmx_fpa_async_alloc_finish(u64 scr_addr,u64 pool)140 static inline void *cvmx_fpa_async_alloc_finish(u64 scr_addr, u64 pool)
141 {
142 	if ((octeon_has_feature(OCTEON_FEATURE_FPA3)))
143 		return cvmx_fpa3_async_alloc_finish(scr_addr, cvmx_fpa1_pool_to_fpa3_aura(pool));
144 	else
145 		return cvmx_fpa1_async_alloc_finish(scr_addr, pool);
146 }
147 
148 /**
149  * Free a block allocated with a FPA pool.
150  * Does NOT provide memory ordering in cases where the memory block was
151  * modified by the core.
152  *
153  * @param ptr    Block to free
154  * @param pool   Pool to put it in
155  * @param num_cache_lines
156  *               Cache lines to invalidate
157  */
cvmx_fpa_free_nosync(void * ptr,u64 pool,u64 num_cache_lines)158 static inline void cvmx_fpa_free_nosync(void *ptr, u64 pool, u64 num_cache_lines)
159 {
160 	/* FPA3 is handled differently */
161 	if ((octeon_has_feature(OCTEON_FEATURE_FPA3)))
162 		cvmx_fpa3_free_nosync(ptr, cvmx_fpa1_pool_to_fpa3_aura(pool), num_cache_lines);
163 	else
164 		cvmx_fpa1_free_nosync(ptr, pool, num_cache_lines);
165 }
166 
167 /**
168  * Free a block allocated with a FPA pool.  Provides required memory
169  * ordering in cases where memory block was modified by core.
170  *
171  * @param ptr    Block to free
172  * @param pool   Pool to put it in
173  * @param num_cache_lines
174  *               Cache lines to invalidate
175  */
cvmx_fpa_free(void * ptr,u64 pool,u64 num_cache_lines)176 static inline void cvmx_fpa_free(void *ptr, u64 pool, u64 num_cache_lines)
177 {
178 	if ((octeon_has_feature(OCTEON_FEATURE_FPA3)))
179 		cvmx_fpa3_free(ptr, cvmx_fpa1_pool_to_fpa3_aura(pool), num_cache_lines);
180 	else
181 		cvmx_fpa1_free(ptr, pool, num_cache_lines);
182 }
183 
184 /**
185  * Setup a FPA pool to control a new block of memory.
186  * This can only be called once per pool. Make sure proper
187  * locking enforces this.
188  *
189  * @param pool       Pool to initialize
190  * @param name       Constant character string to name this pool.
191  *                   String is not copied.
192  * @param buffer     Pointer to the block of memory to use. This must be
193  *                   accessible by all processors and external hardware.
194  * @param block_size Size for each block controlled by the FPA
195  * @param num_blocks Number of blocks
196  *
197  * @return the pool number on Success,
198  *         -1 on failure
199  */
200 int cvmx_fpa_setup_pool(int pool, const char *name, void *buffer, u64 block_size, u64 num_blocks);
201 
202 int cvmx_fpa_shutdown_pool(int pool);
203 
204 /**
205  * Gets the block size of buffer in specified pool
206  * @param pool	 Pool to get the block size from
207  * @return       Size of buffer in specified pool
208  */
209 unsigned int cvmx_fpa_get_block_size(int pool);
210 
211 int cvmx_fpa_is_pool_available(int pool_num);
212 u64 cvmx_fpa_get_pool_owner(int pool_num);
213 int cvmx_fpa_get_max_pools(void);
214 int cvmx_fpa_get_current_count(int pool_num);
215 int cvmx_fpa_validate_pool(int pool);
216 
217 #endif /*  __CVM_FPA_H__ */
218