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>
This commit is contained in:
@@ -135,6 +135,9 @@
|
|||||||
#define HSMMC_CLKCTRL_CLKSEL_MASK (1 << 24)
|
#define HSMMC_CLKCTRL_CLKSEL_MASK (1 << 24)
|
||||||
#define HSMMC_CLKCTRL_CLKSEL_DIV_MASK (3 << 25)
|
#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 */
|
/* CM_L3INIT_SATA_CLKCTRL */
|
||||||
#define SATA_CLKCTRL_OPTFCLKEN_MASK (1 << 8)
|
#define SATA_CLKCTRL_OPTFCLKEN_MASK (1 << 8)
|
||||||
|
|
||||||
|
@@ -362,6 +362,10 @@ struct prcm_regs {
|
|||||||
/* IPU */
|
/* IPU */
|
||||||
u32 cm_ipu_clkstctrl;
|
u32 cm_ipu_clkstctrl;
|
||||||
u32 cm_ipu_i2c5_clkctrl;
|
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*/
|
/*l3main1 edma*/
|
||||||
u32 cm_l3main1_tptc1_clkctrl;
|
u32 cm_l3main1_tptc1_clkctrl;
|
||||||
@@ -632,6 +636,12 @@ void do_disable_clocks(u32 const *clk_domains,
|
|||||||
u8 wait_for_disable);
|
u8 wait_for_disable);
|
||||||
#endif /* CONFIG_OMAP44XX || CONFIG_OMAP54XX */
|
#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,
|
void setup_post_dividers(u32 const base,
|
||||||
const struct dpll_params *params);
|
const struct dpll_params *params);
|
||||||
u32 omap_ddr_clk(void);
|
u32 omap_ddr_clk(void);
|
||||||
|
@@ -10,6 +10,8 @@
|
|||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <ahci.h>
|
#include <ahci.h>
|
||||||
#include <log.h>
|
#include <log.h>
|
||||||
|
#include <dm/uclass.h>
|
||||||
|
#include <fs_loader.h>
|
||||||
#include <spl.h>
|
#include <spl.h>
|
||||||
#include <asm/global_data.h>
|
#include <asm/global_data.h>
|
||||||
#include <asm/omap_common.h>
|
#include <asm/omap_common.h>
|
||||||
@@ -19,9 +21,14 @@
|
|||||||
#include <watchdog.h>
|
#include <watchdog.h>
|
||||||
#include <scsi.h>
|
#include <scsi.h>
|
||||||
#include <i2c.h>
|
#include <i2c.h>
|
||||||
|
#include <remoteproc.h>
|
||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
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)
|
__weak u32 omap_sys_boot_device(void)
|
||||||
{
|
{
|
||||||
return BOOT_DEVICE_NONE;
|
return BOOT_DEVICE_NONE;
|
||||||
@@ -194,6 +201,91 @@ u32 spl_mmc_boot_mode(const u32 boot_device)
|
|||||||
return gd->arch.omap_boot_mode;
|
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)
|
void spl_board_init(void)
|
||||||
{
|
{
|
||||||
/* Prepare console output */
|
/* Prepare console output */
|
||||||
@@ -214,6 +306,9 @@ void spl_board_init(void)
|
|||||||
#ifdef CONFIG_AM33XX
|
#ifdef CONFIG_AM33XX
|
||||||
am33xx_spl_board_init();
|
am33xx_spl_board_init();
|
||||||
#endif
|
#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)
|
void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
|
||||||
|
@@ -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,
|
void do_disable_clocks(u32 const *clk_domains,
|
||||||
u32 const *clk_modules_disable,
|
u32 const *clk_modules_disable,
|
||||||
u8 wait_for_disable)
|
u8 wait_for_disable)
|
||||||
|
@@ -376,6 +376,85 @@ struct vcores_data omap5430_volts_es2 = {
|
|||||||
.mm.efuse.reg_bits = OMAP5_ES2_PROD_REGBITS,
|
.mm.efuse.reg_bits = OMAP5_ES2_PROD_REGBITS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
* Enable essential clock domains, modules and
|
||||||
* do some additional special settings needed
|
* do some additional special settings needed
|
||||||
@@ -478,12 +557,13 @@ void enable_basic_clocks(void)
|
|||||||
|
|
||||||
void enable_basic_uboot_clocks(void)
|
void enable_basic_uboot_clocks(void)
|
||||||
{
|
{
|
||||||
u32 const clk_domains_essential[] = {
|
u32 cm_ipu_clkstctrl = 0;
|
||||||
#if defined(CONFIG_DRA7XX)
|
|
||||||
(*prcm)->cm_ipu_clkstctrl,
|
if (IS_ENABLED(CONFIG_DRA7XX) &&
|
||||||
#endif
|
!IS_ENABLED(CONFIG_REMOTEPROC_TI_IPU))
|
||||||
0
|
cm_ipu_clkstctrl = (*prcm)->cm_ipu_clkstctrl;
|
||||||
};
|
|
||||||
|
u32 const clk_domains_essential[] = {cm_ipu_clkstctrl, 0};
|
||||||
|
|
||||||
u32 const clk_modules_hw_auto_essential[] = {
|
u32 const clk_modules_hw_auto_essential[] = {
|
||||||
(*prcm)->cm_l3init_hsusbtll_clkctrl,
|
(*prcm)->cm_l3init_hsusbtll_clkctrl,
|
||||||
|
@@ -832,7 +832,10 @@ struct prcm_regs const dra7xx_prcm = {
|
|||||||
/* cm IPU */
|
/* cm IPU */
|
||||||
.cm_ipu_clkstctrl = 0x4a005540,
|
.cm_ipu_clkstctrl = 0x4a005540,
|
||||||
.cm_ipu_i2c5_clkctrl = 0x4a005578,
|
.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 regs */
|
||||||
.prm_irqstatus_mpu = 0x4ae06010,
|
.prm_irqstatus_mpu = 0x4ae06010,
|
||||||
.prm_irqstatus_mpu_2 = 0x4ae06014,
|
.prm_irqstatus_mpu_2 = 0x4ae06014,
|
||||||
@@ -1013,6 +1016,10 @@ struct prcm_regs const dra7xx_prcm = {
|
|||||||
/*l3main1 edma*/
|
/*l3main1 edma*/
|
||||||
.cm_l3main1_tptc1_clkctrl = 0x4a008778,
|
.cm_l3main1_tptc1_clkctrl = 0x4a008778,
|
||||||
.cm_l3main1_tptc2_clkctrl = 0x4a008780,
|
.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)
|
void clrset_spare_register(u8 spare_type, u32 clear_bits, u32 set_bits)
|
||||||
|
Reference in New Issue
Block a user