arm64: versal: Define board_late_init for versal

Define board_late_init which performs bootmode detection
and prepares corresponding distro boot commaand sequence.

Also disable it for mini platforms because simply there is no need to have
it enabled.
But also disable it for virtual platform because Qemu is not modelling this
register space that's why travis testing would fail. This configuration
should be reverted when mainline Qemu is updated.

Signed-off-by: Siva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
diff --git a/board/xilinx/versal/board.c b/board/xilinx/versal/board.c
index 9075147..b5ddd0c 100644
--- a/board/xilinx/versal/board.c
+++ b/board/xilinx/versal/board.c
@@ -9,6 +9,8 @@
 #include <malloc.h>
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
+#include <dm/device.h>
+#include <dm/uclass.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -65,6 +67,115 @@
 	return 0;
 }
 
+int board_late_init(void)
+{
+	u32 reg = 0;
+	u8 bootmode;
+	struct udevice *dev;
+	int bootseq = -1;
+	int bootseq_len = 0;
+	int env_targets_len = 0;
+	const char *mode;
+	char *new_targets;
+	char *env_targets;
+
+	if (!(gd->flags & GD_FLG_ENV_DEFAULT)) {
+		debug("Saved variables - Skipping\n");
+		return 0;
+	}
+
+	reg = readl(&crp_base->boot_mode_usr);
+
+	if (reg >> BOOT_MODE_ALT_SHIFT)
+		reg >>= BOOT_MODE_ALT_SHIFT;
+
+	bootmode = reg & BOOT_MODES_MASK;
+
+	puts("Bootmode: ");
+	switch (bootmode) {
+	case JTAG_MODE:
+		puts("JTAG_MODE\n");
+		mode = "pxe dhcp";
+		break;
+	case QSPI_MODE_24BIT:
+		puts("QSPI_MODE_24\n");
+		mode = "xspi0";
+		break;
+	case QSPI_MODE_32BIT:
+		puts("QSPI_MODE_32\n");
+		mode = "xspi0";
+		break;
+	case OSPI_MODE:
+		puts("OSPI_MODE\n");
+		mode = "xspi0";
+		break;
+	case EMMC_MODE:
+		puts("EMMC_MODE\n");
+		mode = "mmc0";
+		break;
+	case SD_MODE:
+		puts("SD_MODE\n");
+		if (uclass_get_device_by_name(UCLASS_MMC,
+					      "sdhci@f1040000", &dev)) {
+			puts("Boot from SD0 but without SD0 enabled!\n");
+			return -1;
+		}
+		debug("mmc0 device found at %p, seq %d\n", dev, dev->seq);
+
+		mode = "mmc";
+		bootseq = dev->seq;
+		break;
+	case SD1_LSHFT_MODE:
+		puts("LVL_SHFT_");
+		/* fall through */
+	case SD_MODE1:
+		puts("SD_MODE1\n");
+		if (uclass_get_device_by_name(UCLASS_MMC,
+					      "sdhci@f1050000", &dev)) {
+			puts("Boot from SD1 but without SD1 enabled!\n");
+			return -1;
+		}
+		debug("mmc1 device found at %p, seq %d\n", dev, dev->seq);
+
+		mode = "mmc";
+		bootseq = dev->seq;
+		break;
+	default:
+		mode = "";
+		printf("Invalid Boot Mode:0x%x\n", bootmode);
+		break;
+	}
+
+	if (bootseq >= 0) {
+		bootseq_len = snprintf(NULL, 0, "%i", bootseq);
+		debug("Bootseq len: %x\n", bootseq_len);
+	}
+
+	/*
+	 * One terminating char + one byte for space between mode
+	 * and default boot_targets
+	 */
+	env_targets = env_get("boot_targets");
+	if (env_targets)
+		env_targets_len = strlen(env_targets);
+
+	new_targets = calloc(1, strlen(mode) + env_targets_len + 2 +
+			     bootseq_len);
+	if (!new_targets)
+		return -ENOMEM;
+
+	if (bootseq >= 0)
+		sprintf(new_targets, "%s%x %s", mode, bootseq,
+			env_targets ? env_targets : "");
+	else
+		sprintf(new_targets, "%s %s", mode,
+			env_targets ? env_targets : "");
+
+	env_set("boot_targets", new_targets);
+
+	return 0;
+}
+
 int dram_init_banksize(void)
 {
 	fdtdec_setup_memory_banksize();