blob: 81663e0cd0ed14d123c84429dc053b6729ce2645 [file] [log] [blame]
Michal Simekec48b6c2018-08-22 14:55:27 +02001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2014 - 2018 Xilinx, Inc.
4 * Michal Simek <michal.simek@xilinx.com>
5 */
6
7#include <common.h>
Simon Glass9a3b4ce2019-12-28 10:45:01 -07008#include <cpu_func.h>
Simon Glass09140112020-05-10 11:40:03 -06009#include <env.h>
Michal Simekec48b6c2018-08-22 14:55:27 +020010#include <fdtdec.h>
Simon Glass52559322019-11-14 12:57:46 -070011#include <init.h>
Michal Simekf66d0b52022-03-17 15:25:31 +010012#include <image.h>
Ashok Reddy Soma4fb83c92021-02-23 08:07:46 -070013#include <env_internal.h>
Simon Glassf7ae49f2020-05-10 11:40:05 -060014#include <log.h>
Michal Simekec48b6c2018-08-22 14:55:27 +020015#include <malloc.h>
Simon Glass10453152019-11-14 12:57:30 -070016#include <time.h>
Simon Glass90526e92020-05-10 11:39:56 -060017#include <asm/cache.h>
Simon Glass401d1c42020-10-30 21:38:53 -060018#include <asm/global_data.h>
Michal Simekec48b6c2018-08-22 14:55:27 +020019#include <asm/io.h>
20#include <asm/arch/hardware.h>
Michal Simekaef149e2019-04-29 09:39:09 -070021#include <asm/arch/sys_proto.h>
Siva Durga Prasad Paladugubfd092f2019-01-31 17:28:14 +053022#include <dm/device.h>
23#include <dm/uclass.h>
Siva Durga Prasad Paladugu26e054c2019-08-05 15:54:59 +053024#include <versalpl.h>
Michal Simek80fdef12020-03-31 12:39:37 +020025#include "../common/board.h"
Michal Simekec48b6c2018-08-22 14:55:27 +020026
27DECLARE_GLOBAL_DATA_PTR;
28
Siva Durga Prasad Paladugu26e054c2019-08-05 15:54:59 +053029#if defined(CONFIG_FPGA_VERSALPL)
30static xilinx_desc versalpl = XILINX_VERSAL_DESC;
31#endif
32
Michal Simekec48b6c2018-08-22 14:55:27 +020033int board_init(void)
34{
35 printf("EL Level:\tEL%d\n", current_el());
36
Siva Durga Prasad Paladugu26e054c2019-08-05 15:54:59 +053037#if defined(CONFIG_FPGA_VERSALPL)
38 fpga_init();
39 fpga_add(fpga_xilinx, &versalpl);
40#endif
41
Michal Simekd61728c2020-08-03 13:01:45 +020042 if (CONFIG_IS_ENABLED(DM_I2C) && CONFIG_IS_ENABLED(I2C_EEPROM))
43 xilinx_read_eeprom();
44
Michal Simekec48b6c2018-08-22 14:55:27 +020045 return 0;
46}
47
48int board_early_init_r(void)
49{
Michal Simekfb771792019-01-28 11:08:00 +010050 u32 val;
Michal Simekec48b6c2018-08-22 14:55:27 +020051
Michal Simekfb771792019-01-28 11:08:00 +010052 if (current_el() != 3)
53 return 0;
Michal Simekec48b6c2018-08-22 14:55:27 +020054
Michal Simek47a766f2019-01-28 11:12:41 +010055 debug("iou_switch ctrl div0 %x\n",
56 readl(&crlapb_base->iou_switch_ctrl));
57
Michal Simekfb771792019-01-28 11:08:00 +010058 writel(IOU_SWITCH_CTRL_CLKACT_BIT |
Michal Simek47a766f2019-01-28 11:12:41 +010059 (CONFIG_IOU_SWITCH_DIVISOR0 << IOU_SWITCH_CTRL_DIVISOR0_SHIFT),
Michal Simekfb771792019-01-28 11:08:00 +010060 &crlapb_base->iou_switch_ctrl);
Michal Simekec48b6c2018-08-22 14:55:27 +020061
Michal Simekfb771792019-01-28 11:08:00 +010062 /* Global timer init - Program time stamp reference clk */
63 val = readl(&crlapb_base->timestamp_ref_ctrl);
64 val |= CRL_APB_TIMESTAMP_REF_CTRL_CLKACT_BIT;
65 writel(val, &crlapb_base->timestamp_ref_ctrl);
Michal Simekec48b6c2018-08-22 14:55:27 +020066
Michal Simekfb771792019-01-28 11:08:00 +010067 debug("ref ctrl 0x%x\n",
68 readl(&crlapb_base->timestamp_ref_ctrl));
Michal Simekec48b6c2018-08-22 14:55:27 +020069
Michal Simekfb771792019-01-28 11:08:00 +010070 /* Clear reset of timestamp reg */
71 writel(0, &crlapb_base->rst_timestamp);
Michal Simekec48b6c2018-08-22 14:55:27 +020072
Michal Simekfb771792019-01-28 11:08:00 +010073 /*
74 * Program freq register in System counter and
75 * enable system counter.
76 */
Peng Fand8c033a2022-04-13 17:47:17 +080077 writel(CONFIG_COUNTER_FREQUENCY,
Michal Simekfb771792019-01-28 11:08:00 +010078 &iou_scntr_secure->base_frequency_id_register);
Michal Simekec48b6c2018-08-22 14:55:27 +020079
Michal Simekfb771792019-01-28 11:08:00 +010080 debug("counter val 0x%x\n",
81 readl(&iou_scntr_secure->base_frequency_id_register));
Michal Simekec48b6c2018-08-22 14:55:27 +020082
Michal Simekfb771792019-01-28 11:08:00 +010083 writel(IOU_SCNTRS_CONTROL_EN,
84 &iou_scntr_secure->counter_control_register);
85
86 debug("scntrs control 0x%x\n",
87 readl(&iou_scntr_secure->counter_control_register));
88 debug("timer 0x%llx\n", get_ticks());
89 debug("timer 0x%llx\n", get_ticks());
Michal Simekec48b6c2018-08-22 14:55:27 +020090
91 return 0;
92}
93
Ashok Reddy Soma2eeceb42022-05-05 23:53:45 -060094unsigned long do_go_exec(ulong (*entry)(int, char * const []), int argc,
95 char *const argv[])
96{
97 int ret = 0;
98
99 if (current_el() > 1) {
100 smp_kick_all_cpus();
101 dcache_disable();
102 armv8_switch_to_el1(0x0, 0, 0, 0, (unsigned long)entry,
103 ES_TO_AARCH64);
104 } else {
105 printf("FAIL: current EL is not above EL1\n");
106 ret = EINVAL;
107 }
108 return ret;
109}
110
Michal Simek51f6c522020-04-08 11:04:41 +0200111static u8 versal_get_bootmode(void)
112{
113 u8 bootmode;
114 u32 reg = 0;
115
116 reg = readl(&crp_base->boot_mode_usr);
117
118 if (reg >> BOOT_MODE_ALT_SHIFT)
119 reg >>= BOOT_MODE_ALT_SHIFT;
120
121 bootmode = reg & BOOT_MODES_MASK;
122
123 return bootmode;
124}
125
Siva Durga Prasad Paladugubfd092f2019-01-31 17:28:14 +0530126int board_late_init(void)
127{
Siva Durga Prasad Paladugubfd092f2019-01-31 17:28:14 +0530128 u8 bootmode;
129 struct udevice *dev;
130 int bootseq = -1;
131 int bootseq_len = 0;
132 int env_targets_len = 0;
133 const char *mode;
134 char *new_targets;
135 char *env_targets;
136
137 if (!(gd->flags & GD_FLG_ENV_DEFAULT)) {
138 debug("Saved variables - Skipping\n");
139 return 0;
140 }
141
Michal Simek62b96262020-07-28 12:45:47 +0200142 if (!CONFIG_IS_ENABLED(ENV_VARS_UBOOT_RUNTIME_CONFIG))
143 return 0;
144
Michal Simek51f6c522020-04-08 11:04:41 +0200145 bootmode = versal_get_bootmode();
Siva Durga Prasad Paladugubfd092f2019-01-31 17:28:14 +0530146
147 puts("Bootmode: ");
148 switch (bootmode) {
T Karthik Reddyf0c16cd2019-07-11 16:07:57 +0530149 case USB_MODE:
150 puts("USB_MODE\n");
T Karthik Reddy82cb49d2021-03-30 23:24:57 -0600151 mode = "usb_dfu0 usb_dfu1";
T Karthik Reddyf0c16cd2019-07-11 16:07:57 +0530152 break;
Siva Durga Prasad Paladugubfd092f2019-01-31 17:28:14 +0530153 case JTAG_MODE:
154 puts("JTAG_MODE\n");
Siva Durga Prasad Paladugu3d865ac2019-06-25 17:13:14 +0530155 mode = "jtag pxe dhcp";
Siva Durga Prasad Paladugubfd092f2019-01-31 17:28:14 +0530156 break;
157 case QSPI_MODE_24BIT:
158 puts("QSPI_MODE_24\n");
159 mode = "xspi0";
160 break;
161 case QSPI_MODE_32BIT:
162 puts("QSPI_MODE_32\n");
163 mode = "xspi0";
164 break;
165 case OSPI_MODE:
166 puts("OSPI_MODE\n");
167 mode = "xspi0";
168 break;
169 case EMMC_MODE:
170 puts("EMMC_MODE\n");
T Karthik Reddy7c5b7bb2019-12-16 04:44:26 -0700171 if (uclass_get_device_by_name(UCLASS_MMC,
T Karthik Reddy5f4e1ff2021-11-18 12:57:20 +0100172 "mmc@f1050000", &dev) &&
173 uclass_get_device_by_name(UCLASS_MMC,
T Karthik Reddy7c5b7bb2019-12-16 04:44:26 -0700174 "sdhci@f1050000", &dev)) {
175 puts("Boot from EMMC but without SD1 enabled!\n");
176 return -1;
177 }
Simon Glass8b85dfc2020-12-16 21:20:07 -0700178 debug("mmc1 device found at %p, seq %d\n", dev, dev_seq(dev));
T Karthik Reddy7c5b7bb2019-12-16 04:44:26 -0700179 mode = "mmc";
Simon Glass8b85dfc2020-12-16 21:20:07 -0700180 bootseq = dev_seq(dev);
Siva Durga Prasad Paladugubfd092f2019-01-31 17:28:14 +0530181 break;
182 case SD_MODE:
183 puts("SD_MODE\n");
184 if (uclass_get_device_by_name(UCLASS_MMC,
T Karthik Reddy5f4e1ff2021-11-18 12:57:20 +0100185 "mmc@f1040000", &dev) &&
186 uclass_get_device_by_name(UCLASS_MMC,
Siva Durga Prasad Paladugubfd092f2019-01-31 17:28:14 +0530187 "sdhci@f1040000", &dev)) {
188 puts("Boot from SD0 but without SD0 enabled!\n");
189 return -1;
190 }
Simon Glass8b85dfc2020-12-16 21:20:07 -0700191 debug("mmc0 device found at %p, seq %d\n", dev, dev_seq(dev));
Siva Durga Prasad Paladugubfd092f2019-01-31 17:28:14 +0530192
193 mode = "mmc";
Simon Glass8b85dfc2020-12-16 21:20:07 -0700194 bootseq = dev_seq(dev);
Siva Durga Prasad Paladugubfd092f2019-01-31 17:28:14 +0530195 break;
196 case SD1_LSHFT_MODE:
197 puts("LVL_SHFT_");
198 /* fall through */
199 case SD_MODE1:
200 puts("SD_MODE1\n");
201 if (uclass_get_device_by_name(UCLASS_MMC,
T Karthik Reddy5f4e1ff2021-11-18 12:57:20 +0100202 "mmc@f1050000", &dev) &&
203 uclass_get_device_by_name(UCLASS_MMC,
Siva Durga Prasad Paladugubfd092f2019-01-31 17:28:14 +0530204 "sdhci@f1050000", &dev)) {
205 puts("Boot from SD1 but without SD1 enabled!\n");
206 return -1;
207 }
Simon Glass8b85dfc2020-12-16 21:20:07 -0700208 debug("mmc1 device found at %p, seq %d\n", dev, dev_seq(dev));
Siva Durga Prasad Paladugubfd092f2019-01-31 17:28:14 +0530209
210 mode = "mmc";
Simon Glass8b85dfc2020-12-16 21:20:07 -0700211 bootseq = dev_seq(dev);
Siva Durga Prasad Paladugubfd092f2019-01-31 17:28:14 +0530212 break;
213 default:
214 mode = "";
215 printf("Invalid Boot Mode:0x%x\n", bootmode);
216 break;
217 }
218
219 if (bootseq >= 0) {
220 bootseq_len = snprintf(NULL, 0, "%i", bootseq);
221 debug("Bootseq len: %x\n", bootseq_len);
222 }
223
224 /*
225 * One terminating char + one byte for space between mode
226 * and default boot_targets
227 */
228 env_targets = env_get("boot_targets");
229 if (env_targets)
230 env_targets_len = strlen(env_targets);
231
232 new_targets = calloc(1, strlen(mode) + env_targets_len + 2 +
233 bootseq_len);
234 if (!new_targets)
235 return -ENOMEM;
236
237 if (bootseq >= 0)
238 sprintf(new_targets, "%s%x %s", mode, bootseq,
239 env_targets ? env_targets : "");
240 else
241 sprintf(new_targets, "%s %s", mode,
242 env_targets ? env_targets : "");
243
244 env_set("boot_targets", new_targets);
245
Michal Simek80fdef12020-03-31 12:39:37 +0200246 return board_late_init_xilinx();
Siva Durga Prasad Paladugubfd092f2019-01-31 17:28:14 +0530247}
248
Michal Simekec48b6c2018-08-22 14:55:27 +0200249int dram_init_banksize(void)
250{
Michal Simekaef149e2019-04-29 09:39:09 -0700251 int ret;
252
253 ret = fdtdec_setup_memory_banksize();
254 if (ret)
255 return ret;
256
257 mem_map_fill();
Michal Simekec48b6c2018-08-22 14:55:27 +0200258
259 return 0;
260}
261
262int dram_init(void)
263{
Michal Simek22b6bb62020-07-10 12:42:09 +0200264 if (fdtdec_setup_mem_size_base_lowest() != 0)
Michal Simekec48b6c2018-08-22 14:55:27 +0200265 return -EINVAL;
266
267 return 0;
268}
269
Michal Simekf66d0b52022-03-17 15:25:31 +0100270ulong board_get_usable_ram_top(ulong total_size)
271{
272 phys_size_t size;
273 phys_addr_t reg;
274 struct lmb lmb;
275
Michal Simek9c563e92022-04-29 11:52:27 +0200276 if (!total_size)
277 return gd->ram_top;
278
Michal Simekf66d0b52022-03-17 15:25:31 +0100279 /* found enough not-reserved memory to relocated U-Boot */
280 lmb_init(&lmb);
281 lmb_add(&lmb, gd->ram_base, gd->ram_size);
282 boot_fdt_add_mem_rsv_regions(&lmb, (void *)gd->fdt_blob);
283 size = ALIGN(CONFIG_SYS_MALLOC_LEN + total_size, MMU_SECTION_SIZE);
284 reg = lmb_alloc(&lmb, size, MMU_SECTION_SIZE);
285
286 if (!reg)
287 reg = gd->ram_top - size;
288
289 return reg + size;
290}
291
Harald Seiler35b65dd2020-12-15 16:47:52 +0100292void reset_cpu(void)
Michal Simekec48b6c2018-08-22 14:55:27 +0200293{
294}
Ashok Reddy Soma4fb83c92021-02-23 08:07:46 -0700295
296enum env_location env_get_location(enum env_operation op, int prio)
297{
298 u32 bootmode = versal_get_bootmode();
299
300 if (prio)
301 return ENVL_UNKNOWN;
302
303 switch (bootmode) {
304 case EMMC_MODE:
305 case SD_MODE:
306 case SD1_LSHFT_MODE:
307 case SD_MODE1:
308 if (IS_ENABLED(CONFIG_ENV_IS_IN_FAT))
309 return ENVL_FAT;
310 if (IS_ENABLED(CONFIG_ENV_IS_IN_EXT4))
311 return ENVL_EXT4;
T Karthik Reddybf97c462021-11-24 12:16:55 +0100312 return ENVL_NOWHERE;
Ashok Reddy Soma4fb83c92021-02-23 08:07:46 -0700313 case OSPI_MODE:
314 case QSPI_MODE_24BIT:
315 case QSPI_MODE_32BIT:
316 if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH))
317 return ENVL_SPI_FLASH;
T Karthik Reddybf97c462021-11-24 12:16:55 +0100318 return ENVL_NOWHERE;
Ashok Reddy Soma4fb83c92021-02-23 08:07:46 -0700319 case JTAG_MODE:
320 default:
321 return ENVL_NOWHERE;
322 }
323}