1ad7673adSKarl Li /*
283f836c9SKarl Li * Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
3ad7673adSKarl Li *
4ad7673adSKarl Li * SPDX-License-Identifier: BSD-3-Clause
5ad7673adSKarl Li */
6ad7673adSKarl Li
75e5c57d5SKarl Li #include <errno.h>
85e5c57d5SKarl Li
9ad7673adSKarl Li /* TF-A system header */
10ad7673adSKarl Li #include <common/debug.h>
1194a9e624SChungying Lu #include <drivers/delay_timer.h>
12ad7673adSKarl Li #include <lib/mmio.h>
1394a9e624SChungying Lu #include <lib/spinlock.h>
14ad7673adSKarl Li
15ad7673adSKarl Li /* Vendor header */
1694a9e624SChungying Lu #include "apusys.h"
17ad7673adSKarl Li #include "apusys_rv.h"
18ad7673adSKarl Li #include "apusys_rv_mbox_mpu.h"
1983f836c9SKarl Li #include "apusys_rv_pwr_ctrl.h"
205e5c57d5SKarl Li #include "apusys_rv_sec_info.h"
215e5c57d5SKarl Li #ifdef CONFIG_MTK_APUSYS_SEC_CTRL
225e5c57d5SKarl Li #include "apusys_security_ctrl_perm.h"
235e5c57d5SKarl Li #endif
245e5c57d5SKarl Li #include "apusys_security_ctrl_plat.h"
25*2d134d28SKarl Li #include <drivers/apusys_rv_public.h>
265e5c57d5SKarl Li #include <mtk_mmap_pool.h>
275e5c57d5SKarl Li #include <mtk_sip_svc.h>
28ad7673adSKarl Li
29e534d4f6SKarl Li #ifdef CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT
30e534d4f6SKarl Li #include "apusys_ammu.h"
31e534d4f6SKarl Li #endif
32e534d4f6SKarl Li
3394a9e624SChungying Lu static spinlock_t apusys_rv_lock;
3494a9e624SChungying Lu
apusys_rv_mbox_mpu_init(void)35ad7673adSKarl Li void apusys_rv_mbox_mpu_init(void)
36ad7673adSKarl Li {
37ad7673adSKarl Li int i;
38ad7673adSKarl Li
39ad7673adSKarl Li for (i = 0; i < APU_MBOX_NUM; i++) {
40ad7673adSKarl Li mmio_write_32(APU_MBOX_FUNC_CFG(i),
41ad7673adSKarl Li (MBOX_CTRL_LOCK |
42ad7673adSKarl Li (mbox_mpu_setting_tab[i].no_mpu << MBOX_NO_MPU_SHIFT)));
43ad7673adSKarl Li mmio_write_32(APU_MBOX_DOMAIN_CFG(i),
44ad7673adSKarl Li (MBOX_CTRL_LOCK |
45ad7673adSKarl Li (mbox_mpu_setting_tab[i].rx_ns << MBOX_RX_NS_SHIFT) |
46ad7673adSKarl Li (mbox_mpu_setting_tab[i].rx_domain << MBOX_RX_DOMAIN_SHIFT) |
47ad7673adSKarl Li (mbox_mpu_setting_tab[i].tx_ns << MBOX_TX_NS_SHIFT) |
48ad7673adSKarl Li (mbox_mpu_setting_tab[i].tx_domain << MBOX_TX_DOMAIN_SHIFT)));
49ad7673adSKarl Li }
50ad7673adSKarl Li }
5194a9e624SChungying Lu
apusys_kernel_apusys_rv_setup_reviser(void)5294a9e624SChungying Lu int apusys_kernel_apusys_rv_setup_reviser(void)
5394a9e624SChungying Lu {
5494a9e624SChungying Lu spin_lock(&apusys_rv_lock);
5594a9e624SChungying Lu
5694a9e624SChungying Lu mmio_write_32(USERFW_CTXT, CFG_4GB_SEL_EN | CFG_4GB_SEL);
5794a9e624SChungying Lu mmio_write_32(SECUREFW_CTXT, CFG_4GB_SEL_EN | CFG_4GB_SEL);
5894a9e624SChungying Lu
5994a9e624SChungying Lu mmio_write_32(UP_IOMMU_CTRL, MMU_CTRL_LOCK | MMU_CTRL | MMU_EN);
6094a9e624SChungying Lu
6194a9e624SChungying Lu mmio_write_32(UP_NORMAL_DOMAIN_NS,
6294a9e624SChungying Lu (UP_NORMAL_DOMAIN << UP_DOMAIN_SHIFT) | (UP_NORMAL_NS << UP_NS_SHIFT));
6394a9e624SChungying Lu mmio_write_32(UP_PRI_DOMAIN_NS,
6494a9e624SChungying Lu (UP_PRI_DOMAIN << UP_DOMAIN_SHIFT) | (UP_PRI_NS << UP_NS_SHIFT));
6594a9e624SChungying Lu
6694a9e624SChungying Lu mmio_write_32(UP_CORE0_VABASE0,
6794a9e624SChungying Lu VLD | PARTIAL_ENABLE | (THREAD_NUM_PRI << THREAD_NUM_SHIFT));
6894a9e624SChungying Lu mmio_write_32(UP_CORE0_MVABASE0, VASIZE_1MB | (APU_SEC_FW_IOVA >> MVA_34BIT_SHIFT));
6994a9e624SChungying Lu
7094a9e624SChungying Lu mmio_write_32(UP_CORE0_VABASE1,
7194a9e624SChungying Lu VLD | PARTIAL_ENABLE | (THREAD_NUM_NORMAL << THREAD_NUM_SHIFT));
7294a9e624SChungying Lu mmio_write_32(UP_CORE0_MVABASE1, VASIZE_1MB | (APU_SEC_FW_IOVA >> MVA_34BIT_SHIFT));
7394a9e624SChungying Lu
7494a9e624SChungying Lu spin_unlock(&apusys_rv_lock);
7594a9e624SChungying Lu
7694a9e624SChungying Lu return 0;
7794a9e624SChungying Lu }
7894a9e624SChungying Lu
apusys_kernel_apusys_rv_reset_mp(void)7994a9e624SChungying Lu int apusys_kernel_apusys_rv_reset_mp(void)
8094a9e624SChungying Lu {
8194a9e624SChungying Lu spin_lock(&apusys_rv_lock);
8294a9e624SChungying Lu
8394a9e624SChungying Lu mmio_write_32(MD32_SYS_CTRL, MD32_SYS_CTRL_RST);
8494a9e624SChungying Lu
85b254b981SKarl Li dsb();
8694a9e624SChungying Lu udelay(RESET_DEALY_US);
8794a9e624SChungying Lu
8894a9e624SChungying Lu mmio_write_32(MD32_SYS_CTRL, MD32_G2B_CG_EN | MD32_DBG_EN | MD32_DM_AWUSER_IOMMU_EN |
8994a9e624SChungying Lu MD32_DM_ARUSER_IOMMU_EN | MD32_PM_AWUSER_IOMMU_EN | MD32_PM_ARUSER_IOMMU_EN |
9094a9e624SChungying Lu MD32_SOFT_RSTN);
9194a9e624SChungying Lu
9294a9e624SChungying Lu mmio_write_32(MD32_CLK_CTRL, MD32_CLK_EN);
9394a9e624SChungying Lu mmio_write_32(UP_WAKE_HOST_MASK0, WDT_IRQ_EN);
9494a9e624SChungying Lu mmio_write_32(UP_WAKE_HOST_MASK1, MBOX0_IRQ_EN | MBOX1_IRQ_EN | MBOX2_IRQ_EN);
9594a9e624SChungying Lu
9694a9e624SChungying Lu spin_unlock(&apusys_rv_lock);
9794a9e624SChungying Lu
9894a9e624SChungying Lu return 0;
9994a9e624SChungying Lu }
10094a9e624SChungying Lu
apusys_kernel_apusys_rv_setup_boot(void)10194a9e624SChungying Lu int apusys_kernel_apusys_rv_setup_boot(void)
10294a9e624SChungying Lu {
10394a9e624SChungying Lu spin_lock(&apusys_rv_lock);
10494a9e624SChungying Lu
10594a9e624SChungying Lu mmio_write_32(MD32_BOOT_CTRL, APU_SEC_FW_IOVA);
10694a9e624SChungying Lu
10794a9e624SChungying Lu mmio_write_32(MD32_PRE_DEFINE, (PREDEFINE_CACHE_TCM << PREDEF_1G_OFS) |
10894a9e624SChungying Lu (PREDEFINE_CACHE << PREDEF_2G_OFS) | (PREDEFINE_CACHE << PREDEF_3G_OFS) |
10994a9e624SChungying Lu (PREDEFINE_CACHE << PREDEF_4G_OFS));
11094a9e624SChungying Lu
1113ee4b2deSKarl Li apusys_infra_dcm_setup();
1123ee4b2deSKarl Li
11394a9e624SChungying Lu spin_unlock(&apusys_rv_lock);
11494a9e624SChungying Lu return 0;
11594a9e624SChungying Lu }
11694a9e624SChungying Lu
apusys_kernel_apusys_rv_start_mp(void)11794a9e624SChungying Lu int apusys_kernel_apusys_rv_start_mp(void)
11894a9e624SChungying Lu {
11994a9e624SChungying Lu spin_lock(&apusys_rv_lock);
12094a9e624SChungying Lu mmio_write_32(MD32_RUNSTALL, MD32_RUN);
12194a9e624SChungying Lu spin_unlock(&apusys_rv_lock);
12294a9e624SChungying Lu
12394a9e624SChungying Lu return 0;
12494a9e624SChungying Lu }
12594a9e624SChungying Lu
hw_sema2_release(uint32_t timeout)1265e5c57d5SKarl Li static int hw_sema2_release(uint32_t timeout)
1275e5c57d5SKarl Li {
1285e5c57d5SKarl Li #ifdef CONFIG_MTK_APUSYS_RV_COREDUMP_WA_SUPPORT
1295e5c57d5SKarl Li int ret;
1305e5c57d5SKarl Li
1315e5c57d5SKarl Li ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_USER, 0, timeout, 0);
1325e5c57d5SKarl Li if (ret) {
1335e5c57d5SKarl Li ERROR("%s: HW semaphore release timeout\n", __func__);
1345e5c57d5SKarl Li }
1355e5c57d5SKarl Li
1365e5c57d5SKarl Li return ret;
1375e5c57d5SKarl Li #else
1385e5c57d5SKarl Li return 0;
1395e5c57d5SKarl Li #endif
1405e5c57d5SKarl Li }
1415e5c57d5SKarl Li
hw_sema2_acquire(uint32_t timeout)1425e5c57d5SKarl Li static int hw_sema2_acquire(uint32_t timeout)
1435e5c57d5SKarl Li {
1445e5c57d5SKarl Li #ifdef CONFIG_MTK_APUSYS_RV_COREDUMP_WA_SUPPORT
1455e5c57d5SKarl Li int ret;
1465e5c57d5SKarl Li
1475e5c57d5SKarl Li ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_USER, 1, timeout, 0);
1485e5c57d5SKarl Li if (ret) {
1495e5c57d5SKarl Li ERROR("%s: HW semaphore acquire timeout\n", __func__);
1505e5c57d5SKarl Li }
1515e5c57d5SKarl Li
1525e5c57d5SKarl Li return ret;
1535e5c57d5SKarl Li #else
1545e5c57d5SKarl Li return 0;
1555e5c57d5SKarl Li #endif
1565e5c57d5SKarl Li }
1575e5c57d5SKarl Li
apusys_kernel_apusys_rv_stop_mp(void)15894a9e624SChungying Lu int apusys_kernel_apusys_rv_stop_mp(void)
15994a9e624SChungying Lu {
1605e5c57d5SKarl Li int ret;
1615e5c57d5SKarl Li
1625e5c57d5SKarl Li ret = hw_sema2_acquire(HW_SEM_TIMEOUT);
1635e5c57d5SKarl Li if (ret)
1645e5c57d5SKarl Li return ret;
1655e5c57d5SKarl Li
16694a9e624SChungying Lu spin_lock(&apusys_rv_lock);
16794a9e624SChungying Lu mmio_write_32(MD32_RUNSTALL, MD32_STALL);
16894a9e624SChungying Lu spin_unlock(&apusys_rv_lock);
16994a9e624SChungying Lu
1705e5c57d5SKarl Li ret = hw_sema2_release(HW_SEM_TIMEOUT);
1715e5c57d5SKarl Li
1725e5c57d5SKarl Li return ret;
17394a9e624SChungying Lu }
174176846a5SChungying Lu
apusys_kernel_apusys_rv_setup_sec_mem(void)175176846a5SChungying Lu int apusys_kernel_apusys_rv_setup_sec_mem(void)
176176846a5SChungying Lu {
1777ed4d67cSKarl Li int ret = 0;
178176846a5SChungying Lu
179176846a5SChungying Lu spin_lock(&apusys_rv_lock);
180176846a5SChungying Lu
1817ed4d67cSKarl Li ret = apusys_plat_setup_sec_mem();
1827ed4d67cSKarl Li if (ret != 0)
183176846a5SChungying Lu ERROR(MODULE_TAG "%s: set emimpu protection failed\n", __func__);
184176846a5SChungying Lu
185176846a5SChungying Lu spin_unlock(&apusys_rv_lock);
186176846a5SChungying Lu return ret;
187176846a5SChungying Lu }
188baa0d45cSChungying Lu
apusys_kernel_apusys_rv_disable_wdt_isr(void)189baa0d45cSChungying Lu int apusys_kernel_apusys_rv_disable_wdt_isr(void)
190baa0d45cSChungying Lu {
1915e5c57d5SKarl Li int ret;
1925e5c57d5SKarl Li
1935e5c57d5SKarl Li ret = hw_sema2_acquire(0);
1945e5c57d5SKarl Li if (ret)
1955e5c57d5SKarl Li return ret;
1965e5c57d5SKarl Li
197baa0d45cSChungying Lu spin_lock(&apusys_rv_lock);
198baa0d45cSChungying Lu mmio_clrbits_32(WDT_CTRL0, WDT_EN);
199baa0d45cSChungying Lu spin_unlock(&apusys_rv_lock);
200baa0d45cSChungying Lu
2015e5c57d5SKarl Li ret = hw_sema2_release(0);
2025e5c57d5SKarl Li
2035e5c57d5SKarl Li return ret;
204baa0d45cSChungying Lu }
205baa0d45cSChungying Lu
apusys_kernel_apusys_rv_clear_wdt_isr(void)206baa0d45cSChungying Lu int apusys_kernel_apusys_rv_clear_wdt_isr(void)
207baa0d45cSChungying Lu {
2085e5c57d5SKarl Li int ret;
2095e5c57d5SKarl Li
2105e5c57d5SKarl Li ret = hw_sema2_acquire(HW_SEM_TIMEOUT);
2115e5c57d5SKarl Li if (ret)
2125e5c57d5SKarl Li return ret;
2135e5c57d5SKarl Li
214baa0d45cSChungying Lu spin_lock(&apusys_rv_lock);
215baa0d45cSChungying Lu mmio_clrbits_32(UP_INT_EN2, DBG_APB_EN);
216baa0d45cSChungying Lu mmio_write_32(WDT_INT, WDT_INT_W1C);
217baa0d45cSChungying Lu spin_unlock(&apusys_rv_lock);
218baa0d45cSChungying Lu
2195e5c57d5SKarl Li ret = hw_sema2_release(HW_SEM_TIMEOUT);
2205e5c57d5SKarl Li
2215e5c57d5SKarl Li return ret;
222baa0d45cSChungying Lu }
223baa0d45cSChungying Lu
apusys_kernel_apusys_rv_cg_gating(void)224baa0d45cSChungying Lu int apusys_kernel_apusys_rv_cg_gating(void)
225baa0d45cSChungying Lu {
2265e5c57d5SKarl Li int ret;
2275e5c57d5SKarl Li
2285e5c57d5SKarl Li ret = hw_sema2_acquire(HW_SEM_TIMEOUT);
2295e5c57d5SKarl Li if (ret)
2305e5c57d5SKarl Li return ret;
2315e5c57d5SKarl Li
232baa0d45cSChungying Lu spin_lock(&apusys_rv_lock);
233baa0d45cSChungying Lu mmio_write_32(MD32_CLK_CTRL, MD32_CLK_DIS);
234baa0d45cSChungying Lu spin_unlock(&apusys_rv_lock);
235baa0d45cSChungying Lu
2365e5c57d5SKarl Li ret = hw_sema2_release(HW_SEM_TIMEOUT);
2375e5c57d5SKarl Li
2385e5c57d5SKarl Li return ret;
239baa0d45cSChungying Lu }
240baa0d45cSChungying Lu
apusys_kernel_apusys_rv_cg_ungating(void)241baa0d45cSChungying Lu int apusys_kernel_apusys_rv_cg_ungating(void)
242baa0d45cSChungying Lu {
2435e5c57d5SKarl Li int ret;
2445e5c57d5SKarl Li
2455e5c57d5SKarl Li ret = hw_sema2_acquire(HW_SEM_TIMEOUT);
2465e5c57d5SKarl Li if (ret)
2475e5c57d5SKarl Li return ret;
2485e5c57d5SKarl Li
249baa0d45cSChungying Lu spin_lock(&apusys_rv_lock);
250baa0d45cSChungying Lu mmio_write_32(MD32_CLK_CTRL, MD32_CLK_EN);
251baa0d45cSChungying Lu spin_unlock(&apusys_rv_lock);
252baa0d45cSChungying Lu
2535e5c57d5SKarl Li ret = hw_sema2_release(HW_SEM_TIMEOUT);
2545e5c57d5SKarl Li
2555e5c57d5SKarl Li return ret;
256baa0d45cSChungying Lu }
257e534d4f6SKarl Li
apusys_kernel_apusys_rv_setup_apummu(void)258e534d4f6SKarl Li int apusys_kernel_apusys_rv_setup_apummu(void)
259e534d4f6SKarl Li {
260e534d4f6SKarl Li spin_lock(&apusys_rv_lock);
261e534d4f6SKarl Li
262e534d4f6SKarl Li #ifdef CONFIG_MTK_APUSYS_SEC_CTRL
263e534d4f6SKarl Li sec_set_rv_dns();
264e534d4f6SKarl Li #endif
265e534d4f6SKarl Li
266e534d4f6SKarl Li #ifdef CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT
267e534d4f6SKarl Li uint32_t apummu_tcm_sz_select = 0;
268e534d4f6SKarl Li
269e534d4f6SKarl Li if (APU_MD32_TCM_SZ <= 0x20000)
270e534d4f6SKarl Li apummu_tcm_sz_select = APUMMU_PAGE_LEN_128KB;
271e534d4f6SKarl Li else if (APU_MD32_TCM_SZ <= 0x40000)
272e534d4f6SKarl Li apummu_tcm_sz_select = APUMMU_PAGE_LEN_256KB;
273e534d4f6SKarl Li else if (APU_MD32_TCM_SZ <= 0x80000)
274e534d4f6SKarl Li apummu_tcm_sz_select = APUMMU_PAGE_LEN_512KB;
275e534d4f6SKarl Li else if (APU_MD32_TCM_SZ <= 0x100000)
276e534d4f6SKarl Li apummu_tcm_sz_select = APUMMU_PAGE_LEN_1MB;
277e534d4f6SKarl Li else {
278e534d4f6SKarl Li ERROR("%s: APU_MD32_TCM_SZ = 0x%x > 1MB", __func__, APU_MD32_TCM_SZ);
279e534d4f6SKarl Li spin_unlock(&apusys_rv_lock);
280e534d4f6SKarl Li return -EINVAL;
281e534d4f6SKarl Li }
282e534d4f6SKarl Li
283e534d4f6SKarl Li INFO("%s: apummu_tcm_sz_select = %u\n", __func__, apummu_tcm_sz_select);
284e534d4f6SKarl Li rv_boot(APU_SEC_FW_IOVA, 0, APUMMU_PAGE_LEN_1MB,
285e534d4f6SKarl Li APU_MD32_TCM, apummu_tcm_sz_select);
286e534d4f6SKarl Li #endif
287e534d4f6SKarl Li
288e534d4f6SKarl Li spin_unlock(&apusys_rv_lock);
289e534d4f6SKarl Li return 0;
290e534d4f6SKarl Li }
2913ee4b2deSKarl Li
apusys_kernel_apusys_rv_pwr_ctrl(enum APU_PWR_OP op)2923ee4b2deSKarl Li int apusys_kernel_apusys_rv_pwr_ctrl(enum APU_PWR_OP op)
2933ee4b2deSKarl Li {
2943ee4b2deSKarl Li return apusys_rv_pwr_ctrl(op);
2953ee4b2deSKarl Li }
2965e5c57d5SKarl Li
2975e5c57d5SKarl Li #ifdef CONFIG_MTK_APUSYS_LOGTOP_SUPPORT
apusys_kernel_apusys_logtop_reg_dump(uint32_t op,struct smccc_res * smccc_ret)2985e5c57d5SKarl Li int apusys_kernel_apusys_logtop_reg_dump(uint32_t op, struct smccc_res *smccc_ret)
2995e5c57d5SKarl Li {
3005e5c57d5SKarl Li int ret = 0;
3015e5c57d5SKarl Li uint8_t smc_op;
3025e5c57d5SKarl Li uint32_t reg_addr[MAX_SMC_OP_NUM];
3035e5c57d5SKarl Li uint32_t i;
3045e5c57d5SKarl Li
3055e5c57d5SKarl Li if (op == 0) {
3065e5c57d5SKarl Li ERROR("%s empty op = 0x%08x\n", MODULE_TAG, op);
3075e5c57d5SKarl Li return -EINVAL;
3085e5c57d5SKarl Li }
3095e5c57d5SKarl Li
3105e5c57d5SKarl Li for (i = 0; i < MAX_SMC_OP_NUM; i++) {
3115e5c57d5SKarl Li smc_op = (op >> (LOGTOP_OP_SHIFT * i)) & LOGTOP_OP_MASK;
3125e5c57d5SKarl Li switch (smc_op) {
3135e5c57d5SKarl Li case SMC_OP_APU_LOG_BUF_NULL:
3145e5c57d5SKarl Li reg_addr[i] = 0x0;
3155e5c57d5SKarl Li break;
3165e5c57d5SKarl Li case SMC_OP_APU_LOG_BUF_T_SIZE:
3175e5c57d5SKarl Li reg_addr[i] = APU_LOG_BUF_T_SIZE;
3185e5c57d5SKarl Li break;
3195e5c57d5SKarl Li case SMC_OP_APU_LOG_BUF_W_PTR:
3205e5c57d5SKarl Li reg_addr[i] = APU_LOG_BUF_W_PTR;
3215e5c57d5SKarl Li break;
3225e5c57d5SKarl Li case SMC_OP_APU_LOG_BUF_R_PTR:
3235e5c57d5SKarl Li reg_addr[i] = APU_LOG_BUF_R_PTR;
3245e5c57d5SKarl Li break;
3255e5c57d5SKarl Li case SMC_OP_APU_LOG_BUF_CON:
3265e5c57d5SKarl Li reg_addr[i] = APU_LOGTOP_CON;
3275e5c57d5SKarl Li break;
3285e5c57d5SKarl Li default:
3295e5c57d5SKarl Li ERROR("%s unknown op = 0x%08x\n", MODULE_TAG, smc_op);
3305e5c57d5SKarl Li return -EINVAL;
3315e5c57d5SKarl Li }
3325e5c57d5SKarl Li }
3335e5c57d5SKarl Li
3345e5c57d5SKarl Li ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_LOGGER_USER, 1, 0, 0);
3355e5c57d5SKarl Li if (ret)
3365e5c57d5SKarl Li return ret;
3375e5c57d5SKarl Li
3385e5c57d5SKarl Li for (i = 0; i < MAX_SMC_OP_NUM; i++) {
3395e5c57d5SKarl Li if (reg_addr[i] == 0)
3405e5c57d5SKarl Li continue;
3415e5c57d5SKarl Li
3425e5c57d5SKarl Li switch (i) {
3435e5c57d5SKarl Li case 0:
3445e5c57d5SKarl Li smccc_ret->a1 = mmio_read_32(reg_addr[i]);
3455e5c57d5SKarl Li break;
3465e5c57d5SKarl Li case 1:
3475e5c57d5SKarl Li smccc_ret->a2 = mmio_read_32(reg_addr[i]);
3485e5c57d5SKarl Li break;
3495e5c57d5SKarl Li case 2:
3505e5c57d5SKarl Li smccc_ret->a3 = mmio_read_32(reg_addr[i]);
3515e5c57d5SKarl Li break;
3525e5c57d5SKarl Li }
3535e5c57d5SKarl Li }
3545e5c57d5SKarl Li
3555e5c57d5SKarl Li ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_LOGGER_USER, 0, 0, 0);
3565e5c57d5SKarl Li if (ret)
3575e5c57d5SKarl Li ERROR("%s(%d): sem release timeout\n", __func__, op);
3585e5c57d5SKarl Li
3595e5c57d5SKarl Li return ret;
3605e5c57d5SKarl Li }
3615e5c57d5SKarl Li
apusys_kernel_apusys_logtop_reg_rw(uint32_t op,uint32_t write_val,bool w1c,struct smccc_res * smccc_ret)3625e5c57d5SKarl Li static int apusys_kernel_apusys_logtop_reg_rw(uint32_t op, uint32_t write_val,
3635e5c57d5SKarl Li bool w1c, struct smccc_res *smccc_ret)
3645e5c57d5SKarl Li {
3655e5c57d5SKarl Li int ret = 0;
3665e5c57d5SKarl Li uint32_t reg_addr = 0, reg_val = 0;
3675e5c57d5SKarl Li
3685e5c57d5SKarl Li switch (op) {
3695e5c57d5SKarl Li case SMC_OP_APU_LOG_BUF_R_PTR:
3705e5c57d5SKarl Li reg_addr = APU_LOG_BUF_R_PTR;
3715e5c57d5SKarl Li break;
3725e5c57d5SKarl Li case SMC_OP_APU_LOG_BUF_CON:
3735e5c57d5SKarl Li reg_addr = APU_LOGTOP_CON;
3745e5c57d5SKarl Li break;
3755e5c57d5SKarl Li default:
3765e5c57d5SKarl Li ERROR("%s unknown or not support op = %x\n", MODULE_TAG, op);
3775e5c57d5SKarl Li return -EINVAL;
3785e5c57d5SKarl Li }
3795e5c57d5SKarl Li
3805e5c57d5SKarl Li ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_LOGGER_USER, 1, 0, 0);
3815e5c57d5SKarl Li if (ret)
3825e5c57d5SKarl Li return ret;
3835e5c57d5SKarl Li
3845e5c57d5SKarl Li if (w1c) {
3855e5c57d5SKarl Li reg_val = mmio_read_32(reg_addr);
3865e5c57d5SKarl Li mmio_write_32(reg_addr, reg_val);
3875e5c57d5SKarl Li smccc_ret->a1 = reg_val;
3885e5c57d5SKarl Li } else {
3895e5c57d5SKarl Li mmio_write_32(reg_addr, write_val);
3905e5c57d5SKarl Li }
3915e5c57d5SKarl Li
3925e5c57d5SKarl Li ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_LOGGER_USER, 0, 0, 0);
3935e5c57d5SKarl Li if (ret)
3945e5c57d5SKarl Li ERROR("%s(%d): sem release timeout\n", __func__, op);
3955e5c57d5SKarl Li
3965e5c57d5SKarl Li return ret;
3975e5c57d5SKarl Li }
3985e5c57d5SKarl Li
apusys_kernel_apusys_logtop_reg_write(uint32_t op,uint32_t write_val,struct smccc_res * smccc_ret)3995e5c57d5SKarl Li int apusys_kernel_apusys_logtop_reg_write(uint32_t op, uint32_t write_val,
4005e5c57d5SKarl Li struct smccc_res *smccc_ret)
4015e5c57d5SKarl Li {
4025e5c57d5SKarl Li return apusys_kernel_apusys_logtop_reg_rw(op, write_val, false, smccc_ret);
4035e5c57d5SKarl Li }
4045e5c57d5SKarl Li
apusys_kernel_apusys_logtop_reg_w1c(uint32_t op,struct smccc_res * smccc_ret)4055e5c57d5SKarl Li int apusys_kernel_apusys_logtop_reg_w1c(uint32_t op, struct smccc_res *smccc_ret)
4065e5c57d5SKarl Li {
4075e5c57d5SKarl Li return apusys_kernel_apusys_logtop_reg_rw(op, 0, true, smccc_ret);
4085e5c57d5SKarl Li }
4095e5c57d5SKarl Li
4105e5c57d5SKarl Li #endif /* CONFIG_MTK_APUSYS_LOGTOP_SUPPORT */
4115e5c57d5SKarl Li
apusys_rv_cold_boot_clr_mbox_dummy(void)4125e5c57d5SKarl Li int apusys_rv_cold_boot_clr_mbox_dummy(void)
4135e5c57d5SKarl Li {
4145e5c57d5SKarl Li #ifdef SUPPORT_APU_CLEAR_MBOX_DUMMY
4155e5c57d5SKarl Li mmio_write_32(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_DUMMY, 0);
4165e5c57d5SKarl Li #else
4175e5c57d5SKarl Li WARN("Not support clear mbox dummy on this platform\n");
4185e5c57d5SKarl Li #endif
4195e5c57d5SKarl Li return 0;
4205e5c57d5SKarl Li }
4215e5c57d5SKarl Li
422*2d134d28SKarl Li #ifdef CONFIG_MTK_APUSYS_RV_IOMMU_HW_SEM_SUPPORT
apusys_rv_iommu_hw_sem_trylock(void)423*2d134d28SKarl Li int apusys_rv_iommu_hw_sem_trylock(void)
424*2d134d28SKarl Li {
425*2d134d28SKarl Li return rv_iommu_hw_sem_trylock();
426*2d134d28SKarl Li }
427*2d134d28SKarl Li
apusys_rv_iommu_hw_sem_unlock(void)428*2d134d28SKarl Li int apusys_rv_iommu_hw_sem_unlock(void)
429*2d134d28SKarl Li {
430*2d134d28SKarl Li return rv_iommu_hw_sem_unlock();
431*2d134d28SKarl Li }
432*2d134d28SKarl Li #endif /* CONFIG_MTK_APUSYS_RV_IOMMU_HW_SEM_SUPPORT */
433*2d134d28SKarl Li
apusys_rv_setup_ce_bin(void)4345e5c57d5SKarl Li int apusys_rv_setup_ce_bin(void)
4355e5c57d5SKarl Li {
4365e5c57d5SKarl Li #ifdef CONFIG_MTK_APUSYS_CE_SUPPORT
4375e5c57d5SKarl Li uintptr_t apusys_rv_sec_buf_pa;
4385e5c57d5SKarl Li struct apusys_secure_info_t *apusys_secure_info;
4395e5c57d5SKarl Li struct ce_main_hdr_t *ce_main_hdr;
4405e5c57d5SKarl Li struct ce_sub_hdr_t *ce_sub_hdr;
4415e5c57d5SKarl Li unsigned int cnt, i, reg_val;
4425e5c57d5SKarl Li uint64_t ce_sub_hdr_bin;
4435e5c57d5SKarl Li int ret;
4445e5c57d5SKarl Li
4455e5c57d5SKarl Li apusys_rv_sec_buf_pa = APU_RESERVE_MEMORY;
4465e5c57d5SKarl Li /* create mapping */
4475e5c57d5SKarl Li ret = mmap_add_dynamic_region(apusys_rv_sec_buf_pa, apusys_rv_sec_buf_pa,
4485e5c57d5SKarl Li round_up(APU_RESERVE_SIZE, PAGE_SIZE),
4495e5c57d5SKarl Li MT_MEMORY | MT_RW | MT_NS);
4505e5c57d5SKarl Li if (ret) {
4515e5c57d5SKarl Li ERROR("%s: mmap_add_dynamic_region() fail, ret=0x%x\n", __func__, ret);
4525e5c57d5SKarl Li return ret;
4535e5c57d5SKarl Li }
4545e5c57d5SKarl Li
4555e5c57d5SKarl Li apusys_secure_info = (struct apusys_secure_info_t *)
4565e5c57d5SKarl Li (apusys_rv_sec_buf_pa + APU_SEC_INFO_OFFSET);
4575e5c57d5SKarl Li
4585e5c57d5SKarl Li ce_main_hdr = (struct ce_main_hdr_t *)(apusys_rv_sec_buf_pa +
4595e5c57d5SKarl Li apusys_secure_info->ce_bin_ofs);
4605e5c57d5SKarl Li ce_sub_hdr = (struct ce_sub_hdr_t *)((uintptr_t)ce_main_hdr + ce_main_hdr->hdr_size);
4615e5c57d5SKarl Li
4625e5c57d5SKarl Li if (ce_main_hdr->magic != CE_MAIN_MAGIC) {
4635e5c57d5SKarl Li ERROR("%s: invalid header\n", __func__);
4645e5c57d5SKarl Li return -EINVAL;
4655e5c57d5SKarl Li }
4665e5c57d5SKarl Li
4675e5c57d5SKarl Li cnt = 0;
4685e5c57d5SKarl Li
4695e5c57d5SKarl Li while (ce_sub_hdr->magic == CE_SUB_MAGIC && cnt < ce_main_hdr->bin_count) {
4705e5c57d5SKarl Li VERBOSE("%s: job (%d), magic (0x%x)\n", __func__,
4715e5c57d5SKarl Li ce_sub_hdr->ce_enum, ce_sub_hdr->magic);
4725e5c57d5SKarl Li
4735e5c57d5SKarl Li ce_sub_hdr_bin = (uint64_t)ce_sub_hdr + ce_sub_hdr->bin_offset;
4745e5c57d5SKarl Li
4755e5c57d5SKarl Li for (i = 0; i < ce_sub_hdr->bin_size; i += sizeof(uint32_t)) {
4765e5c57d5SKarl Li reg_val = *(uint32_t *)(ce_sub_hdr_bin + i);
4775e5c57d5SKarl Li mmio_write_32(ce_sub_hdr->mem_st + i, reg_val);
4785e5c57d5SKarl Li }
4795e5c57d5SKarl Li
4805e5c57d5SKarl Li if (ce_sub_hdr->hw_entry) {
4815e5c57d5SKarl Li mmio_clrsetbits_32(ce_sub_hdr->hw_entry,
4825e5c57d5SKarl Li ce_sub_hdr->hw_entry_mask << ce_sub_hdr->hw_entry_bit,
4835e5c57d5SKarl Li (ce_sub_hdr->hw_entry_val & ce_sub_hdr->hw_entry_mask)
4845e5c57d5SKarl Li << ce_sub_hdr->hw_entry_bit);
4855e5c57d5SKarl Li }
4865e5c57d5SKarl Li
4875e5c57d5SKarl Li ce_sub_hdr = (struct ce_sub_hdr_t *)(ce_sub_hdr_bin + ce_sub_hdr->bin_size);
4885e5c57d5SKarl Li cnt++;
4895e5c57d5SKarl Li }
4905e5c57d5SKarl Li
4915e5c57d5SKarl Li mmap_remove_dynamic_region(apusys_rv_sec_buf_pa,
4925e5c57d5SKarl Li round_up(APU_RESERVE_SIZE, PAGE_SIZE));
4935e5c57d5SKarl Li
4945e5c57d5SKarl Li INFO("%s: setup CE binary done\n", __func__);
4955e5c57d5SKarl Li #else
4965e5c57d5SKarl Li WARN("Not support CE on this platform\n");
4975e5c57d5SKarl Li #endif
4985e5c57d5SKarl Li return 0;
4995e5c57d5SKarl Li }
500