aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/mach-omap2/boot-common.c
diff options
context:
space:
mode:
authorKeerthy2022-01-27 13:16:52 +0100
committerTom Rini2022-02-08 09:41:27 -0500
commit0197909dd1c166dfb2e92b338b72d164e70db36f (patch)
tree7e3134786b8fcec5ee603ff9a2d21c185b1dc6de /arch/arm/mach-omap2/boot-common.c
parent795b2c476f7dd7ecf9de95d8dca8ef0c8657dde4 (diff)
arm: mach-omap2: load/start remoteproc IPU1/IPU2
First check the presence of the ipu firmware in the boot partition. If present enable the ipu and the related clocks & then move on to load the firmware and eventually start remoteproc IPU1/IPU2. do_enable_clocks by default puts the clock domains into auto which does not work well with reset. Hence adding do_enable_ipu_clocks function. Signed-off-by: Keerthy <j-keerthy@ti.com> [Amjad: fix IPU1_LOAD_ADDR and compile warnings] Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com>
Diffstat (limited to 'arch/arm/mach-omap2/boot-common.c')
-rw-r--r--arch/arm/mach-omap2/boot-common.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/boot-common.c b/arch/arm/mach-omap2/boot-common.c
index fdb8b479ea0..afc35856419 100644
--- a/arch/arm/mach-omap2/boot-common.c
+++ b/arch/arm/mach-omap2/boot-common.c
@@ -10,6 +10,8 @@
#include <common.h>
#include <ahci.h>
#include <log.h>
+#include <dm/uclass.h>
+#include <fs_loader.h>
#include <spl.h>
#include <asm/global_data.h>
#include <asm/omap_common.h>
@@ -19,9 +21,14 @@
#include <watchdog.h>
#include <scsi.h>
#include <i2c.h>
+#include <remoteproc.h>
DECLARE_GLOBAL_DATA_PTR;
+#define IPU1_LOAD_ADDR (0xa17ff000)
+#define MAX_REMOTECORE_BIN_SIZE (8 * 0x100000)
+#define IPU2_LOAD_ADDR (IPU1_LOAD_ADDR + MAX_REMOTECORE_BIN_SIZE)
+
__weak u32 omap_sys_boot_device(void)
{
return BOOT_DEVICE_NONE;
@@ -194,6 +201,91 @@ u32 spl_mmc_boot_mode(const u32 boot_device)
return gd->arch.omap_boot_mode;
}
+int load_firmware(char *name_fw, u32 *loadaddr)
+{
+ struct udevice *fsdev;
+ int size = 0;
+
+ if (!IS_ENABLED(CONFIG_FS_LOADER))
+ return 0;
+
+ if (!*loadaddr)
+ return 0;
+
+ if (!uclass_get_device(UCLASS_FS_FIRMWARE_LOADER, 0, &fsdev)) {
+ size = request_firmware_into_buf(fsdev, name_fw,
+ (void *)*loadaddr, 0, 0);
+ }
+
+ return size;
+}
+
+void spl_boot_ipu(void)
+{
+ int ret, size;
+ u32 loadaddr = IPU1_LOAD_ADDR;
+
+ if (!IS_ENABLED(CONFIG_SPL_BUILD) ||
+ !IS_ENABLED(CONFIG_REMOTEPROC_TI_IPU))
+ return;
+
+ size = load_firmware("dra7-ipu1-fw.xem4", &loadaddr);
+ if (size <= 0) {
+ pr_err("Firmware loading failed\n");
+ goto skip_ipu1;
+ }
+
+ enable_ipu1_clocks();
+ ret = rproc_dev_init(0);
+ if (ret) {
+ debug("%s: IPU1 failed to initialize on rproc (%d)\n",
+ __func__, ret);
+ goto skip_ipu1;
+ }
+
+ ret = rproc_load(0, IPU1_LOAD_ADDR, 0x2000000);
+ if (ret) {
+ debug("%s: IPU1 failed to load on rproc (%d)\n", __func__,
+ ret);
+ goto skip_ipu1;
+ }
+
+ debug("Starting IPU1...\n");
+
+ ret = rproc_start(0);
+ if (ret)
+ debug("%s: IPU1 failed to start (%d)\n", __func__, ret);
+
+skip_ipu1:
+ loadaddr = IPU2_LOAD_ADDR;
+ size = load_firmware("dra7-ipu2-fw.xem4", &loadaddr);
+ if (size <= 0) {
+ pr_err("Firmware loading failed for ipu2\n");
+ return;
+ }
+
+ enable_ipu2_clocks();
+ ret = rproc_dev_init(1);
+ if (ret) {
+ debug("%s: IPU2 failed to initialize on rproc (%d)\n", __func__,
+ ret);
+ return;
+ }
+
+ ret = rproc_load(1, IPU2_LOAD_ADDR, 0x2000000);
+ if (ret) {
+ debug("%s: IPU2 failed to load on rproc (%d)\n", __func__,
+ ret);
+ return;
+ }
+
+ debug("Starting IPU2...\n");
+
+ ret = rproc_start(1);
+ if (ret)
+ debug("%s: IPU2 failed to start (%d)\n", __func__, ret);
+}
+
void spl_board_init(void)
{
/* Prepare console output */
@@ -214,6 +306,9 @@ void spl_board_init(void)
#ifdef CONFIG_AM33XX
am33xx_spl_board_init();
#endif
+ if (IS_ENABLED(CONFIG_SPL_BUILD) &&
+ IS_ENABLED(CONFIG_REMOTEPROC_TI_IPU))
+ spl_boot_ipu();
}
void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)