From: "Steven J. Hill" <Steven.Hill@xxxxxxxxxx> Support Octeon III platforms when printing out the model and SoC information during boot. Signed-off-by: Steven J. Hill <steven.hill@xxxxxxxxxx> Acked-by: David Daney <david.daney@xxxxxxxxxx> --- arch/mips/cavium-octeon/executive/octeon-model.c | 53 ++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/arch/mips/cavium-octeon/executive/octeon-model.c b/arch/mips/cavium-octeon/executive/octeon-model.c index 3410523..069a996 100644 --- a/arch/mips/cavium-octeon/executive/octeon-model.c +++ b/arch/mips/cavium-octeon/executive/octeon-model.c @@ -67,7 +67,7 @@ static const char *__init octeon_model_get_string_buffer(uint32_t chip_id, union cvmx_mio_fus_dat2 fus_dat2; union cvmx_mio_fus_dat3 fus_dat3; char fuse_model[10]; - uint32_t fuse_data = 0; + uint64_t fuse_data = 0; uint64_t l2d_fus3 = 0; if (OCTEON_IS_MODEL(OCTEON_CN3XXX) || OCTEON_IS_MODEL(OCTEON_CN5XXX)) @@ -453,11 +453,13 @@ static const char *__init octeon_model_get_string_buffer(uint32_t chip_id, } clock_mhz = octeon_get_clock_rate() / 1000000; - if (family[0] != '3') { + if (family[0] != '3') + goto out; + + if (OCTEON_IS_OCTEON1PLUS() || OCTEON_IS_OCTEON2()) { int fuse_base = 384 / 8; if (family[0] == '6') fuse_base = 832 / 8; - /* Check for model in fuses, overrides normal decode */ /* This is _not_ valid for Octeon CN3XXX models */ fuse_data |= cvmx_fuse_read_byte(fuse_base + 3); @@ -486,7 +488,52 @@ static const char *__init octeon_model_get_string_buffer(uint32_t chip_id, family = fuse_model; } } + } else { + /* Format for Octeon 3. */ + fuse_data = cvmx_read_csr(CVMX_MIO_FUS_PDF); + if (fuse_data & ((1ULL << 48) - 1)) { + char suffix_str[4] = {0}; + char fuse_suffix[4] = {0}; + int i; + int model = fuse_data & ((1ULL << 17) - 1); + int suf_bits = (fuse_data >> 17) & ((1ULL << 15) - 1); + for (i = 0; i < 3; i++) { + /* A-Z are encoded 1-26, 27-31 are + reserved values. */ + if ((suf_bits & 0x1f) && (suf_bits & 0x1f) <= 26) + suffix_str[i] = 'A' + (suf_bits & 0x1f) - 1; + suf_bits = suf_bits >> 5; + } + if (strlen(suffix_str) && model) { /* Have both number and suffix in fuses, so both */ + sprintf(fuse_model, "%d%s", model, suffix_str); + core_model = ""; + family = fuse_model; + } else if (strlen(suffix_str) && !model) { /* Only have suffix, so add suffix to 'normal' model number */ + sprintf(fuse_model, "%s%s", core_model, suffix_str); + core_model = fuse_model; + } else if (model) { /* Don't have suffix, so just use model from fuses */ + sprintf(fuse_model, "%d", model); + core_model = ""; + family = fuse_model; + } + /* in case of invalid model suffix bits + only set, we do nothing. */ + + /* Check to see if we have a custom type + suffix. */ + suf_bits = (fuse_data >> 33) & ((1ULL << 15) - 1); + for (i = 0; i < 3; i++) { + /* A-Z are encoded 1-26, 27-31 are + reserved values. */ + if ((suf_bits & 0x1f) && (suf_bits & 0x1f) <= 26) + fuse_suffix[i] = 'A' + (suf_bits & 0x1f) - 1; + suf_bits = suf_bits >> 5; + } + if (strlen(fuse_suffix)) + suffix = fuse_suffix; + } } +out: sprintf(buffer, "CN%s%sp%s-%d-%s", family, core_model, pass, clock_mhz, suffix); return buffer; } -- 2.1.4