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