blob: 2f4679e211350b2a70d6bb6a0e305e3b4a32b9cd [file] [log] [blame]
Michal Simekf22651c2012-09-28 09:56:37 +00001/*
2 * (C) Copyright 2012 Michal Simek <monstr@monstr.eu>
Michal Simek3e1b61d2018-01-17 07:37:47 +01003 * (C) Copyright 2013 - 2018 Xilinx, Inc.
Michal Simekf22651c2012-09-28 09:56:37 +00004 *
Wolfgang Denk3765b3e2013-10-07 13:07:26 +02005 * SPDX-License-Identifier: GPL-2.0+
Michal Simekf22651c2012-09-28 09:56:37 +00006 */
7
8#include <common.h>
Michal Simeke6cc3b22018-02-21 17:04:28 +01009#include <dm/uclass.h>
Michal Simek9e0e37a2014-02-24 11:16:32 +010010#include <fdtdec.h>
Michal Simek5b73caf2014-04-25 13:51:17 +020011#include <fpga.h>
12#include <mmc.h>
Michal Simeke6cc3b22018-02-21 17:04:28 +010013#include <wdt.h>
Michal Simekd5dae852013-04-22 15:43:02 +020014#include <zynqpl.h>
Michal Simek71936532013-04-12 16:33:08 +020015#include <asm/arch/hardware.h>
16#include <asm/arch/sys_proto.h>
Michal Simek29fb5702017-11-10 13:01:10 +010017#include <asm/arch/ps7_init_gpl.h>
Michal Simekf22651c2012-09-28 09:56:37 +000018
19DECLARE_GLOBAL_DATA_PTR;
20
Michal Simek0b680202014-03-04 12:41:05 +010021#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \
22 (defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD))
Michal Simek5b73caf2014-04-25 13:51:17 +020023static xilinx_desc fpga;
Michal Simekd5dae852013-04-22 15:43:02 +020024
25/* It can be done differently */
Michal Simek05c59d02016-10-18 16:10:25 +020026static xilinx_desc fpga007s = XILINX_XC7Z007S_DESC(0x7);
Michal Simek5b73caf2014-04-25 13:51:17 +020027static xilinx_desc fpga010 = XILINX_XC7Z010_DESC(0x10);
Michal Simek05c59d02016-10-18 16:10:25 +020028static xilinx_desc fpga012s = XILINX_XC7Z012S_DESC(0x12);
29static xilinx_desc fpga014s = XILINX_XC7Z014S_DESC(0x14);
Michal Simek5b73caf2014-04-25 13:51:17 +020030static xilinx_desc fpga015 = XILINX_XC7Z015_DESC(0x15);
31static xilinx_desc fpga020 = XILINX_XC7Z020_DESC(0x20);
32static xilinx_desc fpga030 = XILINX_XC7Z030_DESC(0x30);
Siva Durga Prasad Paladugub9103802014-11-25 15:29:54 +053033static xilinx_desc fpga035 = XILINX_XC7Z035_DESC(0x35);
Michal Simek5b73caf2014-04-25 13:51:17 +020034static xilinx_desc fpga045 = XILINX_XC7Z045_DESC(0x45);
35static xilinx_desc fpga100 = XILINX_XC7Z100_DESC(0x100);
Michal Simekd5dae852013-04-22 15:43:02 +020036#endif
37
Michal Simeke6cc3b22018-02-21 17:04:28 +010038#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT)
39static struct udevice *watchdog_dev;
40#endif
41
42#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_BOARD_EARLY_INIT_F)
43int board_early_init_f(void)
44{
45# if defined(CONFIG_WDT)
46 /* bss is not cleared at time when watchdog_reset() is called */
47 watchdog_dev = NULL;
48# endif
49
50 return 0;
51}
52#endif
53
Michal Simekf22651c2012-09-28 09:56:37 +000054int board_init(void)
55{
Michal Simek0b680202014-03-04 12:41:05 +010056#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \
57 (defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD))
Michal Simekd5dae852013-04-22 15:43:02 +020058 u32 idcode;
59
60 idcode = zynq_slcr_get_idcode();
61
62 switch (idcode) {
Michal Simek05c59d02016-10-18 16:10:25 +020063 case XILINX_ZYNQ_7007S:
64 fpga = fpga007s;
65 break;
Michal Simekd5dae852013-04-22 15:43:02 +020066 case XILINX_ZYNQ_7010:
67 fpga = fpga010;
68 break;
Michal Simek05c59d02016-10-18 16:10:25 +020069 case XILINX_ZYNQ_7012S:
70 fpga = fpga012s;
71 break;
72 case XILINX_ZYNQ_7014S:
73 fpga = fpga014s;
74 break;
Michal Simek31993d62013-09-26 16:39:03 +020075 case XILINX_ZYNQ_7015:
76 fpga = fpga015;
77 break;
Michal Simekd5dae852013-04-22 15:43:02 +020078 case XILINX_ZYNQ_7020:
79 fpga = fpga020;
80 break;
81 case XILINX_ZYNQ_7030:
82 fpga = fpga030;
83 break;
Siva Durga Prasad Paladugub9103802014-11-25 15:29:54 +053084 case XILINX_ZYNQ_7035:
85 fpga = fpga035;
86 break;
Michal Simekd5dae852013-04-22 15:43:02 +020087 case XILINX_ZYNQ_7045:
88 fpga = fpga045;
89 break;
Michal Simekfd2b10b2013-06-17 13:54:07 +020090 case XILINX_ZYNQ_7100:
91 fpga = fpga100;
92 break;
Michal Simekd5dae852013-04-22 15:43:02 +020093 }
94#endif
95
Michal Simeke6cc3b22018-02-21 17:04:28 +010096#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT)
97 if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) {
98 puts("Watchdog: Not found!\n");
99 } else {
100 wdt_start(watchdog_dev, 0, 0);
101 puts("Watchdog: Started\n");
102 }
103# endif
104
Michal Simek0b680202014-03-04 12:41:05 +0100105#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \
106 (defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD))
Michal Simekd5dae852013-04-22 15:43:02 +0200107 fpga_init();
108 fpga_add(fpga_xilinx, &fpga);
109#endif
110
Michal Simekf22651c2012-09-28 09:56:37 +0000111 return 0;
112}
113
Jagannadha Sutradharudu Tekib3de9242014-01-09 01:48:21 +0530114int board_late_init(void)
115{
116 switch ((zynq_slcr_get_boot_mode()) & ZYNQ_BM_MASK) {
Michal Simek085b2b82016-12-16 13:16:14 +0100117 case ZYNQ_BM_QSPI:
Simon Glass382bee52017-08-03 12:22:09 -0600118 env_set("modeboot", "qspiboot");
Michal Simek085b2b82016-12-16 13:16:14 +0100119 break;
120 case ZYNQ_BM_NAND:
Simon Glass382bee52017-08-03 12:22:09 -0600121 env_set("modeboot", "nandboot");
Michal Simek085b2b82016-12-16 13:16:14 +0100122 break;
Jagannadha Sutradharudu Tekib3de9242014-01-09 01:48:21 +0530123 case ZYNQ_BM_NOR:
Simon Glass382bee52017-08-03 12:22:09 -0600124 env_set("modeboot", "norboot");
Jagannadha Sutradharudu Tekib3de9242014-01-09 01:48:21 +0530125 break;
126 case ZYNQ_BM_SD:
Simon Glass382bee52017-08-03 12:22:09 -0600127 env_set("modeboot", "sdboot");
Jagannadha Sutradharudu Tekib3de9242014-01-09 01:48:21 +0530128 break;
129 case ZYNQ_BM_JTAG:
Simon Glass382bee52017-08-03 12:22:09 -0600130 env_set("modeboot", "jtagboot");
Jagannadha Sutradharudu Tekib3de9242014-01-09 01:48:21 +0530131 break;
132 default:
Simon Glass382bee52017-08-03 12:22:09 -0600133 env_set("modeboot", "");
Jagannadha Sutradharudu Tekib3de9242014-01-09 01:48:21 +0530134 break;
135 }
136
137 return 0;
138}
Michal Simekf22651c2012-09-28 09:56:37 +0000139
Michal Simek5a82d532014-08-28 13:31:02 +0200140#ifdef CONFIG_DISPLAY_BOARDINFO
141int checkboard(void)
142{
Michal Simek29fb5702017-11-10 13:01:10 +0100143 u32 version = zynq_get_silicon_version();
144
145 version <<= 1;
146 if (version > (PCW_SILICON_VERSION_3 << 1))
147 version += 1;
148
Michal Simek5af08552016-01-25 11:04:21 +0100149 puts("Board: Xilinx Zynq\n");
Michal Simek29fb5702017-11-10 13:01:10 +0100150 printf("Silicon: v%d.%d\n", version >> 1, version & 1);
151
Michal Simek5a82d532014-08-28 13:31:02 +0200152 return 0;
153}
154#endif
155
Joe Hershbergera509a1d2016-01-26 11:57:03 -0600156int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
157{
158#if defined(CONFIG_ZYNQ_GEM_EEPROM_ADDR) && \
159 defined(CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET)
160 if (eeprom_read(CONFIG_ZYNQ_GEM_EEPROM_ADDR,
161 CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET,
162 ethaddr, 6))
163 printf("I2C EEPROM MAC address read failed\n");
164#endif
165
166 return 0;
167}
168
Michal Simek758f29d2016-04-01 15:56:33 +0200169#if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
Simon Glass76b00ac2017-03-31 08:40:32 -0600170int dram_init_banksize(void)
Tom Rini361a8792016-12-09 07:56:54 -0500171{
Michal Simekda3f0032017-11-03 15:25:51 +0100172 return fdtdec_setup_memory_banksize();
Michal Simek758f29d2016-04-01 15:56:33 +0200173}
174
Michal Simek8a5db0a2016-12-06 16:31:53 +0100175int dram_init(void)
176{
Nathan Rosside9bf1b2016-12-19 00:03:34 +1000177 if (fdtdec_setup_memory_size() != 0)
178 return -EINVAL;
Michal Simek8a5db0a2016-12-06 16:31:53 +0100179
180 zynq_ddrc_init();
181
182 return 0;
183}
Michal Simek758f29d2016-04-01 15:56:33 +0200184#else
185int dram_init(void)
186{
Michal Simek61dc92a2018-04-11 16:12:28 +0200187 gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
188 CONFIG_SYS_SDRAM_SIZE);
Michal Simek758f29d2016-04-01 15:56:33 +0200189
190 zynq_ddrc_init();
191
192 return 0;
193}
194#endif
Michal Simeke6cc3b22018-02-21 17:04:28 +0100195
196#if defined(CONFIG_WATCHDOG)
197/* Called by macro WATCHDOG_RESET */
198void watchdog_reset(void)
199{
200# if !defined(CONFIG_SPL_BUILD)
201 static ulong next_reset;
202 ulong now;
203
204 if (!watchdog_dev)
205 return;
206
207 now = timer_get_us();
208
209 /* Do not reset the watchdog too often */
210 if (now > next_reset) {
211 wdt_reset(watchdog_dev);
212 next_reset = now + 1000;
213 }
214# endif
215}
216#endif