Message ID | 20230516144753.30869-1-ashok.reddy.soma@amd.com |
---|---|
State | Accepted |
Commit | ded539ff6633f3ba493e18bf23ce489bfc03f28d |
Delegated to: | Michal Simek |
Headers | show |
Series | [v2] arm64: versal-net: Detect and display bootmode | expand |
On 5/16/23 16:47, Ashok Reddy Soma wrote: > Read boodmode register using versal_net_get_bootmode() in board_late_init > and prepare corresponding distro boot command sequence based on it. > > versal_net_get_bootmode() will be changed to use smc calls later, but > for now directly reads the register. > > Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@amd.com> > --- > > Changes in v2: > - Remove check for mmc/sdhci node enabled or not in EMMC bootmode > - Remove check for sdhci node enabled or not in SD0 and SD1 bootmode > > .../mach-versal-net/include/mach/hardware.h | 21 ++++ > board/xilinx/versal-net/board.c | 114 ++++++++++++++++++ > 2 files changed, 135 insertions(+) > > diff --git a/arch/arm/mach-versal-net/include/mach/hardware.h b/arch/arm/mach-versal-net/include/mach/hardware.h > index c5e4e22040..89b84a2efc 100644 > --- a/arch/arm/mach-versal-net/include/mach/hardware.h > +++ b/arch/arm/mach-versal-net/include/mach/hardware.h > @@ -27,7 +27,13 @@ struct iou_scntrs_regs { > u32 base_frequency_id_register; /* 0x20 */ > }; > > +struct crp_regs { > + u32 reserved0[128]; > + u32 boot_mode_usr; /* 0x200 */ > +}; > + > #define VERSAL_NET_CRL_APB_BASEADDR 0xEB5E0000 > +#define VERSAL_NET_CRP_BASEADDR 0xF1260000 > #define VERSAL_NET_IOU_SCNTR_SECURE 0xEC920000 > > #define CRL_APB_TIMESTAMP_REF_CTRL_CLKACT_BIT BIT(25) > @@ -36,6 +42,7 @@ struct iou_scntrs_regs { > #define IOU_SCNTRS_CONTROL_EN 1 > > #define crlapb_base ((struct crlapb_regs *)VERSAL_NET_CRL_APB_BASEADDR) > +#define crp_base ((struct crp_regs *)VERSAL_NET_CRP_BASEADDR) > #define iou_scntr_secure ((struct iou_scntrs_regs *)VERSAL_NET_IOU_SCNTR_SECURE) > > #define PMC_TAP 0xF11A0000 > @@ -49,6 +56,20 @@ struct iou_scntrs_regs { > # define PLATFORM_VERSION_MASK GENMASK(31, 28) > #define PMC_TAP_USERCODE (PMC_TAP + 0x8) > > +/* 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 > + > enum versal_net_platform { > VERSAL_NET_SILICON = 0, > VERSAL_NET_SPP = 1, > diff --git a/board/xilinx/versal-net/board.c b/board/xilinx/versal-net/board.c > index 6724c7290f..6595d6f3e8 100644 > --- a/board/xilinx/versal-net/board.c > +++ b/board/xilinx/versal-net/board.c > @@ -10,6 +10,7 @@ > #include <cpu_func.h> > #include <fdtdec.h> > #include <init.h> > +#include <env_internal.h> > #include <log.h> > #include <malloc.h> > #include <time.h> > @@ -165,8 +166,32 @@ int board_early_init_r(void) > return 0; > } > > +static u8 versal_net_get_bootmode(void) > +{ > + u8 bootmode; > + u32 reg = 0; > + > + reg = readl(&crp_base->boot_mode_usr); > + > + if (reg >> BOOT_MODE_ALT_SHIFT) > + reg >>= BOOT_MODE_ALT_SHIFT; > + > + bootmode = reg & BOOT_MODES_MASK; > + > + return bootmode; > +} > + > int board_late_init(void) > { > + 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; > @@ -175,6 +200,95 @@ int board_late_init(void) > if (!IS_ENABLED(CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG)) > return 0; > > + bootmode = versal_net_get_bootmode(); > + > + puts("Bootmode: "); > + switch (bootmode) { > + case USB_MODE: > + puts("USB_MODE\n"); > + mode = "usb_dfu0 usb_dfu1"; > + break; > + case JTAG_MODE: > + puts("JTAG_MODE\n"); > + mode = "jtag 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 = "mmc"; > + bootseq = dev_seq(dev); > + break; > + case SD_MODE: > + puts("SD_MODE\n"); > + if (uclass_get_device_by_name(UCLASS_MMC, > + "mmc@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(dev)); > + > + mode = "mmc"; > + bootseq = dev_seq(dev); > + break; > + case SD1_LSHFT_MODE: > + puts("LVL_SHFT_"); > + fallthrough; > + case SD_MODE1: > + puts("SD_MODE1\n"); > + if (uclass_get_device_by_name(UCLASS_MMC, > + "mmc@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(dev)); > + > + mode = "mmc"; > + bootseq = dev_seq(dev); > + 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 board_late_init_xilinx(); > } > Applied. M
diff --git a/arch/arm/mach-versal-net/include/mach/hardware.h b/arch/arm/mach-versal-net/include/mach/hardware.h index c5e4e22040..89b84a2efc 100644 --- a/arch/arm/mach-versal-net/include/mach/hardware.h +++ b/arch/arm/mach-versal-net/include/mach/hardware.h @@ -27,7 +27,13 @@ struct iou_scntrs_regs { u32 base_frequency_id_register; /* 0x20 */ }; +struct crp_regs { + u32 reserved0[128]; + u32 boot_mode_usr; /* 0x200 */ +}; + #define VERSAL_NET_CRL_APB_BASEADDR 0xEB5E0000 +#define VERSAL_NET_CRP_BASEADDR 0xF1260000 #define VERSAL_NET_IOU_SCNTR_SECURE 0xEC920000 #define CRL_APB_TIMESTAMP_REF_CTRL_CLKACT_BIT BIT(25) @@ -36,6 +42,7 @@ struct iou_scntrs_regs { #define IOU_SCNTRS_CONTROL_EN 1 #define crlapb_base ((struct crlapb_regs *)VERSAL_NET_CRL_APB_BASEADDR) +#define crp_base ((struct crp_regs *)VERSAL_NET_CRP_BASEADDR) #define iou_scntr_secure ((struct iou_scntrs_regs *)VERSAL_NET_IOU_SCNTR_SECURE) #define PMC_TAP 0xF11A0000 @@ -49,6 +56,20 @@ struct iou_scntrs_regs { # define PLATFORM_VERSION_MASK GENMASK(31, 28) #define PMC_TAP_USERCODE (PMC_TAP + 0x8) +/* 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 + enum versal_net_platform { VERSAL_NET_SILICON = 0, VERSAL_NET_SPP = 1, diff --git a/board/xilinx/versal-net/board.c b/board/xilinx/versal-net/board.c index 6724c7290f..6595d6f3e8 100644 --- a/board/xilinx/versal-net/board.c +++ b/board/xilinx/versal-net/board.c @@ -10,6 +10,7 @@ #include <cpu_func.h> #include <fdtdec.h> #include <init.h> +#include <env_internal.h> #include <log.h> #include <malloc.h> #include <time.h> @@ -165,8 +166,32 @@ int board_early_init_r(void) return 0; } +static u8 versal_net_get_bootmode(void) +{ + u8 bootmode; + u32 reg = 0; + + reg = readl(&crp_base->boot_mode_usr); + + if (reg >> BOOT_MODE_ALT_SHIFT) + reg >>= BOOT_MODE_ALT_SHIFT; + + bootmode = reg & BOOT_MODES_MASK; + + return bootmode; +} + int board_late_init(void) { + 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; @@ -175,6 +200,95 @@ int board_late_init(void) if (!IS_ENABLED(CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG)) return 0; + bootmode = versal_net_get_bootmode(); + + puts("Bootmode: "); + switch (bootmode) { + case USB_MODE: + puts("USB_MODE\n"); + mode = "usb_dfu0 usb_dfu1"; + break; + case JTAG_MODE: + puts("JTAG_MODE\n"); + mode = "jtag 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 = "mmc"; + bootseq = dev_seq(dev); + break; + case SD_MODE: + puts("SD_MODE\n"); + if (uclass_get_device_by_name(UCLASS_MMC, + "mmc@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(dev)); + + mode = "mmc"; + bootseq = dev_seq(dev); + break; + case SD1_LSHFT_MODE: + puts("LVL_SHFT_"); + fallthrough; + case SD_MODE1: + puts("SD_MODE1\n"); + if (uclass_get_device_by_name(UCLASS_MMC, + "mmc@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(dev)); + + mode = "mmc"; + bootseq = dev_seq(dev); + 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 board_late_init_xilinx(); }
Read boodmode register using versal_net_get_bootmode() in board_late_init and prepare corresponding distro boot command sequence based on it. versal_net_get_bootmode() will be changed to use smc calls later, but for now directly reads the register. Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@amd.com> --- Changes in v2: - Remove check for mmc/sdhci node enabled or not in EMMC bootmode - Remove check for sdhci node enabled or not in SD0 and SD1 bootmode .../mach-versal-net/include/mach/hardware.h | 21 ++++ board/xilinx/versal-net/board.c | 114 ++++++++++++++++++ 2 files changed, 135 insertions(+)