1 // SPDX-License-Identifier: GPL-2.0+
3 * Board specific initialization for IOT2050
4 * Copyright (c) Siemens AG, 2018-2021
7 * Le Jin <le.jin@siemens.com>
8 * Jan Kiszka <jan.kiszka@siemens.com>
12 #include <bootstage.h>
21 #include <linux/delay.h>
22 #include <asm/arch/sys_proto.h>
23 #include <asm/arch/hardware.h>
27 #define IOT2050_INFO_MAGIC 0x20502050
38 u8 mac_addr[8][ARP_HLEN];
39 char seboot_version[40 + 1];
43 * Scratch SRAM (available before DDR RAM) contains extracted EEPROM data.
45 #define IOT2050_INFO_DATA ((struct iot2050_info *) \
46 TI_SRAM_SCRATCH_BOARD_EEPROM_START)
48 DECLARE_GLOBAL_DATA_PTR;
50 static bool board_is_advanced(void)
52 struct iot2050_info *info = IOT2050_INFO_DATA;
54 return info->magic == IOT2050_INFO_MAGIC &&
55 strstr((char *)info->name, "IOT2050-ADVANCED") != NULL;
58 static bool board_is_sr1(void)
60 struct iot2050_info *info = IOT2050_INFO_DATA;
62 return info->magic == IOT2050_INFO_MAGIC &&
63 !strstr((char *)info->name, "-PG2");
66 static void remove_mmc1_target(void)
68 char *boot_targets = strdup(env_get("boot_targets"));
69 char *mmc1 = strstr(boot_targets, "mmc1");
72 memmove(mmc1, mmc1 + 4, strlen(mmc1 + 4) + 1);
73 env_set("boot_targets", boot_targets);
79 void set_board_info_env(void)
81 struct iot2050_info *info = IOT2050_INFO_DATA;
82 u8 __maybe_unused mac_cnt;
85 if (info->magic != IOT2050_INFO_MAGIC) {
86 pr_err("IOT2050: Board info parsing error!\n");
90 if (env_get("board_uuid"))
93 env_set("board_name", info->name);
94 env_set("board_serial", info->serial);
95 env_set("mlfb", info->mlfb);
96 env_set("board_uuid", info->uuid);
97 env_set("board_a5e", info->a5e);
98 env_set("fw_version", PLAIN_VERSION);
99 env_set("seboot_version", info->seboot_version);
101 if (IS_ENABLED(CONFIG_NET)) {
102 /* set MAC addresses to ensure forwarding to the OS */
103 for (mac_cnt = 0; mac_cnt < info->mac_addr_cnt; mac_cnt++) {
104 if (is_valid_ethaddr(info->mac_addr[mac_cnt]))
105 eth_env_set_enetaddr_by_index("eth",
107 info->mac_addr[mac_cnt]);
111 if (board_is_advanced()) {
113 fdtfile = "ti/k3-am6548-iot2050-advanced.dtb";
115 fdtfile = "ti/k3-am6548-iot2050-advanced-pg2.dtb";
118 fdtfile = "ti/k3-am6528-iot2050-basic.dtb";
120 fdtfile = "ti/k3-am6528-iot2050-basic-pg2.dtb";
121 /* remove the unavailable eMMC (mmc1) from the list */
122 remove_mmc1_target();
124 env_set("fdtfile", fdtfile);
136 if (board_is_advanced())
137 gd->ram_size = SZ_2G;
139 gd->ram_size = SZ_1G;
144 int dram_init_banksize(void)
148 /* Bank 0 declares the memory available in the DDR low region */
149 gd->bd->bi_dram[0].start = CFG_SYS_SDRAM_BASE;
150 gd->bd->bi_dram[0].size = gd->ram_size;
152 /* Bank 1 declares the memory available in the DDR high region */
153 gd->bd->bi_dram[1].start = 0;
154 gd->bd->bi_dram[1].size = 0;
159 #ifdef CONFIG_SPL_LOAD_FIT
160 int board_fit_config_name_match(const char *name)
162 struct iot2050_info *info = IOT2050_INFO_DATA;
165 if (info->magic != IOT2050_INFO_MAGIC ||
166 strlen(name) >= sizeof(upper_name))
169 str_to_upper(name, upper_name, sizeof(upper_name));
170 if (!strcmp(upper_name, (char *)info->name))
177 int do_board_detect(void)
182 #ifdef CONFIG_IOT2050_BOOT_SWITCH
183 static bool user_button_pressed(void)
185 struct udevice *red_led = NULL;
186 unsigned long count = 0;
187 struct gpio_desc gpio;
189 memset(&gpio, 0, sizeof(gpio));
191 if (dm_gpio_lookup_name("25", &gpio) < 0 ||
192 dm_gpio_request(&gpio, "USER button") < 0 ||
193 dm_gpio_set_dir_flags(&gpio, GPIOD_IS_IN) < 0)
196 if (dm_gpio_get_value(&gpio) == 1)
199 printf("USER button pressed - booting from external media only\n");
201 led_get_by_label("status-led-red", &red_led);
204 led_set_state(red_led, LEDST_ON);
206 while (dm_gpio_get_value(&gpio) == 0 && count++ < 10000)
210 led_set_state(red_led, LEDST_OFF);
216 #define SERDES0_LANE_SELECT 0x00104080
218 int board_late_init(void)
220 /* change CTRL_MMR register to let serdes0 not output USB3.0 signals. */
221 writel(0x3, SERDES0_LANE_SELECT);
223 set_board_info_env();
225 /* remove the eMMC if requested via button */
226 if (IS_ENABLED(CONFIG_IOT2050_BOOT_SWITCH) && board_is_advanced() &&
227 user_button_pressed())
228 remove_mmc1_target();
233 #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
234 int ft_board_setup(void *blob, struct bd_info *bd)
238 ret = fdt_fixup_msmc_ram(blob, "/bus@100000", "sram@70000000");
240 ret = fdt_fixup_msmc_ram(blob, "/interconnect@100000",
243 pr_err("%s: fixing up msmc ram failed %d\n", __func__, ret);
249 void spl_board_init(void)
253 #if CONFIG_IS_ENABLED(LED) && CONFIG_IS_ENABLED(SHOW_BOOT_PROGRESS)
255 * Indicate any error or (accidental?) entering of CLI via the red status LED.
257 void show_boot_progress(int progress)
262 if ((progress < 0 && progress != -BOOTSTAGE_ID_NET_ETH_START) ||
263 progress == BOOTSTAGE_ID_ENTER_CLI_LOOP) {
264 ret = led_get_by_label("status-led-green", &dev);
266 led_set_state(dev, LEDST_OFF);
268 ret = led_get_by_label("status-led-red", &dev);
270 led_set_state(dev, LEDST_ON);