xref: /openbmc/u-boot/board/xilinx/zynqmp/zynqmp.c (revision e3963c09)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2014 - 2015 Xilinx, Inc.
4  * Michal Simek <michal.simek@xilinx.com>
5  */
6 
7 #include <common.h>
8 #include <sata.h>
9 #include <ahci.h>
10 #include <scsi.h>
11 #include <malloc.h>
12 #include <wdt.h>
13 #include <asm/arch/clk.h>
14 #include <asm/arch/hardware.h>
15 #include <asm/arch/sys_proto.h>
16 #include <asm/arch/psu_init_gpl.h>
17 #include <asm/io.h>
18 #include <dm/device.h>
19 #include <dm/uclass.h>
20 #include <usb.h>
21 #include <dwc3-uboot.h>
22 #include <zynqmppl.h>
23 #include <i2c.h>
24 #include <g_dnl.h>
25 
26 DECLARE_GLOBAL_DATA_PTR;
27 
28 #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT)
29 static struct udevice *watchdog_dev;
30 #endif
31 
32 #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
33     !defined(CONFIG_SPL_BUILD)
34 static xilinx_desc zynqmppl = XILINX_ZYNQMP_DESC;
35 
36 static const struct {
37 	u32 id;
38 	u32 ver;
39 	char *name;
40 	bool evexists;
41 } zynqmp_devices[] = {
42 	{
43 		.id = 0x10,
44 		.name = "3eg",
45 	},
46 	{
47 		.id = 0x10,
48 		.ver = 0x2c,
49 		.name = "3cg",
50 	},
51 	{
52 		.id = 0x11,
53 		.name = "2eg",
54 	},
55 	{
56 		.id = 0x11,
57 		.ver = 0x2c,
58 		.name = "2cg",
59 	},
60 	{
61 		.id = 0x20,
62 		.name = "5ev",
63 		.evexists = 1,
64 	},
65 	{
66 		.id = 0x20,
67 		.ver = 0x100,
68 		.name = "5eg",
69 		.evexists = 1,
70 	},
71 	{
72 		.id = 0x20,
73 		.ver = 0x12c,
74 		.name = "5cg",
75 		.evexists = 1,
76 	},
77 	{
78 		.id = 0x21,
79 		.name = "4ev",
80 		.evexists = 1,
81 	},
82 	{
83 		.id = 0x21,
84 		.ver = 0x100,
85 		.name = "4eg",
86 		.evexists = 1,
87 	},
88 	{
89 		.id = 0x21,
90 		.ver = 0x12c,
91 		.name = "4cg",
92 		.evexists = 1,
93 	},
94 	{
95 		.id = 0x30,
96 		.name = "7ev",
97 		.evexists = 1,
98 	},
99 	{
100 		.id = 0x30,
101 		.ver = 0x100,
102 		.name = "7eg",
103 		.evexists = 1,
104 	},
105 	{
106 		.id = 0x30,
107 		.ver = 0x12c,
108 		.name = "7cg",
109 		.evexists = 1,
110 	},
111 	{
112 		.id = 0x38,
113 		.name = "9eg",
114 	},
115 	{
116 		.id = 0x38,
117 		.ver = 0x2c,
118 		.name = "9cg",
119 	},
120 	{
121 		.id = 0x39,
122 		.name = "6eg",
123 	},
124 	{
125 		.id = 0x39,
126 		.ver = 0x2c,
127 		.name = "6cg",
128 	},
129 	{
130 		.id = 0x40,
131 		.name = "11eg",
132 	},
133 	{ /* For testing purpose only */
134 		.id = 0x50,
135 		.ver = 0x2c,
136 		.name = "15cg",
137 	},
138 	{
139 		.id = 0x50,
140 		.name = "15eg",
141 	},
142 	{
143 		.id = 0x58,
144 		.name = "19eg",
145 	},
146 	{
147 		.id = 0x59,
148 		.name = "17eg",
149 	},
150 	{
151 		.id = 0x61,
152 		.name = "21dr",
153 	},
154 	{
155 		.id = 0x63,
156 		.name = "23dr",
157 	},
158 	{
159 		.id = 0x65,
160 		.name = "25dr",
161 	},
162 	{
163 		.id = 0x64,
164 		.name = "27dr",
165 	},
166 	{
167 		.id = 0x60,
168 		.name = "28dr",
169 	},
170 	{
171 		.id = 0x62,
172 		.name = "29dr",
173 	},
174 };
175 #endif
176 
177 int chip_id(unsigned char id)
178 {
179 	struct pt_regs regs;
180 	int val = -EINVAL;
181 
182 	if (current_el() != 3) {
183 		regs.regs[0] = ZYNQMP_SIP_SVC_CSU_DMA_CHIPID;
184 		regs.regs[1] = 0;
185 		regs.regs[2] = 0;
186 		regs.regs[3] = 0;
187 
188 		smc_call(&regs);
189 
190 		/*
191 		 * SMC returns:
192 		 * regs[0][31:0]  = status of the operation
193 		 * regs[0][63:32] = CSU.IDCODE register
194 		 * regs[1][31:0]  = CSU.version register
195 		 * regs[1][63:32] = CSU.IDCODE2 register
196 		 */
197 		switch (id) {
198 		case IDCODE:
199 			regs.regs[0] = upper_32_bits(regs.regs[0]);
200 			regs.regs[0] &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
201 					ZYNQMP_CSU_IDCODE_SVD_MASK;
202 			regs.regs[0] >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
203 			val = regs.regs[0];
204 			break;
205 		case VERSION:
206 			regs.regs[1] = lower_32_bits(regs.regs[1]);
207 			regs.regs[1] &= ZYNQMP_CSU_SILICON_VER_MASK;
208 			val = regs.regs[1];
209 			break;
210 		case IDCODE2:
211 			regs.regs[1] = lower_32_bits(regs.regs[1]);
212 			regs.regs[1] >>= ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
213 			val = regs.regs[1];
214 			break;
215 		default:
216 			printf("%s, Invalid Req:0x%x\n", __func__, id);
217 		}
218 	} else {
219 		switch (id) {
220 		case IDCODE:
221 			val = readl(ZYNQMP_CSU_IDCODE_ADDR);
222 			val &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
223 			       ZYNQMP_CSU_IDCODE_SVD_MASK;
224 			val >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
225 			break;
226 		case VERSION:
227 			val = readl(ZYNQMP_CSU_VER_ADDR);
228 			val &= ZYNQMP_CSU_SILICON_VER_MASK;
229 			break;
230 		default:
231 			printf("%s, Invalid Req:0x%x\n", __func__, id);
232 		}
233 	}
234 
235 	return val;
236 }
237 
238 #define ZYNQMP_VERSION_SIZE		9
239 #define ZYNQMP_PL_STATUS_BIT		9
240 #define ZYNQMP_IPDIS_VCU_BIT		8
241 #define ZYNQMP_PL_STATUS_MASK		BIT(ZYNQMP_PL_STATUS_BIT)
242 #define ZYNQMP_CSU_VERSION_MASK		~(ZYNQMP_PL_STATUS_MASK)
243 #define ZYNQMP_CSU_VCUDIS_VER_MASK	ZYNQMP_CSU_VERSION_MASK & \
244 					~BIT(ZYNQMP_IPDIS_VCU_BIT)
245 #define MAX_VARIANTS_EV			3
246 
247 #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
248 	!defined(CONFIG_SPL_BUILD)
249 static char *zynqmp_get_silicon_idcode_name(void)
250 {
251 	u32 i, id, ver, j;
252 	char *buf;
253 	static char name[ZYNQMP_VERSION_SIZE];
254 
255 	id = chip_id(IDCODE);
256 	ver = chip_id(IDCODE2);
257 
258 	for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
259 		if (zynqmp_devices[i].id == id) {
260 			if (zynqmp_devices[i].evexists &&
261 			    !(ver & ZYNQMP_PL_STATUS_MASK))
262 				break;
263 			if (zynqmp_devices[i].ver == (ver &
264 			    ZYNQMP_CSU_VERSION_MASK))
265 				break;
266 		}
267 	}
268 
269 	if (i >= ARRAY_SIZE(zynqmp_devices))
270 		return "unknown";
271 
272 	strncat(name, "zu", 2);
273 	if (!zynqmp_devices[i].evexists ||
274 	    (ver & ZYNQMP_PL_STATUS_MASK)) {
275 		strncat(name, zynqmp_devices[i].name,
276 			ZYNQMP_VERSION_SIZE - 3);
277 		return name;
278 	}
279 
280 	/*
281 	 * Here we are means, PL not powered up and ev variant
282 	 * exists. So, we need to ignore VCU disable bit(8) in
283 	 * version and findout if its CG or EG/EV variant.
284 	 */
285 	for (j = 0; j < MAX_VARIANTS_EV; j++, i++) {
286 		if ((zynqmp_devices[i].ver & ~BIT(ZYNQMP_IPDIS_VCU_BIT)) ==
287 		    (ver & ZYNQMP_CSU_VCUDIS_VER_MASK)) {
288 			strncat(name, zynqmp_devices[i].name,
289 				ZYNQMP_VERSION_SIZE - 3);
290 			break;
291 		}
292 	}
293 
294 	if (j >= MAX_VARIANTS_EV)
295 		return "unknown";
296 
297 	if (strstr(name, "eg") || strstr(name, "ev")) {
298 		buf = strstr(name, "e");
299 		*buf = '\0';
300 	}
301 
302 	return name;
303 }
304 #endif
305 
306 int board_early_init_f(void)
307 {
308 	int ret = 0;
309 #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_CLK_ZYNQMP)
310 	u32 pm_api_version;
311 
312 	pm_api_version = zynqmp_pmufw_version();
313 	printf("PMUFW:\tv%d.%d\n",
314 	       pm_api_version >> ZYNQMP_PM_VERSION_MAJOR_SHIFT,
315 	       pm_api_version & ZYNQMP_PM_VERSION_MINOR_MASK);
316 
317 	if (pm_api_version < ZYNQMP_PM_VERSION)
318 		panic("PMUFW version error. Expected: v%d.%d\n",
319 		      ZYNQMP_PM_VERSION_MAJOR, ZYNQMP_PM_VERSION_MINOR);
320 #endif
321 
322 #if defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED)
323 	ret = psu_init();
324 #endif
325 
326 #if defined(CONFIG_WDT) && !defined(CONFIG_SPL_BUILD)
327 	/* bss is not cleared at time when watchdog_reset() is called */
328 	watchdog_dev = NULL;
329 #endif
330 
331 	return ret;
332 }
333 
334 int board_init(void)
335 {
336 	printf("EL Level:\tEL%d\n", current_el());
337 
338 #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
339     !defined(CONFIG_SPL_BUILD) || (defined(CONFIG_SPL_FPGA_SUPPORT) && \
340     defined(CONFIG_SPL_BUILD))
341 	if (current_el() != 3) {
342 		zynqmppl.name = zynqmp_get_silicon_idcode_name();
343 		printf("Chip ID:\t%s\n", zynqmppl.name);
344 		fpga_init();
345 		fpga_add(fpga_xilinx, &zynqmppl);
346 	}
347 #endif
348 
349 #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT)
350 	if (uclass_get_device_by_seq(UCLASS_WDT, 0, &watchdog_dev)) {
351 		debug("Watchdog: Not found by seq!\n");
352 		if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) {
353 			puts("Watchdog: Not found!\n");
354 			return 0;
355 		}
356 	}
357 
358 	wdt_start(watchdog_dev, 0, 0);
359 	puts("Watchdog: Started\n");
360 #endif
361 
362 	return 0;
363 }
364 
365 #ifdef CONFIG_WATCHDOG
366 /* Called by macro WATCHDOG_RESET */
367 void watchdog_reset(void)
368 {
369 # if !defined(CONFIG_SPL_BUILD)
370 	static ulong next_reset;
371 	ulong now;
372 
373 	if (!watchdog_dev)
374 		return;
375 
376 	now = timer_get_us();
377 
378 	/* Do not reset the watchdog too often */
379 	if (now > next_reset) {
380 		wdt_reset(watchdog_dev);
381 		next_reset = now + 1000;
382 	}
383 # endif
384 }
385 #endif
386 
387 int board_early_init_r(void)
388 {
389 	u32 val;
390 
391 	if (current_el() != 3)
392 		return 0;
393 
394 	val = readl(&crlapb_base->timestamp_ref_ctrl);
395 	val &= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT;
396 
397 	if (!val) {
398 		val = readl(&crlapb_base->timestamp_ref_ctrl);
399 		val |= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT;
400 		writel(val, &crlapb_base->timestamp_ref_ctrl);
401 
402 		/* Program freq register in System counter */
403 		writel(zynqmp_get_system_timer_freq(),
404 		       &iou_scntr_secure->base_frequency_id_register);
405 		/* And enable system counter */
406 		writel(ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_EN,
407 		       &iou_scntr_secure->counter_control_register);
408 	}
409 	return 0;
410 }
411 
412 int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
413 {
414 #if defined(CONFIG_ZYNQ_GEM_EEPROM_ADDR) && \
415     defined(CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET) && \
416     defined(CONFIG_ZYNQ_EEPROM_BUS)
417 	i2c_set_bus_num(CONFIG_ZYNQ_EEPROM_BUS);
418 
419 	if (eeprom_read(CONFIG_ZYNQ_GEM_EEPROM_ADDR,
420 			CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET,
421 			ethaddr, 6))
422 		printf("I2C EEPROM MAC address read failed\n");
423 #endif
424 
425 	return 0;
426 }
427 
428 unsigned long do_go_exec(ulong (*entry)(int, char * const []), int argc,
429 			 char * const argv[])
430 {
431 	int ret = 0;
432 
433 	if (current_el() > 1) {
434 		smp_kick_all_cpus();
435 		dcache_disable();
436 		armv8_switch_to_el1(0x0, 0, 0, 0, (unsigned long)entry,
437 				    ES_TO_AARCH64);
438 	} else {
439 		printf("FAIL: current EL is not above EL1\n");
440 		ret = EINVAL;
441 	}
442 	return ret;
443 }
444 
445 #if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
446 int dram_init_banksize(void)
447 {
448 	int ret;
449 
450 	ret = fdtdec_setup_memory_banksize();
451 	if (ret)
452 		return ret;
453 
454 	mem_map_fill();
455 
456 	return 0;
457 }
458 
459 int dram_init(void)
460 {
461 	if (fdtdec_setup_mem_size_base() != 0)
462 		return -EINVAL;
463 
464 	return 0;
465 }
466 #else
467 int dram_init_banksize(void)
468 {
469 #if defined(CONFIG_NR_DRAM_BANKS)
470 	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
471 	gd->bd->bi_dram[0].size = get_effective_memsize();
472 #endif
473 
474 	mem_map_fill();
475 
476 	return 0;
477 }
478 
479 int dram_init(void)
480 {
481 	gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
482 				    CONFIG_SYS_SDRAM_SIZE);
483 
484 	return 0;
485 }
486 #endif
487 
488 void reset_cpu(ulong addr)
489 {
490 }
491 
492 static const struct {
493 	u32 bit;
494 	const char *name;
495 } reset_reasons[] = {
496 	{ RESET_REASON_DEBUG_SYS, "DEBUG" },
497 	{ RESET_REASON_SOFT, "SOFT" },
498 	{ RESET_REASON_SRST, "SRST" },
499 	{ RESET_REASON_PSONLY, "PS-ONLY" },
500 	{ RESET_REASON_PMU, "PMU" },
501 	{ RESET_REASON_INTERNAL, "INTERNAL" },
502 	{ RESET_REASON_EXTERNAL, "EXTERNAL" },
503 	{}
504 };
505 
506 static u32 reset_reason(void)
507 {
508 	u32 ret;
509 	int i;
510 	const char *reason = NULL;
511 
512 	ret = readl(&crlapb_base->reset_reason);
513 
514 	puts("Reset reason:\t");
515 
516 	for (i = 0; i < ARRAY_SIZE(reset_reasons); i++) {
517 		if (ret & reset_reasons[i].bit) {
518 			reason = reset_reasons[i].name;
519 			printf("%s ", reset_reasons[i].name);
520 			break;
521 		}
522 	}
523 
524 	puts("\n");
525 
526 	env_set("reset_reason", reason);
527 
528 	writel(~0, &crlapb_base->reset_reason);
529 
530 	return ret;
531 }
532 
533 int board_late_init(void)
534 {
535 	u32 reg = 0;
536 	u8 bootmode;
537 	struct udevice *dev;
538 	int bootseq = -1;
539 	int bootseq_len = 0;
540 	int env_targets_len = 0;
541 	const char *mode;
542 	char *new_targets;
543 	char *env_targets;
544 	int ret;
545 
546 #if defined(CONFIG_USB_ETHER) && !defined(CONFIG_USB_GADGET_DOWNLOAD)
547 	usb_ether_init();
548 #endif
549 
550 	if (!(gd->flags & GD_FLG_ENV_DEFAULT)) {
551 		debug("Saved variables - Skipping\n");
552 		return 0;
553 	}
554 
555 	ret = zynqmp_mmio_read((ulong)&crlapb_base->boot_mode, &reg);
556 	if (ret)
557 		return -EINVAL;
558 
559 	if (reg >> BOOT_MODE_ALT_SHIFT)
560 		reg >>= BOOT_MODE_ALT_SHIFT;
561 
562 	bootmode = reg & BOOT_MODES_MASK;
563 
564 	puts("Bootmode: ");
565 	switch (bootmode) {
566 	case USB_MODE:
567 		puts("USB_MODE\n");
568 		mode = "usb";
569 		env_set("modeboot", "usb_dfu_spl");
570 		break;
571 	case JTAG_MODE:
572 		puts("JTAG_MODE\n");
573 		mode = "pxe dhcp";
574 		env_set("modeboot", "jtagboot");
575 		break;
576 	case QSPI_MODE_24BIT:
577 	case QSPI_MODE_32BIT:
578 		mode = "qspi0";
579 		puts("QSPI_MODE\n");
580 		env_set("modeboot", "qspiboot");
581 		break;
582 	case EMMC_MODE:
583 		puts("EMMC_MODE\n");
584 		mode = "mmc0";
585 		env_set("modeboot", "emmcboot");
586 		break;
587 	case SD_MODE:
588 		puts("SD_MODE\n");
589 		if (uclass_get_device_by_name(UCLASS_MMC,
590 					      "sdhci@ff160000", &dev)) {
591 			puts("Boot from SD0 but without SD0 enabled!\n");
592 			return -1;
593 		}
594 		debug("mmc0 device found at %p, seq %d\n", dev, dev->seq);
595 
596 		mode = "mmc";
597 		bootseq = dev->seq;
598 		env_set("modeboot", "sdboot");
599 		break;
600 	case SD1_LSHFT_MODE:
601 		puts("LVL_SHFT_");
602 		/* fall through */
603 	case SD_MODE1:
604 		puts("SD_MODE1\n");
605 		if (uclass_get_device_by_name(UCLASS_MMC,
606 					      "sdhci@ff170000", &dev)) {
607 			puts("Boot from SD1 but without SD1 enabled!\n");
608 			return -1;
609 		}
610 		debug("mmc1 device found at %p, seq %d\n", dev, dev->seq);
611 
612 		mode = "mmc";
613 		bootseq = dev->seq;
614 		env_set("modeboot", "sdboot");
615 		break;
616 	case NAND_MODE:
617 		puts("NAND_MODE\n");
618 		mode = "nand0";
619 		env_set("modeboot", "nandboot");
620 		break;
621 	default:
622 		mode = "";
623 		printf("Invalid Boot Mode:0x%x\n", bootmode);
624 		break;
625 	}
626 
627 	if (bootseq >= 0) {
628 		bootseq_len = snprintf(NULL, 0, "%i", bootseq);
629 		debug("Bootseq len: %x\n", bootseq_len);
630 	}
631 
632 	/*
633 	 * One terminating char + one byte for space between mode
634 	 * and default boot_targets
635 	 */
636 	env_targets = env_get("boot_targets");
637 	if (env_targets)
638 		env_targets_len = strlen(env_targets);
639 
640 	new_targets = calloc(1, strlen(mode) + env_targets_len + 2 +
641 			     bootseq_len);
642 	if (!new_targets)
643 		return -ENOMEM;
644 
645 	if (bootseq >= 0)
646 		sprintf(new_targets, "%s%x %s", mode, bootseq,
647 			env_targets ? env_targets : "");
648 	else
649 		sprintf(new_targets, "%s %s", mode,
650 			env_targets ? env_targets : "");
651 
652 	env_set("boot_targets", new_targets);
653 
654 	reset_reason();
655 
656 	return 0;
657 }
658 
659 int checkboard(void)
660 {
661 	puts("Board: Xilinx ZynqMP\n");
662 	return 0;
663 }
664