blob: fe36cf7eff8c9891d62e1c9994fa684ea177ad56 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Michal Simekaf482d52012-09-28 09:56:37 +00002/*
3 * (C) Copyright 2012 Michal Simek <monstr@monstr.eu>
Michal Simek98d0f1f2018-01-17 07:37:47 +01004 * (C) Copyright 2013 - 2018 Xilinx, Inc.
Michal Simekaf482d52012-09-28 09:56:37 +00005 */
6
7#include <common.h>
Michal Simek309ef802018-02-21 17:04:28 +01008#include <dm/uclass.h>
Michal Simek65ef52f2014-02-24 11:16:32 +01009#include <fdtdec.h>
Michal Simek0f796702014-04-25 13:51:17 +020010#include <fpga.h>
11#include <mmc.h>
Michal Simek309ef802018-02-21 17:04:28 +010012#include <wdt.h>
Michal Simek15d654c2013-04-22 15:43:02 +020013#include <zynqpl.h>
Michal Simek242192b2013-04-12 16:33:08 +020014#include <asm/arch/hardware.h>
15#include <asm/arch/sys_proto.h>
Michal Simekb8262d02017-11-10 13:01:10 +010016#include <asm/arch/ps7_init_gpl.h>
Michal Simekaf482d52012-09-28 09:56:37 +000017
18DECLARE_GLOBAL_DATA_PTR;
19
Michal Simekda713862014-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 Simek0f796702014-04-25 13:51:17 +020022static xilinx_desc fpga;
Michal Simek15d654c2013-04-22 15:43:02 +020023
24/* It can be done differently */
Michal Simek82c97022016-10-18 16:10:25 +020025static xilinx_desc fpga007s = XILINX_XC7Z007S_DESC(0x7);
Michal Simek0f796702014-04-25 13:51:17 +020026static xilinx_desc fpga010 = XILINX_XC7Z010_DESC(0x10);
Michal Simek82c97022016-10-18 16:10:25 +020027static xilinx_desc fpga012s = XILINX_XC7Z012S_DESC(0x12);
28static xilinx_desc fpga014s = XILINX_XC7Z014S_DESC(0x14);
Michal Simek0f796702014-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 Paladugu77fc12c2014-11-25 15:29:54 +053032static xilinx_desc fpga035 = XILINX_XC7Z035_DESC(0x35);
Michal Simek0f796702014-04-25 13:51:17 +020033static xilinx_desc fpga045 = XILINX_XC7Z045_DESC(0x45);
34static xilinx_desc fpga100 = XILINX_XC7Z100_DESC(0x100);
Michal Simek15d654c2013-04-22 15:43:02 +020035#endif
36
Michal Simek309ef802018-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 Simekaf482d52012-09-28 09:56:37 +000053int board_init(void)
54{
Michal Simekda713862014-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 Simek15d654c2013-04-22 15:43:02 +020057 u32 idcode;
58
59 idcode = zynq_slcr_get_idcode();
60
61 switch (idcode) {
Michal Simek82c97022016-10-18 16:10:25 +020062 case XILINX_ZYNQ_7007S:
63 fpga = fpga007s;
64 break;
Michal Simek15d654c2013-04-22 15:43:02 +020065 case XILINX_ZYNQ_7010:
66 fpga = fpga010;
67 break;
Michal Simek82c97022016-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 Simek0e91d3a2013-09-26 16:39:03 +020074 case XILINX_ZYNQ_7015:
75 fpga = fpga015;
76 break;
Michal Simek15d654c2013-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 Paladugu77fc12c2014-11-25 15:29:54 +053083 case XILINX_ZYNQ_7035:
84 fpga = fpga035;
85 break;
Michal Simek15d654c2013-04-22 15:43:02 +020086 case XILINX_ZYNQ_7045:
87 fpga = fpga045;
88 break;
Michal Simek52f91b52013-06-17 13:54:07 +020089 case XILINX_ZYNQ_7100:
90 fpga = fpga100;
91 break;
Michal Simek15d654c2013-04-22 15:43:02 +020092 }
93#endif
94
Michal Simek309ef802018-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 Simekda713862014-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 Simek15d654c2013-04-22 15:43:02 +0200106 fpga_init();
107 fpga_add(fpga_xilinx, &fpga);
108#endif
109
Michal Simekaf482d52012-09-28 09:56:37 +0000110 return 0;
111}
112
Jagannadha Sutradharudu Teki11704c22014-01-09 01:48:21 +0530113int board_late_init(void)
114{
115 switch ((zynq_slcr_get_boot_mode()) & ZYNQ_BM_MASK) {
Michal Simek19356712016-12-16 13:16:14 +0100116 case ZYNQ_BM_QSPI:
Simon Glass6a38e412017-08-03 12:22:09 -0600117 env_set("modeboot", "qspiboot");
Michal Simek19356712016-12-16 13:16:14 +0100118 break;
119 case ZYNQ_BM_NAND:
Simon Glass6a38e412017-08-03 12:22:09 -0600120 env_set("modeboot", "nandboot");
Michal Simek19356712016-12-16 13:16:14 +0100121 break;
Jagannadha Sutradharudu Teki11704c22014-01-09 01:48:21 +0530122 case ZYNQ_BM_NOR:
Simon Glass6a38e412017-08-03 12:22:09 -0600123 env_set("modeboot", "norboot");
Jagannadha Sutradharudu Teki11704c22014-01-09 01:48:21 +0530124 break;
125 case ZYNQ_BM_SD:
Simon Glass6a38e412017-08-03 12:22:09 -0600126 env_set("modeboot", "sdboot");
Jagannadha Sutradharudu Teki11704c22014-01-09 01:48:21 +0530127 break;
128 case ZYNQ_BM_JTAG:
Simon Glass6a38e412017-08-03 12:22:09 -0600129 env_set("modeboot", "jtagboot");
Jagannadha Sutradharudu Teki11704c22014-01-09 01:48:21 +0530130 break;
131 default:
Simon Glass6a38e412017-08-03 12:22:09 -0600132 env_set("modeboot", "");
Jagannadha Sutradharudu Teki11704c22014-01-09 01:48:21 +0530133 break;
134 }
135
136 return 0;
137}
Michal Simekaf482d52012-09-28 09:56:37 +0000138
Michal Simek3fa64452014-08-28 13:31:02 +0200139#ifdef CONFIG_DISPLAY_BOARDINFO
140int checkboard(void)
141{
Michal Simekb8262d02017-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 Simek47ce9362016-01-25 11:04:21 +0100148 puts("Board: Xilinx Zynq\n");
Michal Simekb8262d02017-11-10 13:01:10 +0100149 printf("Silicon: v%d.%d\n", version >> 1, version & 1);
150
Michal Simek3fa64452014-08-28 13:31:02 +0200151 return 0;
152}
153#endif
154
Joe Hershberger7f4e5552016-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 Simekf4780a72016-04-01 15:56:33 +0200168#if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
Simon Glass2f949c32017-03-31 08:40:32 -0600169int dram_init_banksize(void)
Nathan Rossic12892b2016-12-04 19:33:22 +1000170{
Michal Simekd5b7de62017-11-03 15:25:51 +0100171 return fdtdec_setup_memory_banksize();
Tom Riniedcfdbd2016-12-09 07:56:54 -0500172}
Michal Simekf4780a72016-04-01 15:56:33 +0200173
Tom Riniedcfdbd2016-12-09 07:56:54 -0500174int dram_init(void)
175{
Nathan Rossi58ea0d82016-12-19 00:03:34 +1000176 if (fdtdec_setup_memory_size() != 0)
177 return -EINVAL;
Tom Riniedcfdbd2016-12-09 07:56:54 -0500178
179 zynq_ddrc_init();
180
181 return 0;
Michal Simekf4780a72016-04-01 15:56:33 +0200182}
Michal Simekf4780a72016-04-01 15:56:33 +0200183#else
184int dram_init(void)
185{
Michal Simek1b846212018-04-11 16:12:28 +0200186 gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
187 CONFIG_SYS_SDRAM_SIZE);
Michal Simekf4780a72016-04-01 15:56:33 +0200188
Michal Simekf5ff7bc2013-06-17 14:37:01 +0200189 zynq_ddrc_init();
190
Michal Simekaf482d52012-09-28 09:56:37 +0000191 return 0;
192}
Michal Simekf4780a72016-04-01 15:56:33 +0200193#endif
Michal Simek309ef802018-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