]> Git Repo - J-u-boot.git/commitdiff
Merge https://source.denx.de/u-boot/custodians/u-boot-sunxi
authorTom Rini <[email protected]>
Sun, 6 Mar 2022 01:46:55 +0000 (20:46 -0500)
committerTom Rini <[email protected]>
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 08be7ed11aa0664d64ffe9e49fad752c7e5455e4..25924033c63da0c7e7c82382adecf4e3f5232eaa 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 7f7eb0517cf8b80639c2396b827d31cf657dbe6e..edd0fbf49fe02e97ad90feed466fbf3271ea64f2 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 58cdf806d9a9324373e452635bc7d66ba07f8fa5..b543d24e5a0f28f7ee5902e53ecd6e2815b5d7b7 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 205fe3c9d3ca972adb5b3879169b800e1f56d17b..d1c60d2408268783f8b6f38ee02838ff02da9e95 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 57078f7a7b28b65a5b75b79a3762860d96904924..0071de19ffd419f30d8bd223ccdcf5c1e9988ba9 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 910e80501617e5d326f9a3123d2277de00f2db5b..734c165e5d2715dab7fedfe7d3443bc1d78c8ebc 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 2ac0ef428567bedee4ba80ea99bbc41c6e6c5a3f..67b7b85c4914d4b63049011f10e9ad86d3c332da 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
This page took 0.051075 seconds and 4 git commands to generate.