global: Move remaining CONFIG_SYS_SDRAM_* to CFG_SYS_SDRAM_*
[platform/kernel/u-boot.git] / board / siemens / iot2050 / board.c
1 // 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
29 struct 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
48 DECLARE_GLOBAL_DATA_PTR;
49
50 static 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
58 static bool board_is_sr1(void)
59 {
60         struct iot2050_info *info = IOT2050_INFO_DATA;
61
62         return info->magic == IOT2050_INFO_MAGIC &&
63                 !strstr((char *)info->name, "-PG2");
64 }
65
66 static void remove_mmc1_target(void)
67 {
68         char *boot_targets = strdup(env_get("boot_targets"));
69         char *mmc1 = strstr(boot_targets, "mmc1");
70
71         if (mmc1) {
72                 memmove(mmc1, mmc1 + 4, strlen(mmc1 + 4) + 1);
73                 env_set("boot_targets", boot_targets);
74         }
75
76         free(boot_targets);
77 }
78
79 void set_board_info_env(void)
80 {
81         struct iot2050_info *info = IOT2050_INFO_DATA;
82         u8 __maybe_unused mac_cnt;
83         const char *fdtfile;
84
85         if (info->magic != IOT2050_INFO_MAGIC) {
86                 pr_err("IOT2050: Board info parsing error!\n");
87                 return;
88         }
89
90         if (env_get("board_uuid"))
91                 return;
92
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);
100
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",
106                                                               mac_cnt + 1,
107                                                               info->mac_addr[mac_cnt]);
108                 }
109         }
110
111         if (board_is_advanced()) {
112                 if (board_is_sr1())
113                         fdtfile = "ti/k3-am6548-iot2050-advanced.dtb";
114                 else
115                         fdtfile = "ti/k3-am6548-iot2050-advanced-pg2.dtb";
116         } else {
117                 if (board_is_sr1())
118                         fdtfile = "ti/k3-am6528-iot2050-basic.dtb";
119                 else
120                         fdtfile = "ti/k3-am6528-iot2050-basic-pg2.dtb";
121                 /* remove the unavailable eMMC (mmc1) from the list */
122                 remove_mmc1_target();
123         }
124         env_set("fdtfile", fdtfile);
125
126         env_save();
127 }
128
129 int board_init(void)
130 {
131         return 0;
132 }
133
134 int dram_init(void)
135 {
136         if (board_is_advanced())
137                 gd->ram_size = SZ_2G;
138         else
139                 gd->ram_size = SZ_1G;
140
141         return 0;
142 }
143
144 int dram_init_banksize(void)
145 {
146         dram_init();
147
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;
151
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;
155
156         return 0;
157 }
158
159 #ifdef CONFIG_SPL_LOAD_FIT
160 int board_fit_config_name_match(const char *name)
161 {
162         struct iot2050_info *info = IOT2050_INFO_DATA;
163         char upper_name[32];
164
165         if (info->magic != IOT2050_INFO_MAGIC ||
166             strlen(name) >= sizeof(upper_name))
167                 return -1;
168
169         str_to_upper(name, upper_name, sizeof(upper_name));
170         if (!strcmp(upper_name, (char *)info->name))
171                 return 0;
172
173         return -1;
174 }
175 #endif
176
177 int do_board_detect(void)
178 {
179         return 0;
180 }
181
182 #ifdef CONFIG_IOT2050_BOOT_SWITCH
183 static bool user_button_pressed(void)
184 {
185         struct udevice *red_led = NULL;
186         unsigned long count = 0;
187         struct gpio_desc gpio;
188
189         memset(&gpio, 0, sizeof(gpio));
190
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)
194                 return false;
195
196         if (dm_gpio_get_value(&gpio) == 1)
197                 return false;
198
199         printf("USER button pressed - booting from external media only\n");
200
201         led_get_by_label("status-led-red", &red_led);
202
203         if (red_led)
204                 led_set_state(red_led, LEDST_ON);
205
206         while (dm_gpio_get_value(&gpio) == 0 && count++ < 10000)
207                 mdelay(1);
208
209         if (red_led)
210                 led_set_state(red_led, LEDST_OFF);
211
212         return true;
213 }
214 #endif
215
216 #define SERDES0_LANE_SELECT     0x00104080
217
218 int board_late_init(void)
219 {
220         /* change CTRL_MMR register to let serdes0 not output USB3.0 signals. */
221         writel(0x3, SERDES0_LANE_SELECT);
222
223         set_board_info_env();
224
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();
229
230         return 0;
231 }
232
233 #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
234 int ft_board_setup(void *blob, struct bd_info *bd)
235 {
236         int ret;
237
238         ret = fdt_fixup_msmc_ram(blob, "/bus@100000", "sram@70000000");
239         if (ret < 0)
240                 ret = fdt_fixup_msmc_ram(blob, "/interconnect@100000",
241                                          "sram@70000000");
242         if (ret)
243                 pr_err("%s: fixing up msmc ram failed %d\n", __func__, ret);
244
245         return ret;
246 }
247 #endif
248
249 void spl_board_init(void)
250 {
251 }
252
253 #if CONFIG_IS_ENABLED(LED) && CONFIG_IS_ENABLED(SHOW_BOOT_PROGRESS)
254 /*
255  * Indicate any error or (accidental?) entering of CLI via the red status LED.
256  */
257 void show_boot_progress(int progress)
258 {
259         struct udevice *dev;
260         int ret;
261
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);
265                 if (ret == 0)
266                         led_set_state(dev, LEDST_OFF);
267
268                 ret = led_get_by_label("status-led-red", &dev);
269                 if (ret == 0)
270                         led_set_state(dev, LEDST_ON);
271         }
272 }
273 #endif