diff options
author | Andrey Smirnov <andrew.smirnov@gmail.com> | 2018-04-16 12:31:56 -0700 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2018-04-17 09:13:07 +0200 |
commit | 23da05b9e9a6827b19cf8f89255a378fbbf0fbfe (patch) | |
tree | 789d41e8c4a1f9fa7485b075a10bf3a6a05b8511 | |
parent | 0b3c9e61273b641c6f80c0bf85c5c471fbc137b0 (diff) | |
download | barebox-23da05b9e9a6827b19cf8f89255a378fbbf0fbfe.tar.gz barebox-23da05b9e9a6827b19cf8f89255a378fbbf0fbfe.tar.xz |
ARM: VFxxx: Implement code to detect bootsource
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r-- | arch/arm/mach-imx/boot.c | 101 | ||||
-rw-r--r-- | arch/arm/mach-imx/include/mach/generic.h | 2 |
2 files changed, 103 insertions, 0 deletions
diff --git a/arch/arm/mach-imx/boot.c b/arch/arm/mach-imx/boot.c index b08b122509..9e67cedf6d 100644 --- a/arch/arm/mach-imx/boot.c +++ b/arch/arm/mach-imx/boot.c @@ -27,6 +27,7 @@ #include <mach/imx53-regs.h> #include <mach/imx6-regs.h> #include <mach/imx7-regs.h> +#include <mach/vf610-regs.h> /* [CTRL][TYPE] */ static const enum bootsource locations[4][4] = { @@ -550,3 +551,103 @@ void imx7_boot_save_loc(void) bootsource_set(src); bootsource_set_instance(instance); } + +static int vf610_boot_instance_spi(uint32_t r) +{ + return FIELD_GET(BOOT_CFG1_1, r); +} + +static int vf610_boot_instance_nor(uint32_t r) +{ + return FIELD_GET(BOOT_CFG1_3, r); +} + +/* + * Vybrid's Serial ROM boot sources (BOOT_CFG4[2:0]) are as follows: + * + * 000 - SPI0 + * 001 - SPI1 + * 010 - SPI2 + * 011 - SPI3 + * 100 - I2C0 + * 101 - I2C1 + * 110 - I2C2 + * 111 - I2C3 + * + * Which we can neatly divide in two halves and use MSb to detect if + * bootsource is I2C or SPI EEPROM and 2 LSbs directly as boot + * insance. + */ +static enum bootsource vf610_bootsource_serial_rom(uint32_t r) +{ + return FIELD_GET(BOOT_CFG4_2, r) ? BOOTSOURCE_I2C : BOOTSOURCE_SPI_NOR; +} + +static int vf610_boot_instance_serial_rom(uint32_t r) +{ + return __imx6_bootsource_serial_rom(r) & 0b11; +} + +static int vf610_boot_instance_can(uint32_t r) +{ + return FIELD_GET(BOOT_CFG1_0, r); +} + +static int vf610_boot_instance_mmc(uint32_t r) +{ + return FIELD_GET(BOOT_CFG2_3, r); +} + +void vf610_get_boot_source(enum bootsource *src, int *instance) +{ + void __iomem *src_base = IOMEM(VF610_SRC_BASE_ADDR); + uint32_t sbmr1 = readl(src_base + IMX6_SRC_SBMR1); + uint32_t sbmr2 = readl(src_base + IMX6_SRC_SBMR2); + + if (imx6_bootsource_reserved(sbmr2)) + return; + + if (imx6_bootsource_serial(sbmr2)) { + *src = BOOTSOURCE_SERIAL; + return; + } + + switch (imx53_bootsource_internal(sbmr1)) { + case 0: + *src = BOOTSOURCE_SPI; /* Really: qspi */ + *instance = vf610_boot_instance_spi(sbmr1); + break; + case 1: + *src = BOOTSOURCE_NOR; + *instance = vf610_boot_instance_nor(sbmr1); + break; + case 2: + *src = vf610_bootsource_serial_rom(sbmr1); + *instance = vf610_boot_instance_serial_rom(sbmr1); + break; + case 3: + *src = BOOTSOURCE_CAN; + *instance = vf610_boot_instance_can(sbmr1); + break; + case 6: + case 7: + *src = BOOTSOURCE_MMC; + *instance = vf610_boot_instance_mmc(sbmr1); + break; + default: + if (imx53_bootsource_nand(sbmr1)) + *src = BOOTSOURCE_NAND; + break; + } +} + +void vf610_boot_save_loc(void) +{ + enum bootsource src = BOOTSOURCE_UNKNOWN; + int instance = BOOTSOURCE_INSTANCE_UNKNOWN; + + vf610_get_boot_source(&src, &instance); + + bootsource_set(src); + bootsource_set_instance(instance); +} diff --git a/arch/arm/mach-imx/include/mach/generic.h b/arch/arm/mach-imx/include/mach/generic.h index f68dc875b0..dedb4bbf06 100644 --- a/arch/arm/mach-imx/include/mach/generic.h +++ b/arch/arm/mach-imx/include/mach/generic.h @@ -15,6 +15,7 @@ void imx51_boot_save_loc(void); void imx53_boot_save_loc(void); void imx6_boot_save_loc(void); void imx7_boot_save_loc(void); +void vf610_boot_save_loc(void); void imx25_get_boot_source(enum bootsource *src, int *instance); void imx35_get_boot_source(enum bootsource *src, int *instance); @@ -22,6 +23,7 @@ void imx51_get_boot_source(enum bootsource *src, int *instance); void imx53_get_boot_source(enum bootsource *src, int *instance); void imx6_get_boot_source(enum bootsource *src, int *instance); void imx7_get_boot_source(enum bootsource *src, int *instance); +void vf610_get_boot_source(enum bootsource *src, int *instance); int imx1_init(void); int imx21_init(void); |