1139743Simp// SPDX-License-Identifier: GPL-2.0+
243412Snewton/*
343412Snewton * (C) Copyright 2014 - 2018 Xilinx, Inc.
443412Snewton * Michal Simek <michal.simek@amd.com>
543412Snewton */
643412Snewton
743412Snewton#include <command.h>
843412Snewton#include <common.h>
943412Snewton#include <cpu_func.h>
1043412Snewton#include <env.h>
1143412Snewton#include <fdtdec.h>
1243412Snewton#include <init.h>
1343412Snewton#include <env_internal.h>
1443412Snewton#include <log.h>
1543412Snewton#include <malloc.h>
1643412Snewton#include <time.h>
1743412Snewton#include <asm/cache.h>
1843412Snewton#include <asm/global_data.h>
1943412Snewton#include <asm/io.h>
2043412Snewton#include <asm/arch/hardware.h>
2143412Snewton#include <asm/arch/sys_proto.h>
2243412Snewton#include <dm/device.h>
2343412Snewton#include <dm/uclass.h>
2443412Snewton#include <versalpl.h>
2543412Snewton#include "../common/board.h"
2643412Snewton
2743412SnewtonDECLARE_GLOBAL_DATA_PTR;
2843412Snewton
29116174Sobrien#if defined(CONFIG_FPGA_VERSALPL)
30116174Sobrienstatic xilinx_desc versalpl = {
31116174Sobrien	xilinx_versal, csu_dma, 1, &versal_op, 0, &versal_op, NULL,
3243412Snewton	FPGA_LEGACY
3343412Snewton};
3443412Snewton#endif
3543412Snewton
3643412Snewtonint board_init(void)
3791386Srobert{
3843412Snewton	printf("EL Level:\tEL%d\n", current_el());
39141486Sjhb
40195458Strasz#if defined(CONFIG_FPGA_VERSALPL)
4143412Snewton	fpga_init();
4254305Snewton	fpga_add(fpga_xilinx, &versalpl);
43141486Sjhb#endif
4454305Snewton
4554305Snewton	if (CONFIG_IS_ENABLED(DM_I2C) && CONFIG_IS_ENABLED(I2C_EEPROM))
46115550Sphk		xilinx_read_eeprom();
4743412Snewton
4843412Snewton	return 0;
4954305Snewton}
5043412Snewton
5143412Snewtonint board_early_init_r(void)
5265302Sobrien{
5365302Sobrien	u32 val;
5465302Sobrien
5565302Sobrien	if (current_el() != 3)
5665302Sobrien		return 0;
5765302Sobrien
5865302Sobrien	debug("iou_switch ctrl div0 %x\n",
5965302Sobrien	      readl(&crlapb_base->iou_switch_ctrl));
6065302Sobrien
6165302Sobrien	writel(IOU_SWITCH_CTRL_CLKACT_BIT |
6265302Sobrien	       (CONFIG_IOU_SWITCH_DIVISOR0 << IOU_SWITCH_CTRL_DIVISOR0_SHIFT),
6343412Snewton	       &crlapb_base->iou_switch_ctrl);
6443412Snewton
6543412Snewton	/* Global timer init - Program time stamp reference clk */
6643412Snewton	val = readl(&crlapb_base->timestamp_ref_ctrl);
6743412Snewton	val |= CRL_APB_TIMESTAMP_REF_CTRL_CLKACT_BIT;
6843412Snewton	writel(val, &crlapb_base->timestamp_ref_ctrl);
6943412Snewton
7043412Snewton	debug("ref ctrl 0x%x\n",
7143412Snewton	      readl(&crlapb_base->timestamp_ref_ctrl));
7243412Snewton
7343412Snewton	/* Clear reset of timestamp reg */
7443412Snewton	writel(0, &crlapb_base->rst_timestamp);
7543412Snewton
7643412Snewton	/*
7743412Snewton	 * Program freq register in System counter and
7843412Snewton	 * enable system counter.
7943412Snewton	 */
8092761Salfred	writel(CONFIG_COUNTER_FREQUENCY,
8192761Salfred	       &iou_scntr_secure->base_frequency_id_register);
8292761Salfred
8392761Salfred	debug("counter val 0x%x\n",
8443412Snewton	      readl(&iou_scntr_secure->base_frequency_id_register));
8543412Snewton
8643412Snewton	writel(IOU_SCNTRS_CONTROL_EN,
8743412Snewton	       &iou_scntr_secure->counter_control_register);
8843412Snewton
8943412Snewton	debug("scntrs control 0x%x\n",
9043412Snewton	      readl(&iou_scntr_secure->counter_control_register));
9143412Snewton	debug("timer 0x%llx\n", get_ticks());
9243412Snewton	debug("timer 0x%llx\n", get_ticks());
9392761Salfred
9443412Snewton	return 0;
9543412Snewton}
9643412Snewton
9743412Snewtonunsigned long do_go_exec(ulong (*entry)(int, char * const []), int argc,
9843412Snewton			 char *const argv[])
9943412Snewton{
10043412Snewton	int ret = 0;
10143412Snewton
10243412Snewton	if (current_el() > 1) {
10343412Snewton		smp_kick_all_cpus();
10443412Snewton		dcache_disable();
10543412Snewton		armv8_switch_to_el1(0x0, 0, 0, 0, (unsigned long)entry,
10643412Snewton				    ES_TO_AARCH64);
10743412Snewton	} else {
10843412Snewton		printf("FAIL: current EL is not above EL1\n");
109205792Sed		ret = EINVAL;
110205792Sed	}
111205792Sed	return ret;
11243412Snewton}
11343412Snewton
11443412Snewtonstatic u8 versal_get_bootmode(void)
11543412Snewton{
11643412Snewton	u8 bootmode;
11743412Snewton	u32 reg = 0;
11843412Snewton
11943412Snewton	reg = readl(&crp_base->boot_mode_usr);
12043412Snewton
12143412Snewton	if (reg >> BOOT_MODE_ALT_SHIFT)
12243412Snewton		reg >>= BOOT_MODE_ALT_SHIFT;
12343412Snewton
12443412Snewton	bootmode = reg & BOOT_MODES_MASK;
12543412Snewton
12643412Snewton	return bootmode;
12743412Snewton}
12843412Snewton
12943412Snewtonstatic int boot_targets_setup(void)
130205792Sed{
131205792Sed	u8 bootmode;
132205792Sed	struct udevice *dev;
13343412Snewton	int bootseq = -1;
13443412Snewton	int bootseq_len = 0;
13543412Snewton	int env_targets_len = 0;
13643412Snewton	const char *mode = NULL;
13743412Snewton	char *new_targets;
13843412Snewton	char *env_targets;
13943412Snewton
14043412Snewton	bootmode = versal_get_bootmode();
14143412Snewton
14243412Snewton	puts("Bootmode: ");
14343412Snewton	switch (bootmode) {
14443412Snewton	case USB_MODE:
14543412Snewton		puts("USB_MODE\n");
14643412Snewton		mode = "usb_dfu0 usb_dfu1";
14743412Snewton		break;
14843412Snewton	case JTAG_MODE:
14943412Snewton		puts("JTAG_MODE\n");
15043412Snewton		mode = "jtag pxe dhcp";
15143412Snewton		break;
15243412Snewton	case QSPI_MODE_24BIT:
153205792Sed		puts("QSPI_MODE_24\n");
154205792Sed		mode = "xspi0";
155205792Sed		break;
15643412Snewton	case QSPI_MODE_32BIT:
15743412Snewton		puts("QSPI_MODE_32\n");
15843412Snewton		mode = "xspi0";
15943412Snewton		break;
16043412Snewton	case OSPI_MODE:
16143412Snewton		puts("OSPI_MODE\n");
16283366Sjulian		mode = "xspi0";
16383366Sjulian		break;
16443412Snewton	case EMMC_MODE:
16543412Snewton		puts("EMMC_MODE\n");
166141486Sjhb		if (uclass_get_device_by_name(UCLASS_MMC,
167141486Sjhb					      "mmc@f1050000", &dev) &&
168141486Sjhb		    uclass_get_device_by_name(UCLASS_MMC,
169141486Sjhb					      "sdhci@f1050000", &dev)) {
17043412Snewton			debug("SD1 driver for SD1 device is not present\n");
171141486Sjhb			break;
17243412Snewton		}
173141486Sjhb		debug("mmc1 device found at %p, seq %d\n", dev, dev_seq(dev));
174141486Sjhb		mode = "mmc";
175141486Sjhb		bootseq = dev_seq(dev);
176141486Sjhb		break;
17743412Snewton	case SELECTMAP_MODE:
17843412Snewton		puts("SELECTMAP_MODE\n");
17943412Snewton		break;
180107849Salfred	case SD_MODE:
18143412Snewton		puts("SD_MODE\n");
182141486Sjhb		if (uclass_get_device_by_name(UCLASS_MMC,
18343412Snewton					      "mmc@f1040000", &dev) &&
18443412Snewton		    uclass_get_device_by_name(UCLASS_MMC,
18543412Snewton					      "sdhci@f1040000", &dev)) {
18643412Snewton			debug("SD0 driver for SD0 device is not present\n");
18783366Sjulian			break;
188193014Sdelphij		}
18943412Snewton		debug("mmc0 device found at %p, seq %d\n", dev, dev_seq(dev));
19043412Snewton
191141486Sjhb		mode = "mmc";
192141486Sjhb		bootseq = dev_seq(dev);
193141486Sjhb		break;
194141486Sjhb	case SD1_LSHFT_MODE:
19543412Snewton		puts("LVL_SHFT_");
196141486Sjhb		/* fall through */
19743412Snewton	case SD_MODE1:
198141486Sjhb		puts("SD_MODE1\n");
199141486Sjhb		if (uclass_get_device_by_name(UCLASS_MMC,
200141486Sjhb					      "mmc@f1050000", &dev) &&
201141486Sjhb		    uclass_get_device_by_name(UCLASS_MMC,
20243412Snewton					      "sdhci@f1050000", &dev)) {
20343412Snewton			debug("SD1 driver for SD1 device is not present\n");
20443412Snewton			break;
205107849Salfred		}
20643412Snewton		debug("mmc1 device found at %p, seq %d\n", dev, dev_seq(dev));
207141486Sjhb
20843412Snewton		mode = "mmc";
20943412Snewton		bootseq = dev_seq(dev);
21043412Snewton		break;
21143412Snewton	default:
21283366Sjulian		printf("Invalid Boot Mode:0x%x\n", bootmode);
213193014Sdelphij		break;
21443412Snewton	}
21543412Snewton
216141486Sjhb	if (mode) {
217141486Sjhb		if (bootseq >= 0) {
218141486Sjhb			bootseq_len = snprintf(NULL, 0, "%i", bootseq);
21943412Snewton			debug("Bootseq len: %x\n", bootseq_len);
22043412Snewton		}
221141486Sjhb
222141486Sjhb		/*
223141486Sjhb		 * One terminating char + one byte for space between mode
22443412Snewton		 * and default boot_targets
225141486Sjhb		 */
22643412Snewton		env_targets = env_get("boot_targets");
22743412Snewton		if (env_targets)
22843412Snewton			env_targets_len = strlen(env_targets);
22943412Snewton
23083366Sjulian		new_targets = calloc(1, strlen(mode) + env_targets_len + 2 +
231193014Sdelphij				     bootseq_len);
23243412Snewton		if (!new_targets)
23343412Snewton			return -ENOMEM;
234141486Sjhb
235141486Sjhb		if (bootseq >= 0)
236141486Sjhb			sprintf(new_targets, "%s%x %s", mode, bootseq,
237141486Sjhb				env_targets ? env_targets : "");
23843412Snewton		else
239141486Sjhb			sprintf(new_targets, "%s %s", mode,
24043412Snewton				env_targets ? env_targets : "");
241141486Sjhb
242141486Sjhb		env_set("boot_targets", new_targets);
243141486Sjhb	}
244141486Sjhb
24543412Snewton	return 0;
24643412Snewton}
24743412Snewton
24843412Snewtonint board_late_init(void)
24943412Snewton{
250107849Salfred	int ret;
25143412Snewton
25243412Snewton	if (!(gd->flags & GD_FLG_ENV_DEFAULT)) {
253141486Sjhb		debug("Saved variables - Skipping\n");
25443412Snewton		return 0;
25543412Snewton	}
25643412Snewton
25783366Sjulian	if (!IS_ENABLED(CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG))
258193014Sdelphij		return 0;
25943412Snewton
26043412Snewton	if (IS_ENABLED(CONFIG_DISTRO_DEFAULTS)) {
261141486Sjhb		ret = boot_targets_setup();
262141486Sjhb		if (ret)
263141486Sjhb			return ret;
264141486Sjhb	}
26543412Snewton
266141486Sjhb	return board_late_init_xilinx();
26743412Snewton}
268141486Sjhb
269141486Sjhbint dram_init_banksize(void)
270141486Sjhb{
271141486Sjhb	int ret;
27243412Snewton
27343412Snewton	ret = fdtdec_setup_memory_banksize();
27443412Snewton	if (ret)
27543412Snewton		return ret;
27643412Snewton
277107849Salfred	mem_map_fill();
27843412Snewton
279141486Sjhb	return 0;
28043412Snewton}
28143412Snewton
28243412Snewtonint dram_init(void)
28343412Snewton{
28483366Sjulian	if (fdtdec_setup_mem_size_base_lowest() != 0)
285193014Sdelphij		return -EINVAL;
28643412Snewton
28743412Snewton	return 0;
288141486Sjhb}
289141486Sjhb
290141486Sjhbvoid reset_cpu(void)
29143412Snewton{
29243412Snewton}
293141486Sjhb
294141486Sjhb#if defined(CONFIG_ENV_IS_NOWHERE)
295141486Sjhbenum env_location env_get_location(enum env_operation op, int prio)
29643412Snewton{
297141486Sjhb	u32 bootmode = versal_get_bootmode();
29843412Snewton
29943412Snewton	if (prio)
30043412Snewton		return ENVL_UNKNOWN;
30183366Sjulian
302193014Sdelphij	switch (bootmode) {
30343412Snewton	case EMMC_MODE:
30443412Snewton	case SD_MODE:
305141486Sjhb	case SD1_LSHFT_MODE:
306141486Sjhb	case SD_MODE1:
307141486Sjhb		if (IS_ENABLED(CONFIG_ENV_IS_IN_FAT))
308141486Sjhb			return ENVL_FAT;
30943412Snewton		if (IS_ENABLED(CONFIG_ENV_IS_IN_EXT4))
310141486Sjhb			return ENVL_EXT4;
31143412Snewton		return ENVL_NOWHERE;
312141486Sjhb	case OSPI_MODE:
313141486Sjhb	case QSPI_MODE_24BIT:
314141486Sjhb	case QSPI_MODE_32BIT:
315141486Sjhb		if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH))
31643412Snewton			return ENVL_SPI_FLASH;
31743412Snewton		return ENVL_NOWHERE;
31843412Snewton	case JTAG_MODE:
31943412Snewton	case SELECTMAP_MODE:
320107849Salfred	default:
32143412Snewton		return ENVL_NOWHERE;
322141486Sjhb	}
32343412Snewton}
32443412Snewton#endif
32543412Snewton