blob: dbf893000a7d4010a6f7b0bef3acf77110c6309a [file] [log] [blame]
Jan Kiszka8ff2ff82021-09-18 08:17:53 +02001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Board specific initialization for IOT2050
4 * Copyright (c) Siemens AG, 2018-2021
5 *
6 * Authors:
7 * Le Jin <le.jin@siemens.com>
8 * Jan Kiszka <jan.kiszka@siemens.com>
9 */
10
11#include <common.h>
12#include <bootstage.h>
13#include <dm.h>
14#include <i2c.h>
15#include <led.h>
16#include <malloc.h>
17#include <net.h>
18#include <phy.h>
19#include <spl.h>
20#include <version.h>
21#include <linux/delay.h>
22#include <asm/arch/sys_proto.h>
23#include <asm/arch/hardware.h>
24#include <asm/gpio.h>
25#include <asm/io.h>
26
27#define IOT2050_INFO_MAGIC 0x20502050
28
29struct iot2050_info {
30 u32 magic;
31 u16 size;
32 char name[20 + 1];
33 char serial[16 + 1];
34 char mlfb[18 + 1];
35 char uuid[32 + 1];
36 char a5e[18 + 1];
37 u8 mac_addr_cnt;
38 u8 mac_addr[8][ARP_HLEN];
39 char seboot_version[40 + 1];
40} __packed;
41
42/*
43 * Scratch SRAM (available before DDR RAM) contains extracted EEPROM data.
44 */
45#define IOT2050_INFO_DATA ((struct iot2050_info *) \
46 TI_SRAM_SCRATCH_BOARD_EEPROM_START)
47
48DECLARE_GLOBAL_DATA_PTR;
49
50static bool board_is_advanced(void)
51{
52 struct iot2050_info *info = IOT2050_INFO_DATA;
53
54 return info->magic == IOT2050_INFO_MAGIC &&
55 strstr((char *)info->name, "IOT2050-ADVANCED") != NULL;
56}
57
Jan Kiszka8ff2ff82021-09-18 08:17:53 +020058static void remove_mmc1_target(void)
59{
60 char *boot_targets = strdup(env_get("boot_targets"));
61 char *mmc1 = strstr(boot_targets, "mmc1");
62
63 if (mmc1) {
64 memmove(mmc1, mmc1 + 4, strlen(mmc1 + 4) + 1);
65 env_set("boot_targets", boot_targets);
66 }
67
68 free(boot_targets);
69}
70
71void set_board_info_env(void)
72{
73 struct iot2050_info *info = IOT2050_INFO_DATA;
74 u8 __maybe_unused mac_cnt;
75 const char *fdtfile;
76
77 if (info->magic != IOT2050_INFO_MAGIC) {
78 pr_err("IOT2050: Board info parsing error!\n");
79 return;
80 }
81
82 if (env_get("board_uuid"))
83 return;
84
85 env_set("board_name", info->name);
86 env_set("board_serial", info->serial);
87 env_set("mlfb", info->mlfb);
88 env_set("board_uuid", info->uuid);
89 env_set("board_a5e", info->a5e);
90 env_set("fw_version", PLAIN_VERSION);
91 env_set("seboot_version", info->seboot_version);
92
93 if (IS_ENABLED(CONFIG_NET)) {
94 /* set MAC addresses to ensure forwarding to the OS */
95 for (mac_cnt = 0; mac_cnt < info->mac_addr_cnt; mac_cnt++) {
96 if (is_valid_ethaddr(info->mac_addr[mac_cnt]))
97 eth_env_set_enetaddr_by_index("eth",
98 mac_cnt + 1,
99 info->mac_addr[mac_cnt]);
100 }
101 }
102
103 if (board_is_advanced()) {
Su Baocheng0dcd3372023-02-28 19:19:09 +0100104 if (IS_ENABLED(CONFIG_TARGET_IOT2050_A53_PG1))
Jan Kiszka8ff2ff82021-09-18 08:17:53 +0200105 fdtfile = "ti/k3-am6548-iot2050-advanced.dtb";
106 else
107 fdtfile = "ti/k3-am6548-iot2050-advanced-pg2.dtb";
108 } else {
Su Baocheng0dcd3372023-02-28 19:19:09 +0100109 if (IS_ENABLED(CONFIG_TARGET_IOT2050_A53_PG1))
Jan Kiszka8ff2ff82021-09-18 08:17:53 +0200110 fdtfile = "ti/k3-am6528-iot2050-basic.dtb";
111 else
112 fdtfile = "ti/k3-am6528-iot2050-basic-pg2.dtb";
113 /* remove the unavailable eMMC (mmc1) from the list */
114 remove_mmc1_target();
115 }
116 env_set("fdtfile", fdtfile);
117
118 env_save();
119}
120
121int board_init(void)
122{
123 return 0;
124}
125
126int dram_init(void)
127{
128 if (board_is_advanced())
129 gd->ram_size = SZ_2G;
130 else
131 gd->ram_size = SZ_1G;
132
133 return 0;
134}
135
136int dram_init_banksize(void)
137{
138 dram_init();
139
140 /* Bank 0 declares the memory available in the DDR low region */
Tom Rinibb4dd962022-11-16 13:10:37 -0500141 gd->bd->bi_dram[0].start = CFG_SYS_SDRAM_BASE;
Jan Kiszka8ff2ff82021-09-18 08:17:53 +0200142 gd->bd->bi_dram[0].size = gd->ram_size;
143
144 /* Bank 1 declares the memory available in the DDR high region */
145 gd->bd->bi_dram[1].start = 0;
146 gd->bd->bi_dram[1].size = 0;
147
148 return 0;
149}
150
151#ifdef CONFIG_SPL_LOAD_FIT
152int board_fit_config_name_match(const char *name)
153{
154 struct iot2050_info *info = IOT2050_INFO_DATA;
155 char upper_name[32];
156
157 if (info->magic != IOT2050_INFO_MAGIC ||
158 strlen(name) >= sizeof(upper_name))
159 return -1;
160
161 str_to_upper(name, upper_name, sizeof(upper_name));
162 if (!strcmp(upper_name, (char *)info->name))
163 return 0;
164
165 return -1;
166}
167#endif
168
169int do_board_detect(void)
170{
171 return 0;
172}
173
174#ifdef CONFIG_IOT2050_BOOT_SWITCH
175static bool user_button_pressed(void)
176{
177 struct udevice *red_led = NULL;
178 unsigned long count = 0;
179 struct gpio_desc gpio;
180
181 memset(&gpio, 0, sizeof(gpio));
182
183 if (dm_gpio_lookup_name("25", &gpio) < 0 ||
184 dm_gpio_request(&gpio, "USER button") < 0 ||
185 dm_gpio_set_dir_flags(&gpio, GPIOD_IS_IN) < 0)
186 return false;
187
188 if (dm_gpio_get_value(&gpio) == 1)
189 return false;
190
191 printf("USER button pressed - booting from external media only\n");
192
193 led_get_by_label("status-led-red", &red_led);
194
195 if (red_led)
196 led_set_state(red_led, LEDST_ON);
197
198 while (dm_gpio_get_value(&gpio) == 0 && count++ < 10000)
199 mdelay(1);
200
201 if (red_led)
202 led_set_state(red_led, LEDST_OFF);
203
204 return true;
205}
206#endif
207
208#define SERDES0_LANE_SELECT 0x00104080
209
210int board_late_init(void)
211{
212 /* change CTRL_MMR register to let serdes0 not output USB3.0 signals. */
213 writel(0x3, SERDES0_LANE_SELECT);
214
215 set_board_info_env();
216
217 /* remove the eMMC if requested via button */
218 if (IS_ENABLED(CONFIG_IOT2050_BOOT_SWITCH) && board_is_advanced() &&
219 user_button_pressed())
220 remove_mmc1_target();
221
222 return 0;
223}
224
225#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
226int ft_board_setup(void *blob, struct bd_info *bd)
227{
228 int ret;
229
230 ret = fdt_fixup_msmc_ram(blob, "/bus@100000", "sram@70000000");
231 if (ret < 0)
232 ret = fdt_fixup_msmc_ram(blob, "/interconnect@100000",
233 "sram@70000000");
234 if (ret)
235 pr_err("%s: fixing up msmc ram failed %d\n", __func__, ret);
236
237 return ret;
238}
239#endif
240
241void spl_board_init(void)
242{
243}
244
Marek Vasut98154342021-10-23 03:06:03 +0200245#if CONFIG_IS_ENABLED(LED) && CONFIG_IS_ENABLED(SHOW_BOOT_PROGRESS)
Jan Kiszka8ff2ff82021-09-18 08:17:53 +0200246/*
247 * Indicate any error or (accidental?) entering of CLI via the red status LED.
248 */
249void show_boot_progress(int progress)
250{
251 struct udevice *dev;
252 int ret;
253
Jan Kiszkaa8ea4f42021-11-03 15:12:30 +0100254 if ((progress < 0 && progress != -BOOTSTAGE_ID_NET_ETH_START) ||
255 progress == BOOTSTAGE_ID_ENTER_CLI_LOOP) {
Jan Kiszka8ff2ff82021-09-18 08:17:53 +0200256 ret = led_get_by_label("status-led-green", &dev);
257 if (ret == 0)
258 led_set_state(dev, LEDST_OFF);
259
260 ret = led_get_by_label("status-led-red", &dev);
261 if (ret == 0)
262 led_set_state(dev, LEDST_ON);
263 }
264}
265#endif