Files
gk-sdk/source/bootloader/u-boot-2020.01/lotus/misc/mcu.c
T

81 lines
1.9 KiB
C

#define pr_fmt(fmt) "%s: " fmt, "LOAD MCU S2"
#include <common.h>
#include <malloc.h>
#include <linux/io.h>
#include <linux/lotus/flash_read.h>
#include <linux/lotus/image.h>
static int do_load_mcu_stage2(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
int ret = -1;
u32 res, aligned_offset, aligned_size;
u32 total_size;
u32 stage1_size;
u32 mcu_offset = CONFIG_MCU_FW_AREA_POS;
struct mcu_fw_head *fw_head = (struct mcu_fw_head *)MCU_SRAM_BASE;
u8 *buf = (u8 *)CONFIG_MCU_FW_BUF_ADDR;
u32 v;
if (CONFIG_LOAD_MCU_FW_FLAG == 0 || CONFIG_MCU_FW_AREA_LEN == 0)
goto error;
if (fw_head->fw_magic != _MCU_FW_MAGIC) {
pr_info("No MCU FW\n");
goto error;
}
total_size = fw_head->fw_total_size;
stage1_size = fw_head->fw_stage1_size;
if (total_size < stage1_size
|| (((total_size + 1024 - 1) >> 10) & (~((1 << 10) - 1))) != 0) {
pr_err("Invalid MCU FW size!Total: %u, Stage1: %u\n", total_size, stage1_size);
goto error;
}
res = mcu_offset & (FLASH_ALIGNED_SIZE - 1);
aligned_offset = rounddown(mcu_offset, FLASH_ALIGNED_SIZE);
aligned_size = roundup(total_size + res, FLASH_ALIGNED_SIZE);
if (aligned_size > CONFIG_MCU_FW_BUF_SIZE) {
pr_err("No buffer for MCU FW!\n");
goto error;
}
ret = flash_read(aligned_offset, aligned_size, buf);
if (ret != 0) {
pr_err("Fail to read MCU area!\n");
goto error;
}
memcpy((void *)MCU_SRAM_BASE + stage1_size, buf + res + stage1_size, total_size - stage1_size);
memmove(buf, buf + res, total_size);
printf("MCU FW location in DDR: 0x%x, 0x%x Bytes\n", (u32)buf, total_size);
v = readl(REG_MCU_FW_DDR_SIZE);
v &= ~((1 << 10) - 1);
v |= (total_size + 1024 - 1) >> 10;
writel(v, REG_MCU_FW_DDR_SIZE);
dsb();
isb();
/* Release MCU to stage2 */
writel(0xbeef0001, SYS_CTRL_REG_BASE + REG_SC_SYSBOOT7);
dsb();
isb();
return 1;
error:
return CMD_RET_FAILURE;
}
U_BOOT_CMD(
loadmcustage2, 1, 0, do_load_mcu_stage2,
"Load MCU Stage2",
"loadmcustage2\n"
""
);