1/***********************license start***************
2 * Author: Cavium Networks
3 *
4 * Contact: support@caviumnetworks.com
5 * This file is part of the OCTEON SDK
6 *
7 * Copyright (c) 2003-2017 Cavium, Inc.
8 *
9 * This file is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License, Version 2, as
11 * published by the Free Software Foundation.
12 *
13 * This file is distributed in the hope that it will be useful, but
14 * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
16 * NONINFRINGEMENT.  See the GNU General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this file; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 * or visit http://www.gnu.org/licenses/.
23 *
24 * This file may also be available under a different license from Cavium.
25 * Contact Cavium Networks for more information
26 ***********************license end**************************************/
27
28#include <asm/octeon/octeon.h>
29
30enum octeon_feature_bits __octeon_feature_bits __read_mostly;
31EXPORT_SYMBOL_GPL(__octeon_feature_bits);
32
33/**
34 * Read a byte of fuse data
35 * @byte_addr:	 address to read
36 *
37 * Returns fuse value: 0 or 1
38 */
39static uint8_t __init cvmx_fuse_read_byte(int byte_addr)
40{
41	union cvmx_mio_fus_rcmd read_cmd;
42
43	read_cmd.u64 = 0;
44	read_cmd.s.addr = byte_addr;
45	read_cmd.s.pend = 1;
46	cvmx_write_csr(CVMX_MIO_FUS_RCMD, read_cmd.u64);
47	while ((read_cmd.u64 = cvmx_read_csr(CVMX_MIO_FUS_RCMD))
48	       && read_cmd.s.pend)
49		;
50	return read_cmd.s.dat;
51}
52
53/*
54 * Version of octeon_model_get_string() that takes buffer as argument,
55 * as running early in u-boot static/global variables don't work when
56 * running from flash.
57 */
58static const char *__init octeon_model_get_string_buffer(uint32_t chip_id,
59							 char *buffer)
60{
61	const char *family;
62	const char *core_model;
63	char pass[4];
64	int clock_mhz;
65	const char *suffix;
66	int num_cores;
67	union cvmx_mio_fus_dat2 fus_dat2;
68	union cvmx_mio_fus_dat3 fus_dat3;
69	char fuse_model[10];
70	uint32_t fuse_data = 0;
71	uint64_t l2d_fus3 = 0;
72
73	if (OCTEON_IS_MODEL(OCTEON_CN3XXX) || OCTEON_IS_MODEL(OCTEON_CN5XXX))
74		l2d_fus3 = (cvmx_read_csr(CVMX_L2D_FUS3) >> 34) & 0x3;
75	fus_dat2.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT2);
76	fus_dat3.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT3);
77	num_cores = cvmx_octeon_num_cores();
78
79	/* Make sure the non existent devices look disabled */
80	switch ((chip_id >> 8) & 0xff) {
81	case 6:		/* CN50XX */
82	case 2:		/* CN30XX */
83		fus_dat3.s.nodfa_dte = 1;
84		fus_dat3.s.nozip = 1;
85		break;
86	case 4:		/* CN57XX or CN56XX */
87		fus_dat3.s.nodfa_dte = 1;
88		break;
89	default:
90		break;
91	}
92
93	/* Make a guess at the suffix */
94	/* NSP = everything */
95	/* EXP = No crypto */
96	/* SCP = No DFA, No zip */
97	/* CP = No DFA, No crypto, No zip */
98	if (fus_dat3.s.nodfa_dte) {
99		if (fus_dat2.s.nocrypto)
100			suffix = "CP";
101		else
102			suffix = "SCP";
103	} else if (fus_dat2.s.nocrypto)
104		suffix = "EXP";
105	else
106		suffix = "NSP";
107
108	if (!fus_dat2.s.nocrypto)
109		__octeon_feature_bits |= OCTEON_HAS_CRYPTO;
110
111	/*
112	 * Assume pass number is encoded using <5:3><2:0>. Exceptions
113	 * will be fixed later.
114	 */
115	sprintf(pass, "%d.%d", (int)((chip_id >> 3) & 7) + 1, (int)chip_id & 7);
116
117	/*
118	 * Use the number of cores to determine the last 2 digits of
119	 * the model number. There are some exceptions that are fixed
120	 * later.
121	 */
122	switch (num_cores) {
123	case 48:
124		core_model = "90";
125		break;
126	case 44:
127		core_model = "88";
128		break;
129	case 40:
130		core_model = "85";
131		break;
132	case 32:
133		core_model = "80";
134		break;
135	case 24:
136		core_model = "70";
137		break;
138	case 16:
139		core_model = "60";
140		break;
141	case 15:
142		core_model = "58";
143		break;
144	case 14:
145		core_model = "55";
146		break;
147	case 13:
148		core_model = "52";
149		break;
150	case 12:
151		core_model = "50";
152		break;
153	case 11:
154		core_model = "48";
155		break;
156	case 10:
157		core_model = "45";
158		break;
159	case 9:
160		core_model = "42";
161		break;
162	case 8:
163		core_model = "40";
164		break;
165	case 7:
166		core_model = "38";
167		break;
168	case 6:
169		core_model = "34";
170		break;
171	case 5:
172		core_model = "32";
173		break;
174	case 4:
175		core_model = "30";
176		break;
177	case 3:
178		core_model = "25";
179		break;
180	case 2:
181		core_model = "20";
182		break;
183	case 1:
184		core_model = "10";
185		break;
186	default:
187		core_model = "XX";
188		break;
189	}
190
191	/* Now figure out the family, the first two digits */
192	switch ((chip_id >> 8) & 0xff) {
193	case 0:		/* CN38XX, CN37XX or CN36XX */
194		if (l2d_fus3) {
195			/*
196			 * For some unknown reason, the 16 core one is
197			 * called 37 instead of 36.
198			 */
199			if (num_cores >= 16)
200				family = "37";
201			else
202				family = "36";
203		} else
204			family = "38";
205		/*
206		 * This series of chips didn't follow the standard
207		 * pass numbering.
208		 */
209		switch (chip_id & 0xf) {
210		case 0:
211			strcpy(pass, "1.X");
212			break;
213		case 1:
214			strcpy(pass, "2.X");
215			break;
216		case 3:
217			strcpy(pass, "3.X");
218			break;
219		default:
220			strcpy(pass, "X.X");
221			break;
222		}
223		break;
224	case 1:		/* CN31XX or CN3020 */
225		if ((chip_id & 0x10) || l2d_fus3)
226			family = "30";
227		else
228			family = "31";
229		/*
230		 * This series of chips didn't follow the standard
231		 * pass numbering.
232		 */
233		switch (chip_id & 0xf) {
234		case 0:
235			strcpy(pass, "1.0");
236			break;
237		case 2:
238			strcpy(pass, "1.1");
239			break;
240		default:
241			strcpy(pass, "X.X");
242			break;
243		}
244		break;
245	case 2:		/* CN3010 or CN3005 */
246		family = "30";
247		/* A chip with half cache is an 05 */
248		if (l2d_fus3)
249			core_model = "05";
250		/*
251		 * This series of chips didn't follow the standard
252		 * pass numbering.
253		 */
254		switch (chip_id & 0xf) {
255		case 0:
256			strcpy(pass, "1.0");
257			break;
258		case 2:
259			strcpy(pass, "1.1");
260			break;
261		default:
262			strcpy(pass, "X.X");
263			break;
264		}
265		break;
266	case 3:		/* CN58XX */
267		family = "58";
268		/* Special case. 4 core, half cache (CP with half cache) */
269		if ((num_cores == 4) && l2d_fus3 && !strncmp(suffix, "CP", 2))
270			core_model = "29";
271
272		/* Pass 1 uses different encodings for pass numbers */
273		if ((chip_id & 0xFF) < 0x8) {
274			switch (chip_id & 0x3) {
275			case 0:
276				strcpy(pass, "1.0");
277				break;
278			case 1:
279				strcpy(pass, "1.1");
280				break;
281			case 3:
282				strcpy(pass, "1.2");
283				break;
284			default:
285				strcpy(pass, "1.X");
286				break;
287			}
288		}
289		break;
290	case 4:		/* CN57XX, CN56XX, CN55XX, CN54XX */
291		if (fus_dat2.cn56xx.raid_en) {
292			if (l2d_fus3)
293				family = "55";
294			else
295				family = "57";
296			if (fus_dat2.cn56xx.nocrypto)
297				suffix = "SP";
298			else
299				suffix = "SSP";
300		} else {
301			if (fus_dat2.cn56xx.nocrypto)
302				suffix = "CP";
303			else {
304				suffix = "NSP";
305				if (fus_dat3.s.nozip)
306					suffix = "SCP";
307
308				if (fus_dat3.cn38xx.bar2_en)
309					suffix = "NSPB2";
310			}
311			if (l2d_fus3)
312				family = "54";
313			else
314				family = "56";
315		}
316		break;
317	case 6:		/* CN50XX */
318		family = "50";
319		break;
320	case 7:		/* CN52XX */
321		if (l2d_fus3)
322			family = "51";
323		else
324			family = "52";
325		break;
326	case 0x93:		/* CN61XX */
327		family = "61";
328		if (fus_dat2.cn61xx.nocrypto && fus_dat2.cn61xx.dorm_crypto)
329			suffix = "AP";
330		if (fus_dat2.cn61xx.nocrypto)
331			suffix = "CP";
332		else if (fus_dat2.cn61xx.dorm_crypto)
333			suffix = "DAP";
334		else if (fus_dat3.cn61xx.nozip)
335			suffix = "SCP";
336		break;
337	case 0x90:		/* CN63XX */
338		family = "63";
339		if (fus_dat3.s.l2c_crip == 2)
340			family = "62";
341		if (num_cores == 6)	/* Other core counts match generic */
342			core_model = "35";
343		if (fus_dat2.cn63xx.nocrypto)
344			suffix = "CP";
345		else if (fus_dat2.cn63xx.dorm_crypto)
346			suffix = "DAP";
347		else if (fus_dat3.cn61xx.nozip)
348			suffix = "SCP";
349		else
350			suffix = "AAP";
351		break;
352	case 0x92:		/* CN66XX */
353		family = "66";
354		if (num_cores == 6)	/* Other core counts match generic */
355			core_model = "35";
356		if (fus_dat2.cn66xx.nocrypto && fus_dat2.cn66xx.dorm_crypto)
357			suffix = "AP";
358		if (fus_dat2.cn66xx.nocrypto)
359			suffix = "CP";
360		else if (fus_dat2.cn66xx.dorm_crypto)
361			suffix = "DAP";
362		else if (fus_dat3.cn61xx.nozip)
363			suffix = "SCP";
364		else
365			suffix = "AAP";
366		break;
367	case 0x91:		/* CN68XX */
368		family = "68";
369		if (fus_dat2.cn68xx.nocrypto && fus_dat3.cn61xx.nozip)
370			suffix = "CP";
371		else if (fus_dat2.cn68xx.dorm_crypto)
372			suffix = "DAP";
373		else if (fus_dat3.cn61xx.nozip)
374			suffix = "SCP";
375		else if (fus_dat2.cn68xx.nocrypto)
376			suffix = "SP";
377		else
378			suffix = "AAP";
379		break;
380	case 0x94:		/* CNF71XX */
381		family = "F71";
382		if (fus_dat3.cn61xx.nozip)
383			suffix = "SCP";
384		else
385			suffix = "AAP";
386		break;
387	case 0x95:		/* CN78XX */
388		if (num_cores == 6)	/* Other core counts match generic */
389			core_model = "35";
390		if (OCTEON_IS_MODEL(OCTEON_CN76XX))
391			family = "76";
392		else
393			family = "78";
394		if (fus_dat3.cn78xx.l2c_crip == 2)
395			family = "77";
396		if (fus_dat3.cn78xx.nozip
397		    && fus_dat3.cn78xx.nodfa_dte
398		    && fus_dat3.cn78xx.nohna_dte) {
399			if (fus_dat3.cn78xx.nozip &&
400				!fus_dat2.cn78xx.raid_en &&
401				fus_dat3.cn78xx.nohna_dte) {
402				suffix = "CP";
403			} else {
404				suffix = "SCP";
405			}
406		} else if (fus_dat2.cn78xx.raid_en == 0)
407			suffix = "HCP";
408		else
409			suffix = "AAP";
410		break;
411	case 0x96:		/* CN70XX */
412		family = "70";
413		if (cvmx_read_csr(CVMX_MIO_FUS_PDF) & (0x1ULL << 32))
414			family = "71";
415		if (fus_dat2.cn70xx.nocrypto)
416			suffix = "CP";
417		else if (fus_dat3.cn70xx.nodfa_dte)
418			suffix = "SCP";
419		else
420			suffix = "AAP";
421		break;
422	case 0x97:		/* CN73XX */
423		if (num_cores == 6)	/* Other core counts match generic */
424			core_model = "35";
425		family = "73";
426		if (fus_dat3.cn73xx.l2c_crip == 2)
427			family = "72";
428		if (fus_dat3.cn73xx.nozip
429				&& fus_dat3.cn73xx.nodfa_dte
430				&& fus_dat3.cn73xx.nohna_dte) {
431			if (!fus_dat2.cn73xx.raid_en)
432				suffix = "CP";
433			else
434				suffix = "SCP";
435		} else
436			suffix = "AAP";
437		break;
438	case 0x98:		/* CN75XX */
439		family = "F75";
440		if (fus_dat3.cn78xx.nozip
441		    && fus_dat3.cn78xx.nodfa_dte
442		    && fus_dat3.cn78xx.nohna_dte)
443			suffix = "SCP";
444		else
445			suffix = "AAP";
446		break;
447	default:
448		family = "XX";
449		core_model = "XX";
450		strcpy(pass, "X.X");
451		suffix = "XXX";
452		break;
453	}
454
455	clock_mhz = octeon_get_clock_rate() / 1000000;
456	if (family[0] != '3') {
457		int fuse_base = 384 / 8;
458		if (family[0] == '6')
459			fuse_base = 832 / 8;
460
461		/* Check for model in fuses, overrides normal decode */
462		/* This is _not_ valid for Octeon CN3XXX models */
463		fuse_data |= cvmx_fuse_read_byte(fuse_base + 3);
464		fuse_data = fuse_data << 8;
465		fuse_data |= cvmx_fuse_read_byte(fuse_base + 2);
466		fuse_data = fuse_data << 8;
467		fuse_data |= cvmx_fuse_read_byte(fuse_base + 1);
468		fuse_data = fuse_data << 8;
469		fuse_data |= cvmx_fuse_read_byte(fuse_base);
470		if (fuse_data & 0x7ffff) {
471			int model = fuse_data & 0x3fff;
472			int suffix = (fuse_data >> 14) & 0x1f;
473			if (suffix && model) {
474				/* Have both number and suffix in fuses, so both */
475				sprintf(fuse_model, "%d%c", model, 'A' + suffix - 1);
476				core_model = "";
477				family = fuse_model;
478			} else if (suffix && !model) {
479				/* Only have suffix, so add suffix to 'normal' model number */
480				sprintf(fuse_model, "%s%c", core_model, 'A' + suffix - 1);
481				core_model = fuse_model;
482			} else {
483				/* Don't have suffix, so just use model from fuses */
484				sprintf(fuse_model, "%d", model);
485				core_model = "";
486				family = fuse_model;
487			}
488		}
489	}
490	sprintf(buffer, "CN%s%sp%s-%d-%s", family, core_model, pass, clock_mhz, suffix);
491	return buffer;
492}
493
494/**
495 * Given the chip processor ID from COP0, this function returns a
496 * string representing the chip model number. The string is of the
497 * form CNXXXXpX.X-FREQ-SUFFIX.
498 * - XXXX = The chip model number
499 * - X.X = Chip pass number
500 * - FREQ = Current frequency in Mhz
501 * - SUFFIX = NSP, EXP, SCP, SSP, or CP
502 *
503 * @chip_id: Chip ID
504 *
505 * Returns Model string
506 */
507const char *__init octeon_model_get_string(uint32_t chip_id)
508{
509	static char buffer[32];
510	return octeon_model_get_string_buffer(chip_id, buffer);
511}
512