sunxi: Automate loading from 128KB MMC offset
[platform/kernel/u-boot.git] / arch / arm / mach-sunxi / board.c
index 921e4c5..b487b26 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <common.h>
+#include <cpu_func.h>
 #include <mmc.h>
 #include <i2c.h>
 #include <serial.h>
@@ -65,6 +66,7 @@ struct mm_region *mem_map = sunxi_mem_map;
 
 static int gpio_init(void)
 {
+       __maybe_unused uint val;
 #if CONFIG_CONS_INDEX == 1 && defined(CONFIG_UART0_PORT_F)
 #if defined(CONFIG_MACH_SUN4I) || \
     defined(CONFIG_MACH_SUN7I) || \
@@ -139,6 +141,14 @@ static int gpio_init(void)
 #error Unsupported console port number. Please fix pin mux settings in board.c
 #endif
 
+#ifdef CONFIG_MACH_SUN50I_H6
+       /* Update PIO power bias configuration by copy hardware detected value */
+       val = readl(SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
+       writel(val, SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
+       val = readl(SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
+       writel(val, SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
+#endif
+
        return 0;
 }
 
@@ -211,12 +221,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"
@@ -234,11 +254,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;
@@ -256,6 +274,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();
@@ -305,7 +343,7 @@ void reset_cpu(ulong addr)
 #endif
 }
 
-#if !defined(CONFIG_SYS_DCACHE_OFF) && !defined(CONFIG_ARM64)
+#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) && !defined(CONFIG_ARM64)
 void enable_caches(void)
 {
        /* Enable D-cache. I-cache is already enabled in start.S */