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