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