blob: fe36cf7eff8c9891d62e1c9994fa684ea177ad56 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Michal Simekf22651c2012-09-28 09:56:37 +00002/*
3 * (C) Copyright 2012 Michal Simek <monstr@monstr.eu>
Michal Simek3e1b61d2018-01-17 07:37:47 +01004 * (C) Copyright 2013 - 2018 Xilinx, Inc.
Michal Simekf22651c2012-09-28 09:56:37 +00005 */
6
7#include <common.h>
Michal Simeke6cc3b22018-02-21 17:04:28 +01008#include <dm/uclass.h>
Michal Simek9e0e37a2014-02-24 11:16:32 +01009#include <fdtdec.h>
Michal Simek5b73caf2014-04-25 13:51:17 +020010#include <fpga.h>
11#include <mmc.h>
Michal Simeke6cc3b22018-02-21 17:04:28 +010012#include <wdt.h>
Michal Simekd5dae852013-04-22 15:43:02 +020013#include <zynqpl.h>
Michal Simek71936532013-04-12 16:33:08 +020014#include <asm/arch/hardware.h>
15#include <asm/arch/sys_proto.h>
Michal Simek29fb5702017-11-10 13:01:10 +010016#include <asm/arch/ps7_init_gpl.h>
Michal Simekf22651c2012-09-28 09:56:37 +000017
18DECLARE_GLOBAL_DATA_PTR;
19
Michal Simek0b680202014-03-04 12:41:05 +010020#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \
21 (defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD))
Michal Simek5b73caf2014-04-25 13:51:17 +020022static xilinx_desc fpga;
Michal Simekd5dae852013-04-22 15:43:02 +020023
24/* It can be done differently */
Michal Simek05c59d02016-10-18 16:10:25 +020025static xilinx_desc fpga007s = XILINX_XC7Z007S_DESC(0x7);
Michal Simek5b73caf2014-04-25 13:51:17 +020026static xilinx_desc fpga010 = XILINX_XC7Z010_DESC(0x10);
Michal Simek05c59d02016-10-18 16:10:25 +020027static xilinx_desc fpga012s = XILINX_XC7Z012S_DESC(0x12);
28static xilinx_desc fpga014s = XILINX_XC7Z014S_DESC(0x14);
Michal Simek5b73caf2014-04-25 13:51:17 +020029static xilinx_desc fpga015 = XILINX_XC7Z015_DESC(0x15);
30static xilinx_desc fpga020 = XILINX_XC7Z020_DESC(0x20);
31static xilinx_desc fpga030 = XILINX_XC7Z030_DESC(0x30);
Siva Durga Prasad Paladugub9103802014-11-25 15:29:54 +053032static xilinx_desc fpga035 = XILINX_XC7Z035_DESC(0x35);
Michal Simek5b73caf2014-04-25 13:51:17 +020033static xilinx_desc fpga045 = XILINX_XC7Z045_DESC(0x45);
34static xilinx_desc fpga100 = XILINX_XC7Z100_DESC(0x100);
Michal Simekd5dae852013-04-22 15:43:02 +020035#endif
36
Michal Simeke6cc3b22018-02-21 17:04:28 +010037#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT)
38static struct udevice *watchdog_dev;
39#endif
40
41#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_BOARD_EARLY_INIT_F)
42int board_early_init_f(void)
43{
44# if defined(CONFIG_WDT)
45 /* bss is not cleared at time when watchdog_reset() is called */
46 watchdog_dev = NULL;
47# endif
48
49 return 0;
50}
51#endif
52
Michal Simekf22651c2012-09-28 09:56:37 +000053int board_init(void)
54{
Michal Simek0b680202014-03-04 12:41:05 +010055#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \
56 (defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD))
Michal Simekd5dae852013-04-22 15:43:02 +020057 u32 idcode;
58
59 idcode = zynq_slcr_get_idcode();
60
61 switch (idcode) {
Michal Simek05c59d02016-10-18 16:10:25 +020062 case XILINX_ZYNQ_7007S:
63 fpga = fpga007s;
64 break;
Michal Simekd5dae852013-04-22 15:43:02 +020065 case XILINX_ZYNQ_7010:
66 fpga = fpga010;
67 break;
Michal Simek05c59d02016-10-18 16:10:25 +020068 case XILINX_ZYNQ_7012S:
69 fpga = fpga012s;
70 break;
71 case XILINX_ZYNQ_7014S:
72 fpga = fpga014s;
73 break;
Michal Simek31993d62013-09-26 16:39:03 +020074 case XILINX_ZYNQ_7015:
75 fpga = fpga015;
76 break;
Michal Simekd5dae852013-04-22 15:43:02 +020077 case XILINX_ZYNQ_7020:
78 fpga = fpga020;
79 break;
80 case XILINX_ZYNQ_7030:
81 fpga = fpga030;
82 break;
Siva Durga Prasad Paladugub9103802014-11-25 15:29:54 +053083 case XILINX_ZYNQ_7035:
84 fpga = fpga035;
85 break;
Michal Simekd5dae852013-04-22 15:43:02 +020086 case XILINX_ZYNQ_7045:
87 fpga = fpga045;
88 break;
Michal Simekfd2b10b2013-06-17 13:54:07 +020089 case XILINX_ZYNQ_7100:
90 fpga = fpga100;
91 break;
Michal Simekd5dae852013-04-22 15:43:02 +020092 }
93#endif
94
Michal Simeke6cc3b22018-02-21 17:04:28 +010095#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT)
96 if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) {
97 puts("Watchdog: Not found!\n");
98 } else {
99 wdt_start(watchdog_dev, 0, 0);
100 puts("Watchdog: Started\n");
101 }
102# endif
103
Michal Simek0b680202014-03-04 12:41:05 +0100104#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \
105 (defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD))
Michal Simekd5dae852013-04-22 15:43:02 +0200106 fpga_init();
107 fpga_add(fpga_xilinx, &fpga);
108#endif
109
Michal Simekf22651c2012-09-28 09:56:37 +0000110 return 0;
111}
112
Jagannadha Sutradharudu Tekib3de9242014-01-09 01:48:21 +0530113int board_late_init(void)
114{
115 switch ((zynq_slcr_get_boot_mode()) & ZYNQ_BM_MASK) {
Michal Simek085b2b82016-12-16 13:16:14 +0100116 case ZYNQ_BM_QSPI:
Simon Glass382bee52017-08-03 12:22:09 -0600117 env_set("modeboot", "qspiboot");
Michal Simek085b2b82016-12-16 13:16:14 +0100118 break;
119 case ZYNQ_BM_NAND:
Simon Glass382bee52017-08-03 12:22:09 -0600120 env_set("modeboot", "nandboot");
Michal Simek085b2b82016-12-16 13:16:14 +0100121 break;
Jagannadha Sutradharudu Tekib3de9242014-01-09 01:48:21 +0530122 case ZYNQ_BM_NOR:
Simon Glass382bee52017-08-03 12:22:09 -0600123 env_set("modeboot", "norboot");
Jagannadha Sutradharudu Tekib3de9242014-01-09 01:48:21 +0530124 break;
125 case ZYNQ_BM_SD:
Simon Glass382bee52017-08-03 12:22:09 -0600126 env_set("modeboot", "sdboot");
Jagannadha Sutradharudu Tekib3de9242014-01-09 01:48:21 +0530127 break;
128 case ZYNQ_BM_JTAG:
Simon Glass382bee52017-08-03 12:22:09 -0600129 env_set("modeboot", "jtagboot");
Jagannadha Sutradharudu Tekib3de9242014-01-09 01:48:21 +0530130 break;
131 default:
Simon Glass382bee52017-08-03 12:22:09 -0600132 env_set("modeboot", "");
Jagannadha Sutradharudu Tekib3de9242014-01-09 01:48:21 +0530133 break;
134 }
135
136 return 0;
137}
Michal Simekf22651c2012-09-28 09:56:37 +0000138
Michal Simek5a82d532014-08-28 13:31:02 +0200139#ifdef CONFIG_DISPLAY_BOARDINFO
140int checkboard(void)
141{
Michal Simek29fb5702017-11-10 13:01:10 +0100142 u32 version = zynq_get_silicon_version();
143
144 version <<= 1;
145 if (version > (PCW_SILICON_VERSION_3 << 1))
146 version += 1;
147
Michal Simek5af08552016-01-25 11:04:21 +0100148 puts("Board: Xilinx Zynq\n");
Michal Simek29fb5702017-11-10 13:01:10 +0100149 printf("Silicon: v%d.%d\n", version >> 1, version & 1);
150
Michal Simek5a82d532014-08-28 13:31:02 +0200151 return 0;
152}
153#endif
154
Joe Hershbergera509a1d2016-01-26 11:57:03 -0600155int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
156{
157#if defined(CONFIG_ZYNQ_GEM_EEPROM_ADDR) && \
158 defined(CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET)
159 if (eeprom_read(CONFIG_ZYNQ_GEM_EEPROM_ADDR,
160 CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET,
161 ethaddr, 6))
162 printf("I2C EEPROM MAC address read failed\n");
163#endif
164
165 return 0;
166}
167
Michal Simek758f29d2016-04-01 15:56:33 +0200168#if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
Simon Glass76b00ac2017-03-31 08:40:32 -0600169int dram_init_banksize(void)
Tom Rini361a8792016-12-09 07:56:54 -0500170{
Michal Simekda3f0032017-11-03 15:25:51 +0100171 return fdtdec_setup_memory_banksize();
Michal Simek758f29d2016-04-01 15:56:33 +0200172}
173
Michal Simek8a5db0a2016-12-06 16:31:53 +0100174int dram_init(void)
175{
Nathan Rosside9bf1b2016-12-19 00:03:34 +1000176 if (fdtdec_setup_memory_size() != 0)
177 return -EINVAL;
Michal Simek8a5db0a2016-12-06 16:31:53 +0100178
179 zynq_ddrc_init();
180
181 return 0;
182}
Michal Simek758f29d2016-04-01 15:56:33 +0200183#else
184int dram_init(void)
185{
Michal Simek61dc92a2018-04-11 16:12:28 +0200186 gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
187 CONFIG_SYS_SDRAM_SIZE);
Michal Simek758f29d2016-04-01 15:56:33 +0200188
189 zynq_ddrc_init();
190
191 return 0;
192}
193#endif
Michal Simeke6cc3b22018-02-21 17:04:28 +0100194
195#if defined(CONFIG_WATCHDOG)
196/* Called by macro WATCHDOG_RESET */
197void watchdog_reset(void)
198{
199# if !defined(CONFIG_SPL_BUILD)
200 static ulong next_reset;
201 ulong now;
202
203 if (!watchdog_dev)
204 return;
205
206 now = timer_get_us();
207
208 /* Do not reset the watchdog too often */
209 if (now > next_reset) {
210 wdt_reset(watchdog_dev);
211 next_reset = now + 1000;
212 }
213# endif
214}
215#endif