command: Remove the cmd_tbl_t typedef
[oweals/u-boot.git] / board / siemens / capricorn / board.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2017-2019 NXP
4  *
5  * Copyright 2019 Siemens AG
6  *
7  */
8 #include <common.h>
9 #include <command.h>
10 #include <dm.h>
11 #include <env.h>
12 #include <errno.h>
13 #include <init.h>
14 #include <netdev.h>
15 #include <env_internal.h>
16 #include <fsl_esdhc_imx.h>
17 #include <i2c.h>
18 #include <led.h>
19 #include <pca953x.h>
20 #include <power-domain.h>
21 #include <asm/gpio.h>
22 #include <asm/arch/imx8-pins.h>
23 #include <asm/arch/iomux.h>
24 #include <asm/arch/sci/sci.h>
25 #include <asm/arch/sys_proto.h>
26 #ifndef CONFIG_SPL
27 #include <asm/arch-imx8/clock.h>
28 #endif
29 #include "../common/factoryset.h"
30
31 #define GPIO_PAD_CTRL \
32                 ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | \
33                  (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \
34                  (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \
35                  (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT))
36
37 #define ENET_NORMAL_PAD_CTRL \
38                 ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | \
39                  (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \
40                  (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | \
41                  (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT))
42
43 #define UART_PAD_CTRL \
44                 ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \
45                  (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \
46                  (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \
47                  (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT))
48
49 static iomux_cfg_t uart2_pads[] = {
50         SC_P_UART2_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
51         SC_P_UART2_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
52 };
53
54 static void setup_iomux_uart(void)
55 {
56         imx8_iomux_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads));
57 }
58
59 int board_early_init_f(void)
60 {
61         /* Set UART clock root to 80 MHz */
62         sc_pm_clock_rate_t rate = SC_80MHZ;
63         int ret;
64
65         ret = sc_pm_setup_uart(SC_R_UART_0, rate);
66         ret |= sc_pm_setup_uart(SC_R_UART_2, rate);
67         if (ret)
68                 return ret;
69
70         setup_iomux_uart();
71
72         return 0;
73 }
74
75 #define ENET_PHY_RESET  IMX_GPIO_NR(0, 3)
76 #define ENET_TEST_1     IMX_GPIO_NR(0, 8)
77 #define ENET_TEST_2     IMX_GPIO_NR(0, 9)
78
79 /*#define ETH_IO_TEST*/
80 static iomux_cfg_t enet_reset[] = {
81         SC_P_ESAI0_SCKT | MUX_MODE_ALT(4) | MUX_PAD_CTRL(GPIO_PAD_CTRL),
82 #ifdef ETH_IO_TEST
83         /* GPIO0.IO08 MODE3: TXD0 */
84         SC_P_ESAI0_TX4_RX1 | MUX_MODE_ALT(4) |
85         MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
86         /* GPIO0.IO09 MODE3: TXD1 */
87         SC_P_ESAI0_TX5_RX0 | MUX_MODE_ALT(4) |
88         MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
89 #endif
90 };
91
92 static void enet_device_phy_reset(void)
93 {
94         int ret = 0;
95
96         imx8_iomux_setup_multiple_pads(enet_reset, ARRAY_SIZE(enet_reset));
97
98         ret = gpio_request(ENET_PHY_RESET, "enet_phy_reset");
99         if (!ret) {
100                 gpio_direction_output(ENET_PHY_RESET, 1);
101                 gpio_set_value(ENET_PHY_RESET, 0);
102                 /* SMSC9303 TRM chapter 14.5.2 */
103                 udelay(200);
104                 gpio_set_value(ENET_PHY_RESET, 1);
105         } else {
106                 printf("ENET RESET failed!\n");
107         }
108
109 #ifdef ETH_IO_TEST
110         ret =  gpio_request(ENET_TEST_1, "enet_test1");
111         if (!ret) {
112                 int i;
113
114                 printf("ENET TEST 1!\n");
115                 for (i = 0; i < 20; i++) {
116                         gpio_direction_output(ENET_TEST_1, 1);
117                         gpio_set_value(ENET_TEST_1, 0);
118                         udelay(50);
119                         gpio_set_value(ENET_TEST_1, 1);
120                         udelay(50);
121                 }
122                 gpio_free(ENET_TEST_1);
123         } else {
124                 printf("GPIO for ENET TEST 1 failed!\n");
125         }
126         ret =  gpio_request(ENET_TEST_2, "enet_test2");
127         if (!ret) {
128                 int i;
129
130                 printf("ENET TEST 2!\n");
131                 for (i = 0; i < 20; i++) {
132                         gpio_direction_output(ENET_TEST_2, 1);
133                         gpio_set_value(ENET_TEST_2, 0);
134                         udelay(50);
135                         gpio_set_value(ENET_TEST_2, 1);
136                         udelay(50);
137                 }
138                 gpio_free(ENET_TEST_2);
139         } else {
140                 printf("GPIO for ENET TEST 2 failed!\n");
141         }
142 #endif
143 }
144
145 int setup_gpr_fec(void)
146 {
147         sc_ipc_t ipc_handle = -1;
148         sc_err_t err = 0;
149         unsigned int test;
150
151         /*
152          * TX_CLK_SEL: it controls a mux between clock coming from the pad 50M
153          * input pin and clock generated internally to connectivity subsystem
154          *      0: internal clock
155          *      1: external clock --->  your choice for RMII
156          *
157          * CLKDIV_SEL: it controls a div by 2 on the internal clock path à
158          *      it should be don’t care when using external clock
159          *      0: non-divided clock
160          *      1: clock divided by 2
161          * 50_DISABLE or 125_DISABLE:
162          *      it’s used to disable the clock tree going outside the chip
163          *      when reference clock is generated internally.
164          *      It should be don’t care when reference clock is provided
165          *      externally.
166          *      0: clock is enabled
167          *      1: clock is disabled
168          *
169          * SC_C_TXCLK           = 24,
170          * SC_C_CLKDIV          = 25,
171          * SC_C_DISABLE_50      = 26,
172          * SC_C_DISABLE_125     = 27,
173          */
174
175         err = sc_misc_set_control(ipc_handle, SC_R_ENET_1, SC_C_TXCLK, 1);
176         if (err != SC_ERR_NONE)
177                 printf("Error in setting up SC_C %d\n\r", SC_C_TXCLK);
178
179         sc_misc_get_control(ipc_handle, SC_R_ENET_1, SC_C_TXCLK, &test);
180         debug("TEST SC_C %d-->%d\n\r", SC_C_TXCLK, test);
181
182         err = sc_misc_set_control(ipc_handle, SC_R_ENET_1, SC_C_CLKDIV, 0);
183         if (err != SC_ERR_NONE)
184                 printf("Error in setting up SC_C %d\n\r", SC_C_CLKDIV);
185
186         sc_misc_get_control(ipc_handle, SC_R_ENET_1, SC_C_CLKDIV, &test);
187         debug("TEST SC_C %d-->%d\n\r", SC_C_CLKDIV, test);
188
189         err = sc_misc_set_control(ipc_handle, SC_R_ENET_1, SC_C_DISABLE_50, 0);
190         if (err != SC_ERR_NONE)
191                 printf("Error in setting up SC_C %d\n\r", SC_C_DISABLE_50);
192
193         sc_misc_get_control(ipc_handle, SC_R_ENET_1, SC_C_TXCLK, &test);
194         debug("TEST SC_C %d-->%d\n\r", SC_C_DISABLE_50, test);
195
196         err = sc_misc_set_control(ipc_handle, SC_R_ENET_1, SC_C_DISABLE_125, 1);
197         if (err != SC_ERR_NONE)
198                 printf("Error in setting up SC_C %d\n\r", SC_C_DISABLE_125);
199
200         sc_misc_get_control(ipc_handle, SC_R_ENET_1, SC_C_TXCLK, &test);
201         debug("TEST SC_C %d-->%d\n\r", SC_C_DISABLE_125, test);
202
203         err = sc_misc_set_control(ipc_handle, SC_R_ENET_1, SC_C_SEL_125, 1);
204         if (err != SC_ERR_NONE)
205                 printf("Error in setting up SC_C %d\n\r", SC_C_SEL_125);
206
207         sc_misc_get_control(ipc_handle, SC_R_ENET_1, SC_C_SEL_125, &test);
208         debug("TEST SC_C %d-->%d\n\r", SC_C_SEL_125, test);
209
210         return 0;
211 }
212
213 #if IS_ENABLED(CONFIG_FEC_MXC)
214 #include <miiphy.h>
215 int board_phy_config(struct phy_device *phydev)
216 {
217         if (phydev->drv->config)
218                 phydev->drv->config(phydev);
219
220         return 0;
221 }
222
223 #endif
224
225 static int setup_fec(void)
226 {
227         setup_gpr_fec();
228         /* Reset ENET PHY */
229         enet_device_phy_reset();
230         return 0;
231 }
232
233 void reset_cpu(ulong addr)
234 {
235 }
236
237 #ifndef CONFIG_SPL_BUILD
238 /* LED's */
239 static int board_led_init(void)
240 {
241         struct udevice *bus, *dev;
242         u8 pca_led[2] = { 0x00, 0x00 };
243         int ret;
244
245         /* init all GPIO LED's */
246         if (IS_ENABLED(CONFIG_LED))
247                 led_default_state();
248
249         /* enable all leds on PCA9552 */
250         ret = uclass_get_device_by_seq(UCLASS_I2C, PCA9552_1_I2C_BUS, &bus);
251         if (ret) {
252                 printf("ERROR: I2C get %d\n", ret);
253                 return ret;
254         }
255
256         ret = dm_i2c_probe(bus, PCA9552_1_I2C_ADDR, 0, &dev);
257         if (ret) {
258                 printf("ERROR: PCA9552 probe failed\n");
259                 return ret;
260         }
261
262         ret = dm_i2c_write(dev, 0x16, pca_led, sizeof(pca_led));
263         if (ret) {
264                 printf("ERROR: PCA9552 write failed\n");
265                 return ret;
266         }
267
268         mdelay(1);
269         return ret;
270 }
271 #endif /* !CONFIG_SPL_BUILD */
272
273 int checkboard(void)
274 {
275         puts("Board: Capricorn\n");
276
277         /*
278          * Running build_info() doesn't work with current SCFW blob.
279          * Uncomment below call when new blob is available.
280          */
281         /*build_info();*/
282
283         print_bootinfo();
284         return 0;
285 }
286
287 int board_init(void)
288 {
289         setup_fec();
290         return 0;
291 }
292
293 #ifdef CONFIG_OF_BOARD_SETUP
294 int ft_board_setup(void *blob, bd_t *bd)
295 {
296         return 0;
297 }
298 #endif
299
300 int board_mmc_get_env_dev(int devno)
301 {
302         return devno;
303 }
304
305 static int check_mmc_autodetect(void)
306 {
307         char *autodetect_str = env_get("mmcautodetect");
308
309         if (autodetect_str && (strcmp(autodetect_str, "yes") == 0))
310                 return 1;
311
312         return 0;
313 }
314
315 /* This should be defined for each board */
316 __weak int mmc_map_to_kernel_blk(int dev_no)
317 {
318         return dev_no;
319 }
320
321 void board_late_mmc_env_init(void)
322 {
323         char cmd[32];
324         char mmcblk[32];
325         u32 dev_no = mmc_get_env_dev();
326
327         if (!check_mmc_autodetect())
328                 return;
329
330         env_set_ulong("mmcdev", dev_no);
331
332         /* Set mmcblk env */
333         sprintf(mmcblk, "/dev/mmcblk%dp2 rootwait rw",
334                 mmc_map_to_kernel_blk(dev_no));
335         env_set("mmcroot", mmcblk);
336
337         sprintf(cmd, "mmc dev %d", dev_no);
338         run_command(cmd, 0);
339 }
340
341 #ifndef CONFIG_SPL_BUILD
342 int factoryset_read_eeprom(int i2c_addr);
343
344 static int load_parameters_from_factoryset(void)
345 {
346         int ret;
347
348         ret = factoryset_read_eeprom(EEPROM_I2C_ADDR);
349         if (ret)
350                 return ret;
351
352         return factoryset_env_set();
353 }
354
355 int board_late_init(void)
356 {
357         env_set("sec_boot", "no");
358 #ifdef CONFIG_AHAB_BOOT
359         env_set("sec_boot", "yes");
360 #endif
361
362 #ifdef CONFIG_ENV_IS_IN_MMC
363         board_late_mmc_env_init();
364 #endif
365         /* Init LEDs */
366         if (board_led_init())
367                 printf("I2C LED init failed\n");
368
369         /* Set environment from factoryset */
370         if (load_parameters_from_factoryset())
371                 printf("Loading factoryset parameters failed!\n");
372
373         return 0;
374 }
375
376 /* Service button */
377 #define MAX_PIN_NUMBER                  128
378 #define BOARD_DEFAULT_BUTTON_GPIO       IMX_GPIO_NR(1, 31)
379
380 unsigned char get_button_state(char * const envname, unsigned char def)
381 {
382         int button = 0;
383         int gpio;
384         char *ptr_env;
385
386         /* If button is not found we take default */
387         ptr_env = env_get(envname);
388         if (!ptr_env) {
389                 printf("Using default: %u\n", def);
390                 gpio = def;
391         } else {
392                 gpio = (unsigned char)simple_strtoul(ptr_env, NULL, 0);
393                 if (gpio > MAX_PIN_NUMBER)
394                         gpio = def;
395         }
396
397         gpio_request(gpio, "");
398         gpio_direction_input(gpio);
399         if (gpio_get_value(gpio))
400                 button = 1;
401         else
402                 button = 0;
403
404         gpio_free(gpio);
405
406         return button;
407 }
408
409 /*
410  * This command returns the status of the user button on
411  * Input - none
412  * Returns -    1 if button is held down
413  *              0 if button is not held down
414  */
415 static int
416 do_userbutton(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
417 {
418         int button = 0;
419
420         button = get_button_state("button_usr1", BOARD_DEFAULT_BUTTON_GPIO);
421
422         if (argc > 1)
423                 printf("Button state: %u\n", button);
424
425         return button;
426 }
427
428 U_BOOT_CMD(
429         usrbutton, CONFIG_SYS_MAXARGS, 2, do_userbutton,
430         "Return the status of user button",
431         "[print]"
432 );
433
434 #define ERST    IMX_GPIO_NR(0, 3)
435
436 static int
437 do_eth_reset(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
438 {
439         gpio_request(ERST, "ERST");
440         gpio_direction_output(ERST, 0);
441         udelay(200);
442         gpio_set_value(ERST, 1);
443         return 0;
444 }
445
446 U_BOOT_CMD(
447         switch_rst, CONFIG_SYS_MAXARGS, 2, do_eth_reset,
448         "Reset eth phy",
449         "[print]"
450 );
451 #endif /* ! CONFIG_SPL_BUILD */