1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2018-2022 Marvell International Ltd.
4  */
5 
6 #include <errno.h>
7 #include <log.h>
8 #include <time.h>
9 #include <linux/delay.h>
10 
11 #include <mach/cvmx-regs.h>
12 #include <mach/cvmx-csr.h>
13 #include <mach/cvmx-bootmem.h>
14 #include <mach/octeon-model.h>
15 #include <mach/cvmx-fuse.h>
16 #include <mach/octeon-feature.h>
17 #include <mach/cvmx-qlm.h>
18 #include <mach/octeon_qlm.h>
19 #include <mach/cvmx-pcie.h>
20 #include <mach/cvmx-coremask.h>
21 #include <mach/cvmx-range.h>
22 #include <mach/cvmx-global-resources.h>
23 
24 #include <mach/cvmx-agl-defs.h>
25 #include <mach/cvmx-bgxx-defs.h>
26 #include <mach/cvmx-ciu-defs.h>
27 #include <mach/cvmx-gmxx-defs.h>
28 #include <mach/cvmx-gserx-defs.h>
29 #include <mach/cvmx-ilk-defs.h>
30 #include <mach/cvmx-ipd-defs.h>
31 #include <mach/cvmx-pcsx-defs.h>
32 #include <mach/cvmx-pcsxx-defs.h>
33 #include <mach/cvmx-pki-defs.h>
34 #include <mach/cvmx-pko-defs.h>
35 #include <mach/cvmx-xcv-defs.h>
36 
37 #include <mach/cvmx-hwpko.h>
38 #include <mach/cvmx-ilk.h>
39 #include <mach/cvmx-ipd.h>
40 #include <mach/cvmx-pki.h>
41 #include <mach/cvmx-pko3.h>
42 #include <mach/cvmx-pko3-queue.h>
43 #include <mach/cvmx-pko3-resources.h>
44 
45 #include <mach/cvmx-helper.h>
46 #include <mach/cvmx-helper-board.h>
47 #include <mach/cvmx-helper-cfg.h>
48 
49 #include <mach/cvmx-helper-bgx.h>
50 #include <mach/cvmx-helper-cfg.h>
51 #include <mach/cvmx-helper-util.h>
52 #include <mach/cvmx-helper-pki.h>
53 
get_fpa1_resource_tag(void)54 static struct global_resource_tag get_fpa1_resource_tag(void)
55 {
56 	return CVMX_GR_TAG_FPA;
57 }
58 
get_fpa3_aura_resource_tag(int node)59 static struct global_resource_tag get_fpa3_aura_resource_tag(int node)
60 {
61 	return cvmx_get_gr_tag('c', 'v', 'm', '_', 'a', 'u', 'r', 'a', '_',
62 			       node + '0', '.', '.', '.', '.', '.', '.');
63 }
64 
get_fpa3_pool_resource_tag(int node)65 static struct global_resource_tag get_fpa3_pool_resource_tag(int node)
66 {
67 	return cvmx_get_gr_tag('c', 'v', 'm', '_', 'p', 'o', 'o', 'l', '_',
68 			       node + '0', '.', '.', '.', '.', '.', '.');
69 }
70 
cvmx_fpa_get_max_pools(void)71 int cvmx_fpa_get_max_pools(void)
72 {
73 	if (octeon_has_feature(OCTEON_FEATURE_FPA3))
74 		return cvmx_fpa3_num_auras();
75 	else if (OCTEON_IS_MODEL(OCTEON_CN68XX))
76 		/* 68xx pool 8 is not available via API */
77 		return CVMX_FPA1_NUM_POOLS;
78 	else
79 		return CVMX_FPA1_NUM_POOLS;
80 }
81 
cvmx_fpa3_reserve_aura(int node,int desired_aura_num)82 cvmx_fpa3_gaura_t cvmx_fpa3_reserve_aura(int node, int desired_aura_num)
83 {
84 	u64 owner = cvmx_get_app_id();
85 	int rv = 0;
86 	struct global_resource_tag tag;
87 	cvmx_fpa3_gaura_t aura;
88 
89 	if (node == -1)
90 		node = cvmx_get_node_num();
91 
92 	tag = get_fpa3_aura_resource_tag(node);
93 
94 	if (cvmx_create_global_resource_range(tag, cvmx_fpa3_num_auras()) !=
95 	    0) {
96 		printf("ERROR: %s: global resource create node=%u\n", __func__,
97 		       node);
98 		return CVMX_FPA3_INVALID_GAURA;
99 	}
100 
101 	if (desired_aura_num >= 0)
102 		rv = cvmx_reserve_global_resource_range(tag, owner,
103 							desired_aura_num, 1);
104 	else
105 		rv = cvmx_resource_alloc_reverse(tag, owner);
106 
107 	if (rv < 0) {
108 		printf("ERROR: %s: node=%u desired aura=%d\n", __func__, node,
109 		       desired_aura_num);
110 		return CVMX_FPA3_INVALID_GAURA;
111 	}
112 
113 	aura = __cvmx_fpa3_gaura(node, rv);
114 
115 	return aura;
116 }
117 
cvmx_fpa3_release_aura(cvmx_fpa3_gaura_t aura)118 int cvmx_fpa3_release_aura(cvmx_fpa3_gaura_t aura)
119 {
120 	struct global_resource_tag tag = get_fpa3_aura_resource_tag(aura.node);
121 	int laura = aura.laura;
122 
123 	if (!__cvmx_fpa3_aura_valid(aura))
124 		return -1;
125 
126 	return cvmx_free_global_resource_range_multiple(tag, &laura, 1);
127 }
128 
129 /**
130  */
cvmx_fpa3_reserve_pool(int node,int desired_pool_num)131 cvmx_fpa3_pool_t cvmx_fpa3_reserve_pool(int node, int desired_pool_num)
132 {
133 	u64 owner = cvmx_get_app_id();
134 	int rv = 0;
135 	struct global_resource_tag tag;
136 	cvmx_fpa3_pool_t pool;
137 
138 	if (node == -1)
139 		node = cvmx_get_node_num();
140 
141 	tag = get_fpa3_pool_resource_tag(node);
142 
143 	if (cvmx_create_global_resource_range(tag, cvmx_fpa3_num_pools()) !=
144 	    0) {
145 		printf("ERROR: %s: global resource create node=%u\n", __func__,
146 		       node);
147 		return CVMX_FPA3_INVALID_POOL;
148 	}
149 
150 	if (desired_pool_num >= 0)
151 		rv = cvmx_reserve_global_resource_range(tag, owner,
152 							desired_pool_num, 1);
153 	else
154 		rv = cvmx_resource_alloc_reverse(tag, owner);
155 
156 	if (rv < 0) {
157 		/* Desired pool is already in use */
158 		return CVMX_FPA3_INVALID_POOL;
159 	}
160 
161 	pool = __cvmx_fpa3_pool(node, rv);
162 
163 	return pool;
164 }
165 
cvmx_fpa3_release_pool(cvmx_fpa3_pool_t pool)166 int cvmx_fpa3_release_pool(cvmx_fpa3_pool_t pool)
167 {
168 	struct global_resource_tag tag = get_fpa3_pool_resource_tag(pool.node);
169 	int lpool = pool.lpool;
170 
171 	if (!__cvmx_fpa3_pool_valid(pool))
172 		return -1;
173 
174 	if (cvmx_create_global_resource_range(tag, cvmx_fpa3_num_pools()) !=
175 	    0) {
176 		printf("ERROR: %s: global resource create node=%u\n", __func__,
177 		       pool.node);
178 		return -1;
179 	}
180 
181 	return cvmx_free_global_resource_range_multiple(tag, &lpool, 1);
182 }
183 
cvmx_fpa1_reserve_pool(int desired_pool_num)184 cvmx_fpa1_pool_t cvmx_fpa1_reserve_pool(int desired_pool_num)
185 {
186 	u64 owner = cvmx_get_app_id();
187 	struct global_resource_tag tag;
188 	int rv;
189 
190 	tag = get_fpa1_resource_tag();
191 
192 	if (cvmx_create_global_resource_range(tag, CVMX_FPA1_NUM_POOLS) != 0) {
193 		printf("ERROR: %s: global resource not created\n", __func__);
194 		return -1;
195 	}
196 
197 	if (desired_pool_num >= 0) {
198 		rv = cvmx_reserve_global_resource_range(tag, owner,
199 							desired_pool_num, 1);
200 	} else {
201 		rv = cvmx_resource_alloc_reverse(tag, owner);
202 	}
203 
204 	if (rv < 0) {
205 		printf("ERROR: %s: FPA_POOL %d unavailable\n", __func__,
206 		       desired_pool_num);
207 		return CVMX_RESOURCE_ALREADY_RESERVED;
208 	}
209 	return (cvmx_fpa1_pool_t)rv;
210 }
211 
cvmx_fpa1_release_pool(cvmx_fpa1_pool_t pool)212 int cvmx_fpa1_release_pool(cvmx_fpa1_pool_t pool)
213 {
214 	struct global_resource_tag tag;
215 
216 	tag = get_fpa1_resource_tag();
217 
218 	return cvmx_free_global_resource_range_multiple(tag, &pool, 1);
219 }
220