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