aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2022-03-05 20:46:55 -0500
committerTom Rini <trini@konsulko.com>2022-03-05 20:46:55 -0500
commit6d3c46ed0e230d999c3f20f7fd4f3a88c03b14ca (patch)
tree5fc59b93a273da67332d73bce74ab707d608a7c9
parent0444cbbe77ef3583c84086b8e80dc8f86cc80e40 (diff)
parentcfcf1952c11e6ffcbbf88eb63c49edca2acf1d5e (diff)
downloadu-boot-WIP/05Mar2022.zip
u-boot-WIP/05Mar2022.tar.gz
u-boot-WIP/05Mar2022.tar.bz2
Merge https://source.denx.de/u-boot/custodians/u-boot-sunxiWIP/05Mar2022
- Fix ARMv5/F1C100 FEL booting - Fix F1C100 reset - Introduce proper F1C100 boot method detection - Enable SPI booting for F1C100 Boot tested from FEL, SPI, SD card and eMMC (where applicable) on Pine64-LTS, Pine-H64, BananaPi M1, OrangePi Zero, LicheePi Nano(F1C100).
-rw-r--r--arch/arm/cpu/arm926ejs/sunxi/fel_utils.S4
-rw-r--r--arch/arm/include/asm/arch-sunxi/gpio.h1
-rw-r--r--arch/arm/include/asm/arch-sunxi/spl.h9
-rw-r--r--arch/arm/mach-sunxi/Kconfig2
-rw-r--r--arch/arm/mach-sunxi/board.c64
-rw-r--r--arch/arm/mach-sunxi/spl_spi_sunxi.c24
-rw-r--r--configs/licheepi_nano_defconfig2
7 files changed, 69 insertions, 37 deletions
diff --git a/arch/arm/cpu/arm926ejs/sunxi/fel_utils.S b/arch/arm/cpu/arm926ejs/sunxi/fel_utils.S
index 08be7ed..2592403 100644
--- a/arch/arm/cpu/arm926ejs/sunxi/fel_utils.S
+++ b/arch/arm/cpu/arm926ejs/sunxi/fel_utils.S
@@ -25,9 +25,9 @@ ENTRY(return_to_fel)
mov sp, r0
mov lr, r1
ldr r0, =fel_stash
- ldr r1, [r0, #16]
- mcr p15, 0, r1, c1, c0, 0 @ Write CP15 Control Register
ldr r1, [r0, #12]
+ mcr p15, 0, r1, c1, c0, 0 @ Write CP15 SCTLR register
+ ldr r1, [r0, #8]
msr cpsr, r1 @ Write CPSR
bx lr
ENDPROC(return_to_fel)
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
index 7f7eb05..edd0fbf 100644
--- a/arch/arm/include/asm/arch-sunxi/gpio.h
+++ b/arch/arm/include/asm/arch-sunxi/gpio.h
@@ -160,6 +160,7 @@ enum sunxi_gpio_number {
#define SUNXI_GPC_SDC2 3
#define SUN6I_GPC_SDC3 4
#define SUN50I_GPC_SPI0 4
+#define SUNIV_GPC_SPI0 2
#define SUNXI_GPD_LCD0 2
#define SUNXI_GPD_LVDS0 3
diff --git a/arch/arm/include/asm/arch-sunxi/spl.h b/arch/arm/include/asm/arch-sunxi/spl.h
index 58cdf80..b543d24 100644
--- a/arch/arm/include/asm/arch-sunxi/spl.h
+++ b/arch/arm/include/asm/arch-sunxi/spl.h
@@ -19,6 +19,15 @@
#define SUNXI_BOOTED_FROM_MMC0_HIGH 0x10
#define SUNXI_BOOTED_FROM_MMC2_HIGH 0x12
+/*
+ * Values taken from the F1C200s BootROM stack
+ * to determine where we booted from.
+ */
+#define SUNIV_BOOTED_FROM_MMC0 0xffff40f8
+#define SUNIV_BOOTED_FROM_NAND 0xffff4114
+#define SUNIV_BOOTED_FROM_SPI 0xffff4130
+#define SUNIV_BOOTED_FROM_MMC1 0xffff4150
+
#define is_boot0_magic(addr) (memcmp((void *)(addr), BOOT0_MAGIC, 8) == 0)
uint32_t sunxi_get_boot_device(void);
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 205fe3c..d1c60d2 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -1038,7 +1038,7 @@ config SPL_STACK_R_ADDR
config SPL_SPI_SUNXI
bool "Support for SPI Flash on Allwinner SoCs in SPL"
- depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUNXI_H3_H5 || MACH_SUN50I || MACH_SUN8I_R40 || MACH_SUN50I_H6
+ depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUNXI_H3_H5 || MACH_SUN50I || MACH_SUN8I_R40 || MACH_SUN50I_H6 || MACH_SUNIV
help
Enable support for SPI Flash. This option allows SPL to read from
sunxi SPI Flash. It uses the same method as the boot ROM, so does
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
index 57078f7..0071de1 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -191,12 +191,48 @@ SPL_LOAD_IMAGE_METHOD("FEL", 0, BOOT_DEVICE_BOARD, spl_board_load_image);
#define SUNXI_INVALID_BOOT_SOURCE -1
+static int suniv_get_boot_source(void)
+{
+ /* Get the last function call from BootROM's stack. */
+ u32 brom_call = *(u32 *)(uintptr_t)(fel_stash.sp - 4);
+
+ /* translate SUNIV BootROM stack to standard SUNXI boot sources */
+ switch (brom_call) {
+ case SUNIV_BOOTED_FROM_MMC0:
+ return SUNXI_BOOTED_FROM_MMC0;
+ case SUNIV_BOOTED_FROM_SPI:
+ return SUNXI_BOOTED_FROM_SPI;
+ case SUNIV_BOOTED_FROM_MMC1:
+ return SUNXI_BOOTED_FROM_MMC2;
+ /* SPI NAND is not supported yet. */
+ case SUNIV_BOOTED_FROM_NAND:
+ return SUNXI_INVALID_BOOT_SOURCE;
+ }
+ /* If we get here something went wrong try to boot from FEL.*/
+ printf("Unknown boot source from BROM: 0x%x\n", brom_call);
+ return SUNXI_INVALID_BOOT_SOURCE;
+}
+
static int sunxi_get_boot_source(void)
{
+ /*
+ * On the ARMv5 SoCs, the SPL header in SRAM is overwritten by the
+ * exception vectors in U-Boot proper, so we won't find any
+ * information there. Also the FEL stash is only valid in the SPL,
+ * so we can't use that either. So if this is called from U-Boot
+ * proper, just return MMC0 as a placeholder, for now.
+ */
+ if (IS_ENABLED(CONFIG_MACH_SUNIV) &&
+ !IS_ENABLED(CONFIG_SPL_BUILD))
+ return SUNXI_BOOTED_FROM_MMC0;
+
if (!is_boot0_magic(SPL_ADDR + 4)) /* eGON.BT0 */
return SUNXI_INVALID_BOOT_SOURCE;
- return readb(SPL_ADDR + 0x28);
+ if (IS_ENABLED(CONFIG_MACH_SUNIV))
+ return suniv_get_boot_source();
+ else
+ return readb(SPL_ADDR + 0x28);
}
/* The sunxi internal brom will try to loader external bootloader
@@ -276,36 +312,10 @@ unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc,
return sector;
}
-#ifdef CONFIG_MACH_SUNIV
-/*
- * The suniv BROM does not pass the boot media type to SPL, so we try with the
- * boot sequence in BROM: mmc0->spinor->fail.
- * TODO: This has the slight chance of being wrong (invalid SPL signature,
- * but valid U-Boot legacy image on the SD card), but this should be rare.
- * It looks like we can deduce from some BROM state upon entering the SPL
- * (registers, SP, or stack itself) where the BROM was coming from and use
- * that here.
- */
-void board_boot_order(u32 *spl_boot_list)
-{
- /*
- * See the comments above in sunxi_get_boot_device() for information
- * about FEL boot.
- */
- if (!is_boot0_magic(SPL_ADDR + 4)) {
- spl_boot_list[0] = BOOT_DEVICE_BOARD;
- return;
- }
-
- spl_boot_list[0] = BOOT_DEVICE_MMC1;
- spl_boot_list[1] = BOOT_DEVICE_SPI;
-}
-#else
u32 spl_boot_device(void)
{
return sunxi_get_boot_device();
}
-#endif
__weak void sunxi_sram_init(void)
{
diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c
index 910e805..734c165 100644
--- a/arch/arm/mach-sunxi/spl_spi_sunxi.c
+++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c
@@ -90,6 +90,7 @@
#define SPI0_CLK_DIV_BY_2 0x1000
#define SPI0_CLK_DIV_BY_4 0x1001
+#define SPI0_CLK_DIV_BY_32 0x100f
/*****************************************************************************/
@@ -132,7 +133,8 @@ static uintptr_t spi0_base_address(void)
if (IS_ENABLED(CONFIG_MACH_SUN50I_H6))
return 0x05010000;
- if (!is_sun6i_gen_spi())
+ if (!is_sun6i_gen_spi() ||
+ IS_ENABLED(CONFIG_MACH_SUNIV))
return 0x01C05000;
return 0x01C68000;
@@ -156,11 +158,16 @@ static void spi0_enable_clock(void)
if (!IS_ENABLED(CONFIG_MACH_SUN50I_H6))
setbits_le32(CCM_AHB_GATING0, (1 << AHB_GATE_OFFSET_SPI0));
- /* Divide by 4 */
- writel(SPI0_CLK_DIV_BY_4, base + (is_sun6i_gen_spi() ?
- SUN6I_SPI0_CCTL : SUN4I_SPI0_CCTL));
- /* 24MHz from OSC24M */
- writel((1 << 31), CCM_SPI0_CLK);
+ if (IS_ENABLED(CONFIG_MACH_SUNIV)) {
+ /* Divide by 32, clock source is AHB clock 200MHz */
+ writel(SPI0_CLK_DIV_BY_32, base + SUN6I_SPI0_CCTL);
+ } else {
+ /* Divide by 4 */
+ writel(SPI0_CLK_DIV_BY_4, base + (is_sun6i_gen_spi() ?
+ SUN6I_SPI0_CCTL : SUN4I_SPI0_CCTL));
+ /* 24MHz from OSC24M */
+ writel((1 << 31), CCM_SPI0_CLK);
+ }
if (is_sun6i_gen_spi()) {
/* Enable SPI in the master mode and do a soft reset */
@@ -191,7 +198,8 @@ static void spi0_disable_clock(void)
SUN4I_CTL_ENABLE);
/* Disable the SPI0 clock */
- writel(0, CCM_SPI0_CLK);
+ if (!IS_ENABLED(CONFIG_MACH_SUNIV))
+ writel(0, CCM_SPI0_CLK);
/* Close the SPI0 gate */
if (!IS_ENABLED(CONFIG_MACH_SUN50I_H6))
@@ -212,6 +220,8 @@ static void spi0_init(void)
if (IS_ENABLED(CONFIG_MACH_SUN50I) ||
IS_ENABLED(CONFIG_MACH_SUN50I_H6))
pin_function = SUN50I_GPC_SPI0;
+ else if (IS_ENABLED(CONFIG_MACH_SUNIV))
+ pin_function = SUNIV_GPC_SPI0;
spi0_pinmux_setup(pin_function);
spi0_enable_clock();
diff --git a/configs/licheepi_nano_defconfig b/configs/licheepi_nano_defconfig
index 2ac0ef4..67b7b85 100644
--- a/configs/licheepi_nano_defconfig
+++ b/configs/licheepi_nano_defconfig
@@ -9,3 +9,5 @@ CONFIG_MACH_SUNIV=y
CONFIG_DRAM_CLK=156
CONFIG_DRAM_ZQ=0
# CONFIG_VIDEO_SUNXI is not set
+CONFIG_SPL_SPI_SUNXI=y
+# CONFIG_SYSRESET is not set