diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 3b0e315061aafcaee60309bcf00443c7d5006596..a93138aa0ada6a14f69005a8c5cd69c88782e24f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -980,6 +980,7 @@ config ARCH_VERSAL select DM_MMC if MMC select DM_SERIAL select OF_CONTROL + imply BOARD_LATE_INIT config ARCH_VF610 bool "Freescale Vybrid" diff --git a/arch/arm/mach-versal/include/mach/hardware.h b/arch/arm/mach-versal/include/mach/hardware.h index 23fbc3d8f5363b13aa53565949839197db99b6c6..e26beab2e9cde409b1e0ddfab043593a7f45cead 100644 --- a/arch/arm/mach-versal/include/mach/hardware.h +++ b/arch/arm/mach-versal/include/mach/hardware.h @@ -51,3 +51,26 @@ struct rpu_regs { }; #define rpu_base ((struct rpu_regs *)VERSAL_RPU_BASEADDR) + +#define VERSAL_CRP_BASEADDR 0xF1260000 + +struct crp_regs { + u32 reserved0[128]; + u32 boot_mode_usr; +}; + +#define crp_base ((struct crp_regs *)VERSAL_CRP_BASEADDR) + +/* Bootmode setting values */ +#define BOOT_MODES_MASK 0x0000000F +#define QSPI_MODE_24BIT 0x00000001 +#define QSPI_MODE_32BIT 0x00000002 +#define SD_MODE 0x00000003 /* sd 0 */ +#define SD_MODE1 0x00000005 /* sd 1 */ +#define EMMC_MODE 0x00000006 +#define USB_MODE 0x00000007 +#define OSPI_MODE 0x00000008 +#define SD1_LSHFT_MODE 0x0000000E /* SD1 Level shifter */ +#define JTAG_MODE 0x00000000 +#define BOOT_MODE_USE_ALT 0x100 +#define BOOT_MODE_ALT_SHIFT 12 diff --git a/board/xilinx/versal/board.c b/board/xilinx/versal/board.c index 90751477b5e1d0aa54ab5a0c1ba6b0ac304a8bb2..b5ddd0c5ad2465096e973a55dea1968464141556 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 @@ int board_early_init_r(void) 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(); diff --git a/configs/xilinx_versal_mini_defconfig b/configs/xilinx_versal_mini_defconfig index 012ba3ebbebfdbf4ca72a8341d321b920e22967c..98759d0705e20dec76964a05bff38e88e04f751a 100644 --- a/configs/xilinx_versal_mini_defconfig +++ b/configs/xilinx_versal_mini_defconfig @@ -10,6 +10,7 @@ CONFIG_SYS_MEM_RSVD_FOR_MMU=y CONFIG_COUNTER_FREQUENCY=2720000 # CONFIG_LEGACY_IMAGE_FORMAT is not set CONFIG_SYS_CONSOLE_INFO_QUIET=y +# CONFIG_BOARD_LATE_INIT is not set # CONFIG_DISPLAY_CPUINFO is not set CONFIG_BOARD_EARLY_INIT_R=y # CONFIG_CMDLINE_EDITING is not set diff --git a/configs/xilinx_versal_mini_emmc0_defconfig b/configs/xilinx_versal_mini_emmc0_defconfig index 440035f53bbca3c2fba7f57ebedf54e5d7485677..08d23243bee40af17a3b4213d589ec8e11432480 100644 --- a/configs/xilinx_versal_mini_emmc0_defconfig +++ b/configs/xilinx_versal_mini_emmc0_defconfig @@ -8,6 +8,7 @@ CONFIG_NR_DRAM_BANKS=1 CONFIG_SYS_MALLOC_LEN=0x80000 CONFIG_COUNTER_FREQUENCY=2720000 CONFIG_SYS_CONSOLE_INFO_QUIET=y +# CONFIG_BOARD_LATE_INIT is not set # CONFIG_DISPLAY_CPUINFO is not set CONFIG_BOARD_EARLY_INIT_R=y # CONFIG_CMDLINE_EDITING is not set diff --git a/configs/xilinx_versal_mini_emmc1_defconfig b/configs/xilinx_versal_mini_emmc1_defconfig index 07ec6ebd664bad8fcd7bcc2e96d1111b86b8971a..fef5cadd6ea767af2b2b52918bdd9ebc6b703e76 100644 --- a/configs/xilinx_versal_mini_emmc1_defconfig +++ b/configs/xilinx_versal_mini_emmc1_defconfig @@ -8,6 +8,7 @@ CONFIG_NR_DRAM_BANKS=1 CONFIG_SYS_MALLOC_LEN=0x80000 CONFIG_COUNTER_FREQUENCY=2720000 CONFIG_SYS_CONSOLE_INFO_QUIET=y +# CONFIG_BOARD_LATE_INIT is not set # CONFIG_DISPLAY_CPUINFO is not set CONFIG_BOARD_EARLY_INIT_R=y # CONFIG_CMDLINE_EDITING is not set diff --git a/configs/xilinx_versal_virt_defconfig b/configs/xilinx_versal_virt_defconfig index 3b07545ac4af73b2a1fc5201c8389845ea87e828..75f8b983080d01e76f15c6f3316ac70d475030ea 100644 --- a/configs/xilinx_versal_virt_defconfig +++ b/configs/xilinx_versal_virt_defconfig @@ -12,6 +12,7 @@ CONFIG_FIT_VERBOSE=y # CONFIG_ARCH_FIXUP_FDT_MEMORY is not set CONFIG_BOOTDELAY=-1 CONFIG_SUPPORT_RAW_INITRD=y +# CONFIG_BOARD_LATE_INIT is not set # CONFIG_DISPLAY_CPUINFO is not set CONFIG_BOARD_EARLY_INIT_R=y CONFIG_HUSH_PARSER=y