armV7R: K3: am654: Load SYSFW binary and config from boot media
[oweals/u-boot.git] / arch / arm / mach-k3 / am6_init.c
index fef01075056e8baa8fe98c59282d5190dd15184a..e326f575e5f51d78275e43dcb9330e08b1b3f58a 100644 (file)
 #include <asm/io.h>
 #include <spl.h>
 #include <asm/arch/hardware.h>
+#include <asm/arch/sysfw-loader.h>
 #include "common.h"
+#include <dm.h>
+#include <dm/uclass-internal.h>
+#include <dm/pinctrl.h>
 
 #ifdef CONFIG_SPL_BUILD
 static void mmr_unlock(u32 base, u32 partition)
@@ -48,15 +52,24 @@ static void ctrl_mmr_unlock(void)
        mmr_unlock(CTRL_MMR0_BASE, 7);
 }
 
+/*
+ * This uninitialized global variable would normal end up in the .bss section,
+ * but the .bss is cleared between writing and reading this variable, so move
+ * it to the .data section.
+ */
+u32 bootindex __attribute__((section(".data")));
+
 static void store_boot_index_from_rom(void)
 {
-       u32 *boot_index = (u32 *)K3_BOOT_PARAM_TABLE_INDEX_VAL;
-
-       *boot_index = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX);
+       bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX);
 }
 
 void board_init_f(ulong dummy)
 {
+#if defined(CONFIG_K3_LOAD_SYSFW) || defined(CONFIG_K3_AM654_DDRSS)
+       struct udevice *dev;
+       int ret;
+#endif
        /*
         * Cannot delay this further as there is a chance that
         * K3_BOOT_PARAM_TABLE_INDEX can be over written by SPL MALLOC section.
@@ -73,15 +86,42 @@ void board_init_f(ulong dummy)
        /* Init DM early in-order to invoke system controller */
        spl_early_init();
 
+#ifdef CONFIG_K3_LOAD_SYSFW
+       /*
+        * Process pinctrl for the serial0 a.k.a. WKUP_UART0 module and continue
+        * regardless of the result of pinctrl. Do this without probing the
+        * device, but instead by searching the device that would request the
+        * given sequence number if probed. The UART will be used by the system
+        * firmware (SYSFW) image for various purposes and SYSFW depends on us
+        * to initialize its pin settings.
+        */
+       ret = uclass_find_device_by_seq(UCLASS_SERIAL, 0, true, &dev);
+       if (!ret)
+               pinctrl_select_state(dev, "default");
+
+       /*
+        * Load, start up, and configure system controller firmware. Provide
+        * the U-Boot console init function to the SYSFW post-PM configuration
+        * callback hook, effectively switching on (or over) the console
+        * output.
+        */
+       k3_sysfw_loader(preloader_console_init);
+#else
        /* Prepare console output */
        preloader_console_init();
+#endif
+
+#ifdef CONFIG_K3_AM654_DDRSS
+       ret = uclass_get_device(UCLASS_RAM, 0, &dev);
+       if (ret)
+               panic("DRAM init failed: %d\n", ret);
+#endif
 }
 
 u32 spl_boot_mode(const u32 boot_device)
 {
 #if defined(CONFIG_SUPPORT_EMMC_BOOT)
        u32 devstat = readl(CTRLMMR_MAIN_DEVSTAT);
-       u32 bootindex = readl(K3_BOOT_PARAM_TABLE_INDEX_VAL);
 
        u32 bootmode = (devstat & CTRLMMR_MAIN_DEVSTAT_BOOTMODE_MASK) >>
                        CTRLMMR_MAIN_DEVSTAT_BOOTMODE_SHIFT;
@@ -93,7 +133,7 @@ u32 spl_boot_mode(const u32 boot_device)
 #endif
 
        /* Everything else use filesystem if available */
-#if defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT)
+#if defined(CONFIG_SPL_FS_FAT) || defined(CONFIG_SPL_FS_EXT4)
        return MMCSD_MODE_FS;
 #else
        return MMCSD_MODE_RAW;
@@ -157,7 +197,6 @@ static u32 __get_primary_bootmedia(u32 devstat)
 u32 spl_boot_device(void)
 {
        u32 devstat = readl(CTRLMMR_MAIN_DEVSTAT);
-       u32 bootindex = readl(K3_BOOT_PARAM_TABLE_INDEX_VAL);
 
        if (bootindex == K3_PRIMARY_BOOTMODE)
                return __get_primary_bootmedia(devstat);