0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #include <asm/octeon/octeon.h>
0029
0030 enum octeon_feature_bits __octeon_feature_bits __read_mostly;
0031 EXPORT_SYMBOL_GPL(__octeon_feature_bits);
0032
0033
0034
0035
0036
0037
0038
0039 static uint8_t __init cvmx_fuse_read_byte(int byte_addr)
0040 {
0041 union cvmx_mio_fus_rcmd read_cmd;
0042
0043 read_cmd.u64 = 0;
0044 read_cmd.s.addr = byte_addr;
0045 read_cmd.s.pend = 1;
0046 cvmx_write_csr(CVMX_MIO_FUS_RCMD, read_cmd.u64);
0047 while ((read_cmd.u64 = cvmx_read_csr(CVMX_MIO_FUS_RCMD))
0048 && read_cmd.s.pend)
0049 ;
0050 return read_cmd.s.dat;
0051 }
0052
0053
0054
0055
0056
0057
0058 static const char *__init octeon_model_get_string_buffer(uint32_t chip_id,
0059 char *buffer)
0060 {
0061 const char *family;
0062 const char *core_model;
0063 char pass[4];
0064 int clock_mhz;
0065 const char *suffix;
0066 int num_cores;
0067 union cvmx_mio_fus_dat2 fus_dat2;
0068 union cvmx_mio_fus_dat3 fus_dat3;
0069 char fuse_model[10];
0070 uint32_t fuse_data = 0;
0071 uint64_t l2d_fus3 = 0;
0072
0073 if (OCTEON_IS_MODEL(OCTEON_CN3XXX) || OCTEON_IS_MODEL(OCTEON_CN5XXX))
0074 l2d_fus3 = (cvmx_read_csr(CVMX_L2D_FUS3) >> 34) & 0x3;
0075 fus_dat2.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT2);
0076 fus_dat3.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT3);
0077 num_cores = cvmx_octeon_num_cores();
0078
0079
0080 switch ((chip_id >> 8) & 0xff) {
0081 case 6:
0082 case 2:
0083 fus_dat3.s.nodfa_dte = 1;
0084 fus_dat3.s.nozip = 1;
0085 break;
0086 case 4:
0087 fus_dat3.s.nodfa_dte = 1;
0088 break;
0089 default:
0090 break;
0091 }
0092
0093
0094
0095
0096
0097
0098 if (fus_dat3.s.nodfa_dte) {
0099 if (fus_dat2.s.nocrypto)
0100 suffix = "CP";
0101 else
0102 suffix = "SCP";
0103 } else if (fus_dat2.s.nocrypto)
0104 suffix = "EXP";
0105 else
0106 suffix = "NSP";
0107
0108 if (!fus_dat2.s.nocrypto)
0109 __octeon_feature_bits |= OCTEON_HAS_CRYPTO;
0110
0111
0112
0113
0114
0115 sprintf(pass, "%d.%d", (int)((chip_id >> 3) & 7) + 1, (int)chip_id & 7);
0116
0117
0118
0119
0120
0121
0122 switch (num_cores) {
0123 case 48:
0124 core_model = "90";
0125 break;
0126 case 44:
0127 core_model = "88";
0128 break;
0129 case 40:
0130 core_model = "85";
0131 break;
0132 case 32:
0133 core_model = "80";
0134 break;
0135 case 24:
0136 core_model = "70";
0137 break;
0138 case 16:
0139 core_model = "60";
0140 break;
0141 case 15:
0142 core_model = "58";
0143 break;
0144 case 14:
0145 core_model = "55";
0146 break;
0147 case 13:
0148 core_model = "52";
0149 break;
0150 case 12:
0151 core_model = "50";
0152 break;
0153 case 11:
0154 core_model = "48";
0155 break;
0156 case 10:
0157 core_model = "45";
0158 break;
0159 case 9:
0160 core_model = "42";
0161 break;
0162 case 8:
0163 core_model = "40";
0164 break;
0165 case 7:
0166 core_model = "38";
0167 break;
0168 case 6:
0169 core_model = "34";
0170 break;
0171 case 5:
0172 core_model = "32";
0173 break;
0174 case 4:
0175 core_model = "30";
0176 break;
0177 case 3:
0178 core_model = "25";
0179 break;
0180 case 2:
0181 core_model = "20";
0182 break;
0183 case 1:
0184 core_model = "10";
0185 break;
0186 default:
0187 core_model = "XX";
0188 break;
0189 }
0190
0191
0192 switch ((chip_id >> 8) & 0xff) {
0193 case 0:
0194 if (l2d_fus3) {
0195
0196
0197
0198
0199 if (num_cores >= 16)
0200 family = "37";
0201 else
0202 family = "36";
0203 } else
0204 family = "38";
0205
0206
0207
0208
0209 switch (chip_id & 0xf) {
0210 case 0:
0211 strcpy(pass, "1.X");
0212 break;
0213 case 1:
0214 strcpy(pass, "2.X");
0215 break;
0216 case 3:
0217 strcpy(pass, "3.X");
0218 break;
0219 default:
0220 strcpy(pass, "X.X");
0221 break;
0222 }
0223 break;
0224 case 1:
0225 if ((chip_id & 0x10) || l2d_fus3)
0226 family = "30";
0227 else
0228 family = "31";
0229
0230
0231
0232
0233 switch (chip_id & 0xf) {
0234 case 0:
0235 strcpy(pass, "1.0");
0236 break;
0237 case 2:
0238 strcpy(pass, "1.1");
0239 break;
0240 default:
0241 strcpy(pass, "X.X");
0242 break;
0243 }
0244 break;
0245 case 2:
0246 family = "30";
0247
0248 if (l2d_fus3)
0249 core_model = "05";
0250
0251
0252
0253
0254 switch (chip_id & 0xf) {
0255 case 0:
0256 strcpy(pass, "1.0");
0257 break;
0258 case 2:
0259 strcpy(pass, "1.1");
0260 break;
0261 default:
0262 strcpy(pass, "X.X");
0263 break;
0264 }
0265 break;
0266 case 3:
0267 family = "58";
0268
0269 if ((num_cores == 4) && l2d_fus3 && !strncmp(suffix, "CP", 2))
0270 core_model = "29";
0271
0272
0273 if ((chip_id & 0xFF) < 0x8) {
0274 switch (chip_id & 0x3) {
0275 case 0:
0276 strcpy(pass, "1.0");
0277 break;
0278 case 1:
0279 strcpy(pass, "1.1");
0280 break;
0281 case 3:
0282 strcpy(pass, "1.2");
0283 break;
0284 default:
0285 strcpy(pass, "1.X");
0286 break;
0287 }
0288 }
0289 break;
0290 case 4:
0291 if (fus_dat2.cn56xx.raid_en) {
0292 if (l2d_fus3)
0293 family = "55";
0294 else
0295 family = "57";
0296 if (fus_dat2.cn56xx.nocrypto)
0297 suffix = "SP";
0298 else
0299 suffix = "SSP";
0300 } else {
0301 if (fus_dat2.cn56xx.nocrypto)
0302 suffix = "CP";
0303 else {
0304 suffix = "NSP";
0305 if (fus_dat3.s.nozip)
0306 suffix = "SCP";
0307
0308 if (fus_dat3.cn38xx.bar2_en)
0309 suffix = "NSPB2";
0310 }
0311 if (l2d_fus3)
0312 family = "54";
0313 else
0314 family = "56";
0315 }
0316 break;
0317 case 6:
0318 family = "50";
0319 break;
0320 case 7:
0321 if (l2d_fus3)
0322 family = "51";
0323 else
0324 family = "52";
0325 break;
0326 case 0x93:
0327 family = "61";
0328 if (fus_dat2.cn61xx.nocrypto && fus_dat2.cn61xx.dorm_crypto)
0329 suffix = "AP";
0330 if (fus_dat2.cn61xx.nocrypto)
0331 suffix = "CP";
0332 else if (fus_dat2.cn61xx.dorm_crypto)
0333 suffix = "DAP";
0334 else if (fus_dat3.cn61xx.nozip)
0335 suffix = "SCP";
0336 break;
0337 case 0x90:
0338 family = "63";
0339 if (fus_dat3.s.l2c_crip == 2)
0340 family = "62";
0341 if (num_cores == 6)
0342 core_model = "35";
0343 if (fus_dat2.cn63xx.nocrypto)
0344 suffix = "CP";
0345 else if (fus_dat2.cn63xx.dorm_crypto)
0346 suffix = "DAP";
0347 else if (fus_dat3.cn61xx.nozip)
0348 suffix = "SCP";
0349 else
0350 suffix = "AAP";
0351 break;
0352 case 0x92:
0353 family = "66";
0354 if (num_cores == 6)
0355 core_model = "35";
0356 if (fus_dat2.cn66xx.nocrypto && fus_dat2.cn66xx.dorm_crypto)
0357 suffix = "AP";
0358 if (fus_dat2.cn66xx.nocrypto)
0359 suffix = "CP";
0360 else if (fus_dat2.cn66xx.dorm_crypto)
0361 suffix = "DAP";
0362 else if (fus_dat3.cn61xx.nozip)
0363 suffix = "SCP";
0364 else
0365 suffix = "AAP";
0366 break;
0367 case 0x91:
0368 family = "68";
0369 if (fus_dat2.cn68xx.nocrypto && fus_dat3.cn61xx.nozip)
0370 suffix = "CP";
0371 else if (fus_dat2.cn68xx.dorm_crypto)
0372 suffix = "DAP";
0373 else if (fus_dat3.cn61xx.nozip)
0374 suffix = "SCP";
0375 else if (fus_dat2.cn68xx.nocrypto)
0376 suffix = "SP";
0377 else
0378 suffix = "AAP";
0379 break;
0380 case 0x94:
0381 family = "F71";
0382 if (fus_dat3.cn61xx.nozip)
0383 suffix = "SCP";
0384 else
0385 suffix = "AAP";
0386 break;
0387 case 0x95:
0388 if (num_cores == 6)
0389 core_model = "35";
0390 if (OCTEON_IS_MODEL(OCTEON_CN76XX))
0391 family = "76";
0392 else
0393 family = "78";
0394 if (fus_dat3.cn78xx.l2c_crip == 2)
0395 family = "77";
0396 if (fus_dat3.cn78xx.nozip
0397 && fus_dat3.cn78xx.nodfa_dte
0398 && fus_dat3.cn78xx.nohna_dte) {
0399 if (fus_dat3.cn78xx.nozip &&
0400 !fus_dat2.cn78xx.raid_en &&
0401 fus_dat3.cn78xx.nohna_dte) {
0402 suffix = "CP";
0403 } else {
0404 suffix = "SCP";
0405 }
0406 } else if (fus_dat2.cn78xx.raid_en == 0)
0407 suffix = "HCP";
0408 else
0409 suffix = "AAP";
0410 break;
0411 case 0x96:
0412 family = "70";
0413 if (cvmx_read_csr(CVMX_MIO_FUS_PDF) & (0x1ULL << 32))
0414 family = "71";
0415 if (fus_dat2.cn70xx.nocrypto)
0416 suffix = "CP";
0417 else if (fus_dat3.cn70xx.nodfa_dte)
0418 suffix = "SCP";
0419 else
0420 suffix = "AAP";
0421 break;
0422 case 0x97:
0423 if (num_cores == 6)
0424 core_model = "35";
0425 family = "73";
0426 if (fus_dat3.cn73xx.l2c_crip == 2)
0427 family = "72";
0428 if (fus_dat3.cn73xx.nozip
0429 && fus_dat3.cn73xx.nodfa_dte
0430 && fus_dat3.cn73xx.nohna_dte) {
0431 if (!fus_dat2.cn73xx.raid_en)
0432 suffix = "CP";
0433 else
0434 suffix = "SCP";
0435 } else
0436 suffix = "AAP";
0437 break;
0438 case 0x98:
0439 family = "F75";
0440 if (fus_dat3.cn78xx.nozip
0441 && fus_dat3.cn78xx.nodfa_dte
0442 && fus_dat3.cn78xx.nohna_dte)
0443 suffix = "SCP";
0444 else
0445 suffix = "AAP";
0446 break;
0447 default:
0448 family = "XX";
0449 core_model = "XX";
0450 strcpy(pass, "X.X");
0451 suffix = "XXX";
0452 break;
0453 }
0454
0455 clock_mhz = octeon_get_clock_rate() / 1000000;
0456 if (family[0] != '3') {
0457 int fuse_base = 384 / 8;
0458 if (family[0] == '6')
0459 fuse_base = 832 / 8;
0460
0461
0462
0463 fuse_data |= cvmx_fuse_read_byte(fuse_base + 3);
0464 fuse_data = fuse_data << 8;
0465 fuse_data |= cvmx_fuse_read_byte(fuse_base + 2);
0466 fuse_data = fuse_data << 8;
0467 fuse_data |= cvmx_fuse_read_byte(fuse_base + 1);
0468 fuse_data = fuse_data << 8;
0469 fuse_data |= cvmx_fuse_read_byte(fuse_base);
0470 if (fuse_data & 0x7ffff) {
0471 int model = fuse_data & 0x3fff;
0472 int suffix = (fuse_data >> 14) & 0x1f;
0473 if (suffix && model) {
0474
0475 sprintf(fuse_model, "%d%c", model, 'A' + suffix - 1);
0476 core_model = "";
0477 family = fuse_model;
0478 } else if (suffix && !model) {
0479
0480 sprintf(fuse_model, "%s%c", core_model, 'A' + suffix - 1);
0481 core_model = fuse_model;
0482 } else {
0483
0484 sprintf(fuse_model, "%d", model);
0485 core_model = "";
0486 family = fuse_model;
0487 }
0488 }
0489 }
0490 sprintf(buffer, "CN%s%sp%s-%d-%s", family, core_model, pass, clock_mhz, suffix);
0491 return buffer;
0492 }
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507 const char *__init octeon_model_get_string(uint32_t chip_id)
0508 {
0509 static char buffer[32];
0510 return octeon_model_get_string_buffer(chip_id, buffer);
0511 }