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