Merge branch 'getname2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[pandora-kernel.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_CN6XXX))
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_pop(cvmx_read_csr(CVMX_CIU_FUSE));
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 32:
125                 core_model = "80";
126                 break;
127         case 24:
128                 core_model = "70";
129                 break;
130         case 16:
131                 core_model = "60";
132                 break;
133         case 15:
134                 core_model = "58";
135                 break;
136         case 14:
137                 core_model = "55";
138                 break;
139         case 13:
140                 core_model = "52";
141                 break;
142         case 12:
143                 core_model = "50";
144                 break;
145         case 11:
146                 core_model = "48";
147                 break;
148         case 10:
149                 core_model = "45";
150                 break;
151         case 9:
152                 core_model = "42";
153                 break;
154         case 8:
155                 core_model = "40";
156                 break;
157         case 7:
158                 core_model = "38";
159                 break;
160         case 6:
161                 core_model = "34";
162                 break;
163         case 5:
164                 core_model = "32";
165                 break;
166         case 4:
167                 core_model = "30";
168                 break;
169         case 3:
170                 core_model = "25";
171                 break;
172         case 2:
173                 core_model = "20";
174                 break;
175         case 1:
176                 core_model = "10";
177                 break;
178         default:
179                 core_model = "XX";
180                 break;
181         }
182
183         /* Now figure out the family, the first two digits */
184         switch ((chip_id >> 8) & 0xff) {
185         case 0:         /* CN38XX, CN37XX or CN36XX */
186                 if (fus3.cn38xx.crip_512k) {
187                         /*
188                          * For some unknown reason, the 16 core one is
189                          * called 37 instead of 36.
190                          */
191                         if (num_cores >= 16)
192                                 family = "37";
193                         else
194                                 family = "36";
195                 } else
196                         family = "38";
197                 /*
198                  * This series of chips didn't follow the standard
199                  * pass numbering.
200                  */
201                 switch (chip_id & 0xf) {
202                 case 0:
203                         strcpy(pass, "1.X");
204                         break;
205                 case 1:
206                         strcpy(pass, "2.X");
207                         break;
208                 case 3:
209                         strcpy(pass, "3.X");
210                         break;
211                 default:
212                         strcpy(pass, "X.X");
213                         break;
214                 }
215                 break;
216         case 1:         /* CN31XX or CN3020 */
217                 if ((chip_id & 0x10) || fus3.cn31xx.crip_128k)
218                         family = "30";
219                 else
220                         family = "31";
221                 /*
222                  * This series of chips didn't follow the standard
223                  * pass numbering.
224                  */
225                 switch (chip_id & 0xf) {
226                 case 0:
227                         strcpy(pass, "1.0");
228                         break;
229                 case 2:
230                         strcpy(pass, "1.1");
231                         break;
232                 default:
233                         strcpy(pass, "X.X");
234                         break;
235                 }
236                 break;
237         case 2:         /* CN3010 or CN3005 */
238                 family = "30";
239                 /* A chip with half cache is an 05 */
240                 if (fus3.cn30xx.crip_64k)
241                         core_model = "05";
242                 /*
243                  * This series of chips didn't follow the standard
244                  * pass numbering.
245                  */
246                 switch (chip_id & 0xf) {
247                 case 0:
248                         strcpy(pass, "1.0");
249                         break;
250                 case 2:
251                         strcpy(pass, "1.1");
252                         break;
253                 default:
254                         strcpy(pass, "X.X");
255                         break;
256                 }
257                 break;
258         case 3:         /* CN58XX */
259                 family = "58";
260                 /* Special case. 4 core, half cache (CP with half cache) */
261                 if ((num_cores == 4) && fus3.cn58xx.crip_1024k && !strncmp(suffix, "CP", 2))
262                         core_model = "29";
263
264                 /* Pass 1 uses different encodings for pass numbers */
265                 if ((chip_id & 0xFF) < 0x8) {
266                         switch (chip_id & 0x3) {
267                         case 0:
268                                 strcpy(pass, "1.0");
269                                 break;
270                         case 1:
271                                 strcpy(pass, "1.1");
272                                 break;
273                         case 3:
274                                 strcpy(pass, "1.2");
275                                 break;
276                         default:
277                                 strcpy(pass, "1.X");
278                                 break;
279                         }
280                 }
281                 break;
282         case 4:         /* CN57XX, CN56XX, CN55XX, CN54XX */
283                 if (fus_dat2.cn56xx.raid_en) {
284                         if (fus3.cn56xx.crip_1024k)
285                                 family = "55";
286                         else
287                                 family = "57";
288                         if (fus_dat2.cn56xx.nocrypto)
289                                 suffix = "SP";
290                         else
291                                 suffix = "SSP";
292                 } else {
293                         if (fus_dat2.cn56xx.nocrypto)
294                                 suffix = "CP";
295                         else {
296                                 suffix = "NSP";
297                                 if (fus_dat3.s.nozip)
298                                         suffix = "SCP";
299
300                                 if (fus_dat3.s.bar2_en)
301                                         suffix = "NSPB2";
302                         }
303                         if (fus3.cn56xx.crip_1024k)
304                                 family = "54";
305                         else
306                                 family = "56";
307                 }
308                 break;
309         case 6:         /* CN50XX */
310                 family = "50";
311                 break;
312         case 7:         /* CN52XX */
313                 if (fus3.cn52xx.crip_256k)
314                         family = "51";
315                 else
316                         family = "52";
317                 break;
318         case 0x93:              /* CN61XX */
319                 family = "61";
320                 if (fus_dat2.cn61xx.nocrypto && fus_dat2.cn61xx.dorm_crypto)
321                         suffix = "AP";
322                 if (fus_dat2.cn61xx.nocrypto)
323                         suffix = "CP";
324                 else if (fus_dat2.cn61xx.dorm_crypto)
325                         suffix = "DAP";
326                 else if (fus_dat3.cn61xx.nozip)
327                         suffix = "SCP";
328                 break;
329         case 0x90:              /* CN63XX */
330                 family = "63";
331                 if (fus_dat3.s.l2c_crip == 2)
332                         family = "62";
333                 if (num_cores == 6)     /* Other core counts match generic */
334                         core_model = "35";
335                 if (fus_dat2.cn63xx.nocrypto)
336                         suffix = "CP";
337                 else if (fus_dat2.cn63xx.dorm_crypto)
338                         suffix = "DAP";
339                 else if (fus_dat3.cn63xx.nozip)
340                         suffix = "SCP";
341                 else
342                         suffix = "AAP";
343                 break;
344         case 0x92:              /* CN66XX */
345                 family = "66";
346                 if (num_cores == 6)     /* Other core counts match generic */
347                         core_model = "35";
348                 if (fus_dat2.cn66xx.nocrypto && fus_dat2.cn66xx.dorm_crypto)
349                         suffix = "AP";
350                 if (fus_dat2.cn66xx.nocrypto)
351                         suffix = "CP";
352                 else if (fus_dat2.cn66xx.dorm_crypto)
353                         suffix = "DAP";
354                 else if (fus_dat3.cn66xx.nozip)
355                         suffix = "SCP";
356                 else
357                         suffix = "AAP";
358                 break;
359         case 0x91:              /* CN68XX */
360                 family = "68";
361                 if (fus_dat2.cn68xx.nocrypto && fus_dat3.cn68xx.nozip)
362                         suffix = "CP";
363                 else if (fus_dat2.cn68xx.dorm_crypto)
364                         suffix = "DAP";
365                 else if (fus_dat3.cn68xx.nozip)
366                         suffix = "SCP";
367                 else if (fus_dat2.cn68xx.nocrypto)
368                         suffix = "SP";
369                 else
370                         suffix = "AAP";
371                 break;
372         default:
373                 family = "XX";
374                 core_model = "XX";
375                 strcpy(pass, "X.X");
376                 suffix = "XXX";
377                 break;
378         }
379
380         clock_mhz = octeon_get_clock_rate() / 1000000;
381         if (family[0] != '3') {
382                 int fuse_base = 384 / 8;
383                 if (family[0] == '6')
384                         fuse_base = 832 / 8;
385
386                 /* Check for model in fuses, overrides normal decode */
387                 /* This is _not_ valid for Octeon CN3XXX models */
388                 fuse_data |= cvmx_fuse_read_byte(fuse_base + 3);
389                 fuse_data = fuse_data << 8;
390                 fuse_data |= cvmx_fuse_read_byte(fuse_base + 2);
391                 fuse_data = fuse_data << 8;
392                 fuse_data |= cvmx_fuse_read_byte(fuse_base + 1);
393                 fuse_data = fuse_data << 8;
394                 fuse_data |= cvmx_fuse_read_byte(fuse_base);
395                 if (fuse_data & 0x7ffff) {
396                         int model = fuse_data & 0x3fff;
397                         int suffix = (fuse_data >> 14) & 0x1f;
398                         if (suffix && model) {
399                                 /* Have both number and suffix in fuses, so both */
400                                 sprintf(fuse_model, "%d%c", model, 'A' + suffix - 1);
401                                 core_model = "";
402                                 family = fuse_model;
403                         } else if (suffix && !model) {
404                                 /* Only have suffix, so add suffix to 'normal' model number */
405                                 sprintf(fuse_model, "%s%c", core_model, 'A' + suffix - 1);
406                                 core_model = fuse_model;
407                         } else {
408                                 /* Don't have suffix, so just use model from fuses */
409                                 sprintf(fuse_model, "%d", model);
410                                 core_model = "";
411                                 family = fuse_model;
412                         }
413                 }
414         }
415         sprintf(buffer, "CN%s%sp%s-%d-%s", family, core_model, pass, clock_mhz, suffix);
416         return buffer;
417 }
418
419 /**
420  * Given the chip processor ID from COP0, this function returns a
421  * string representing the chip model number. The string is of the
422  * form CNXXXXpX.X-FREQ-SUFFIX.
423  * - XXXX = The chip model number
424  * - X.X = Chip pass number
425  * - FREQ = Current frequency in Mhz
426  * - SUFFIX = NSP, EXP, SCP, SSP, or CP
427  *
428  * @chip_id: Chip ID
429  *
430  * Returns Model string
431  */
432 const char *__init octeon_model_get_string(uint32_t chip_id)
433 {
434         static char buffer[32];
435         return octeon_model_get_string_buffer(chip_id, buffer);
436 }