diff options
author | Keerthy <j-keerthy@ti.com> | 2022-01-27 15:16:52 +0300 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2022-02-08 17:41:27 +0300 |
commit | 0197909dd1c166dfb2e92b338b72d164e70db36f (patch) | |
tree | 7e3134786b8fcec5ee603ff9a2d21c185b1dc6de | |
parent | 795b2c476f7dd7ecf9de95d8dca8ef0c8657dde4 (diff) | |
download | u-boot-0197909dd1c166dfb2e92b338b72d164e70db36f.tar.xz |
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>
-rw-r--r-- | arch/arm/include/asm/arch-omap5/clock.h | 3 | ||||
-rw-r--r-- | arch/arm/include/asm/omap_common.h | 10 | ||||
-rw-r--r-- | arch/arm/mach-omap2/boot-common.c | 95 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clocks-common.c | 33 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap5/hw_data.c | 92 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap5/prcm-regs.c | 9 |
6 files changed, 235 insertions, 7 deletions
diff --git a/arch/arm/include/asm/arch-omap5/clock.h b/arch/arm/include/asm/arch-omap5/clock.h index 87eb3f335a..a00626e357 100644 --- a/arch/arm/include/asm/arch-omap5/clock.h +++ b/arch/arm/include/asm/arch-omap5/clock.h @@ -135,6 +135,9 @@ #define HSMMC_CLKCTRL_CLKSEL_MASK (1 << 24) #define HSMMC_CLKCTRL_CLKSEL_DIV_MASK (3 << 25) +/* CM_IPU1_IPU1_CLKCTRL CLKSEL MASK */ +#define IPU1_CLKCTRL_CLKSEL_MASK BIT(24) + /* CM_L3INIT_SATA_CLKCTRL */ #define SATA_CLKCTRL_OPTFCLKEN_MASK (1 << 8) diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index de8fc99d04..264a2e717a 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -362,6 +362,10 @@ struct prcm_regs { /* IPU */ u32 cm_ipu_clkstctrl; u32 cm_ipu_i2c5_clkctrl; + u32 cm_ipu1_clkstctrl; + u32 cm_ipu1_ipu1_clkctrl; + u32 cm_ipu2_clkstctrl; + u32 cm_ipu2_ipu2_clkctrl; /*l3main1 edma*/ u32 cm_l3main1_tptc1_clkctrl; @@ -632,6 +636,12 @@ void do_disable_clocks(u32 const *clk_domains, u8 wait_for_disable); #endif /* CONFIG_OMAP44XX || CONFIG_OMAP54XX */ +void do_enable_ipu_clocks(u32 const *clk_domains, + u32 const *clk_modules_hw_auto, + u32 const *clk_modules_explicit_en, + u8 wait_for_enable); +void enable_ipu1_clocks(void); +void enable_ipu2_clocks(void); void setup_post_dividers(u32 const base, const struct dpll_params *params); u32 omap_ddr_clk(void); diff --git a/arch/arm/mach-omap2/boot-common.c b/arch/arm/mach-omap2/boot-common.c index fdb8b479ea..afc3585641 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) diff --git a/arch/arm/mach-omap2/clocks-common.c b/arch/arm/mach-omap2/clocks-common.c index 1d8eab2dab..390d1f2a64 100644 --- a/arch/arm/mach-omap2/clocks-common.c +++ b/arch/arm/mach-omap2/clocks-common.c @@ -858,6 +858,39 @@ void do_enable_clocks(u32 const *clk_domains, } } +void do_enable_ipu_clocks(u32 const *clk_domains, + u32 const *clk_modules_hw_auto, + u32 const *clk_modules_explicit_en, + u8 wait_for_enable) +{ + u32 i, max = 10; + + if (!IS_ENABLED(CONFIG_REMOTEPROC_TI_IPU)) + return; + + /* Put the clock domains in SW_WKUP mode */ + for (i = 0; (i < max) && clk_domains && clk_domains[i]; i++) { + enable_clock_domain(clk_domains[i], + CD_CLKCTRL_CLKTRCTRL_SW_WKUP); + } + + /* Clock modules that need to be put in HW_AUTO */ + for (i = 0; (i < max) && clk_modules_hw_auto && + clk_modules_hw_auto[i]; i++) { + enable_clock_module(clk_modules_hw_auto[i], + MODULE_CLKCTRL_MODULEMODE_HW_AUTO, + wait_for_enable); + }; + + /* Clock modules that need to be put in SW_EXPLICIT_EN mode */ + for (i = 0; (i < max) && clk_modules_explicit_en && + clk_modules_explicit_en[i]; i++) { + enable_clock_module(clk_modules_explicit_en[i], + MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN, + wait_for_enable); + }; +} + void do_disable_clocks(u32 const *clk_domains, u32 const *clk_modules_disable, u8 wait_for_disable) diff --git a/arch/arm/mach-omap2/omap5/hw_data.c b/arch/arm/mach-omap2/omap5/hw_data.c index fa4e27063c..e6bee48dfc 100644 --- a/arch/arm/mach-omap2/omap5/hw_data.c +++ b/arch/arm/mach-omap2/omap5/hw_data.c @@ -377,6 +377,85 @@ struct vcores_data omap5430_volts_es2 = { }; /* + * Enable IPU1 clock domains, modules and + * do some additional special settings needed + */ +void enable_ipu1_clocks(void) +{ + if (!IS_ENABLED(CONFIG_DRA7XX) || + !IS_ENABLED(CONFIG_REMOTEPROC_TI_IPU)) + return; + + u32 const clk_domains[] = { + (*prcm)->cm_ipu_clkstctrl, + (*prcm)->cm_ipu1_clkstctrl, + 0 + }; + + u32 const clk_modules_hw_auto_essential[] = { + (*prcm)->cm_ipu1_ipu1_clkctrl, + 0 + }; + + u32 const clk_modules_explicit_en_essential[] = { + (*prcm)->cm_l4per_gptimer11_clkctrl, + (*prcm)->cm1_abe_timer7_clkctrl, + (*prcm)->cm1_abe_timer8_clkctrl, + 0 + }; + do_enable_ipu_clocks(clk_domains, clk_modules_hw_auto_essential, + clk_modules_explicit_en_essential, 0); + + /* Enable optional additional functional clock for IPU1 */ + setbits_le32((*prcm)->cm_ipu1_ipu1_clkctrl, + IPU1_CLKCTRL_CLKSEL_MASK); + /* Enable optional additional functional clock for IPU1 */ + setbits_le32((*prcm)->cm1_abe_timer7_clkctrl, + IPU1_CLKCTRL_CLKSEL_MASK); + /* Enable optional additional functional clock for IPU1 */ + setbits_le32((*prcm)->cm1_abe_timer8_clkctrl, + IPU1_CLKCTRL_CLKSEL_MASK); +} + +/* + * Enable IPU2 clock domains, modules and + * do some additional special settings needed + */ +void enable_ipu2_clocks(void) +{ + if (!IS_ENABLED(CONFIG_DRA7XX) || + !IS_ENABLED(CONFIG_REMOTEPROC_TI_IPU)) + return; + + u32 const clk_domains[] = { + (*prcm)->cm_ipu_clkstctrl, + (*prcm)->cm_ipu2_clkstctrl, + 0 + }; + + u32 const clk_modules_hw_auto_essential[] = { + (*prcm)->cm_ipu2_ipu2_clkctrl, + 0 + }; + + u32 const clk_modules_explicit_en_essential[] = { + (*prcm)->cm_l4per_gptimer3_clkctrl, + (*prcm)->cm_l4per_gptimer4_clkctrl, + (*prcm)->cm_l4per_gptimer9_clkctrl, + 0 + }; + do_enable_ipu_clocks(clk_domains, clk_modules_hw_auto_essential, + clk_modules_explicit_en_essential, 0); + + /* Enable optional additional functional clock for IPU2 */ + setbits_le32((*prcm)->cm_l4per_gptimer4_clkctrl, + IPU1_CLKCTRL_CLKSEL_MASK); + /* Enable optional additional functional clock for IPU2 */ + setbits_le32((*prcm)->cm_l4per_gptimer9_clkctrl, + IPU1_CLKCTRL_CLKSEL_MASK); +} + +/* * Enable essential clock domains, modules and * do some additional special settings needed */ @@ -478,12 +557,13 @@ void enable_basic_clocks(void) void enable_basic_uboot_clocks(void) { - u32 const clk_domains_essential[] = { -#if defined(CONFIG_DRA7XX) - (*prcm)->cm_ipu_clkstctrl, -#endif - 0 - }; + u32 cm_ipu_clkstctrl = 0; + + if (IS_ENABLED(CONFIG_DRA7XX) && + !IS_ENABLED(CONFIG_REMOTEPROC_TI_IPU)) + cm_ipu_clkstctrl = (*prcm)->cm_ipu_clkstctrl; + + u32 const clk_domains_essential[] = {cm_ipu_clkstctrl, 0}; u32 const clk_modules_hw_auto_essential[] = { (*prcm)->cm_l3init_hsusbtll_clkctrl, diff --git a/arch/arm/mach-omap2/omap5/prcm-regs.c b/arch/arm/mach-omap2/omap5/prcm-regs.c index 28c4f4f737..d7196a3156 100644 --- a/arch/arm/mach-omap2/omap5/prcm-regs.c +++ b/arch/arm/mach-omap2/omap5/prcm-regs.c @@ -832,7 +832,10 @@ struct prcm_regs const dra7xx_prcm = { /* cm IPU */ .cm_ipu_clkstctrl = 0x4a005540, .cm_ipu_i2c5_clkctrl = 0x4a005578, - + .cm_ipu1_clkstctrl = 0x4a005500, + .cm_ipu1_ipu1_clkctrl = 0x4a005520, + .cm_ipu2_clkstctrl = 0x4a008900, + .cm_ipu2_ipu2_clkctrl = 0x4a008920, /* prm irqstatus regs */ .prm_irqstatus_mpu = 0x4ae06010, .prm_irqstatus_mpu_2 = 0x4ae06014, @@ -1013,6 +1016,10 @@ struct prcm_regs const dra7xx_prcm = { /*l3main1 edma*/ .cm_l3main1_tptc1_clkctrl = 0x4a008778, .cm_l3main1_tptc2_clkctrl = 0x4a008780, + + /* cm1.abe */ + .cm1_abe_timer7_clkctrl = 0x4a005568, + .cm1_abe_timer8_clkctrl = 0x4a005570, }; void clrset_spare_register(u8 spare_type, u32 clear_bits, u32 set_bits) |