uboot/board/ti/common/board_detect.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0+ */
   2/*
   3 * Library to support early TI EVM EEPROM handling
   4 *
   5 * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com
   6 */
   7
   8#ifndef __BOARD_DETECT_H
   9#define __BOARD_DETECT_H
  10
  11/* TI EEPROM MAGIC Header identifier */
  12#include <linux/bitops.h>
  13#define TI_EEPROM_HEADER_MAGIC  0xEE3355AA
  14#define TI_DEAD_EEPROM_MAGIC    0xADEAD12C
  15
  16#define TI_EEPROM_HDR_NAME_LEN          8
  17#define TI_EEPROM_HDR_REV_LEN           4
  18#define TI_EEPROM_HDR_SERIAL_LEN        12
  19#define TI_EEPROM_HDR_CONFIG_LEN        32
  20#define TI_EEPROM_HDR_NO_OF_MAC_ADDR    3
  21#define TI_EEPROM_HDR_ETH_ALEN          6
  22
  23/**
  24 * struct ti_am_eeprom - This structure holds data read in from the
  25 *                     AM335x, AM437x, AM57xx TI EVM EEPROMs.
  26 * @header: This holds the magic number
  27 * @name: The name of the board
  28 * @version: Board revision
  29 * @serial: Board serial number
  30 * @config: Reserved
  31 * @mac_addr: Any MAC addresses written in the EEPROM
  32 *
  33 * The data is this structure is read from the EEPROM on the board.
  34 * It is used for board detection which is based on name. It is used
  35 * to configure specific TI boards. This allows booting of multiple
  36 * TI boards with a single MLO and u-boot.
  37 */
  38struct ti_am_eeprom {
  39        unsigned int header;
  40        char name[TI_EEPROM_HDR_NAME_LEN];
  41        char version[TI_EEPROM_HDR_REV_LEN];
  42        char serial[TI_EEPROM_HDR_SERIAL_LEN];
  43        char config[TI_EEPROM_HDR_CONFIG_LEN];
  44        char mac_addr[TI_EEPROM_HDR_NO_OF_MAC_ADDR][TI_EEPROM_HDR_ETH_ALEN];
  45} __attribute__ ((__packed__));
  46
  47/* AM6x TI EVM EEPROM Definitions */
  48#define TI_AM6_EEPROM_RECORD_BOARD_ID           0x01
  49#define TI_AM6_EEPROM_RECORD_BOARD_INFO         0x10
  50#define TI_AM6_EEPROM_RECORD_DDR_INFO           0x11
  51#define TI_AM6_EEPROM_RECORD_DDR_SPD            0x12
  52#define TI_AM6_EEPROM_RECORD_MAC_INFO           0x13
  53#define TI_AM6_EEPROM_RECORD_END_LIST           0xFE
  54
  55/*
  56 * Common header for AM6x TI EVM EEPROM records. Used to encapsulate the config
  57 * EEPROM in its entirety as well as for individual records contained within.
  58 */
  59struct ti_am6_eeprom_record_header {
  60        u8 id;
  61        u16 len;
  62} __attribute__ ((__packed__));
  63
  64/* AM6x TI EVM EEPROM board ID structure */
  65struct ti_am6_eeprom_record_board_id {
  66        u32 magic_number;
  67        struct ti_am6_eeprom_record_header header;
  68} __attribute__ ((__packed__));
  69
  70/* AM6x TI EVM EEPROM board info structure */
  71#define AM6_EEPROM_HDR_NAME_LEN                 16
  72#define AM6_EEPROM_HDR_VERSION_LEN              2
  73#define AM6_EEPROM_HDR_PROC_NR_LEN              4
  74#define AM6_EEPROM_HDR_VARIANT_LEN              2
  75#define AM6_EEPROM_HDR_PCB_REV_LEN              2
  76#define AM6_EEPROM_HDR_SCH_BOM_REV_LEN          2
  77#define AM6_EEPROM_HDR_SW_REV_LEN               2
  78#define AM6_EEPROM_HDR_VID_LEN                  2
  79#define AM6_EEPROM_HDR_BLD_WK_LEN               2
  80#define AM6_EEPROM_HDR_BLD_YR_LEN               2
  81#define AM6_EEPROM_HDR_4P_NR_LEN                6
  82#define AM6_EEPROM_HDR_SERIAL_LEN               4
  83
  84struct ti_am6_eeprom_record_board_info {
  85        char name[AM6_EEPROM_HDR_NAME_LEN];
  86        char version[AM6_EEPROM_HDR_VERSION_LEN];
  87        char proc_number[AM6_EEPROM_HDR_PROC_NR_LEN];
  88        char variant[AM6_EEPROM_HDR_VARIANT_LEN];
  89        char pcb_revision[AM6_EEPROM_HDR_PCB_REV_LEN];
  90        char schematic_bom_revision[AM6_EEPROM_HDR_SCH_BOM_REV_LEN];
  91        char software_revision[AM6_EEPROM_HDR_SW_REV_LEN];
  92        char vendor_id[AM6_EEPROM_HDR_VID_LEN];
  93        char build_week[AM6_EEPROM_HDR_BLD_WK_LEN];
  94        char build_year[AM6_EEPROM_HDR_BLD_YR_LEN];
  95        char board_4p_number[AM6_EEPROM_HDR_4P_NR_LEN];
  96        char serial[AM6_EEPROM_HDR_SERIAL_LEN];
  97} __attribute__ ((__packed__));
  98
  99/* Memory location to keep a copy of the AM6 board info record */
 100#define TI_AM6_EEPROM_BD_INFO_DATA ((struct ti_am6_eeprom_record_board_info *) \
 101                                             TI_SRAM_SCRATCH_BOARD_EEPROM_START)
 102
 103/* AM6x TI EVM EEPROM DDR info structure */
 104#define TI_AM6_EEPROM_DDR_CTRL_INSTANCE_MASK            GENMASK(1, 0)
 105#define TI_AM6_EEPROM_DDR_CTRL_INSTANCE_SHIFT           0
 106#define TI_AM6_EEPROM_DDR_CTRL_SPD_DATA_LOC_MASK        GENMASK(3, 2)
 107#define TI_AM6_EEPROM_DDR_CTRL_SPD_DATA_LOC_NA          (0 << 2)
 108#define TI_AM6_EEPROM_DDR_CTRL_SPD_DATA_LOC_BOARDID     (2 << 2)
 109#define TI_AM6_EEPROM_DDR_CTRL_SPD_DATA_LOC_I2C51       (3 << 2)
 110#define TI_AM6_EEPROM_DDR_CTRL_MEM_TYPE_MASK            GENMASK(5, 4)
 111#define TI_AM6_EEPROM_DDR_CTRL_MEM_TYPE_DDR3            (0 << 4)
 112#define TI_AM6_EEPROM_DDR_CTRL_MEM_TYPE_DDR4            (1 << 4)
 113#define TI_AM6_EEPROM_DDR_CTRL_MEM_TYPE_LPDDR4          (2 << 4)
 114#define TI_AM6_EEPROM_DDR_CTRL_IF_DATA_WIDTH_MASK       GENMASK(7, 6)
 115#define TI_AM6_EEPROM_DDR_CTRL_IF_DATA_WIDTH_16         (0 << 6)
 116#define TI_AM6_EEPROM_DDR_CTRL_IF_DATA_WIDTH_32         (1 << 6)
 117#define TI_AM6_EEPROM_DDR_CTRL_IF_DATA_WIDTH_64         (2 << 6)
 118#define TI_AM6_EEPROM_DDR_CTRL_DEV_DATA_WIDTH_MASK      GENMASK(9, 8)
 119#define TI_AM6_EEPROM_DDR_CTRL_DEV_DATA_WIDTH_8         (0 << 8)
 120#define TI_AM6_EEPROM_DDR_CTRL_DEV_DATA_WIDTH_16        (1 << 8)
 121#define TI_AM6_EEPROM_DDR_CTRL_DEV_DATA_WIDTH_32        (2 << 8)
 122#define TI_AM6_EEPROM_DDR_CTRL_RANKS_2                  BIT(10)
 123#define TI_AM6_EEPROM_DDR_CTRL_DENS_MASK                GENMASK(13, 11)
 124#define TI_AM6_EEPROM_DDR_CTRL_DENS_1GB                 (0 << 11)
 125#define TI_AM6_EEPROM_DDR_CTRL_DENS_2GB                 (1 << 11)
 126#define TI_AM6_EEPROM_DDR_CTRL_DENS_4GB                 (2 << 11)
 127#define TI_AM6_EEPROM_DDR_CTRL_DENS_8GB                 (3 << 11)
 128#define TI_AM6_EEPROM_DDR_CTRL_DENS_12GB                (4 << 11)
 129#define TI_AM6_EEPROM_DDR_CTRL_DENS_16GB                (5 << 11)
 130#define TI_AM6_EEPROM_DDR_CTRL_DENS_24GB                (6 << 11)
 131#define TI_AM6_EEPROM_DDR_CTRL_DENS_32GB                (7 << 11)
 132#define TI_AM6_EEPROM_DDR_CTRL_ECC                      BIT(14)
 133
 134struct ti_am6_eeprom_record_ddr_info {
 135        u16 ddr_control;
 136} __attribute__ ((__packed__));
 137
 138/* AM6x TI EVM EEPROM DDR SPD structure */
 139#define TI_AM6_EEPROM_DDR_SPD_INSTANCE_MASK             GENMASK(1, 0)
 140#define TI_AM6_EEPROM_DDR_SPD_INSTANCE_SHIFT            0
 141#define TI_AM6_EEPROM_DDR_SPD_MEM_TYPE_MASK             GENMASK(4, 3)
 142#define TI_AM6_EEPROM_DDR_SPD_MEM_TYPE_DDR3             (0 << 3)
 143#define TI_AM6_EEPROM_DDR_SPD_MEM_TYPE_DDR4             (1 << 3)
 144#define TI_AM6_EEPROM_DDR_SPD_MEM_TYPE_LPDDR4           (2 << 3)
 145#define TI_AM6_EEPROM_DDR_SPD_DATA_LEN                  512
 146
 147struct ti_am6_eeprom_record_ddr_spd {
 148        u16 spd_control;
 149        u8 data[TI_AM6_EEPROM_DDR_SPD_DATA_LEN];
 150} __attribute__ ((__packed__));
 151
 152/* AM6x TI EVM EEPROM MAC info structure */
 153#define TI_AM6_EEPROM_MAC_INFO_INSTANCE_MASK            GENMASK(2, 0)
 154#define TI_AM6_EEPROM_MAC_INFO_INSTANCE_SHIFT           0
 155#define TI_AM6_EEPROM_MAC_ADDR_COUNT_MASK               GENMASK(7, 3)
 156#define TI_AM6_EEPROM_MAC_ADDR_COUNT_SHIFT              3
 157#define TI_AM6_EEPROM_MAC_ADDR_MAX_COUNT                32
 158
 159struct ti_am6_eeprom_record_mac_info {
 160        u16 mac_control;
 161        u8 mac_addr[TI_AM6_EEPROM_MAC_ADDR_MAX_COUNT][TI_EEPROM_HDR_ETH_ALEN];
 162} __attribute__ ((__packed__));
 163
 164struct ti_am6_eeprom_record {
 165        struct ti_am6_eeprom_record_header header;
 166        union {
 167                struct ti_am6_eeprom_record_board_info board_info;
 168                struct ti_am6_eeprom_record_ddr_info ddr_info;
 169                struct ti_am6_eeprom_record_ddr_spd ddr_spd;
 170                struct ti_am6_eeprom_record_mac_info mac_info;
 171        } data;
 172} __attribute__ ((__packed__));
 173
 174/* DRA7 EEPROM MAGIC Header identifier */
 175#define DRA7_EEPROM_HEADER_MAGIC        0xAA5533EE
 176#define DRA7_EEPROM_HDR_NAME_LEN        16
 177#define DRA7_EEPROM_HDR_CONFIG_LEN      4
 178
 179/**
 180 * struct dra7_eeprom - This structure holds data read in from the DRA7 EVM
 181 *                      EEPROMs.
 182 * @header: This holds the magic number
 183 * @name: The name of the board
 184 * @version_major: Board major version
 185 * @version_minor: Board minor version
 186 * @config: Board specific config options
 187 * @emif1_size: Size of DDR attached to EMIF1
 188 * @emif2_size: Size of DDR attached to EMIF2
 189 *
 190 * The data is this structure is read from the EEPROM on the board.
 191 * It is used for board detection which is based on name. It is used
 192 * to configure specific DRA7 boards. This allows booting of multiple
 193 * DRA7 boards with a single MLO and u-boot.
 194 */
 195struct dra7_eeprom {
 196        u32 header;
 197        char name[DRA7_EEPROM_HDR_NAME_LEN];
 198        u16 version_major;
 199        u16 version_minor;
 200        char config[DRA7_EEPROM_HDR_CONFIG_LEN];
 201        u32 emif1_size;
 202        u32 emif2_size;
 203} __attribute__ ((__packed__));
 204
 205/**
 206 * struct ti_common_eeprom - Null terminated, usable EEPROM contents.
 207 * header:      Magic number
 208 * @name:       NULL terminated name
 209 * @version:    NULL terminated version
 210 * @serial:     NULL terminated serial number
 211 * @config:     NULL terminated Board specific config options
 212 * @mac_addr:   MAC addresses
 213 * @emif1_size: Size of the ddr available on emif1
 214 * @emif2_size: Size of the ddr available on emif2
 215 */
 216struct ti_common_eeprom {
 217        u32 header;
 218        char name[TI_EEPROM_HDR_NAME_LEN + 1];
 219        char version[TI_EEPROM_HDR_REV_LEN + 1];
 220        char serial[TI_EEPROM_HDR_SERIAL_LEN + 1];
 221        char config[TI_EEPROM_HDR_CONFIG_LEN + 1];
 222        char mac_addr[TI_EEPROM_HDR_NO_OF_MAC_ADDR][TI_EEPROM_HDR_ETH_ALEN];
 223        u64 emif1_size;
 224        u64 emif2_size;
 225};
 226
 227#define TI_EEPROM_DATA ((struct ti_common_eeprom *)\
 228                                TI_SRAM_SCRATCH_BOARD_EEPROM_START)
 229
 230/*
 231 * Maximum number of Ethernet MAC addresses extracted from the AM6x on-board
 232 * EEPROM during the initial probe and carried forward in SRAM.
 233 */
 234#define AM6_EEPROM_HDR_NO_OF_MAC_ADDR   8
 235
 236/**
 237 * struct ti_am6_eeprom - Null terminated, usable EEPROM contents, as extracted
 238 *      from the AM6 on-board EEPROM. Note that we only carry a subset of data
 239 *      at this time to be considerate about memory consumption.
 240 * @header:             Magic number for data validity indication
 241 * @name:               NULL terminated name
 242 * @version:            NULL terminated version
 243 * @software_revision:  NULL terminated software revision
 244 * @serial:             Board serial number
 245 * @mac_addr_cnt:       Number of MAC addresses stored in this object
 246 * @mac_addr:           MAC addresses
 247 */
 248struct ti_am6_eeprom {
 249        u32 header;
 250        char name[AM6_EEPROM_HDR_NAME_LEN + 1];
 251        char version[AM6_EEPROM_HDR_VERSION_LEN + 1];
 252        char software_revision[AM6_EEPROM_HDR_SW_REV_LEN + 1];
 253        char serial[AM6_EEPROM_HDR_SERIAL_LEN + 1];
 254        u8 mac_addr_cnt;
 255        char mac_addr[AM6_EEPROM_HDR_NO_OF_MAC_ADDR][TI_EEPROM_HDR_ETH_ALEN];
 256};
 257
 258#define TI_AM6_EEPROM_DATA ((struct ti_am6_eeprom *) \
 259                                TI_SRAM_SCRATCH_BOARD_EEPROM_START)
 260
 261/**
 262 * ti_i2c_eeprom_am_get() - Consolidated eeprom data collection for AM* TI EVMs
 263 * @bus_addr:   I2C bus address
 264 * @dev_addr:   I2C slave address
 265 *
 266 * ep in SRAM is populated by the this AM generic function that consolidates
 267 * the basic initialization logic common across all AM* platforms.
 268 */
 269int ti_i2c_eeprom_am_get(int bus_addr, int dev_addr);
 270
 271/**
 272 * ti_emmc_boardid_get() - Fetch board ID information from eMMC
 273 *
 274 * ep in SRAM is populated by the this function that is currently
 275 * based on BeagleBone AI, but could be made more general across AM*
 276 * platforms.
 277 */
 278int __maybe_unused ti_emmc_boardid_get(void);
 279
 280/**
 281 * ti_i2c_eeprom_dra7_get() - Consolidated eeprom data for DRA7 TI EVMs
 282 * @bus_addr:   I2C bus address
 283 * @dev_addr:   I2C slave address
 284 */
 285int ti_i2c_eeprom_dra7_get(int bus_addr, int dev_addr);
 286
 287/**
 288 * ti_i2c_eeprom_am6_get() - Consolidated eeprom data for AM6x TI EVMs and
 289 *                           associated daughter cards, parsed into user-
 290 *                           provided data structures
 291 * @bus_addr:   I2C bus address
 292 * @dev_addr:   I2C slave address
 293 * @ep:         Pointer to structure receiving AM6-specific header data
 294 * @mac_addr:   Pointer to memory receiving parsed MAC addresses. May be
 295 *              NULL to skip MAC parsing.
 296 * @mac_addr_max_cnt: Maximum number of MAC addresses that can be stored into
 297 *                    mac_addr. May be NULL to skip MAC parsing.
 298 * @mac_addr_cnt: Pointer to a location returning how many MAC addressed got
 299 *                actually parsed.
 300 */
 301int __maybe_unused ti_i2c_eeprom_am6_get(int bus_addr, int dev_addr,
 302                                         struct ti_am6_eeprom *ep,
 303                                         char **mac_addr,
 304                                         u8 mac_addr_max_cnt,
 305                                         u8 *mac_addr_cnt);
 306
 307/**
 308 * ti_i2c_eeprom_am6_get_base() - Consolidated eeprom data for AM6x TI EVMs
 309 * @bus_addr:   I2C bus address
 310 * @dev_addr:   I2C slave address
 311 */
 312int __maybe_unused ti_i2c_eeprom_am6_get_base(int bus_addr, int dev_addr);
 313
 314#ifdef CONFIG_TI_I2C_BOARD_DETECT
 315/**
 316 * board_ti_is() - Board detection logic for TI EVMs
 317 * @name_tag:   Tag used in eeprom for the board
 318 *
 319 * Return: false if board information does not match OR eeprom wasn't read.
 320 *         true otherwise
 321 */
 322bool board_ti_is(char *name_tag);
 323
 324/**
 325 * board_ti_k3_is() - Board detection logic for TI K3 EVMs
 326 * @name_tag:   Tag used in eeprom for the board
 327 *
 328 * Return: false if board information does not match OR eeprom wasn't read.
 329 *         true otherwise
 330 */
 331bool board_ti_k3_is(char *name_tag);
 332
 333/**
 334 * board_ti_rev_is() - Compare board revision for TI EVMs
 335 * @rev_tag:    Revision tag to check in eeprom
 336 * @cmp_len:    How many chars to compare?
 337 *
 338 * NOTE: revision information is often messed up (hence the str len match) :(
 339 *
 340 * Return: false if board information does not match OR eeprom wasn't read.
 341 *         true otherwise
 342 */
 343bool board_ti_rev_is(char *rev_tag, int cmp_len);
 344
 345/**
 346 * board_ti_get_rev() - Get board revision for TI EVMs
 347 *
 348 * Return: Empty string if eeprom wasn't read.
 349 *         Board revision otherwise
 350 */
 351char *board_ti_get_rev(void);
 352
 353/**
 354 * board_ti_get_config() - Get board config for TI EVMs
 355 *
 356 * Return: Empty string if eeprom wasn't read.
 357 *         Board config otherwise
 358 */
 359char *board_ti_get_config(void);
 360
 361/**
 362 * board_ti_get_name() - Get board name for TI EVMs
 363 *
 364 * Return: Empty string if eeprom wasn't read.
 365 *         Board name otherwise
 366 */
 367char *board_ti_get_name(void);
 368
 369/**
 370 * board_ti_get_eth_mac_addr() - Get Ethernet MAC address from EEPROM MAC list
 371 * @index:      0 based index within the list of MAC addresses
 372 * @mac_addr:   MAC address contained at the index is returned here
 373 *
 374 * Does not sanity check the mac_addr. Whatever is stored in EEPROM is returned.
 375 */
 376void board_ti_get_eth_mac_addr(int index, u8 mac_addr[TI_EEPROM_HDR_ETH_ALEN]);
 377
 378/**
 379 * board_ti_get_emif1_size() - Get size of the DDR on emif1 for TI EVMs
 380 *
 381 * Return: NULL if eeprom wasn't read or emif1_size is not available.
 382 */
 383u64 board_ti_get_emif1_size(void);
 384
 385/**
 386 * board_ti_get_emif2_size() - Get size of the DDR on emif2 for TI EVMs
 387 *
 388 * Return: NULL if eeprom wasn't read or emif2_size is not available.
 389 */
 390u64 board_ti_get_emif2_size(void);
 391
 392/**
 393 * set_board_info_env() - Setup commonly used board information environment vars
 394 * @name:       Name of the board
 395 *
 396 * If name is NULL, default_name is used.
 397 */
 398void set_board_info_env(char *name);
 399
 400/**
 401 * set_board_info_env_am6() - Setup commonly used board information environment
 402 *                            vars for AM6-type boards
 403 * @name:       Name of the board
 404 *
 405 * If name is NULL, default_name is used.
 406 */
 407void set_board_info_env_am6(char *name);
 408
 409/**
 410 * board_ti_set_ethaddr- Sets the ethaddr environment from EEPROM
 411 * @index: The first eth<index>addr environment variable to set
 412 *
 413 * EEPROM should be already read before calling this function.
 414 * The EEPROM contains 2 MAC addresses which define the MAC address
 415 * range (i.e. first and last MAC address).
 416 * This function sets the ethaddr environment variable for all
 417 * the available MAC addresses starting from eth<index>addr.
 418 */
 419void board_ti_set_ethaddr(int index);
 420
 421/**
 422 * board_ti_am6_set_ethaddr- Sets the ethaddr environment from EEPROM
 423 * @index: The first eth<index>addr environment variable to set
 424 * @count: The number of MAC addresses to process
 425 *
 426 * EEPROM should be already read before calling this function. The EEPROM
 427 * contains n dedicated MAC addresses. This function sets the ethaddr
 428 * environment variable for all the available MAC addresses starting
 429 * from eth<index>addr.
 430 */
 431void board_ti_am6_set_ethaddr(int index, int count);
 432
 433/**
 434 * board_ti_was_eeprom_read() - Check to see if the eeprom contents have been read
 435 *
 436 * This function is useful to determine if the eeprom has already been read and
 437 * its contents have already been loaded into memory. It utiltzes the magic
 438 * number that the header value is set to upon successful eeprom read.
 439 */
 440bool board_ti_was_eeprom_read(void);
 441
 442/**
 443 * ti_i2c_eeprom_am_set() - Setup the eeprom data with predefined values
 444 * @name:       Name of the board
 445 * @rev:        Revision of the board
 446 *
 447 * In some cases such as in RTC-only mode, we are able to skip reading eeprom
 448 * and wasting i2c based initialization time by using predefined flags for
 449 * detecting what platform we are booting on. For those platforms, provide
 450 * a handy function to pre-program information.
 451 *
 452 * NOTE: many eeprom information such as serial number, mac address etc is not
 453 * available.
 454 *
 455 * Return: 0 if all went fine, else return error.
 456 */
 457int ti_i2c_eeprom_am_set(const char *name, const char *rev);
 458#else
 459static inline bool board_ti_is(char *name_tag) { return false; };
 460static inline bool board_ti_k3_is(char *name_tag) { return false; };
 461static inline bool board_ti_rev_is(char *rev_tag, int cmp_len)
 462{ return false; };
 463static inline char *board_ti_get_rev(void) { return NULL; };
 464static inline char *board_ti_get_config(void) { return NULL; };
 465static inline char *board_ti_get_name(void) { return NULL; };
 466static inline bool board_ti_was_eeprom_read(void) { return false; };
 467static inline int ti_i2c_eeprom_am_set(const char *name, const char *rev)
 468{ return -EINVAL; };
 469#endif
 470
 471#endif  /* __BOARD_DETECT_H */
 472