Merge https://source.denx.de/u-boot/custodians/u-boot-sunxi
authorTom Rini <trini@konsulko.com>
Sun, 6 Mar 2022 01:46:55 +0000 (20:46 -0500)
committerTom Rini <trini@konsulko.com>
Sun, 6 Mar 2022 01:46:55 +0000 (20:46 -0500)
- 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).

arch/arm/cpu/arm926ejs/sunxi/fel_utils.S
arch/arm/include/asm/arch-sunxi/gpio.h
arch/arm/include/asm/arch-sunxi/spl.h
arch/arm/mach-sunxi/Kconfig
arch/arm/mach-sunxi/board.c
arch/arm/mach-sunxi/spl_spi_sunxi.c
configs/licheepi_nano_defconfig

index 08be7ed..2592403 100644 (file)
@@ -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)
index 7f7eb05..edd0fbf 100644 (file)
@@ -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
index 58cdf80..b543d24 100644 (file)
 #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);
index 205fe3c..d1c60d2 100644 (file)
@@ -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
index 57078f7..0071de1 100644 (file)
@@ -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)
 {
index 910e805..734c165 100644 (file)
@@ -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();
index 2ac0ef4..67b7b85 100644 (file)
@@ -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