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