1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3 * Copyright (C) 2020 Marvell International Ltd.
4 */
5
6 #ifndef __OCTEON_FEATURE_H__
7 #define __OCTEON_FEATURE_H__
8
9 #include "cvmx-fuse.h"
10
11 /*
12 * Octeon models are declared after the macros in octeon-model.h with the
13 * suffix _FEATURE. The individual features are declared with the
14 * _FEATURE_ infix.
15 */
16 enum octeon_feature {
17 /*
18 * Checks on the critical path are moved to the top (8 positions)
19 * so that the compiler generates one less insn than for the rest
20 * of the checks.
21 */
22 OCTEON_FEATURE_PKND, /* CN68XX uses port kinds for packet interface */
23 /* CN68XX has different fields in word0 - word2 */
24 OCTEON_FEATURE_CN68XX_WQE,
25
26 /*
27 * Features
28 */
29 /*
30 * Octeon models in the CN5XXX family and higher support atomic
31 * add instructions to memory (saa/saad)
32 */
33 OCTEON_FEATURE_SAAD,
34 /* Does this Octeon support the ZIP offload engine? */
35 OCTEON_FEATURE_ZIP,
36 /* Does this Octeon support crypto acceleration using COP2? */
37 OCTEON_FEATURE_CRYPTO,
38 /* Can crypto be enabled by calling cvmx_crypto_dormant_enable()? */
39 OCTEON_FEATURE_DORM_CRYPTO,
40 OCTEON_FEATURE_PCIE, /* Does this Octeon support PCI express? */
41 OCTEON_FEATURE_SRIO, /* Does this Octeon support SRIO */
42 OCTEON_FEATURE_ILK, /* Does this Octeon support Interlaken */
43 /*
44 * Some Octeon models support internal memory for storing
45 * cryptographic keys
46 */
47 OCTEON_FEATURE_KEY_MEMORY,
48 /* Octeon has a LED controller for banks of external LEDs */
49 OCTEON_FEATURE_LED_CONTROLLER,
50 OCTEON_FEATURE_TRA, /* Octeon has a trace buffer */
51 OCTEON_FEATURE_MGMT_PORT, /* Octeon has a management port */
52 OCTEON_FEATURE_RAID, /* Octeon has a raid unit */
53 OCTEON_FEATURE_USB, /* Octeon has a builtin USB */
54 /* Octeon IPD can run without using work queue entries */
55 OCTEON_FEATURE_NO_WPTR,
56 OCTEON_FEATURE_DFA, /* Octeon has DFA state machines */
57 /*
58 * Octeon MDIO block supports clause 45 transactions for
59 * 10 Gig support
60 */
61 OCTEON_FEATURE_MDIO_CLAUSE_45,
62 /*
63 * CN52XX and CN56XX used a block named NPEI for PCIe access.
64 * Newer chips replaced this with SLI+DPI
65 */
66 OCTEON_FEATURE_NPEI,
67 OCTEON_FEATURE_HFA, /* Octeon has DFA/HFA */
68 OCTEON_FEATURE_DFM, /* Octeon has DFM */
69 OCTEON_FEATURE_CIU2, /* Octeon has CIU2 */
70 /* Octeon has DMA Instruction Completion Interrupt mode */
71 OCTEON_FEATURE_DICI_MODE,
72 /* Octeon has Bit Select Extractor schedulor */
73 OCTEON_FEATURE_BIT_EXTRACTOR,
74 OCTEON_FEATURE_NAND, /* Octeon has NAND */
75 OCTEON_FEATURE_MMC, /* Octeon has built-in MMC support */
76 OCTEON_FEATURE_ROM, /* Octeon has built-in ROM support */
77 OCTEON_FEATURE_AUTHENTIK, /* Octeon has Authentik ROM support */
78 OCTEON_FEATURE_MULTICAST_TIMER, /* Octeon has multi_cast timer */
79 OCTEON_FEATURE_MULTINODE, /* Octeon has node support */
80 OCTEON_FEATURE_CIU3, /* Octeon has CIU3 */
81 OCTEON_FEATURE_FPA3, /* Octeon has FPA first seen on 78XX */
82 /* CN78XX has different fields in word0 - word2 */
83 OCTEON_FEATURE_CN78XX_WQE,
84 OCTEON_FEATURE_PKO3, /* Octeon has enhanced PKO block */
85 OCTEON_FEATURE_SPI, /* Octeon supports SPI interfaces */
86 OCTEON_FEATURE_ZIP3, /* Octeon has zip first seen on 78XX */
87 OCTEON_FEATURE_BCH, /* Octeon supports BCH ECC */
88 OCTEON_FEATURE_PKI, /* Octeon has PKI block */
89 OCTEON_FEATURE_OCLA, /* Octeon has OCLA */
90 OCTEON_FEATURE_FAU, /* Octeon has FAU */
91 OCTEON_FEATURE_BGX, /* Octeon has BGX */
92 OCTEON_FEATURE_BGX_MIX, /* On of the BGX is used for MIX */
93 OCTEON_FEATURE_HNA, /* Octeon has HNA */
94 OCTEON_FEATURE_BGX_XCV, /* Octeon has BGX XCV RGMII support */
95 OCTEON_FEATURE_TSO, /* Octeon has tcp segmentation offload */
96 OCTEON_FEATURE_TDM, /* Octeon has PCM/TDM support */
97 OCTEON_FEATURE_PTP, /* Octeon has PTP support */
98 OCTEON_MAX_FEATURE
99 };
100
octeon_has_feature_OCTEON_FEATURE_SAAD(void)101 static inline int octeon_has_feature_OCTEON_FEATURE_SAAD(void)
102 {
103 return true;
104 }
105
octeon_has_feature_OCTEON_FEATURE_ZIP(void)106 static inline int octeon_has_feature_OCTEON_FEATURE_ZIP(void)
107 {
108 if (OCTEON_IS_MODEL(OCTEON_CNF71XX) ||
109 OCTEON_IS_MODEL(OCTEON_CN70XX) || OCTEON_IS_MODEL(OCTEON_CNF75XX))
110 return 0;
111 else
112 return !cvmx_fuse_read(121);
113 }
114
octeon_has_feature_OCTEON_FEATURE_ZIP3(void)115 static inline int octeon_has_feature_OCTEON_FEATURE_ZIP3(void)
116 {
117 return (OCTEON_IS_MODEL(OCTEON_CN78XX) ||
118 OCTEON_IS_MODEL(OCTEON_CN73XX));
119 }
120
octeon_has_feature_OCTEON_FEATURE_BCH(void)121 static inline int octeon_has_feature_OCTEON_FEATURE_BCH(void)
122 {
123 return (OCTEON_IS_MODEL(OCTEON_CN70XX) ||
124 OCTEON_IS_MODEL(OCTEON_CNF75XX) ||
125 OCTEON_IS_MODEL(OCTEON_CN73XX));
126 }
127
octeon_has_feature_OCTEON_FEATURE_CRYPTO(void)128 static inline int octeon_has_feature_OCTEON_FEATURE_CRYPTO(void)
129 {
130 /* OCTEON II and later */
131 u64 val;
132
133 val = csr_rd(CVMX_MIO_FUS_DAT2);
134 if (val & MIO_FUS_DAT2_NOCRYPTO || val & MIO_FUS_DAT2_NOMUL)
135 return 0;
136 else if (!(val & MIO_FUS_DAT2_DORM_CRYPTO))
137 return 1;
138
139 val = csr_rd(CVMX_RNM_CTL_STATUS);
140 return val & RNM_CTL_STATUS_EER_VAL;
141 }
142
octeon_has_feature_OCTEON_FEATURE_DORM_CRYPTO(void)143 static inline int octeon_has_feature_OCTEON_FEATURE_DORM_CRYPTO(void)
144 {
145 /* OCTEON II and later */
146 u64 val;
147
148 val = csr_rd(CVMX_MIO_FUS_DAT2);
149 return !(val & MIO_FUS_DAT2_NOCRYPTO) && !(val & MIO_FUS_DAT2_NOMUL) &&
150 (val & MIO_FUS_DAT2_DORM_CRYPTO);
151 }
152
octeon_has_feature_OCTEON_FEATURE_PCIE(void)153 static inline int octeon_has_feature_OCTEON_FEATURE_PCIE(void)
154 {
155 /* OCTEON II and later have PCIe */
156 return true;
157 }
158
octeon_has_feature_OCTEON_FEATURE_SRIO(void)159 static inline int octeon_has_feature_OCTEON_FEATURE_SRIO(void)
160 {
161 if (OCTEON_IS_MODEL(OCTEON_CNF75XX)) {
162 if (cvmx_fuse_read(1601) == 0)
163 return 0;
164 else
165 return 1;
166 } else {
167 return (OCTEON_IS_MODEL(OCTEON_CN63XX) ||
168 OCTEON_IS_MODEL(OCTEON_CN66XX));
169 }
170 }
171
octeon_has_feature_OCTEON_FEATURE_ILK(void)172 static inline int octeon_has_feature_OCTEON_FEATURE_ILK(void)
173 {
174 return (OCTEON_IS_MODEL(OCTEON_CN68XX) ||
175 OCTEON_IS_MODEL(OCTEON_CN78XX));
176 }
177
octeon_has_feature_OCTEON_FEATURE_KEY_MEMORY(void)178 static inline int octeon_has_feature_OCTEON_FEATURE_KEY_MEMORY(void)
179 {
180 /* OCTEON II or later */
181 return true;
182 }
183
octeon_has_feature_OCTEON_FEATURE_LED_CONTROLLER(void)184 static inline int octeon_has_feature_OCTEON_FEATURE_LED_CONTROLLER(void)
185 {
186 return false;
187 }
188
octeon_has_feature_OCTEON_FEATURE_TRA(void)189 static inline int octeon_has_feature_OCTEON_FEATURE_TRA(void)
190 {
191 return !OCTEON_IS_OCTEON3();
192 }
193
octeon_has_feature_OCTEON_FEATURE_MGMT_PORT(void)194 static inline int octeon_has_feature_OCTEON_FEATURE_MGMT_PORT(void)
195 {
196 /* OCTEON II or later */
197 return true;
198 }
199
octeon_has_feature_OCTEON_FEATURE_RAID(void)200 static inline int octeon_has_feature_OCTEON_FEATURE_RAID(void)
201 {
202 return !OCTEON_IS_MODEL(OCTEON_CNF75XX);
203 }
204
octeon_has_feature_OCTEON_FEATURE_USB(void)205 static inline int octeon_has_feature_OCTEON_FEATURE_USB(void)
206 {
207 return true;
208 }
209
octeon_has_feature_OCTEON_FEATURE_NO_WPTR(void)210 static inline int octeon_has_feature_OCTEON_FEATURE_NO_WPTR(void)
211 {
212 return true;
213 }
214
octeon_has_feature_OCTEON_FEATURE_DFA(void)215 static inline int octeon_has_feature_OCTEON_FEATURE_DFA(void)
216 {
217 return 0;
218 }
219
octeon_has_feature_OCTEON_FEATURE_HFA(void)220 static inline int octeon_has_feature_OCTEON_FEATURE_HFA(void)
221 {
222 if (OCTEON_IS_MODEL(OCTEON_CNF75XX))
223 return 0;
224 else
225 return !cvmx_fuse_read(90);
226 }
227
octeon_has_feature_OCTEON_FEATURE_HNA(void)228 static inline int octeon_has_feature_OCTEON_FEATURE_HNA(void)
229 {
230 if (OCTEON_IS_MODEL(OCTEON_CN78XX) || OCTEON_IS_MODEL(OCTEON_CN73XX))
231 return !cvmx_fuse_read(134);
232 else
233 return 0;
234 }
235
octeon_has_feature_OCTEON_FEATURE_DFM(void)236 static inline int octeon_has_feature_OCTEON_FEATURE_DFM(void)
237 {
238 if (!(OCTEON_IS_MODEL(OCTEON_CN63XX) || OCTEON_IS_MODEL(OCTEON_CN66XX)))
239 return 0;
240 else
241 return !cvmx_fuse_read(90);
242 }
243
octeon_has_feature_OCTEON_FEATURE_MDIO_CLAUSE_45(void)244 static inline int octeon_has_feature_OCTEON_FEATURE_MDIO_CLAUSE_45(void)
245 {
246 return true;
247 }
248
octeon_has_feature_OCTEON_FEATURE_NPEI(void)249 static inline int octeon_has_feature_OCTEON_FEATURE_NPEI(void)
250 {
251 return false;
252 }
253
octeon_has_feature_OCTEON_FEATURE_PKND(void)254 static inline int octeon_has_feature_OCTEON_FEATURE_PKND(void)
255 {
256 return OCTEON_IS_MODEL(OCTEON_CN68XX) ||
257 OCTEON_IS_MODEL(OCTEON_CNF75XX) ||
258 OCTEON_IS_MODEL(OCTEON_CN73XX) ||
259 OCTEON_IS_MODEL(OCTEON_CN78XX);
260 }
261
octeon_has_feature_OCTEON_FEATURE_CN68XX_WQE(void)262 static inline int octeon_has_feature_OCTEON_FEATURE_CN68XX_WQE(void)
263 {
264 return OCTEON_IS_MODEL(OCTEON_CN68XX);
265 }
266
octeon_has_feature_OCTEON_FEATURE_CIU2(void)267 static inline int octeon_has_feature_OCTEON_FEATURE_CIU2(void)
268 {
269 return OCTEON_IS_MODEL(OCTEON_CN68XX);
270 }
271
octeon_has_feature_OCTEON_FEATURE_CIU3(void)272 static inline int octeon_has_feature_OCTEON_FEATURE_CIU3(void)
273 {
274 return (OCTEON_IS_MODEL(OCTEON_CN78XX) ||
275 OCTEON_IS_MODEL(OCTEON_CNF75XX) ||
276 OCTEON_IS_MODEL(OCTEON_CN73XX));
277 }
278
octeon_has_feature_OCTEON_FEATURE_FPA3(void)279 static inline int octeon_has_feature_OCTEON_FEATURE_FPA3(void)
280 {
281 return (OCTEON_IS_MODEL(OCTEON_CN78XX) ||
282 OCTEON_IS_MODEL(OCTEON_CNF75XX) ||
283 OCTEON_IS_MODEL(OCTEON_CN73XX));
284 }
285
octeon_has_feature_OCTEON_FEATURE_NAND(void)286 static inline int octeon_has_feature_OCTEON_FEATURE_NAND(void)
287 {
288 return (OCTEON_IS_MODEL(OCTEON_CN63XX) ||
289 OCTEON_IS_MODEL(OCTEON_CN66XX) ||
290 OCTEON_IS_MODEL(OCTEON_CN68XX) ||
291 OCTEON_IS_MODEL(OCTEON_CN73XX) ||
292 OCTEON_IS_MODEL(OCTEON_CNF75XX) ||
293 OCTEON_IS_MODEL(OCTEON_CN70XX));
294 }
295
octeon_has_feature_OCTEON_FEATURE_DICI_MODE(void)296 static inline int octeon_has_feature_OCTEON_FEATURE_DICI_MODE(void)
297 {
298 return (OCTEON_IS_MODEL(OCTEON_CN68XX_PASS2_X) ||
299 OCTEON_IS_MODEL(OCTEON_CN61XX) ||
300 OCTEON_IS_MODEL(OCTEON_CNF71XX) ||
301 OCTEON_IS_MODEL(OCTEON_CN70XX));
302 }
303
octeon_has_feature_OCTEON_FEATURE_BIT_EXTRACTOR(void)304 static inline int octeon_has_feature_OCTEON_FEATURE_BIT_EXTRACTOR(void)
305 {
306 return (OCTEON_IS_MODEL(OCTEON_CN68XX_PASS2_X) ||
307 OCTEON_IS_MODEL(OCTEON_CN61XX) ||
308 OCTEON_IS_MODEL(OCTEON_CNF71XX) ||
309 OCTEON_IS_MODEL(OCTEON_CN70XX));
310 }
311
octeon_has_feature_OCTEON_FEATURE_MMC(void)312 static inline int octeon_has_feature_OCTEON_FEATURE_MMC(void)
313 {
314 return (OCTEON_IS_MODEL(OCTEON_CN61XX) ||
315 OCTEON_IS_MODEL(OCTEON_CNF71XX) || OCTEON_IS_OCTEON3());
316 }
317
octeon_has_feature_OCTEON_FEATURE_ROM(void)318 static inline int octeon_has_feature_OCTEON_FEATURE_ROM(void)
319 {
320 return OCTEON_IS_MODEL(OCTEON_CN66XX) ||
321 OCTEON_IS_MODEL(OCTEON_CN61XX) ||
322 OCTEON_IS_MODEL(OCTEON_CNF71XX);
323 }
324
octeon_has_feature_OCTEON_FEATURE_AUTHENTIK(void)325 static inline int octeon_has_feature_OCTEON_FEATURE_AUTHENTIK(void)
326 {
327 if (OCTEON_IS_MODEL(OCTEON_CN66XX) ||
328 OCTEON_IS_MODEL(OCTEON_CN61XX) ||
329 OCTEON_IS_MODEL(OCTEON_CNF71XX) ||
330 OCTEON_IS_MODEL(OCTEON_CN70XX)) {
331 u64 val;
332
333 val = csr_rd(CVMX_MIO_FUS_DAT2);
334 return (val & MIO_FUS_DAT2_NOCRYPTO) &&
335 (val & MIO_FUS_DAT2_DORM_CRYPTO);
336 }
337
338 return 0;
339 }
340
octeon_has_feature_OCTEON_FEATURE_MULTICAST_TIMER(void)341 static inline int octeon_has_feature_OCTEON_FEATURE_MULTICAST_TIMER(void)
342 {
343 return (OCTEON_IS_MODEL(OCTEON_CN66XX_PASS1_2) ||
344 OCTEON_IS_MODEL(OCTEON_CN61XX) ||
345 OCTEON_IS_MODEL(OCTEON_CNF71XX) ||
346 OCTEON_IS_MODEL(OCTEON_CN70XX));
347 }
348
octeon_has_feature_OCTEON_FEATURE_MULTINODE(void)349 static inline int octeon_has_feature_OCTEON_FEATURE_MULTINODE(void)
350 {
351 return (!OCTEON_IS_MODEL(OCTEON_CN76XX) &&
352 OCTEON_IS_MODEL(OCTEON_CN78XX));
353 }
354
octeon_has_feature_OCTEON_FEATURE_CN78XX_WQE(void)355 static inline int octeon_has_feature_OCTEON_FEATURE_CN78XX_WQE(void)
356 {
357 return (OCTEON_IS_MODEL(OCTEON_CN78XX) ||
358 OCTEON_IS_MODEL(OCTEON_CNF75XX) ||
359 OCTEON_IS_MODEL(OCTEON_CN73XX));
360 }
361
octeon_has_feature_OCTEON_FEATURE_SPI(void)362 static inline int octeon_has_feature_OCTEON_FEATURE_SPI(void)
363 {
364 return (OCTEON_IS_MODEL(OCTEON_CN66XX) ||
365 OCTEON_IS_MODEL(OCTEON_CN61XX) ||
366 OCTEON_IS_MODEL(OCTEON_CNF71XX) || OCTEON_IS_OCTEON3());
367 }
368
octeon_has_feature_OCTEON_FEATURE_PKI(void)369 static inline int octeon_has_feature_OCTEON_FEATURE_PKI(void)
370 {
371 return (OCTEON_IS_MODEL(OCTEON_CN78XX) ||
372 OCTEON_IS_MODEL(OCTEON_CNF75XX) ||
373 OCTEON_IS_MODEL(OCTEON_CN73XX));
374 }
375
octeon_has_feature_OCTEON_FEATURE_PKO3(void)376 static inline int octeon_has_feature_OCTEON_FEATURE_PKO3(void)
377 {
378 return (OCTEON_IS_MODEL(OCTEON_CN78XX) ||
379 OCTEON_IS_MODEL(OCTEON_CNF75XX) ||
380 OCTEON_IS_MODEL(OCTEON_CN73XX));
381 }
382
octeon_has_feature_OCTEON_FEATURE_OCLA(void)383 static inline int octeon_has_feature_OCTEON_FEATURE_OCLA(void)
384 {
385 return OCTEON_IS_OCTEON3();
386 }
387
octeon_has_feature_OCTEON_FEATURE_FAU(void)388 static inline int octeon_has_feature_OCTEON_FEATURE_FAU(void)
389 {
390 return (!OCTEON_IS_MODEL(OCTEON_CN78XX) &&
391 !OCTEON_IS_MODEL(OCTEON_CNF75XX) &&
392 !OCTEON_IS_MODEL(OCTEON_CN73XX));
393 }
394
octeon_has_feature_OCTEON_FEATURE_BGX(void)395 static inline int octeon_has_feature_OCTEON_FEATURE_BGX(void)
396 {
397 return (OCTEON_IS_MODEL(OCTEON_CN78XX) ||
398 OCTEON_IS_MODEL(OCTEON_CNF75XX) ||
399 OCTEON_IS_MODEL(OCTEON_CN73XX));
400 }
401
octeon_has_feature_OCTEON_FEATURE_BGX_MIX(void)402 static inline int octeon_has_feature_OCTEON_FEATURE_BGX_MIX(void)
403 {
404 return (OCTEON_IS_MODEL(OCTEON_CN78XX) ||
405 OCTEON_IS_MODEL(OCTEON_CNF75XX) ||
406 OCTEON_IS_MODEL(OCTEON_CN73XX));
407 }
408
octeon_has_feature_OCTEON_FEATURE_BGX_XCV(void)409 static inline int octeon_has_feature_OCTEON_FEATURE_BGX_XCV(void)
410 {
411 return OCTEON_IS_MODEL(OCTEON_CN73XX);
412 }
413
octeon_has_feature_OCTEON_FEATURE_TSO(void)414 static inline int octeon_has_feature_OCTEON_FEATURE_TSO(void)
415 {
416 return (OCTEON_IS_MODEL(OCTEON_CN73XX) ||
417 OCTEON_IS_MODEL(OCTEON_CNF75XX) ||
418 OCTEON_IS_MODEL(OCTEON_CN78XX_PASS2_X));
419 }
420
octeon_has_feature_OCTEON_FEATURE_TDM(void)421 static inline int octeon_has_feature_OCTEON_FEATURE_TDM(void)
422 {
423 return OCTEON_IS_MODEL(OCTEON_CN61XX) ||
424 OCTEON_IS_MODEL(OCTEON_CNF71XX) ||
425 OCTEON_IS_MODEL(OCTEON_CN70XX);
426 }
427
octeon_has_feature_OCTEON_FEATURE_PTP(void)428 static inline int octeon_has_feature_OCTEON_FEATURE_PTP(void)
429 {
430 return OCTEON_IS_MODEL(OCTEON_CN6XXX) ||
431 OCTEON_IS_MODEL(OCTEON_CNF7XXX) ||
432 OCTEON_IS_MODEL(OCTEON_CN73XX) ||
433 OCTEON_IS_MODEL(OCTEON_CNF75XX) ||
434 OCTEON_IS_MODEL(OCTEON_CN78XX_PASS2_X);
435 }
436
437 /*
438 * Answer ``Is the bit for feature set in the bitmap?''
439 * @param feature
440 * @return 1 when the feature is present and 0 otherwise, -1 in case of error.
441 */
442 #define octeon_has_feature(feature_x) octeon_has_feature_##feature_x()
443
444 #endif /* __OCTEON_FEATURE_H__ */
445