arm-trusted-firmware/plat/mediatek/drivers/apusys/apusys.c
Karl Li 5e5c57d52b feat(mt8196): add APU kernel control operations
Add APU kernel control operations to provide the bootup init functions.

1. Add software workaround for certain operations on mt8196.
2. Add APU logger operations.
3. Add function to clear mbox spare register, which is used in APU
   booting process.
4. Add function to setup CE binary to make sure the CE binary version
   is align with the APU firmware.

Change-Id: Ic99adba1409c020c72179ea135e0d4291fc3f384
Signed-off-by: Karl Li <karl.li@mediatek.com>
2024-12-19 09:56:04 +08:00

116 lines
3.2 KiB
C

/*
* Copyright (c) 2023, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/* TF-A system header */
#include <common/debug.h>
/* Vendor header */
#include "apusys.h"
#include "apusys_devapc.h"
#include "apusys_power.h"
#include "apusys_rv.h"
#include "apusys_security_ctrl_plat.h"
#include <lib/mtk_init/mtk_init.h>
#include <mtk_sip_svc.h>
static u_register_t apusys_kernel_handler(u_register_t x1,
u_register_t x2,
u_register_t x3,
u_register_t x4,
void *handle,
struct smccc_res *smccc_ret)
{
uint32_t request_ops;
int32_t ret = -1;
request_ops = (uint32_t)x1;
switch (request_ops) {
case MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_ON:
ret = apusys_kernel_apusys_rv_pwr_ctrl(APU_PWR_ON);
break;
case MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_OFF:
ret = apusys_kernel_apusys_rv_pwr_ctrl(APU_PWR_OFF);
break;
case MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_REVISER:
ret = apusys_kernel_apusys_rv_setup_reviser();
break;
case MTK_APUSYS_KERNEL_OP_APUSYS_RV_RESET_MP:
ret = apusys_kernel_apusys_rv_reset_mp();
break;
case MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_BOOT:
ret = apusys_kernel_apusys_rv_setup_boot();
break;
case MTK_APUSYS_KERNEL_OP_APUSYS_RV_START_MP:
ret = apusys_kernel_apusys_rv_start_mp();
break;
case MTK_APUSYS_KERNEL_OP_APUSYS_RV_STOP_MP:
ret = apusys_kernel_apusys_rv_stop_mp();
break;
case MTK_APUSYS_KERNEL_OP_DEVAPC_INIT_RCX:
ret = apusys_devapc_rcx_init();
break;
case MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_SEC_MEM:
ret = apusys_kernel_apusys_rv_setup_sec_mem();
break;
case MTK_APUSYS_KERNEL_OP_APUSYS_RV_DISABLE_WDT_ISR:
ret = apusys_kernel_apusys_rv_disable_wdt_isr();
break;
case MTK_APUSYS_KERNEL_OP_APUSYS_RV_CLEAR_WDT_ISR:
ret = apusys_kernel_apusys_rv_clear_wdt_isr();
break;
case MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_GATING:
ret = apusys_kernel_apusys_rv_cg_gating();
break;
case MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_UNGATING:
ret = apusys_kernel_apusys_rv_cg_ungating();
break;
case MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_APUMMU:
ret = apusys_kernel_apusys_rv_setup_apummu();
break;
#ifdef CONFIG_MTK_APUSYS_LOGTOP_SUPPORT
case MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_DUMP:
ret = apusys_kernel_apusys_logtop_reg_dump((uint32_t)x2, smccc_ret);
break;
case MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_WRITE:
ret = apusys_kernel_apusys_logtop_reg_write((uint32_t)x2, (uint32_t)x3,
smccc_ret);
break;
case MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_W1C:
ret = apusys_kernel_apusys_logtop_reg_w1c((uint32_t)x2, smccc_ret);
break;
#endif
case MTK_APUSYS_KERNEL_OP_APUSYS_COLD_BOOT_CLR_MBOX_DUMMY:
ret = apusys_rv_cold_boot_clr_mbox_dummy();
break;
case MTK_APUSYS_KERNEL_OP_APUSYS_SETUP_CE_BIN:
ret = apusys_rv_setup_ce_bin();
break;
default:
ERROR(MODULE_TAG "%s unknown request_ops = %x\n", MODULE_TAG, request_ops);
break;
}
return ret;
}
DECLARE_SMC_HANDLER(MTK_SIP_APUSYS_CONTROL, apusys_kernel_handler);
int apusys_init(void)
{
if (apusys_power_init() != 0) {
return -1;
}
if (apusys_devapc_ao_init() != 0) {
return -1;
}
apusys_security_ctrl_init();
apusys_rv_mbox_mpu_init();
return 0;
}
MTK_PLAT_SETUP_1_INIT(apusys_init);