xref: /openbmc/u-boot/board/xilinx/zynq/board.c (revision ccd063e9812a2bdcbeafbbcd8dcb062bfc290f24)
183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2f22651cfSMichal Simek /*
3f22651cfSMichal Simek  * (C) Copyright 2012 Michal Simek <monstr@monstr.eu>
43e1b61deSMichal Simek  * (C) Copyright 2013 - 2018 Xilinx, Inc.
5f22651cfSMichal Simek  */
6f22651cfSMichal Simek 
7f22651cfSMichal Simek #include <common.h>
8e6cc3b25SMichal Simek #include <dm/uclass.h>
99e0e37acSMichal Simek #include <fdtdec.h>
105b73caffSMichal Simek #include <fpga.h>
113c7b4c35SSiva Durga Prasad Paladugu #include <malloc.h>
125b73caffSMichal Simek #include <mmc.h>
130ecd14e6SMichal Simek #include <watchdog.h>
14e6cc3b25SMichal Simek #include <wdt.h>
15d5dae85fSMichal Simek #include <zynqpl.h>
167193653eSMichal Simek #include <asm/arch/hardware.h>
177193653eSMichal Simek #include <asm/arch/sys_proto.h>
18f22651cfSMichal Simek 
19f22651cfSMichal Simek DECLARE_GLOBAL_DATA_PTR;
20f22651cfSMichal Simek 
21e6cc3b25SMichal Simek #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT)
22*ccd063e9SStefan Roese static struct udevice *watchdog_dev __attribute__((section(".data"))) = NULL;
23e6cc3b25SMichal Simek #endif
24e6cc3b25SMichal Simek 
25e6cc3b25SMichal Simek #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_BOARD_EARLY_INIT_F)
board_early_init_f(void)26e6cc3b25SMichal Simek int board_early_init_f(void)
27e6cc3b25SMichal Simek {
28e6cc3b25SMichal Simek 	return 0;
29e6cc3b25SMichal Simek }
30e6cc3b25SMichal Simek #endif
31e6cc3b25SMichal Simek 
board_init(void)32f22651cfSMichal Simek int board_init(void)
33f22651cfSMichal Simek {
34e6cc3b25SMichal Simek #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT)
35501fc50aSMichal Simek 	if (uclass_get_device_by_seq(UCLASS_WDT, 0, &watchdog_dev)) {
36501fc50aSMichal Simek 		debug("Watchdog: Not found by seq!\n");
37e6cc3b25SMichal Simek 		if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) {
38e6cc3b25SMichal Simek 			puts("Watchdog: Not found!\n");
39501fc50aSMichal Simek 			return 0;
40501fc50aSMichal Simek 		}
41501fc50aSMichal Simek 	}
42501fc50aSMichal Simek 
43e6cc3b25SMichal Simek 	wdt_start(watchdog_dev, 0, 0);
44e6cc3b25SMichal Simek 	puts("Watchdog: Started\n");
45e6cc3b25SMichal Simek # endif
46e6cc3b25SMichal Simek 
47f22651cfSMichal Simek 	return 0;
48f22651cfSMichal Simek }
49f22651cfSMichal Simek 
board_late_init(void)50b3de9249SJagannadha Sutradharudu Teki int board_late_init(void)
51b3de9249SJagannadha Sutradharudu Teki {
523c7b4c35SSiva Durga Prasad Paladugu 	int env_targets_len = 0;
533c7b4c35SSiva Durga Prasad Paladugu 	const char *mode;
543c7b4c35SSiva Durga Prasad Paladugu 	char *new_targets;
553c7b4c35SSiva Durga Prasad Paladugu 	char *env_targets;
563c7b4c35SSiva Durga Prasad Paladugu 
57b3de9249SJagannadha Sutradharudu Teki 	switch ((zynq_slcr_get_boot_mode()) & ZYNQ_BM_MASK) {
58085b2b82SMichal Simek 	case ZYNQ_BM_QSPI:
593c7b4c35SSiva Durga Prasad Paladugu 		mode = "qspi";
60382bee57SSimon Glass 		env_set("modeboot", "qspiboot");
61085b2b82SMichal Simek 		break;
62085b2b82SMichal Simek 	case ZYNQ_BM_NAND:
633c7b4c35SSiva Durga Prasad Paladugu 		mode = "nand";
64382bee57SSimon Glass 		env_set("modeboot", "nandboot");
65085b2b82SMichal Simek 		break;
66b3de9249SJagannadha Sutradharudu Teki 	case ZYNQ_BM_NOR:
673c7b4c35SSiva Durga Prasad Paladugu 		mode = "nor";
68382bee57SSimon Glass 		env_set("modeboot", "norboot");
69b3de9249SJagannadha Sutradharudu Teki 		break;
70b3de9249SJagannadha Sutradharudu Teki 	case ZYNQ_BM_SD:
713c7b4c35SSiva Durga Prasad Paladugu 		mode = "mmc";
72382bee57SSimon Glass 		env_set("modeboot", "sdboot");
73b3de9249SJagannadha Sutradharudu Teki 		break;
74b3de9249SJagannadha Sutradharudu Teki 	case ZYNQ_BM_JTAG:
753c7b4c35SSiva Durga Prasad Paladugu 		mode = "pxe dhcp";
76382bee57SSimon Glass 		env_set("modeboot", "jtagboot");
77b3de9249SJagannadha Sutradharudu Teki 		break;
78b3de9249SJagannadha Sutradharudu Teki 	default:
793c7b4c35SSiva Durga Prasad Paladugu 		mode = "";
80382bee57SSimon Glass 		env_set("modeboot", "");
81b3de9249SJagannadha Sutradharudu Teki 		break;
82b3de9249SJagannadha Sutradharudu Teki 	}
83b3de9249SJagannadha Sutradharudu Teki 
843c7b4c35SSiva Durga Prasad Paladugu 	/*
853c7b4c35SSiva Durga Prasad Paladugu 	 * One terminating char + one byte for space between mode
863c7b4c35SSiva Durga Prasad Paladugu 	 * and default boot_targets
873c7b4c35SSiva Durga Prasad Paladugu 	 */
883c7b4c35SSiva Durga Prasad Paladugu 	env_targets = env_get("boot_targets");
893c7b4c35SSiva Durga Prasad Paladugu 	if (env_targets)
903c7b4c35SSiva Durga Prasad Paladugu 		env_targets_len = strlen(env_targets);
913c7b4c35SSiva Durga Prasad Paladugu 
923c7b4c35SSiva Durga Prasad Paladugu 	new_targets = calloc(1, strlen(mode) + env_targets_len + 2);
933c7b4c35SSiva Durga Prasad Paladugu 	if (!new_targets)
943c7b4c35SSiva Durga Prasad Paladugu 		return -ENOMEM;
953c7b4c35SSiva Durga Prasad Paladugu 
963c7b4c35SSiva Durga Prasad Paladugu 	sprintf(new_targets, "%s %s", mode,
973c7b4c35SSiva Durga Prasad Paladugu 		env_targets ? env_targets : "");
983c7b4c35SSiva Durga Prasad Paladugu 
993c7b4c35SSiva Durga Prasad Paladugu 	env_set("boot_targets", new_targets);
1003c7b4c35SSiva Durga Prasad Paladugu 
101b3de9249SJagannadha Sutradharudu Teki 	return 0;
102b3de9249SJagannadha Sutradharudu Teki }
103f22651cfSMichal Simek 
104758f29d0SMichal Simek #if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
dram_init_banksize(void)10576b00acaSSimon Glass int dram_init_banksize(void)
106361a8799STom Rini {
107da3f003bSMichal Simek 	return fdtdec_setup_memory_banksize();
108758f29d0SMichal Simek }
109758f29d0SMichal Simek 
dram_init(void)1108a5db0abSMichal Simek int dram_init(void)
1118a5db0abSMichal Simek {
11212308b12SSiva Durga Prasad Paladugu 	if (fdtdec_setup_mem_size_base() != 0)
113de9bf1b5SNathan Rossi 		return -EINVAL;
1148a5db0abSMichal Simek 
1158a5db0abSMichal Simek 	zynq_ddrc_init();
1168a5db0abSMichal Simek 
1178a5db0abSMichal Simek 	return 0;
1188a5db0abSMichal Simek }
119758f29d0SMichal Simek #else
dram_init(void)120758f29d0SMichal Simek int dram_init(void)
121758f29d0SMichal Simek {
12261dc92a2SMichal Simek 	gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
12361dc92a2SMichal Simek 				    CONFIG_SYS_SDRAM_SIZE);
124758f29d0SMichal Simek 
125758f29d0SMichal Simek 	zynq_ddrc_init();
126758f29d0SMichal Simek 
127758f29d0SMichal Simek 	return 0;
128758f29d0SMichal Simek }
129758f29d0SMichal Simek #endif
130e6cc3b25SMichal Simek 
131e6cc3b25SMichal Simek #if defined(CONFIG_WATCHDOG)
132e6cc3b25SMichal Simek /* Called by macro WATCHDOG_RESET */
watchdog_reset(void)133e6cc3b25SMichal Simek void watchdog_reset(void)
134e6cc3b25SMichal Simek {
135e6cc3b25SMichal Simek # if !defined(CONFIG_SPL_BUILD)
136e6cc3b25SMichal Simek 	static ulong next_reset;
137e6cc3b25SMichal Simek 	ulong now;
138e6cc3b25SMichal Simek 
139e6cc3b25SMichal Simek 	if (!watchdog_dev)
140e6cc3b25SMichal Simek 		return;
141e6cc3b25SMichal Simek 
142e6cc3b25SMichal Simek 	now = timer_get_us();
143e6cc3b25SMichal Simek 
144e6cc3b25SMichal Simek 	/* Do not reset the watchdog too often */
145e6cc3b25SMichal Simek 	if (now > next_reset) {
146e6cc3b25SMichal Simek 		wdt_reset(watchdog_dev);
147e6cc3b25SMichal Simek 		next_reset = now + 1000;
148e6cc3b25SMichal Simek 	}
149e6cc3b25SMichal Simek # endif
150e6cc3b25SMichal Simek }
151e6cc3b25SMichal Simek #endif
152