GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / arch / mips / cavium-octeon / executive / octeon-model.c
blob9bf1ec75a426f18be94b705273adee9cf7ce1140
1 /***********************license start***************
2 * Author: Cavium Networks
4 * Contact: support@caviumnetworks.com
5 * This file is part of the OCTEON SDK
7 * Copyright (c) 2003-2008 Cavium Networks
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.
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.
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/.
24 * This file may also be available under a different license from Cavium.
25 * Contact Cavium Networks for more information
26 ***********************license end**************************************/
29 * File defining functions for working with different Octeon
30 * models.
32 #include <asm/octeon/octeon.h>
34 const char *octeon_model_get_string(uint32_t chip_id)
36 static char buffer[32];
37 return octeon_model_get_string_buffer(chip_id, buffer);
41 * Version of octeon_model_get_string() that takes buffer as argument,
42 * as running early in u-boot static/global variables don't work when
43 * running from flash.
45 const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer)
47 const char *family;
48 const char *core_model;
49 char pass[4];
50 int clock_mhz;
51 const char *suffix;
52 union cvmx_l2d_fus3 fus3;
53 int num_cores;
54 union cvmx_mio_fus_dat2 fus_dat2;
55 union cvmx_mio_fus_dat3 fus_dat3;
56 char fuse_model[10];
57 uint32_t fuse_data = 0;
59 fus3.u64 = cvmx_read_csr(CVMX_L2D_FUS3);
60 fus_dat2.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT2);
61 fus_dat3.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT3);
63 num_cores = cvmx_octeon_num_cores();
65 /* Make sure the non existant devices look disabled */
66 switch ((chip_id >> 8) & 0xff) {
67 case 6: /* CN50XX */
68 case 2: /* CN30XX */
69 fus_dat3.s.nodfa_dte = 1;
70 fus_dat3.s.nozip = 1;
71 break;
72 case 4: /* CN57XX or CN56XX */
73 fus_dat3.s.nodfa_dte = 1;
74 break;
75 default:
76 break;
79 /* Make a guess at the suffix */
80 /* NSP = everything */
81 /* EXP = No crypto */
82 /* SCP = No DFA, No zip */
83 /* CP = No DFA, No crypto, No zip */
84 if (fus_dat3.s.nodfa_dte) {
85 if (fus_dat2.s.nocrypto)
86 suffix = "CP";
87 else
88 suffix = "SCP";
89 } else if (fus_dat2.s.nocrypto)
90 suffix = "EXP";
91 else
92 suffix = "NSP";
95 * Assume pass number is encoded using <5:3><2:0>. Exceptions
96 * will be fixed later.
98 sprintf(pass, "%u.%u", ((chip_id >> 3) & 7) + 1, chip_id & 7);
101 * Use the number of cores to determine the last 2 digits of
102 * the model number. There are some exceptions that are fixed
103 * later.
105 switch (num_cores) {
106 case 16:
107 core_model = "60";
108 break;
109 case 15:
110 core_model = "58";
111 break;
112 case 14:
113 core_model = "55";
114 break;
115 case 13:
116 core_model = "52";
117 break;
118 case 12:
119 core_model = "50";
120 break;
121 case 11:
122 core_model = "48";
123 break;
124 case 10:
125 core_model = "45";
126 break;
127 case 9:
128 core_model = "42";
129 break;
130 case 8:
131 core_model = "40";
132 break;
133 case 7:
134 core_model = "38";
135 break;
136 case 6:
137 core_model = "34";
138 break;
139 case 5:
140 core_model = "32";
141 break;
142 case 4:
143 core_model = "30";
144 break;
145 case 3:
146 core_model = "25";
147 break;
148 case 2:
149 core_model = "20";
150 break;
151 case 1:
152 core_model = "10";
153 break;
154 default:
155 core_model = "XX";
156 break;
159 /* Now figure out the family, the first two digits */
160 switch ((chip_id >> 8) & 0xff) {
161 case 0: /* CN38XX, CN37XX or CN36XX */
162 if (fus3.cn38xx.crip_512k) {
164 * For some unknown reason, the 16 core one is
165 * called 37 instead of 36.
167 if (num_cores >= 16)
168 family = "37";
169 else
170 family = "36";
171 } else
172 family = "38";
174 * This series of chips didn't follow the standard
175 * pass numbering.
177 switch (chip_id & 0xf) {
178 case 0:
179 strcpy(pass, "1.X");
180 break;
181 case 1:
182 strcpy(pass, "2.X");
183 break;
184 case 3:
185 strcpy(pass, "3.X");
186 break;
187 default:
188 strcpy(pass, "X.X");
189 break;
191 break;
192 case 1: /* CN31XX or CN3020 */
193 if ((chip_id & 0x10) || fus3.cn31xx.crip_128k)
194 family = "30";
195 else
196 family = "31";
198 * This series of chips didn't follow the standard
199 * pass numbering.
201 switch (chip_id & 0xf) {
202 case 0:
203 strcpy(pass, "1.0");
204 break;
205 case 2:
206 strcpy(pass, "1.1");
207 break;
208 default:
209 strcpy(pass, "X.X");
210 break;
212 break;
213 case 2: /* CN3010 or CN3005 */
214 family = "30";
215 /* A chip with half cache is an 05 */
216 if (fus3.cn30xx.crip_64k)
217 core_model = "05";
219 * This series of chips didn't follow the standard
220 * pass numbering.
222 switch (chip_id & 0xf) {
223 case 0:
224 strcpy(pass, "1.0");
225 break;
226 case 2:
227 strcpy(pass, "1.1");
228 break;
229 default:
230 strcpy(pass, "X.X");
231 break;
233 break;
234 case 3: /* CN58XX */
235 family = "58";
236 /* Special case. 4 core, no crypto */
237 if ((num_cores == 4) && fus_dat2.cn38xx.nocrypto)
238 core_model = "29";
240 /* Pass 1 uses different encodings for pass numbers */
241 if ((chip_id & 0xFF) < 0x8) {
242 switch (chip_id & 0x3) {
243 case 0:
244 strcpy(pass, "1.0");
245 break;
246 case 1:
247 strcpy(pass, "1.1");
248 break;
249 case 3:
250 strcpy(pass, "1.2");
251 break;
252 default:
253 strcpy(pass, "1.X");
254 break;
257 break;
258 case 4: /* CN57XX, CN56XX, CN55XX, CN54XX */
259 if (fus_dat2.cn56xx.raid_en) {
260 if (fus3.cn56xx.crip_1024k)
261 family = "55";
262 else
263 family = "57";
264 if (fus_dat2.cn56xx.nocrypto)
265 suffix = "SP";
266 else
267 suffix = "SSP";
268 } else {
269 if (fus_dat2.cn56xx.nocrypto)
270 suffix = "CP";
271 else {
272 suffix = "NSP";
273 if (fus_dat3.s.nozip)
274 suffix = "SCP";
276 if (fus3.cn56xx.crip_1024k)
277 family = "54";
278 else
279 family = "56";
281 break;
282 case 6: /* CN50XX */
283 family = "50";
284 break;
285 case 7: /* CN52XX */
286 if (fus3.cn52xx.crip_256k)
287 family = "51";
288 else
289 family = "52";
290 break;
291 default:
292 family = "XX";
293 core_model = "XX";
294 strcpy(pass, "X.X");
295 suffix = "XXX";
296 break;
299 clock_mhz = octeon_get_clock_rate() / 1000000;
301 if (family[0] != '3') {
302 /* Check for model in fuses, overrides normal decode */
303 /* This is _not_ valid for Octeon CN3XXX models */
304 fuse_data |= cvmx_fuse_read_byte(51);
305 fuse_data = fuse_data << 8;
306 fuse_data |= cvmx_fuse_read_byte(50);
307 fuse_data = fuse_data << 8;
308 fuse_data |= cvmx_fuse_read_byte(49);
309 fuse_data = fuse_data << 8;
310 fuse_data |= cvmx_fuse_read_byte(48);
311 if (fuse_data & 0x7ffff) {
312 int model = fuse_data & 0x3fff;
313 int suffix = (fuse_data >> 14) & 0x1f;
314 if (suffix && model) {
316 * Have both number and suffix in
317 * fuses, so both
319 sprintf(fuse_model, "%d%c",
320 model, 'A' + suffix - 1);
321 core_model = "";
322 family = fuse_model;
323 } else if (suffix && !model) {
325 * Only have suffix, so add suffix to
326 * 'normal' model number.
328 sprintf(fuse_model, "%s%c", core_model,
329 'A' + suffix - 1);
330 core_model = fuse_model;
331 } else {
333 * Don't have suffix, so just use
334 * model from fuses.
336 sprintf(fuse_model, "%d", model);
337 core_model = "";
338 family = fuse_model;
342 sprintf(buffer, "CN%s%sp%s-%d-%s",
343 family, core_model, pass, clock_mhz, suffix);
344 return buffer;