11558Srgrimes// SPDX-License-Identifier: GPL-2.0+ 254263Sshin/* 31558Srgrimes * Board specific initialization for J721E EVM 41558Srgrimes * 517046Sjulian * Copyright (C) 2018-2019 Texas Instruments Incorporated - https://www.ti.com/ 61558Srgrimes * Lokesh Vutla <lokeshvutla@ti.com> 71558Srgrimes * 81558Srgrimes */ 9150679Stobez 101558Srgrimes#include <generic-phy.h> 111558Srgrimes#include <image.h> 121558Srgrimes#include <net.h> 13243185Shrs#include <asm/arch/hardware.h> 141558Srgrimes#include <asm/gpio.h> 151558Srgrimes#include <spl.h> 161558Srgrimes#include <dm.h> 171558Srgrimes 181558Srgrimes#include "../common/board_detect.h" 191558Srgrimes#include "../common/fdt_ops.h" 201558Srgrimes 211558Srgrimes#define board_is_j721e_som() (board_ti_k3_is("J721EX-PM1-SOM") || \ 221558Srgrimes board_ti_k3_is("J721EX-PM2-SOM")) 231558Srgrimes 241558Srgrimes#define board_is_j721e_sk() (board_ti_k3_is("J721EX-EAIK") || \ 2554263Sshin board_ti_k3_is("J721EX-SK")) 261558Srgrimes 271558Srgrimes#define board_is_j7200_som() (board_ti_k3_is("J7200X-PM1-SOM") || \ 2817591Sjulian board_ti_k3_is("J7200X-PM2-SOM")) 291558Srgrimes 301558Srgrimes/* Max number of MAC addresses that are parsed/processed per daughter card */ 311558Srgrimes#define DAUGHTER_CARD_NO_OF_MAC_ADDR 8 321558Srgrimes 331558SrgrimesDECLARE_GLOBAL_DATA_PTR; 341558Srgrimes 351558Srgrimesint board_init(void) 361558Srgrimes{ 37191080Skmacy return 0; 381558Srgrimes} 3954263Sshin 401558Srgrimesint dram_init(void) 411558Srgrimes{ 4278140Sru#ifdef CONFIG_PHYS_64BIT 431558Srgrimes gd->ram_size = 0x100000000; 441558Srgrimes#else 451558Srgrimes gd->ram_size = 0x80000000; 461558Srgrimes#endif 471558Srgrimes 481558Srgrimes return 0; 49191080Skmacy} 501558Srgrimes 511558Srgrimesphys_addr_t board_get_usable_ram_top(phys_size_t total_size) 52191080Skmacy{ 53191080Skmacy#ifdef CONFIG_PHYS_64BIT 541558Srgrimes /* Limit RAM used by U-Boot to the DDR low region */ 551558Srgrimes if (gd->ram_top > 0x100000000) 561558Srgrimes return 0x100000000; 57#endif 58 59 return gd->ram_top; 60} 61 62int dram_init_banksize(void) 63{ 64 /* Bank 0 declares the memory available in the DDR low region */ 65 gd->bd->bi_dram[0].start = 0x80000000; 66 gd->bd->bi_dram[0].size = 0x80000000; 67 gd->ram_size = 0x80000000; 68 69#ifdef CONFIG_PHYS_64BIT 70 /* Bank 1 declares the memory available in the DDR high region */ 71 gd->bd->bi_dram[1].start = 0x880000000; 72 gd->bd->bi_dram[1].size = 0x80000000; 73 gd->ram_size = 0x100000000; 74#endif 75 76 return 0; 77} 78 79#ifdef CONFIG_SPL_LOAD_FIT 80int board_fit_config_name_match(const char *name) 81{ 82 bool eeprom_read = board_ti_was_eeprom_read(); 83 84 if (!eeprom_read || board_is_j721e_som()) { 85 if (!strcmp(name, "k3-j721e-common-proc-board") || 86 !strcmp(name, "k3-j721e-r5-common-proc-board")) 87 return 0; 88 } else if (board_is_j721e_sk()) { 89 if (!strcmp(name, "k3-j721e-sk") || 90 !strcmp(name, "k3-j721e-r5-sk")) 91 return 0; 92 } 93 94 return -1; 95} 96#endif 97 98#if CONFIG_IS_ENABLED(DM_GPIO) && CONFIG_IS_ENABLED(OF_LIBFDT) 99/* Returns 1, if onboard mux is set to hyperflash */ 100static void __maybe_unused detect_enable_hyperflash(void *blob) 101{ 102 struct gpio_desc desc = {0}; 103 char *hypermux_sel_gpio = (board_is_j721e_som()) ? "8" : "6"; 104 105 if (dm_gpio_lookup_name(hypermux_sel_gpio, &desc)) 106 return; 107 108 if (dm_gpio_request(&desc, hypermux_sel_gpio)) 109 return; 110 111 if (dm_gpio_set_dir_flags(&desc, GPIOD_IS_IN)) 112 return; 113 114 if (dm_gpio_get_value(&desc)) { 115 int offset; 116 117 do_fixup_by_compat(blob, "ti,am654-hbmc", "status", 118 "okay", sizeof("okay"), 0); 119 offset = fdt_node_offset_by_compatible(blob, -1, 120 "ti,am654-ospi"); 121 fdt_setprop(blob, offset, "status", "disabled", 122 sizeof("disabled")); 123 } 124} 125#endif 126 127#if defined(CONFIG_SPL_BUILD) && (defined(CONFIG_TARGET_J7200_A72_EVM) || defined(CONFIG_TARGET_J7200_R5_EVM) || \ 128 defined(CONFIG_TARGET_J721E_A72_EVM) || defined(CONFIG_TARGET_J721E_R5_EVM)) 129void spl_perform_fixups(struct spl_image_info *spl_image) 130{ 131 detect_enable_hyperflash(spl_image->fdt_addr); 132} 133#endif 134 135#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) 136int ft_board_setup(void *blob, struct bd_info *bd) 137{ 138 detect_enable_hyperflash(blob); 139 140 return 0; 141} 142#endif 143 144#ifdef CONFIG_TI_I2C_BOARD_DETECT 145int do_board_detect(void) 146{ 147 int ret; 148 149 if (board_ti_was_eeprom_read()) 150 return 0; 151 152 ret = ti_i2c_eeprom_am6_get_base(CONFIG_EEPROM_BUS_ADDRESS, 153 CONFIG_EEPROM_CHIP_ADDRESS); 154 if (ret) { 155 printf("EEPROM not available at 0x%02x, trying to read at 0x%02x\n", 156 CONFIG_EEPROM_CHIP_ADDRESS, CONFIG_EEPROM_CHIP_ADDRESS + 1); 157 ret = ti_i2c_eeprom_am6_get_base(CONFIG_EEPROM_BUS_ADDRESS, 158 CONFIG_EEPROM_CHIP_ADDRESS + 1); 159 if (ret) 160 pr_err("Reading on-board EEPROM at 0x%02x failed %d\n", 161 CONFIG_EEPROM_CHIP_ADDRESS + 1, ret); 162 } 163 164 return ret; 165} 166 167int checkboard(void) 168{ 169 struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA; 170 171 if (do_board_detect()) 172 /* EEPROM not populated */ 173 printf("Board: %s rev %s\n", "J721EX-PM1-SOM", "E2"); 174 else 175 printf("Board: %s rev %s\n", ep->name, ep->version); 176 177 return 0; 178} 179 180/* 181 * Declaration of daughtercards to probe. Note that when adding more 182 * cards they should be grouped by the 'i2c_addr' field to allow for a 183 * more efficient probing process. 184 */ 185static const struct { 186 u8 i2c_addr; /* I2C address of card EEPROM */ 187 char *card_name; /* EEPROM-programmed card name */ 188 char *dtbo_name; /* Device tree overlay to apply */ 189 u8 eth_offset; /* ethXaddr MAC address index offset */ 190} ext_cards[] = { 191 { 192 0x51, 193 "J7X-BASE-CPB", 194 "", /* No dtbo for this board */ 195 0, 196 }, 197 { 198 0x52, 199 "J7X-INFOTAN-EXP", 200 "", /* No dtbo for this board */ 201 0, 202 }, 203 { 204 0x52, 205 "J7X-GESI-EXP", 206 "", /* No dtbo for this board */ 207 5, /* Start populating from eth5addr */ 208 }, 209 { 210 0x54, 211 "J7X-VSC8514-ETH", 212 "", /* No dtbo for this board */ 213 1, /* Start populating from eth1addr */ 214 }, 215}; 216 217static bool daughter_card_detect_flags[ARRAY_SIZE(ext_cards)]; 218 219const char *board_fit_get_additionnal_images(int index, const char *type) 220{ 221 int i, j; 222 223 if (strcmp(type, FIT_FDT_PROP)) 224 return NULL; 225 226 j = 0; 227 for (i = 0; i < ARRAY_SIZE(ext_cards); i++) { 228 if (daughter_card_detect_flags[i]) { 229 if (j == index) { 230 /* 231 * Return dtbo name only if populated, 232 * otherwise stop parsing here. 233 */ 234 if (strlen(ext_cards[i].dtbo_name)) 235 return ext_cards[i].dtbo_name; 236 else 237 return NULL; 238 }; 239 240 j++; 241 } 242 } 243 244 return NULL; 245} 246 247static int probe_daughtercards(void) 248{ 249 char mac_addr[DAUGHTER_CARD_NO_OF_MAC_ADDR][TI_EEPROM_HDR_ETH_ALEN]; 250 bool eeprom_read_success; 251 struct ti_am6_eeprom ep; 252 u8 previous_i2c_addr; 253 u8 mac_addr_cnt; 254 int i; 255 int ret; 256 257 /* Mark previous I2C address variable as not populated */ 258 previous_i2c_addr = 0xff; 259 260 /* No EEPROM data was read yet */ 261 eeprom_read_success = false; 262 263 /* Iterate through list of daughtercards */ 264 for (i = 0; i < ARRAY_SIZE(ext_cards); i++) { 265 /* Obtain card-specific I2C address */ 266 u8 i2c_addr = ext_cards[i].i2c_addr; 267 268 /* Read card EEPROM if not already read previously */ 269 if (i2c_addr != previous_i2c_addr) { 270 /* Store I2C address so we can avoid reading twice */ 271 previous_i2c_addr = i2c_addr; 272 273 /* Get and parse the daughter card EEPROM record */ 274 ret = ti_i2c_eeprom_am6_get(CONFIG_EEPROM_BUS_ADDRESS, 275 i2c_addr, 276 &ep, 277 (char **)mac_addr, 278 DAUGHTER_CARD_NO_OF_MAC_ADDR, 279 &mac_addr_cnt); 280 if (ret) { 281 debug("%s: No daughtercard EEPROM at 0x%02x found %d\n", 282 __func__, i2c_addr, ret); 283 eeprom_read_success = false; 284 /* Skip to the next daughtercard to probe */ 285 continue; 286 } 287 288 /* EEPROM read successful, okay to further process. */ 289 eeprom_read_success = true; 290 } 291 292 /* Only continue processing if EEPROM data was read */ 293 if (!eeprom_read_success) 294 continue; 295 296 /* Only process the parsed data if we found a match */ 297 if (strncmp(ep.name, ext_cards[i].card_name, sizeof(ep.name))) 298 continue; 299 300 printf("Detected: %s rev %s\n", ep.name, ep.version); 301 daughter_card_detect_flags[i] = true; 302 303 if (!IS_ENABLED(CONFIG_SPL_BUILD)) { 304 int j; 305 /* 306 * Populate any MAC addresses from daughtercard into the U-Boot 307 * environment, starting with a card-specific offset so we can 308 * have multiple ext_cards contribute to the MAC pool in a well- 309 * defined manner. 310 */ 311 for (j = 0; j < mac_addr_cnt; j++) { 312 if (!is_valid_ethaddr((u8 *)mac_addr[j])) 313 continue; 314 315 eth_env_set_enetaddr_by_index("eth", 316 ext_cards[i].eth_offset + j, 317 (uchar *)mac_addr[j]); 318 } 319 } 320 } 321 322 if (!IS_ENABLED(CONFIG_SPL_BUILD)) { 323 char name_overlays[1024] = { 0 }; 324 325 for (i = 0; i < ARRAY_SIZE(ext_cards); i++) { 326 if (!daughter_card_detect_flags[i]) 327 continue; 328 329 /* Skip if no overlays are to be added */ 330 if (!strlen(ext_cards[i].dtbo_name)) 331 continue; 332 333 /* 334 * Make sure we are not running out of buffer space by checking 335 * if we can fit the new overlay, a trailing space to be used 336 * as a separator, plus the terminating zero. 337 */ 338 if (strlen(name_overlays) + strlen(ext_cards[i].dtbo_name) + 2 > 339 sizeof(name_overlays)) 340 return -ENOMEM; 341 342 /* Append to our list of overlays */ 343 strcat(name_overlays, ext_cards[i].dtbo_name); 344 strcat(name_overlays, " "); 345 } 346 347 /* Apply device tree overlay(s) to the U-Boot environment, if any */ 348 if (strlen(name_overlays)) 349 return env_set("name_overlays", name_overlays); 350 } 351 352 return 0; 353} 354#endif 355 356#ifdef CONFIG_BOARD_LATE_INIT 357static struct ti_fdt_map ti_j721e_evm_fdt_map[] = { 358 {"j721e", "k3-j721e-common-proc-board.dtb"}, 359 {"j721e-sk", "k3-j721e-sk.dtb"}, 360 {"j7200", "k3-j7200-common-proc-board.dtb"}, 361 { /* Sentinel. */ } 362}; 363static void setup_board_eeprom_env(void) 364{ 365 char *name = "j721e"; 366 367 if (do_board_detect()) 368 goto invalid_eeprom; 369 370 if (board_is_j721e_som()) 371 name = "j721e"; 372 else if (board_is_j721e_sk()) 373 name = "j721e-sk"; 374 else if (board_is_j7200_som()) 375 name = "j7200"; 376 else 377 printf("Unidentified board claims %s in eeprom header\n", 378 board_ti_get_name()); 379 380invalid_eeprom: 381 set_board_info_env_am6(name); 382 ti_set_fdt_env(name, ti_j721e_evm_fdt_map); 383} 384 385static void setup_serial(void) 386{ 387 struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA; 388 unsigned long board_serial; 389 char *endp; 390 char serial_string[17] = { 0 }; 391 392 if (env_get("serial#")) 393 return; 394 395 board_serial = hextoul(ep->serial, &endp); 396 if (*endp != '\0') { 397 pr_err("Error: Can't set serial# to %s\n", ep->serial); 398 return; 399 } 400 401 snprintf(serial_string, sizeof(serial_string), "%016lx", board_serial); 402 env_set("serial#", serial_string); 403} 404 405int board_late_init(void) 406{ 407 if (IS_ENABLED(CONFIG_TI_I2C_BOARD_DETECT)) { 408 setup_board_eeprom_env(); 409 setup_serial(); 410 411 /* Check for and probe any plugged-in daughtercards */ 412 if (board_is_j721e_som() || board_is_j7200_som()) 413 probe_daughtercards(); 414 } 415 416 return 0; 417} 418#endif 419 420static int __maybe_unused detect_SW3_1_state(void) 421{ 422 if (IS_ENABLED(CONFIG_TARGET_J7200_A72_EVM) || IS_ENABLED(CONFIG_TARGET_J721E_A72_EVM)) { 423 struct gpio_desc desc = {0}; 424 int ret; 425 char *hypermux_sel_gpio = (board_is_j721e_som()) ? "8" : "6"; 426 427 ret = dm_gpio_lookup_name(hypermux_sel_gpio, &desc); 428 if (ret) { 429 printf("error getting GPIO lookup name: %d\n", ret); 430 return ret; 431 } 432 433 ret = dm_gpio_request(&desc, hypermux_sel_gpio); 434 if (ret) { 435 printf("error requesting GPIO: %d\n", ret); 436 goto err_free_gpio; 437 } 438 439 ret = dm_gpio_set_dir_flags(&desc, GPIOD_IS_IN); 440 if (ret) { 441 printf("error setting direction flag of GPIO: %d\n", ret); 442 goto err_free_gpio; 443 } 444 445 ret = dm_gpio_get_value(&desc); 446 if (ret < 0) 447 printf("error getting value of GPIO: %d\n", ret); 448 449err_free_gpio: 450 dm_gpio_free(desc.dev, &desc); 451 return ret; 452 } 453} 454 455void spl_board_init(void) 456{ 457 struct udevice *dev; 458 int ret; 459 460 if ((IS_ENABLED(CONFIG_TARGET_J721E_A72_EVM) || 461 IS_ENABLED(CONFIG_TARGET_J7200_A72_EVM)) && 462 IS_ENABLED(CONFIG_TI_I2C_BOARD_DETECT)) { 463 if (!board_is_j721e_sk()) 464 probe_daughtercards(); 465 } 466 467 if (IS_ENABLED(CONFIG_ESM_K3)) { 468 ret = uclass_get_device_by_name(UCLASS_MISC, "esm@700000", &dev); 469 if (ret) 470 printf("MISC init for esm@700000 failed: %d\n", ret); 471 472 ret = uclass_get_device_by_name(UCLASS_MISC, "esm@40800000", &dev); 473 if (ret) 474 printf("MISC init for esm@40800000 failed: %d\n", ret); 475 } 476 477 if (IS_ENABLED(CONFIG_ESM_PMIC)) { 478 ret = uclass_get_device_by_driver(UCLASS_MISC, 479 DM_DRIVER_GET(pmic_esm), 480 &dev); 481 if (ret) 482 printf("ESM PMIC init failed: %d\n", ret); 483 } 484 if ((IS_ENABLED(CONFIG_TARGET_J7200_A72_EVM) || IS_ENABLED(CONFIG_TARGET_J721E_A72_EVM)) && 485 IS_ENABLED(CONFIG_HBMC_AM654)) { 486 struct udevice *dev; 487 int ret; 488 489 ret = detect_SW3_1_state(); 490 if (ret == 1) { 491 ret = uclass_get_device_by_driver(UCLASS_MTD, 492 DM_DRIVER_GET(hbmc_am654), 493 &dev); 494 if (ret) 495 debug("Failed to probe hyperflash\n"); 496 } 497 } 498} 499