[PATCH v10 01/17] spacemit: k1: select boot device via config registers
Eric Chung <[email protected]>
| Newsgroups | org.u-boot-project.lists.u-boot |
|---|---|
| Message-ID | <[email protected]> |
Add logic to determine the current boot device by reading the SoC's configuration registers, rather than using a hardcoded default. Signed-off-by: Eric Chung <[email protected]> Reviewed-by: Yao Zi <[email protected]> --- v9: - Enhance detection on booting from SD card. v5: - Add blank lines around the switch statement. v2: - Use FIELD_GET() to parse boot strap mode. - Remove comments on hacking. Since the sequence between eMMC and SD device is exchanged in the upstream DTS. So it isn't a hacking any more. --- board/spacemit/k1/spl.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 1 deletion(-) diff --git a/board/spacemit/k1/spl.c b/board/spacemit/k1/spl.c index d749e21a2d57..b70eed14e6ed 100644 --- a/board/spacemit/k1/spl.c +++ b/board/spacemit/k1/spl.c @@ -13,6 +13,7 @@ #include <dm/device.h> #include <dm/uclass.h> #include <i2c.h> +#include <linux/bitfield.h> #include <linux/ctype.h> #include <linux/delay.h> #include <log.h> @@ -22,6 +23,20 @@ #include <tlv_eeprom.h> #include "tlv_codes.h" +/* boot mode configs */ +#define BOOT_DEV_FLAG_REG 0xd4282d10 +#define BOOT_PIN_SEL_REG 0xd4282c20 + +#define BOOT_STRAP_MODE_OFFSET 9 +#define BOOT_STRAP_MODE_MASK 3 +#define BOOT_STRAP_MODE_EMMC 0 +#define BOOT_STRAP_MODE_SPI 1 +#define BOOT_STRAP_MODE_NAND 2 +#define BOOT_STRAP_MODE_SD 3 + +#define STORAGE_API_P_ADDR 0xc0838498 +#define SDCARD_API_ENTRY 0xffe0a548 + #define MUX_MODE4 4 #define EDGE_NONE BIT(6) #define PULL_UP (6 << 13) /* bit[15:13] 110 */ @@ -46,6 +61,17 @@ typedef void (*puts_func_t)(const char *s); typedef int (*ddr_init_func_t)(u64 ddr_base, u32 cs_num, u32 data_rate, puts_func_t puts); +enum board_boot_mode { + BOOT_MODE_NONE = 0, + BOOT_MODE_USB = 0x55a, + BOOT_MODE_EMMC, + BOOT_MODE_NAND, + BOOT_MODE_SPI, + BOOT_MODE_SD, + BOOT_MODE_SHELL = 0x55f, + BOOT_MODE_BOOTSTRAP, +}; + struct ddr_cfg { u32 data_rate; u32 cs_num; @@ -58,6 +84,69 @@ binman_sym_declare(ulong, ddr_fw, size); char product_name[I2C_BUF_SIZE] = "k1"; +u32 read_boot_mode(void) +{ + void __iomem *boot_dev = (void __iomem *)BOOT_DEV_FLAG_REG; + void __iomem *boot_strap = (void __iomem *)BOOT_PIN_SEL_REG; + void __iomem *storage_api = (void __iomem *)STORAGE_API_P_ADDR; + u32 mode, sel, ret = 0; + + mode = readl(storage_api); + if (mode == SDCARD_API_ENTRY) + return BOOT_MODE_SD; + + mode = readl(boot_dev); + if (mode == BOOT_MODE_NONE || mode > BOOT_MODE_SD) { + sel = FIELD_GET(BOOT_STRAP_MODE_MASK << BOOT_STRAP_MODE_OFFSET, + readl(boot_strap)); + switch (sel) { + case BOOT_STRAP_MODE_EMMC: + mode = BOOT_MODE_EMMC; + break; + case BOOT_STRAP_MODE_NAND: + mode = BOOT_MODE_NAND; + break; + case BOOT_STRAP_MODE_SPI: + mode = BOOT_MODE_SPI; + break; + case BOOT_STRAP_MODE_SD: + default: + mode = BOOT_MODE_SD; + break; + } + } + + switch (mode) { + case BOOT_MODE_EMMC: + ret = BOOT_DEVICE_MMC1; + break; + case BOOT_MODE_NAND: + ret = BOOT_DEVICE_NAND; + break; + case BOOT_MODE_SPI: + ret = BOOT_DEVICE_SPI; + break; + case BOOT_MODE_USB: + ret = BOOT_DEVICE_USB; + break; + case BOOT_MODE_SD: + ret = BOOT_DEVICE_MMC2; + break; + default: + ret = BOOT_DEVICE_MMC1; + break; + } + + return ret; +} + +void write_boot_mode(u32 mode) +{ + void __iomem *boot_dev = (void __iomem *)BOOT_DEV_FLAG_REG; + + writel(mode, boot_dev); +} + static void i2c_early_init(void) { struct udevice *bus; @@ -327,8 +416,12 @@ void nor_early_init(void) void board_init_f(ulong dummy) { + u32 mode; int ret; + mode = read_boot_mode(); + write_boot_mode(mode); + ret = spl_early_init(); if (ret) panic("spl_early_init() failed:%d\n", ret); @@ -354,7 +447,7 @@ void board_init_f(ulong dummy) u32 spl_boot_device(void) { - return BOOT_DEVICE_SPI; + return read_boot_mode(); } void spl_board_init(void) -- 2.51.0