Merge tag 'u-boot-atmel-fixes-2020.07-a' of https://gitlab.denx.de/u-boot/custodians...
[oweals/u-boot.git] / arch / arm / mach-sunxi / board.c
index db506367bf91868b303951678d2e9fd103bbd43c..f40fccd8f8b9ed05bad0eb7b09114d2e235e9201 100644 (file)
  */
 
 #include <common.h>
+#include <cpu_func.h>
+#include <init.h>
+#include <log.h>
 #include <mmc.h>
 #include <i2c.h>
 #include <serial.h>
 #include <spl.h>
+#include <asm/cache.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
@@ -220,12 +224,22 @@ void s_init(void)
        eth_init_board();
 }
 
+#define SUNXI_INVALID_BOOT_SOURCE      -1
+
+static int sunxi_get_boot_source(void)
+{
+       if (!is_boot0_magic(SPL_ADDR + 4)) /* eGON.BT0 */
+               return SUNXI_INVALID_BOOT_SOURCE;
+
+       return readb(SPL_ADDR + 0x28);
+}
+
 /* The sunxi internal brom will try to loader external bootloader
  * from mmc0, nand flash, mmc2.
  */
 uint32_t sunxi_get_boot_device(void)
 {
-       int boot_source;
+       int boot_source = sunxi_get_boot_source();
 
        /*
         * When booting from the SD card or NAND memory, the "eGON.BT0"
@@ -243,11 +257,9 @@ uint32_t sunxi_get_boot_device(void)
         * binary over USB. If it is found, it determines where SPL was
         * read from.
         */
-       if (!is_boot0_magic(SPL_ADDR + 4)) /* eGON.BT0 */
-               return BOOT_DEVICE_BOARD;
-
-       boot_source = readb(SPL_ADDR + 0x28);
        switch (boot_source) {
+       case SUNXI_INVALID_BOOT_SOURCE:
+               return BOOT_DEVICE_BOARD;
        case SUNXI_BOOTED_FROM_MMC0:
        case SUNXI_BOOTED_FROM_MMC0_HIGH:
                return BOOT_DEVICE_MMC1;
@@ -265,6 +277,26 @@ uint32_t sunxi_get_boot_device(void)
 }
 
 #ifdef CONFIG_SPL_BUILD
+/*
+ * The eGON SPL image can be located at 8KB or at 128KB into an SD card or
+ * an eMMC device. The boot source has bit 4 set in the latter case.
+ * By adding 120KB to the normal offset when booting from a "high" location
+ * we can support both cases.
+ */
+unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc)
+{
+       unsigned long sector = CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR;
+
+       switch (sunxi_get_boot_source()) {
+       case SUNXI_BOOTED_FROM_MMC0_HIGH:
+       case SUNXI_BOOTED_FROM_MMC2_HIGH:
+               sector += (128 - 8) * 2;
+               break;
+       }
+
+       return sector;
+}
+
 u32 spl_boot_device(void)
 {
        return sunxi_get_boot_device();