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