uboot/drivers/ram/octeon/dimm_spd_eeprom.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (C) 2020 Marvell International Ltd.
   4 */
   5
   6#include <i2c.h>
   7#include <ram.h>
   8
   9#include <mach/octeon_ddr.h>
  10
  11#define DEVICE_TYPE     DDR4_SPD_KEY_BYTE_DEVICE_TYPE // same for DDR3 and DDR4
  12#define MODULE_TYPE     DDR4_SPD_KEY_BYTE_MODULE_TYPE // same for DDR3 and DDR4
  13#define BUS_WIDTH(t)    (((t) == DDR4_DRAM) ?               \
  14                         DDR4_SPD_MODULE_MEMORY_BUS_WIDTH : \
  15                         DDR3_SPD_MEMORY_BUS_WIDTH)
  16
  17/*
  18 * Allow legacy code to encode bus number in the upper bits of the address
  19 * These are only supported in read_spd()
  20 */
  21#define OCTEON_TWSI_BUS_IN_ADDR_BIT       12
  22#define OCTEON_TWSI_BUS_IN_ADDR_MASK      (15 << OCTEON_TWSI_BUS_IN_ADDR_BIT)
  23#define OCTEON_TWSI_GET_BUS(addr)                       \
  24        (((addr) >> OCTEON_TWSI_BUS_IN_ADDR_BIT) & 0xf)
  25
  26const char *ddr3_dimm_types[] = {
  27        /* 0000 */ "Undefined",
  28        /* 0001 */ "RDIMM",
  29        /* 0010 */ "UDIMM",
  30        /* 0011 */ "SO-DIMM",
  31        /* 0100 */ "Micro-DIMM",
  32        /* 0101 */ "Mini-RDIMM",
  33        /* 0110 */ "Mini-UDIMM",
  34        /* 0111 */ "Mini-CDIMM",
  35        /* 1000 */ "72b-SO-UDIMM",
  36        /* 1001 */ "72b-SO-RDIMM",
  37        /* 1010 */ "72b-SO-CDIMM"
  38        /* 1011 */ "LRDIMM",
  39        /* 1100 */ "16b-SO-DIMM",
  40        /* 1101 */ "32b-SO-DIMM",
  41        /* 1110 */ "Reserved",
  42        /* 1111 */ "Reserved"
  43};
  44
  45const char *ddr4_dimm_types[] = {
  46        /* 0000 */ "Extended",
  47        /* 0001 */ "RDIMM",
  48        /* 0010 */ "UDIMM",
  49        /* 0011 */ "SO-DIMM",
  50        /* 0100 */ "LRDIMM",
  51        /* 0101 */ "Mini-RDIMM",
  52        /* 0110 */ "Mini-UDIMM",
  53        /* 0111 */ "Reserved",
  54        /* 1000 */ "72b-SO-RDIMM",
  55        /* 1001 */ "72b-SO-UDIMM",
  56        /* 1010 */ "Reserved",
  57        /* 1011 */ "Reserved",
  58        /* 1100 */ "16b-SO-DIMM",
  59        /* 1101 */ "32b-SO-DIMM",
  60        /* 1110 */ "Reserved",
  61        /* 1111 */ "Reserved"
  62};
  63
  64static u16 ddr3_crc16(u8 *ptr, int count)
  65{
  66        /* From DDR3 SPD specification */
  67        int crc, i;
  68
  69        crc = 0;
  70        while (--count >= 0) {
  71                crc = crc ^ (int)*ptr++ << 8;
  72                for (i = 0; i < 8; ++i) {
  73                        if (crc & 0x8000)
  74                                crc = crc << 1 ^ 0x1021;
  75                        else
  76                                crc = crc << 1;
  77                }
  78        }
  79
  80        return (crc & 0xFFFF);
  81}
  82
  83static int validate_spd_checksum_ddr4(struct dimm_config *dimm_config,
  84                                      int dimm_index, int twsi_addr, int silent)
  85{
  86        u8 *spd_data = dimm_config->spd_data[dimm_index];
  87        int crc_bytes = 126;
  88        u16 crc_comp;
  89
  90        /* Check byte 0 to see how many bytes checksum is over */
  91        if (spd_data[0] & 0x80)
  92                crc_bytes = 117;
  93
  94        crc_comp = ddr3_crc16(spd_data, crc_bytes);
  95
  96        if (spd_data[126] == (crc_comp & 0xff) &&
  97            spd_data[127] == (crc_comp >> 8))
  98                return 1;
  99
 100        if (!silent) {
 101                printf("DDR4 SPD CRC error, spd addr: 0x%x, calculated crc: 0x%04x, read crc: 0x%02x%02x\n",
 102                       twsi_addr, crc_comp, spd_data[127], spd_data[126]);
 103        }
 104
 105        return 0;
 106}
 107
 108static int validate_spd_checksum(struct ddr_priv *priv,
 109                                 struct dimm_config *dimm_config,
 110                                 int dimm_index, int twsi_addr,
 111                                 int silent, u8 rv)
 112{
 113        if (ddr_verbose(priv))
 114                debug("Validating DIMM at address 0x%x\n", twsi_addr);
 115
 116        if (rv >= 0x8 && rv <= 0xA)
 117                printf("%s: Error: DDR2 support disabled\n", __func__);
 118
 119        if (rv == 0xB)
 120                printf("%s: Error: DDR3 support disabled\n", __func__);
 121
 122        if (rv == 0xC) {
 123                return validate_spd_checksum_ddr4(dimm_config, dimm_index,
 124                                                  twsi_addr, silent);
 125        }
 126
 127        if (!silent) {
 128                printf("Unrecognized DIMM type: 0x%x at spd address: 0x%x\n",
 129                       rv, twsi_addr);
 130        }
 131
 132        return 0;
 133}
 134
 135/*
 136 * Read an DIMM SPD value, either using TWSI to read it from the DIMM, or
 137 * from a provided array.
 138 */
 139int read_spd(struct dimm_config *dimm_config, int dimm_index, int spd_field)
 140{
 141        dimm_index = !!dimm_index;
 142
 143        if (spd_field >= SPD_EEPROM_SIZE) {
 144                printf("ERROR: Trying to read unsupported SPD EEPROM value %d\n",
 145                       spd_field);
 146        }
 147
 148        /*
 149         * If pointer to data is provided, use it, otherwise read from SPD
 150         * over twsi
 151         */
 152        if (dimm_config->spd_ptrs[dimm_index])
 153                return dimm_config->spd_ptrs[dimm_index][spd_field];
 154        else if (dimm_config->spd_addrs[dimm_index])
 155                return dimm_config->spd_data[dimm_index][spd_field];
 156
 157        return -1;
 158}
 159
 160int read_spd_init(struct dimm_config *dimm_config, int dimm_index)
 161{
 162        u8 busno = OCTEON_TWSI_GET_BUS(dimm_config->spd_addrs[dimm_index]);
 163        u8 cmdno = dimm_config->spd_addrs[dimm_index];
 164        struct udevice *dev_i2c;
 165        u8 *spd_data;
 166        int ret;
 167
 168        if (dimm_config->spd_cached[dimm_index])
 169                return 0;
 170
 171        dimm_config->spd_cached[dimm_index] = 1;
 172        spd_data = dimm_config->spd_data[dimm_index];
 173
 174        ret = i2c_get_chip_for_busnum(busno, cmdno, 2, &dev_i2c);
 175        if (ret) {
 176                debug("Cannot find SPL EEPROM: %d\n", ret);
 177                return -ENODEV;
 178        }
 179
 180        ret = dm_i2c_read(dev_i2c, 0, spd_data, SPD_EEPROM_SIZE);
 181
 182        return ret;
 183}
 184
 185int validate_dimm(struct ddr_priv *priv, struct dimm_config *dimm_config,
 186                  int dimm_index)
 187{
 188        int spd_addr;
 189
 190        dimm_index = !!dimm_index;  /* Normalize to 0/1 */
 191        spd_addr = dimm_config->spd_addrs[dimm_index];
 192
 193        debug("Validating dimm %d, spd addr: 0x%02x spd ptr: %p\n",
 194              dimm_index,
 195              dimm_config->spd_addrs[dimm_index],
 196              dimm_config->spd_ptrs[dimm_index]);
 197
 198        /* Only validate 'real' dimms, assume compiled in values are OK */
 199        if (!dimm_config->spd_ptrs[dimm_index]) {
 200                int val0, val1;
 201                int dimm_type;
 202                int ret;
 203
 204                ret = read_spd_init(dimm_config, dimm_index);
 205                if (ret)
 206                        return 0;
 207
 208                dimm_type = read_spd(dimm_config, dimm_index,
 209                                     DDR2_SPD_MEM_TYPE) & 0xff;
 210                switch (dimm_type) {
 211                case 0x0B:              /* DDR3 */
 212                        if (ddr_verbose(priv))
 213                                printf("Validating DDR3 DIMM %d\n", dimm_index);
 214                        val0 = read_spd(dimm_config, dimm_index,
 215                                        DDR3_SPD_DENSITY_BANKS);
 216                        val1 = read_spd(dimm_config, dimm_index,
 217                                        DDR3_SPD_ADDRESSING_ROW_COL_BITS);
 218                        if (val0 < 0 && val1 < 0) {
 219                                if (ddr_verbose(priv))
 220                                        printf("Error reading SPD for DIMM %d\n",
 221                                               dimm_index);
 222                                return 0; /* Failed to read dimm */
 223                        }
 224                        if (val0 == 0xff && val1 == 0xff) {
 225                                if (ddr_verbose(priv))
 226                                        printf("Blank or unreadable SPD for DIMM %d\n",
 227                                               dimm_index);
 228                                /* Blank SPD or otherwise unreadable device */
 229                                return 0;
 230                        }
 231
 232                        /* Don't treat bad checksums as fatal */
 233                        validate_spd_checksum(priv, dimm_config, dimm_index,
 234                                              spd_addr, 0, dimm_type);
 235                        break;
 236
 237                case 0x0C:              /* DDR4 */
 238                        if (ddr_verbose(priv))
 239                                printf("Validating DDR4 DIMM %d\n", dimm_index);
 240                        val0 = read_spd(dimm_config, dimm_index,
 241                                        DDR4_SPD_DENSITY_BANKS);
 242                        val1 = read_spd(dimm_config, dimm_index,
 243                                        DDR4_SPD_ADDRESSING_ROW_COL_BITS);
 244                        if (val0 < 0 && val1 < 0) {
 245                                if (ddr_verbose(priv))
 246                                        printf("Error reading SPD for DIMM %d\n",
 247                                               dimm_index);
 248                                return 0; /* Failed to read dimm */
 249                        }
 250                        if (val0 == 0xff && val1 == 0xff) {
 251                                if (ddr_verbose(priv)) {
 252                                        printf("Blank or unreadable SPD for DIMM %d\n",
 253                                               dimm_index);
 254                                }
 255                                /* Blank SPD or otherwise unreadable device */
 256                                return 0;
 257                        }
 258
 259                        /* Don't treat bad checksums as fatal */
 260                        validate_spd_checksum(priv, dimm_config, dimm_index,
 261                                              spd_addr, 0, dimm_type);
 262                        break;
 263
 264                case 0x00:
 265                        /* Terminator detected. Fail silently. */
 266                        return 0;
 267
 268                default:
 269                        debug("Unknown DIMM type 0x%x for DIMM %d @ 0x%x\n",
 270                              dimm_type, dimm_index,
 271                              dimm_config->spd_addrs[dimm_index]);
 272                        return 0;      /* Failed to read dimm */
 273                }
 274        }
 275
 276        return 1;
 277}
 278
 279int get_ddr_type(struct dimm_config *dimm_config, int upper_dimm)
 280{
 281        int spd_ddr_type;
 282
 283        spd_ddr_type = read_spd(dimm_config, upper_dimm, DEVICE_TYPE);
 284
 285        debug("%s:%d spd_ddr_type=0x%02x\n", __func__, __LINE__,
 286              spd_ddr_type);
 287
 288        /* we return only DDR4 or DDR3 */
 289        return (spd_ddr_type == 0x0C) ? DDR4_DRAM : DDR3_DRAM;
 290}
 291
 292static int get_dimm_ecc(struct dimm_config *dimm_config, int upper_dimm,
 293                        int ddr_type)
 294{
 295        return !!(read_spd(dimm_config, upper_dimm, BUS_WIDTH(ddr_type)) & 8);
 296}
 297
 298int get_dimm_module_type(struct dimm_config *dimm_config, int upper_dimm,
 299                         int ddr_type)
 300{
 301        return read_spd(dimm_config, upper_dimm, MODULE_TYPE) & 0x0f;
 302}
 303
 304char *printable_rank_spec(char *buffer, int num_ranks, int dram_width,
 305                          int spd_package)
 306{
 307        int die_count = ((spd_package >> 4) & 7) + 1;
 308
 309        if (spd_package & 0x80) { // non-monolithic
 310                if ((spd_package & 3) == 2) { // 3DS
 311                        sprintf(buffer, "%dS%dRx%d", num_ranks, die_count,
 312                                dram_width);
 313                } else { // MLS
 314                        char hchar = (die_count == 2) ? 'D' : 'Q';
 315
 316                        sprintf(buffer, "%d%cRx%d", num_ranks, hchar,
 317                                dram_width);
 318                }
 319        } else {
 320                sprintf(buffer, "%dRx%d", num_ranks, dram_width);
 321        }
 322
 323        return buffer;
 324}
 325
 326static void report_common_dimm(struct dimm_config *dimm_config, int upper_dimm,
 327                               int dimm, const char **dimm_types, int ddr_type,
 328                               char *volt_str, int if_num,
 329                               int num_ranks, int dram_width, int spd_package)
 330{
 331        unsigned int spd_module_type;
 332        char rank_spec[8];
 333        int spd_ecc;
 334
 335        spd_module_type = get_dimm_module_type(dimm_config, upper_dimm,
 336                                               ddr_type);
 337        spd_ecc = get_dimm_ecc(dimm_config, upper_dimm, ddr_type);
 338
 339        printable_rank_spec(rank_spec, num_ranks, dram_width, spd_package);
 340        printf("LMC%d.DIMM%d: DDR%d %s %s %s, %s\n",
 341               if_num, dimm, ddr_type, dimm_types[spd_module_type],
 342               rank_spec, spd_ecc ? "ECC" : "non-ECC", volt_str);
 343}
 344
 345static void report_ddr3_dimm(struct dimm_config *dimm_config, int upper_dimm,
 346                             int dimm, int if_num)
 347{
 348        int spd_voltage;
 349        char *volt_str;
 350        int spd_org = read_spd(dimm_config, upper_dimm,
 351                               DDR3_SPD_MODULE_ORGANIZATION);
 352        int num_ranks = 1 +  ((spd_org >> 3) & 0x7);
 353        int dram_width = 4 << ((spd_org >> 0) & 0x7);
 354
 355        spd_voltage = read_spd(dimm_config, upper_dimm,
 356                               DDR3_SPD_NOMINAL_VOLTAGE);
 357        if (spd_voltage == 0 || spd_voltage & 3)
 358                volt_str = "1.5V";
 359        if (spd_voltage & 2)
 360                volt_str = "1.35V";
 361        if (spd_voltage & 4)
 362                volt_str = "1.2xV";
 363
 364        report_common_dimm(dimm_config, upper_dimm, dimm, ddr3_dimm_types,
 365                           DDR3_DRAM, volt_str, if_num,
 366                           num_ranks, dram_width, /*spd_package*/0);
 367}
 368
 369static void report_ddr4_dimm(struct dimm_config *dimm_config, int upper_dimm,
 370                             int dimm, int if_num)
 371{
 372        int spd_voltage;
 373        char *volt_str;
 374        int spd_package = 0xff & read_spd(dimm_config, upper_dimm,
 375                                          DDR4_SPD_PACKAGE_TYPE);
 376        int spd_org     = 0xff & read_spd(dimm_config, upper_dimm,
 377                                          DDR4_SPD_MODULE_ORGANIZATION);
 378        int num_ranks   = 1 +  ((spd_org >> 3) & 0x7);
 379        int dram_width  = 4 << ((spd_org >> 0) & 0x7);
 380
 381        spd_voltage = read_spd(dimm_config, upper_dimm,
 382                               DDR4_SPD_MODULE_NOMINAL_VOLTAGE);
 383        if (spd_voltage == 0x01 || spd_voltage & 0x02)
 384                volt_str = "1.2V";
 385        if (spd_voltage == 0x04 || spd_voltage & 0x08)
 386                volt_str = "TBD1 V";
 387        if (spd_voltage == 0x10 || spd_voltage & 0x20)
 388                volt_str = "TBD2 V";
 389
 390        report_common_dimm(dimm_config, upper_dimm, dimm, ddr4_dimm_types,
 391                           DDR4_DRAM, volt_str, if_num,
 392                           num_ranks, dram_width, spd_package);
 393}
 394
 395void report_dimm(struct dimm_config *dimm_config, int upper_dimm,
 396                 int dimm, int if_num)
 397{
 398        int ddr_type;
 399
 400        /* ddr_type only indicates DDR4 or DDR3 */
 401        ddr_type = get_ddr_type(dimm_config, upper_dimm);
 402
 403        if (ddr_type == DDR4_DRAM)
 404                report_ddr4_dimm(dimm_config, 0, dimm, if_num);
 405        else
 406                report_ddr3_dimm(dimm_config, 0, dimm, if_num);
 407}
 408