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