Merge changes Ic746571b,I1926cab9,Id70162e9,I3a9b014e,Ic99adba1, ... into integration

* changes:
  feat(mt8196): enable APU on mt8196
  feat(mt8196): add APU SMMU hardware semaphore operations
  feat(mt8196): add smpu protection for APU secure memory
  feat(mt8196): add APU RCX DevAPC setting
  feat(mt8196): add APU kernel control operations
  feat(mt8196): add APU power on/off functions
  feat(mt8196): add APUMMU setting
  feat(mt8196): enable apusys mailbox mpu protection
  feat(mt8196): enable apusys security control
  feat(mt8196): add APUSYS AO DevAPC setting
  feat(mt8196): add APU power-on init flow
This commit is contained in:
Manish Pandey 2024-12-24 14:41:31 +01:00 committed by TrustedFirmware Code Review
commit 999503d285
35 changed files with 3058 additions and 55 deletions

View file

@ -30,10 +30,10 @@ static u_register_t apusys_kernel_handler(u_register_t x1,
switch (request_ops) {
case MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_ON:
ret = apusys_kernel_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_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();
@ -68,6 +68,27 @@ static u_register_t apusys_kernel_handler(u_register_t x1,
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;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, MediaTek Inc. All rights reserved.
* Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -10,19 +10,25 @@
#define MODULE_TAG "[APUSYS]"
enum MTK_APUSYS_KERNEL_OP {
MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_ON, /* 0 */
MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_OFF, /* 1 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_REVISER, /* 2 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_RESET_MP, /* 3 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_BOOT, /* 4 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_START_MP, /* 5 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_STOP_MP, /* 6 */
MTK_APUSYS_KERNEL_OP_DEVAPC_INIT_RCX, /* 7 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_SEC_MEM, /* 8 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_DISABLE_WDT_ISR, /* 9 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_CLEAR_WDT_ISR, /* 10 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_GATING, /* 11 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_UNGATING, /* 12 */
MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_ON, /* 0 */
MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_OFF, /* 1 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_REVISER, /* 2 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_RESET_MP, /* 3 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_BOOT, /* 4 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_START_MP, /* 5 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_STOP_MP, /* 6 */
MTK_APUSYS_KERNEL_OP_DEVAPC_INIT_RCX, /* 7 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_SEC_MEM, /* 8 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_DISABLE_WDT_ISR, /* 9 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_CLEAR_WDT_ISR, /* 10 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_GATING, /* 11 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_UNGATING, /* 12 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_APUMMU, /* 13 */
MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_DUMP, /* 14 */
MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_WRITE, /* 15 */
MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_W1C, /* 16 */
MTK_APUSYS_KERNEL_OP_APUSYS_COLD_BOOT_CLR_MBOX_DUMMY, /* 17 */
MTK_APUSYS_KERNEL_OP_APUSYS_SETUP_CE_BIN, /* 18 */
MTK_APUSYS_KERNEL_OP_NUM,
};

View file

@ -1,9 +1,11 @@
/*
* Copyright (c) 2023, MediaTek Inc. All rights reserved.
* Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <errno.h>
/* TF-A system header */
#include <common/debug.h>
#include <drivers/delay_timer.h>
@ -14,7 +16,19 @@
#include "apusys.h"
#include "apusys_rv.h"
#include "apusys_rv_mbox_mpu.h"
#include "emi_mpu.h"
#include "apusys_rv_pwr_ctrl.h"
#include "apusys_rv_sec_info.h"
#ifdef CONFIG_MTK_APUSYS_SEC_CTRL
#include "apusys_security_ctrl_perm.h"
#endif
#include "apusys_security_ctrl_plat.h"
#include <drivers/apusys_rv_public.h>
#include <mtk_mmap_pool.h>
#include <mtk_sip_svc.h>
#ifdef CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT
#include "apusys_ammu.h"
#endif
static spinlock_t apusys_rv_lock;
@ -94,6 +108,8 @@ int apusys_kernel_apusys_rv_setup_boot(void)
(PREDEFINE_CACHE << PREDEF_2G_OFS) | (PREDEFINE_CACHE << PREDEF_3G_OFS) |
(PREDEFINE_CACHE << PREDEF_4G_OFS));
apusys_infra_dcm_setup();
spin_unlock(&apusys_rv_lock);
return 0;
}
@ -107,25 +123,64 @@ int apusys_kernel_apusys_rv_start_mp(void)
return 0;
}
static int hw_sema2_release(uint32_t timeout)
{
#ifdef CONFIG_MTK_APUSYS_RV_COREDUMP_WA_SUPPORT
int ret;
ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_USER, 0, timeout, 0);
if (ret) {
ERROR("%s: HW semaphore release timeout\n", __func__);
}
return ret;
#else
return 0;
#endif
}
static int hw_sema2_acquire(uint32_t timeout)
{
#ifdef CONFIG_MTK_APUSYS_RV_COREDUMP_WA_SUPPORT
int ret;
ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_USER, 1, timeout, 0);
if (ret) {
ERROR("%s: HW semaphore acquire timeout\n", __func__);
}
return ret;
#else
return 0;
#endif
}
int apusys_kernel_apusys_rv_stop_mp(void)
{
int ret;
ret = hw_sema2_acquire(HW_SEM_TIMEOUT);
if (ret)
return ret;
spin_lock(&apusys_rv_lock);
mmio_write_32(MD32_RUNSTALL, MD32_STALL);
spin_unlock(&apusys_rv_lock);
return 0;
ret = hw_sema2_release(HW_SEM_TIMEOUT);
return ret;
}
int apusys_kernel_apusys_rv_setup_sec_mem(void)
{
int ret;
int ret = 0;
spin_lock(&apusys_rv_lock);
ret = set_apu_emi_mpu_region();
if (ret != 0) {
ret = apusys_plat_setup_sec_mem();
if (ret != 0)
ERROR(MODULE_TAG "%s: set emimpu protection failed\n", __func__);
}
spin_unlock(&apusys_rv_lock);
return ret;
@ -133,37 +188,312 @@ int apusys_kernel_apusys_rv_setup_sec_mem(void)
int apusys_kernel_apusys_rv_disable_wdt_isr(void)
{
int ret;
ret = hw_sema2_acquire(0);
if (ret)
return ret;
spin_lock(&apusys_rv_lock);
mmio_clrbits_32(WDT_CTRL0, WDT_EN);
spin_unlock(&apusys_rv_lock);
return 0;
ret = hw_sema2_release(0);
return ret;
}
int apusys_kernel_apusys_rv_clear_wdt_isr(void)
{
int ret;
ret = hw_sema2_acquire(HW_SEM_TIMEOUT);
if (ret)
return ret;
spin_lock(&apusys_rv_lock);
mmio_clrbits_32(UP_INT_EN2, DBG_APB_EN);
mmio_write_32(WDT_INT, WDT_INT_W1C);
spin_unlock(&apusys_rv_lock);
return 0;
ret = hw_sema2_release(HW_SEM_TIMEOUT);
return ret;
}
int apusys_kernel_apusys_rv_cg_gating(void)
{
int ret;
ret = hw_sema2_acquire(HW_SEM_TIMEOUT);
if (ret)
return ret;
spin_lock(&apusys_rv_lock);
mmio_write_32(MD32_CLK_CTRL, MD32_CLK_DIS);
spin_unlock(&apusys_rv_lock);
return 0;
ret = hw_sema2_release(HW_SEM_TIMEOUT);
return ret;
}
int apusys_kernel_apusys_rv_cg_ungating(void)
{
int ret;
ret = hw_sema2_acquire(HW_SEM_TIMEOUT);
if (ret)
return ret;
spin_lock(&apusys_rv_lock);
mmio_write_32(MD32_CLK_CTRL, MD32_CLK_EN);
spin_unlock(&apusys_rv_lock);
ret = hw_sema2_release(HW_SEM_TIMEOUT);
return ret;
}
int apusys_kernel_apusys_rv_setup_apummu(void)
{
spin_lock(&apusys_rv_lock);
#ifdef CONFIG_MTK_APUSYS_SEC_CTRL
sec_set_rv_dns();
#endif
#ifdef CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT
uint32_t apummu_tcm_sz_select = 0;
if (APU_MD32_TCM_SZ <= 0x20000)
apummu_tcm_sz_select = APUMMU_PAGE_LEN_128KB;
else if (APU_MD32_TCM_SZ <= 0x40000)
apummu_tcm_sz_select = APUMMU_PAGE_LEN_256KB;
else if (APU_MD32_TCM_SZ <= 0x80000)
apummu_tcm_sz_select = APUMMU_PAGE_LEN_512KB;
else if (APU_MD32_TCM_SZ <= 0x100000)
apummu_tcm_sz_select = APUMMU_PAGE_LEN_1MB;
else {
ERROR("%s: APU_MD32_TCM_SZ = 0x%x > 1MB", __func__, APU_MD32_TCM_SZ);
spin_unlock(&apusys_rv_lock);
return -EINVAL;
}
INFO("%s: apummu_tcm_sz_select = %u\n", __func__, apummu_tcm_sz_select);
rv_boot(APU_SEC_FW_IOVA, 0, APUMMU_PAGE_LEN_1MB,
APU_MD32_TCM, apummu_tcm_sz_select);
#endif
spin_unlock(&apusys_rv_lock);
return 0;
}
int apusys_kernel_apusys_rv_pwr_ctrl(enum APU_PWR_OP op)
{
return apusys_rv_pwr_ctrl(op);
}
#ifdef CONFIG_MTK_APUSYS_LOGTOP_SUPPORT
int apusys_kernel_apusys_logtop_reg_dump(uint32_t op, struct smccc_res *smccc_ret)
{
int ret = 0;
uint8_t smc_op;
uint32_t reg_addr[MAX_SMC_OP_NUM];
uint32_t i;
if (op == 0) {
ERROR("%s empty op = 0x%08x\n", MODULE_TAG, op);
return -EINVAL;
}
for (i = 0; i < MAX_SMC_OP_NUM; i++) {
smc_op = (op >> (LOGTOP_OP_SHIFT * i)) & LOGTOP_OP_MASK;
switch (smc_op) {
case SMC_OP_APU_LOG_BUF_NULL:
reg_addr[i] = 0x0;
break;
case SMC_OP_APU_LOG_BUF_T_SIZE:
reg_addr[i] = APU_LOG_BUF_T_SIZE;
break;
case SMC_OP_APU_LOG_BUF_W_PTR:
reg_addr[i] = APU_LOG_BUF_W_PTR;
break;
case SMC_OP_APU_LOG_BUF_R_PTR:
reg_addr[i] = APU_LOG_BUF_R_PTR;
break;
case SMC_OP_APU_LOG_BUF_CON:
reg_addr[i] = APU_LOGTOP_CON;
break;
default:
ERROR("%s unknown op = 0x%08x\n", MODULE_TAG, smc_op);
return -EINVAL;
}
}
ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_LOGGER_USER, 1, 0, 0);
if (ret)
return ret;
for (i = 0; i < MAX_SMC_OP_NUM; i++) {
if (reg_addr[i] == 0)
continue;
switch (i) {
case 0:
smccc_ret->a1 = mmio_read_32(reg_addr[i]);
break;
case 1:
smccc_ret->a2 = mmio_read_32(reg_addr[i]);
break;
case 2:
smccc_ret->a3 = mmio_read_32(reg_addr[i]);
break;
}
}
ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_LOGGER_USER, 0, 0, 0);
if (ret)
ERROR("%s(%d): sem release timeout\n", __func__, op);
return ret;
}
static int apusys_kernel_apusys_logtop_reg_rw(uint32_t op, uint32_t write_val,
bool w1c, struct smccc_res *smccc_ret)
{
int ret = 0;
uint32_t reg_addr = 0, reg_val = 0;
switch (op) {
case SMC_OP_APU_LOG_BUF_R_PTR:
reg_addr = APU_LOG_BUF_R_PTR;
break;
case SMC_OP_APU_LOG_BUF_CON:
reg_addr = APU_LOGTOP_CON;
break;
default:
ERROR("%s unknown or not support op = %x\n", MODULE_TAG, op);
return -EINVAL;
}
ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_LOGGER_USER, 1, 0, 0);
if (ret)
return ret;
if (w1c) {
reg_val = mmio_read_32(reg_addr);
mmio_write_32(reg_addr, reg_val);
smccc_ret->a1 = reg_val;
} else {
mmio_write_32(reg_addr, write_val);
}
ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_LOGGER_USER, 0, 0, 0);
if (ret)
ERROR("%s(%d): sem release timeout\n", __func__, op);
return ret;
}
int apusys_kernel_apusys_logtop_reg_write(uint32_t op, uint32_t write_val,
struct smccc_res *smccc_ret)
{
return apusys_kernel_apusys_logtop_reg_rw(op, write_val, false, smccc_ret);
}
int apusys_kernel_apusys_logtop_reg_w1c(uint32_t op, struct smccc_res *smccc_ret)
{
return apusys_kernel_apusys_logtop_reg_rw(op, 0, true, smccc_ret);
}
#endif /* CONFIG_MTK_APUSYS_LOGTOP_SUPPORT */
int apusys_rv_cold_boot_clr_mbox_dummy(void)
{
#ifdef SUPPORT_APU_CLEAR_MBOX_DUMMY
mmio_write_32(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_DUMMY, 0);
#else
WARN("Not support clear mbox dummy on this platform\n");
#endif
return 0;
}
#ifdef CONFIG_MTK_APUSYS_RV_IOMMU_HW_SEM_SUPPORT
int apusys_rv_iommu_hw_sem_trylock(void)
{
return rv_iommu_hw_sem_trylock();
}
int apusys_rv_iommu_hw_sem_unlock(void)
{
return rv_iommu_hw_sem_unlock();
}
#endif /* CONFIG_MTK_APUSYS_RV_IOMMU_HW_SEM_SUPPORT */
int apusys_rv_setup_ce_bin(void)
{
#ifdef CONFIG_MTK_APUSYS_CE_SUPPORT
uintptr_t apusys_rv_sec_buf_pa;
struct apusys_secure_info_t *apusys_secure_info;
struct ce_main_hdr_t *ce_main_hdr;
struct ce_sub_hdr_t *ce_sub_hdr;
unsigned int cnt, i, reg_val;
uint64_t ce_sub_hdr_bin;
int ret;
apusys_rv_sec_buf_pa = APU_RESERVE_MEMORY;
/* create mapping */
ret = mmap_add_dynamic_region(apusys_rv_sec_buf_pa, apusys_rv_sec_buf_pa,
round_up(APU_RESERVE_SIZE, PAGE_SIZE),
MT_MEMORY | MT_RW | MT_NS);
if (ret) {
ERROR("%s: mmap_add_dynamic_region() fail, ret=0x%x\n", __func__, ret);
return ret;
}
apusys_secure_info = (struct apusys_secure_info_t *)
(apusys_rv_sec_buf_pa + APU_SEC_INFO_OFFSET);
ce_main_hdr = (struct ce_main_hdr_t *)(apusys_rv_sec_buf_pa +
apusys_secure_info->ce_bin_ofs);
ce_sub_hdr = (struct ce_sub_hdr_t *)((uintptr_t)ce_main_hdr + ce_main_hdr->hdr_size);
if (ce_main_hdr->magic != CE_MAIN_MAGIC) {
ERROR("%s: invalid header\n", __func__);
return -EINVAL;
}
cnt = 0;
while (ce_sub_hdr->magic == CE_SUB_MAGIC && cnt < ce_main_hdr->bin_count) {
VERBOSE("%s: job (%d), magic (0x%x)\n", __func__,
ce_sub_hdr->ce_enum, ce_sub_hdr->magic);
ce_sub_hdr_bin = (uint64_t)ce_sub_hdr + ce_sub_hdr->bin_offset;
for (i = 0; i < ce_sub_hdr->bin_size; i += sizeof(uint32_t)) {
reg_val = *(uint32_t *)(ce_sub_hdr_bin + i);
mmio_write_32(ce_sub_hdr->mem_st + i, reg_val);
}
if (ce_sub_hdr->hw_entry) {
mmio_clrsetbits_32(ce_sub_hdr->hw_entry,
ce_sub_hdr->hw_entry_mask << ce_sub_hdr->hw_entry_bit,
(ce_sub_hdr->hw_entry_val & ce_sub_hdr->hw_entry_mask)
<< ce_sub_hdr->hw_entry_bit);
}
ce_sub_hdr = (struct ce_sub_hdr_t *)(ce_sub_hdr_bin + ce_sub_hdr->bin_size);
cnt++;
}
mmap_remove_dynamic_region(apusys_rv_sec_buf_pa,
round_up(APU_RESERVE_SIZE, PAGE_SIZE));
INFO("%s: setup CE binary done\n", __func__);
#else
WARN("Not support CE on this platform\n");
#endif
return 0;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, MediaTek Inc. All rights reserved.
* Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -88,24 +88,35 @@
#define WDT_INT_W1C (1)
#define WDT_EN BIT(31)
/* APU MBOX */
#define MBOX_FUNC_CFG (0xb0)
#define MBOX_DOMAIN_CFG (0xe0)
#define MBOX_CTRL_LOCK BIT(0)
#define MBOX_NO_MPU_SHIFT (16)
#define MBOX_RX_NS_SHIFT (16)
#define MBOX_RX_DOMAIN_SHIFT (17)
#define MBOX_TX_NS_SHIFT (24)
#define MBOX_TX_DOMAIN_SHIFT (25)
#define MBOX_SIZE (0x100)
#define MBOX_NUM (8)
enum APU_PWR_OP {
APU_PWR_OFF = 0,
APU_PWR_ON = 1,
};
#define APU_MBOX(i) (((i) < MBOX_NUM) ? (APU_MBOX0 + MBOX_SIZE * (i)) : \
(APU_MBOX1 + MBOX_SIZE * ((i) - MBOX_NUM)))
#define APU_MBOX_FUNC_CFG(i) (APU_MBOX(i) + MBOX_FUNC_CFG)
#define APU_MBOX_DOMAIN_CFG(i) (APU_MBOX(i) + MBOX_DOMAIN_CFG)
/* APU_LOGTOP */
#define APU_LOGTOP_CON (APU_LOGTOP + 0x0)
#define APU_LOG_BUF_T_SIZE (APU_LOGTOP + 0x78)
#define APU_LOG_BUF_W_PTR (APU_LOGTOP + 0x80)
#define APU_LOG_BUF_R_PTR (APU_LOGTOP + 0x84)
#define HW_SEMA2 (APU_ARE_REG_BASE + 0x0E08)
#define HW_SEMA_USER (0x2)
#define HW_SEMA_LOGGER_USER (0x3)
#define MAX_SMC_OP_NUM (0x3)
#define LOGTOP_OP_MASK (0xFF)
#define LOGTOP_OP_SHIFT (8)
enum {
SMC_OP_APU_LOG_BUF_NULL = 0,
SMC_OP_APU_LOG_BUF_T_SIZE,
SMC_OP_APU_LOG_BUF_W_PTR,
SMC_OP_APU_LOG_BUF_R_PTR,
SMC_OP_APU_LOG_BUF_CON,
SMC_OP_APU_LOG_BUF_NUM
};
struct smccc_res;
void apusys_rv_mbox_mpu_init(void);
int apusys_infra_dcm_setup(void);
int apusys_kernel_apusys_rv_setup_reviser(void);
int apusys_kernel_apusys_rv_reset_mp(void);
int apusys_kernel_apusys_rv_setup_boot(void);
@ -116,5 +127,13 @@ int apusys_kernel_apusys_rv_disable_wdt_isr(void);
int apusys_kernel_apusys_rv_clear_wdt_isr(void);
int apusys_kernel_apusys_rv_cg_gating(void);
int apusys_kernel_apusys_rv_cg_ungating(void);
int apusys_kernel_apusys_rv_setup_apummu(void);
int apusys_kernel_apusys_rv_pwr_ctrl(enum APU_PWR_OP op);
int apusys_kernel_apusys_logtop_reg_dump(uint32_t op, struct smccc_res *smccc_ret);
int apusys_kernel_apusys_logtop_reg_write(uint32_t op, uint32_t write_val,
struct smccc_res *smccc_ret);
int apusys_kernel_apusys_logtop_reg_w1c(uint32_t op, struct smccc_res *smccc_ret);
int apusys_rv_cold_boot_clr_mbox_dummy(void);
int apusys_rv_setup_ce_bin(void);
#endif /* APUSYS_RV_H */

View file

@ -0,0 +1,71 @@
/*
* Copyright (c) 2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef APUSYS_RV_SECURE_INFO_H
#define APUSYS_RV_SECURE_INFO_H
#define CE_MAIN_MAGIC (0xCEC0DE88)
#define CE_SUB_MAGIC (0xCEC0DE00)
struct apusys_secure_info_t {
unsigned int total_sz;
unsigned int up_code_buf_ofs;
unsigned int up_code_buf_sz;
unsigned int up_fw_ofs;
unsigned int up_fw_sz;
unsigned int up_xfile_ofs;
unsigned int up_xfile_sz;
unsigned int mdla_fw_boot_ofs;
unsigned int mdla_fw_boot_sz;
unsigned int mdla_fw_main_ofs;
unsigned int mdla_fw_main_sz;
unsigned int mdla_xfile_ofs;
unsigned int mdla_xfile_sz;
unsigned int mvpu_fw_ofs;
unsigned int mvpu_fw_sz;
unsigned int mvpu_xfile_ofs;
unsigned int mvpu_xfile_sz;
unsigned int mvpu_sec_fw_ofs;
unsigned int mvpu_sec_fw_sz;
unsigned int mvpu_sec_xfile_ofs;
unsigned int mvpu_sec_xfile_sz;
unsigned int up_coredump_ofs;
unsigned int up_coredump_sz;
unsigned int mdla_coredump_ofs;
unsigned int mdla_coredump_sz;
unsigned int mvpu_coredump_ofs;
unsigned int mvpu_coredump_sz;
unsigned int mvpu_sec_coredump_ofs;
unsigned int mvpu_sec_coredump_sz;
unsigned int ce_bin_ofs;
unsigned int ce_bin_sz;
};
struct ce_main_hdr_t {
unsigned int magic; /* magic number*/
unsigned int hdr_size; /* header size */
unsigned int img_size; /* img size */
unsigned int bin_count; /* bin count */
};
struct ce_sub_hdr_t {
unsigned int magic; /* magic number */
unsigned int bin_offset; /* binary offset */
unsigned int bin_size; /* binary size */
unsigned int ce_enum; /* ce enum */
char job_name[8]; /* job name */
unsigned int mem_st; /* ce enum */
unsigned int hw_entry; /* hw entry */
unsigned int hw_entry_bit; /* hw entry bit */
unsigned int hw_entry_mask; /* hw entry mask */
unsigned int hw_entry_val; /* hw entry val*/
unsigned int user_info; /* user_info */
};
#endif /* APUSYS_RV_SECURE_INFO_H */

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, MediaTek Inc. All rights reserved.
* Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -13,8 +13,15 @@
* STRUCTURE DEFINITION
******************************************************************************/
enum apusys_apc_err_status {
APUSYS_APC_OK = 0x0,
APUSYS_APC_ERR_GENERIC = 0x1,
APUSYS_APC_OK = 0x0,
APUSYS_APC_ERR_GENERIC = 0x1000,
APUSYS_APC_ERR_INVALID_CMD = 0x1001,
APUSYS_APC_ERR_SLAVE_TYPE_NOT_SUPPORTED = 0x1002,
APUSYS_APC_ERR_SLAVE_IDX_NOT_SUPPORTED = 0x1003,
APUSYS_APC_ERR_DOMAIN_NOT_SUPPORTED = 0x1004,
APUSYS_APC_ERR_PERMISSION_NOT_SUPPORTED = 0x1005,
APUSYS_APC_ERR_OUT_OF_BOUNDARY = 0x1006,
APUSYS_APC_ERR_REQ_TYPE_NOT_SUPPORTED = 0x1007,
};
enum apusys_apc_perm_type {
@ -155,4 +162,110 @@ void dump_apusys_dapc_v1(const char *name, uintptr_t base, uint32_t reg_num, uin
FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
#define SLAVE_FORBID_EXCEPT_D0_D11_NO_PROTECT_D3_D5_D8_SEC_RW(domain) \
APUSYS_APC_AO_ATTR(domain, \
NO_PROTECTION, FORBIDDEN, FORBIDDEN, SEC_RW_ONLY, \
FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, NO_PROTECTION, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
#define SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D3_D5_SEC_RW(domain) \
APUSYS_APC_AO_ATTR(domain, \
SEC_RW_NS_R, FORBIDDEN, FORBIDDEN, SEC_RW_ONLY, \
FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
#define SLAVE_FORBID_EXCEPT_D5_SEC_RW(domain) \
APUSYS_APC_AO_ATTR(domain, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
#define SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW(domain) \
APUSYS_APC_AO_ATTR(domain, \
SEC_RW_NS_R, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
#define SLAVE_FORBID_EXCEPT_D0_NO_PROTECT_D3_D5_SEC_RW(domain) \
APUSYS_APC_AO_ATTR(domain, \
NO_PROTECTION, FORBIDDEN, FORBIDDEN, SEC_RW_ONLY, \
FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
#define SLAVE_FORBID_EXCEPT_D3_D5_SEC_RW_D0_D4_D11_NO_PROTECT(domain) \
APUSYS_APC_AO_ATTR(domain, \
NO_PROTECTION, FORBIDDEN, FORBIDDEN, SEC_RW_ONLY, \
NO_PROTECTION, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
#define SLAVE_FORBID_EXCEPT_D5_SEC_RW_D0_NO_PROTECT(domain) \
APUSYS_APC_AO_ATTR(domain, \
NO_PROTECTION, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
#define SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW(domain) \
APUSYS_APC_AO_ATTR(domain, \
SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
#define SLAVE_FORBID_EXCEPT_D0_NO_PROTECT_D5_SEC_RW(domain) \
APUSYS_APC_AO_ATTR(domain, \
NO_PROTECTION, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
#define SLAVE_FORBID_EXCEPT_D3_D5_SEC_RW_D0_D11_NO_PROTECT(domain) \
APUSYS_APC_AO_ATTR(domain, \
NO_PROTECTION, FORBIDDEN, FORBIDDEN, SEC_RW_ONLY, \
FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
#define SLAVE_FORBID_EXCEPT_D0_NO_PROTECT_D5_D8_SEC_RW(domain) \
APUSYS_APC_AO_ATTR(domain, \
NO_PROTECTION, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
#define SLAVE_FORBID_EXCEPT_D0_D3_D5_SEC_RW(domain) \
APUSYS_APC_AO_ATTR(domain, \
SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, SEC_RW_ONLY, \
FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
#define SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_D8_SEC_RW(domain) \
APUSYS_APC_AO_ATTR(domain, \
SEC_RW_NS_R, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
#define SLAVE_FORBID_EXCEPT_D5_D8_SEC_RW(domain) \
APUSYS_APC_AO_ATTR(domain, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
#define SLAVE_FORBID_EXCEPT_D0_D5_D7_D14_NO_PROTECT(domain) \
APUSYS_APC_AO_ATTR(domain, \
NO_PROTECTION, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, NO_PROTECTION, FORBIDDEN, NO_PROTECTION, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, FORBIDDEN, NO_PROTECTION, FORBIDDEN)
#endif /* APUSYS_DAPC_V1_H */

View file

@ -1,9 +1,10 @@
/*
* Copyright (c) 2023, MediaTek Inc. All rights reserved.
* Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <errno.h>
#include <inttypes.h>
/* TF-A system header */
@ -18,6 +19,7 @@
#include "apusys.h"
#include "apusys_power.h"
#include "apusys_rv.h"
#include "apusys_rv_pwr_ctrl.h"
#include <mtk_mmap_pool.h>
static spinlock_t apu_lock;
@ -118,7 +120,7 @@ static void apu_pwr_flow_remote_sync(uint32_t cfg)
mmio_write_32(APU_MBOX0_BASE + PWR_FLOW_SYNC_REG, (cfg & 0x1));
}
int apusys_kernel_apusys_pwr_top_on(void)
static int apusys_kernel_apusys_pwr_top_on(void)
{
int ret;
@ -184,7 +186,7 @@ static void apu_sleep_rpc_rcx(void)
udelay(100);
}
int apusys_kernel_apusys_pwr_top_off(void)
static int apusys_kernel_apusys_pwr_top_off(void)
{
int ret;
@ -221,6 +223,19 @@ int apusys_kernel_apusys_pwr_top_off(void)
return ret;
}
int apusys_rv_pwr_ctrl(enum APU_PWR_OP op)
{
if (op != APU_PWR_OFF && op != APU_PWR_ON) {
ERROR(MODULE_TAG "%s unknown request_ops = %d\n", __func__, op);
return -EINVAL;
}
if (op == APU_PWR_ON)
return apusys_kernel_apusys_pwr_top_on();
return apusys_kernel_apusys_pwr_top_off();
}
static void get_pll_pcw(const uint32_t clk_rate, uint32_t *r1, uint32_t *r2)
{
unsigned int fvco = clk_rate;
@ -481,3 +496,10 @@ int apusys_power_init(void)
return ret;
}
int apusys_infra_dcm_setup(void)
{
WARN(MODULE_TAG "%s not support\n", __func__);
return -EOPNOTSUPP;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, MediaTek Inc. All rights reserved.
* Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -242,7 +242,5 @@ struct apu_restore_data {
#define CG_CLR (0xffffffff)
int apusys_power_init(void);
int apusys_kernel_apusys_pwr_top_on(void);
int apusys_kernel_apusys_pwr_top_off(void);
#endif /* APUSYS_POWER_H */

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, MediaTek Inc. All rights reserved.
* Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/

View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef APUSYS_RV_PWR_CTL_H
#define APUSYS_RV_PWR_CTL_H
#include "apusys_rv.h"
/* APU MBOX */
#define MBOX_FUNC_CFG (0xb0)
#define MBOX_DOMAIN_CFG (0xe0)
#define MBOX_CTRL_LOCK BIT(0)
#define MBOX_NO_MPU_SHIFT (16)
#define MBOX_RX_NS_SHIFT (16)
#define MBOX_RX_DOMAIN_SHIFT (17)
#define MBOX_TX_NS_SHIFT (24)
#define MBOX_TX_DOMAIN_SHIFT (25)
#define MBOX_SIZE (0x100)
#define MBOX_NUM (8)
#define APU_MBOX(i) (((i) < MBOX_NUM) ? (APU_MBOX0 + MBOX_SIZE * (i)) : \
(APU_MBOX1 + MBOX_SIZE * ((i) - MBOX_NUM)))
#define APU_MBOX_FUNC_CFG(i) (APU_MBOX(i) + MBOX_FUNC_CFG)
#define APU_MBOX_DOMAIN_CFG(i) (APU_MBOX(i) + MBOX_DOMAIN_CFG)
#define HW_SEM_TIMEOUT (0)
int apusys_rv_pwr_ctrl(enum APU_PWR_OP op);
#endif /* APUSYS_RV_PWR_CTL_H */

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, MediaTek Inc. All rights reserved.
* Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -8,6 +8,8 @@
#include <common/debug.h>
#include <lib/mmio.h>
#include "emi_mpu.h"
/* Vendor header */
#include "apusys_security_ctrl_plat.h"
@ -41,3 +43,8 @@ void apusys_security_ctrl_init(void)
{
apusys_domain_remap_init();
}
int apusys_plat_setup_sec_mem(void)
{
return set_apu_emi_mpu_region();
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, MediaTek Inc. All rights reserved.
* Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -34,5 +34,6 @@
#define D15_REMAP_DOMAIN (15)
void apusys_security_ctrl_init(void);
int apusys_plat_setup_sec_mem(void);
#endif /* APUSYS_SECURITY_CTRL_PLAT_H */

View file

@ -0,0 +1,287 @@
/*
* Copyright (c) 2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <errno.h>
#include <common/debug.h>
#include <lib/mmio.h>
#include <lib/utils_def.h>
#include "apusys_ammu.h"
#include <apusys_security_ctrl_perm.h>
#include <mtk_mmap_pool.h>
static void apummu_set_segment_offset0(uint32_t vsid_idx, uint8_t seg_idx, uint32_t input_adr,
uint8_t res_bits, uint8_t page_sel, uint8_t page_len)
{
mmio_write_32(APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, APUMMU_SEG_OFFSET_0),
APUMMU_BUILD_SEGMENT_OFFSET0(input_adr, res_bits, page_sel, page_len));
}
static void apummu_set_segment_offset1(uint32_t vsid_idx, uint8_t seg_idx, uint32_t output_adr,
uint8_t res0, uint8_t iommu_en, uint8_t res1)
{
mmio_write_32(APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, APUMMU_SEG_OFFSET_1),
APUMMU_BUILD_SEGMENT_OFFSET1(output_adr, res0, iommu_en, res1));
}
static void apummu_set_segment_offset2(uint32_t vsid_idx, uint8_t seg_idx, uint8_t resv,
uint8_t domain, uint8_t acp_en, uint8_t aw_clr,
uint8_t aw_invalid, uint8_t ar_exclu, uint8_t ar_sepcu,
uint8_t aw_cache_allocate, uint8_t aw_slc_en,
uint8_t aw_slb_en, uint8_t ar_cache_allocate,
uint8_t ar_slc_en, uint8_t ar_slb_en, uint8_t ro,
uint8_t ns)
{
mmio_write_32(APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, APUMMU_SEG_OFFSET_2),
APUMMU_BUILD_SEGMENT_OFFSET2(resv, domain, acp_en, aw_clr, aw_invalid,
ar_exclu, ar_sepcu, aw_cache_allocate,
aw_slc_en, aw_slb_en, ar_cache_allocate,
ar_slc_en, ar_slb_en, ro, ns));
}
static void apummu_vsid_segment_enable_init(uint8_t vsid_idx)
{
mmio_write_32(APUMMU_VSID_SEGMENT_ENABLE(vsid_idx), 0);
}
static void apummu_set_single_segment(uint8_t vsid_idx, uint8_t seg_idx)
{
mmio_setbits_32(APUMMU_VSID_SEGMENT_ENABLE(vsid_idx), BIT(seg_idx));
}
static int apummu_enable_vsid(uint32_t vsid_idx)
{
if (vsid_idx > (APUMMU_VSID_ACTIVE - 1) &&
vsid_idx < (APUMMU_RSV_VSID_IDX_END - APUMMU_VSID_RSV + 1)) {
ERROR("invalid vsid index %d\n", vsid_idx);
return -1;
}
mmio_write_32(APUMMU_VSID_ENABLE_BASE(vsid_idx), BIT(vsid_idx & APUMMU_VSID_EN_MASK));
mmio_write_32(APUMMU_VSID_VALID_BASE(vsid_idx), BIT(vsid_idx & APUMMU_VSID_EN_MASK));
return 0;
}
static void apummu_enable(void)
{
mmio_setbits_32(APUMMU_CMU_TOP_BASE, 0x1);
}
static void apummu_vsid_sram_config(void)
{
uint32_t idx;
uint32_t base = (APUMMU_VSID_SRAM_TOTAL - APUMMU_VSID_RSV);
for (idx = 0; idx < APUMMU_VSID_RSV; idx++) {
mmio_write_32(APUMMU_VSID(APUMMU_RSV_VSID_IDX_START + idx),
APUMMU_VSID_DESC(base + idx));
apummu_vsid_segment_enable_init(base + idx);
}
}
static void apummu_bind_vsid(uint32_t tcu_base, uint32_t vsid_idx, uint8_t cor_id,
uint8_t hw_thread, uint8_t cor_valid, uint8_t vsid_valid)
{
mmio_write_32((tcu_base + hw_thread * VSID_THREAD_SZ),
(((cor_id & VSID_CORID_MASK) << VSID_CORID_OFF) |
((vsid_idx & VSID_IDX_MASK) << VSID_IDX_OFF) |
((cor_valid & VSID_VALID_MASK) << VSID_COR_VALID_OFF) |
((vsid_valid & VSID_VALID_MASK) << VSID_VALID_OFF)));
}
static int apummu_rv_bind_vsid(uint8_t hw_thread)
{
uint8_t cor_id = 0, cor_valid = 0, vsid_valid = 1;
if (hw_thread > APUMMU_HW_THREAD_MAX) {
ERROR("%s: the hw thread id (%d) is not valid for rv/logger\n", __func__,
hw_thread);
return -EINVAL;
}
apummu_bind_vsid(APUMMU_RCX_UPRV_TCU_BASE, APUMMU_UPRV_RSV_VSID, cor_id, hw_thread,
cor_valid, vsid_valid);
return 0;
}
static int apummu_apmcu_bind_vsid(uint8_t hw_thread)
{
uint8_t cor_id = 0, cor_valid = 0, vsid_valid = 1;
if (hw_thread > APUMMU_HW_THREAD_MAX) {
ERROR("%s: the hw thread id (%d) is not valid for apmcu\n", __func__, hw_thread);
return -EINVAL;
}
apummu_bind_vsid(APUMMU_RCX_EXTM_TCU_BASE, APUMMU_APMCU_RSV_VSID, cor_id, hw_thread,
cor_valid, vsid_valid);
return 0;
}
static int apummu_add_map(uint32_t vsid_idx, uint8_t seg_idx, uint64_t input_adr,
uint64_t output_adr, uint8_t page_sel, uint8_t page_len,
uint8_t domain, uint8_t ns)
{
uint8_t smmu_sid;
bool smmu_sec_id;
if (seg_idx > APUMMU_SEG_MAX) {
ERROR("seg_idx is illegal (0x%x)\n", seg_idx);
return -EINVAL;
}
smmu_sec_id = false;
if (ns == 0)
smmu_sid = SMMU_NORMAL_1_4G_SID;
else
smmu_sid = (output_adr > 0xFFFFFFFF) ? SMMU_NORMAL_4_16G_SID
: SMMU_NORMAL_1_4G_SID;
/* fill segment */
apummu_set_segment_offset0(vsid_idx, seg_idx, (input_adr >> APUMMU_ADDR_SHIFT), 0,
page_sel, page_len);
apummu_set_segment_offset1(vsid_idx, seg_idx, (output_adr >> APUMMU_ADDR_SHIFT),
smmu_sid, 0, smmu_sec_id);
apummu_set_segment_offset2(vsid_idx, seg_idx, 0, domain,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ns);
apummu_set_single_segment(vsid_idx, seg_idx);
return 0;
}
static int apummu_get_dns(enum apusys_dev_type engine_type, enum apusys_sec_level sec_level,
uint8_t *domain, uint8_t *ns)
{
int ret = 0;
if (engine_type != APUSYS_DEVICE_NUM) {
ret = sec_get_dns(engine_type, sec_level, domain, ns);
if (ret)
ERROR("engine:%d, sec: %d\n", engine_type, sec_level);
} else {
*domain = 7;
*ns = 1;
}
return ret;
}
static void apummu_init(void)
{
apummu_vsid_sram_config();
mmio_write_32((APU_VCORE_CONFIG_BASE + APUMMU_SSID_SID_WIDTH_CTRL),
CSR_SMMU_AXMMUSID_WIDTH);
apummu_enable();
}
static void virtual_engine_thread(void)
{
mmio_write_32((APUMMU_RCX_EXTM_TCU_BASE + APUMMU_INT_D2T_TBL0_OFS), APUMMU_THD_ID_TEE);
}
static int apummu_add_apmcu_map(uint32_t seg0_input, uint32_t seg0_output,
enum apummu_page_size page_size)
{
int i, ret;
uint8_t domain, ns, seg;
ret = apummu_get_dns(APUSYS_DEVICE_NUM, SEC_LEVEL_SECURE, &domain, &ns);
if (ret) {
return ret;
}
seg = 0;
ret = apummu_add_map(APUMMU_APMCU_RSV_DESC_IDX, seg, seg0_input, seg0_output, 0,
page_size, domain, ns);
seg += 1;
if (ret)
return ret;
for (i = 0; i < 4; i++) {
ret = apummu_add_map(APUMMU_APMCU_RSV_DESC_IDX, seg,
APUSYS_TCM + (i * APUMMU_1M_SIZE),
APUSYS_TCM + (i * APUMMU_1M_SIZE),
0, APUMMU_PAGE_LEN_1MB, domain, ns);
seg += 1;
if (ret)
return ret;
}
ret = apummu_enable_vsid(APUMMU_APMCU_RSV_VSID);
return ret;
}
static int apummu_add_rv_boot_map(uint32_t seg0_output, uint32_t seg1_output, uint32_t seg2_output)
{
int ret;
uint8_t domain, ns;
ret = apummu_get_dns(APUSYS_DEVICE_UP, SEC_LEVEL_SECURE, &domain, &ns);
if (ret) {
ERROR("sec get dns fail %d\n", ret);
return ret;
}
/* must be in order */
ret |= apummu_add_map(APUMMU_RSV_VSID_DESC_IDX_END, 0, 0, seg0_output, 0,
APUMMU_PAGE_LEN_1MB, domain, ns);
ret |= apummu_add_map(APUMMU_RSV_VSID_DESC_IDX_END, 1, 0, seg1_output, 0,
APUMMU_PAGE_LEN_512MB, domain, ns);
ret |= apummu_get_dns(APUSYS_DEVICE_UP, SEC_LEVEL_NORMAL, &domain, &ns);
if (ret) {
return ret;
}
ret |= apummu_add_map(APUMMU_RSV_VSID_DESC_IDX_END, 2,
0, seg2_output, 0, APUMMU_PAGE_LEN_4GB,
domain, ns);
if (ret) {
ERROR("sec add map fail %d\n", ret);
return ret;
}
ret = apummu_enable_vsid(APUMMU_UPRV_RSV_VSID);
return ret;
}
int rv_boot(uint32_t uP_seg_output, uint8_t uP_hw_thread,
enum apummu_page_size logger_page_size,
uint32_t XPU_seg_output, enum apummu_page_size XPU_page_size)
{
int ret = 0;
apummu_init();
ret = apummu_add_rv_boot_map(uP_seg_output, 0, 0);
if (ret) {
return ret;
}
ret = apummu_rv_bind_vsid(uP_hw_thread);
if (ret)
return ret;
ret = apummu_rv_bind_vsid(uP_hw_thread + 1);
if (ret)
return ret;
virtual_engine_thread();
ret = apummu_add_apmcu_map(XPU_seg_output, XPU_seg_output,
XPU_page_size);
if (ret)
return ret;
ret = apummu_apmcu_bind_vsid(APUMMU_THD_ID_TEE);
return ret;
}

View file

@ -0,0 +1,264 @@
/*
* Copyright (c) 2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef APUSYS_AMMU_H
#define APUSYS_AMMU_H
#include <platform_def.h>
/* CMU */
#define APUMMU_CMU_TOP_BASE (APU_CMU_TOP)
#define APUMMU_CMU_TOP_TOPOLOGY (APUMMU_CMU_TOP_BASE + 0x04)
#define APUMMU_VSID_ENABLE_OFFSET (0x50)
#define APUMMU_VSID_VALID_OFFSET (0xb0)
#define VSID_OFFSET(vsid_idx) (((vsid_idx) >> 5) * 0x4)
#define APUMMU_VSID_ENABLE_BASE(vsid_idx) \
(APUMMU_CMU_TOP_BASE + VSID_OFFSET(vsid_idx) + APUMMU_VSID_ENABLE_OFFSET)
#define APUMMU_VSID_VALID_BASE(vsid_idx) \
(APUMMU_CMU_TOP_BASE + VSID_OFFSET(vsid_idx) + APUMMU_VSID_VALID_OFFSET)
/* VSID SRAM */
#define APUMMU_VSID_BASE (APUMMU_CMU_TOP_BASE + 0x1000)
#define APUMMU_VSID_DESC_BASE (APUMMU_VSID_BASE + 0x400)
#define APUMMU_VSID_SRAM_SZIE (0x5C00)
#define APUMMU_VSID_TBL_SZIE (0xF4)
#define APUMMU_VSID(vsid_idx) (APUMMU_VSID_BASE + (vsid_idx) * 4)
#define APUMMU_VSID_DESC(vsid_idx) \
(APUMMU_VSID_DESC_BASE + (vsid_idx) * APUMMU_VSID_TBL_SZIE)
/* TCU RCX */
#define APU_VCORE_CONFIG_BASE (APU_RCX_VCORE_CONFIG)
#define APUMMU_RCX_EXTM_TCU_BASE (APU_RCX_EXTM_TCU)
#define APUMMU_RCX_UPRV_TCU_BASE (APU_RCX_UPRV_TCU)
#define APUMMU_SSID_SID_WIDTH_CTRL (0xCC0)
#define CSR_SMMU_AXMMUSID_WIDTH BIT(7)
#define APUMMU_1M_SIZE (0x100000)
#define SMMU_NORMAL_0_1G_SID (0x8)
#define SMMU_NORMAL_1_4G_SID (0x9)
#define SMMU_NORMAL_4_16G_SID (0xA)
enum apummu_page_size {
APUMMU_PAGE_LEN_128KB = 0,
APUMMU_PAGE_LEN_256KB,
APUMMU_PAGE_LEN_512KB,
APUMMU_PAGE_LEN_1MB,
APUMMU_PAGE_LEN_128MB,
APUMMU_PAGE_LEN_256MB,
APUMMU_PAGE_LEN_512MB,
APUMMU_PAGE_LEN_4GB,
};
#define APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, seg_offset) \
(APUMMU_VSID_DESC(vsid_idx) + (seg_idx) * 0xC + (seg_offset) * 0x04 + 0x4)
#define APUMMU_VSID_SEGMENT_ENABLE(vsid_idx) (APUMMU_VSID_DESC(vsid_idx))
#define APUMMU_VSID_SRAM_TOTAL (APUMMU_VSID_SRAM_SZIE / APUMMU_VSID_TBL_SZIE)
#define APUMMU_RSV_VSID_DESC_IDX_END (APUMMU_VSID_SRAM_TOTAL - 1)
#define APUMMU_UPRV_RSV_DESC_IDX (APUMMU_RSV_VSID_DESC_IDX_END) /* 53 */
#define APUMMU_LOGGER_RSV_DESC_IDX (APUMMU_RSV_VSID_DESC_IDX_END - 1)
#define APUMMU_APMCU_RSV_DESC_IDX (APUMMU_RSV_VSID_DESC_IDX_END - 2)
#define APUMMU_GPU_RSV_DESC_IDX (APUMMU_RSV_VSID_DESC_IDX_END - 3)
#define APUMMU_SEG_OFFSET_0 (0)
#define APUMMU_SEG_OFFSET_1 (1)
#define APUMMU_SEG_OFFSET_2 (2)
#define APUMMU_VSID_EN_MASK (0x1f)
#define APUMMU_HW_THREAD_MAX (7)
#define APUMMU_SEG_MAX (9)
#define APUMMU_ADDR_SHIFT (12)
#define VSID_THREAD_SZ (0x4)
#define VSID_CORID_MASK (0x7f)
#define VSID_CORID_OFF (11)
#define VSID_IDX_MASK (0xff)
#define VSID_IDX_OFF (3)
#define VSID_VALID_MASK (0x1)
#define VSID_COR_VALID_OFF (1)
#define VSID_VALID_OFF (0)
#define APUMMU_VSID_ACTIVE (32)
#define APUMMU_VSID_RSV (4)
#define APUMMU_VSID_UNUSED (12)
#define APUMMU_VSID_USE_MAX (APUMMU_VSID_ACTIVE + APUMMU_VSID_RSV)
#if ((APUMMU_VSID_RSV + APUMMU_VSID_ACTIVE + APUMMU_VSID_UNUSED + 1) > APUMMU_VSID_SRAM_TOTAL)
#error APUMMU VSID Overflow
#endif
#define APUMMU_RSV_VSID_IDX_END (254)
#define APUMMU_RSV_VSID_IDX_START (APUMMU_RSV_VSID_IDX_END - APUMMU_VSID_RSV + 1)
#if ((APUMMU_RSV_VSID_IDX_END - APUMMU_RSV_VSID_IDX_START) > APUMMU_VSID_RSV)
#error APUMMU VSID RSV Overflow
#endif
/* Reserve */
#define APUMMU_UPRV_RSV_VSID (APUMMU_RSV_VSID_IDX_END)
#define APUMMU_LOGGER_RSV_VSID (APUMMU_RSV_VSID_IDX_END - 1)
#define APUMMU_APMCU_RSV_VSID (APUMMU_RSV_VSID_IDX_END - 2)
#define APUMMU_GPU_RSV_VSID (APUMMU_RSV_VSID_IDX_END - 3)
/* VSID bit mask */
#define APUMMU_VSID_MAX_MASK_WORD ((APUMMU_VSID_USE_MAX + 32 - 1) / 32)
/* VSID fields */
#define READ_VSID_FIELD(vids, sg, offset, shift, mask) \
((mmio_read_32(APUMMU_VSID_SEGMENT_BASE(vsid, seg, offset)) >> sift) & mask)
#define READ_VSID_FIELD_OFFESET0(vids, sg, shift, mask) \
READ_VSID_FIELD(vids, sg, 0, shift, mask)
#define READ_VSID_FIELD_OFFESET1(vids, sg, shift, mask) \
READ_VSID_FIELD(vids, sg, 1, shift, mask)
#define READ_VSID_FIELD_OFFESET2(vids, sg, shift, mask) \
READ_VSID_FIELD(vids, sg, 2, shift, mask)
/* Get segment offset 0 data - 0x00 */
#define APUMMU_SEGMENT_GET_INPUT(vsid, seg) \
READ_VSID_FIELD_OFFESET0(vsid, seg, 10, 0x3FFFFF)
#define APUMMU_SEGMENT_GET_OFFSET0_RSRV(vsid, seg) \
READ_VSID_FIELD_OFFESET0(vsid, seg, 6, 0xF)
#define APUMMU_SEGMENT_GET_PAGELEN(vsid, seg) \
READ_VSID_FIELD_OFFESET0(vsid, seg, 0, 0x7)
#define APUMMU_SEGMENT_GET_PAGESEL(vsid, seg) \
READ_VSID_FIELD_OFFESET0(vsid, seg, 3, 0x7)
/* Get segment offset 1 data - 0x04 */
#define APUMMU_SEGMENT_GET_IOMMU_EN(vsid, seg) \
READ_VSID_FIELD_OFFESET1(vsid, seg, 1, 0x1)
#define APUMMU_SEGMENT_GET_OFFSET1_RSRV0(vsid, seg) \
READ_VSID_FIELD_OFFESET1(vsid, seg, 2, 0xFF)
#define APUMMU_SEGMENT_GET_OFFSET1_RSRV1(vsid, seg) \
READ_VSID_FIELD_OFFESET1(vsid, seg, 0, 0x1)
#define APUMMU_SEGMENT_GET_OUTPUT(vsid, seg) \
READ_VSID_FIELD_OFFESET1(vsid, seg, 10, 0x3FFFFF)
/* Get segment offset 2 data - 0x08 */
#define APUMMU_SEGMENT_GET_ACP_EN(vsid, seg) \
READ_VSID_FIELD_OFFESET2(vsid, seg, 12, 0x1)
#define APUMMU_SEGMENT_GET_AR_CACHE_ALLOC(vsid, seg) \
READ_VSID_FIELD_OFFESET2(vsid, seg, 4, 0x1)
#define APUMMU_SEGMENT_GET_AR_EXCLU(vsid, seg) \
READ_VSID_FIELD_OFFESET2(vsid, seg, 9, 0x1)
#define APUMMU_SEGMENT_GET_AR_SEPCU(vsid, seg) \
READ_VSID_FIELD_OFFESET2(vsid, seg, 8, 0x1)
#define APUMMU_SEGMENT_GET_AR_SLB_EN(vsid, seg) \
READ_VSID_FIELD_OFFESET2(vsid, seg, 2, 0x1)
#define APUMMU_SEGMENT_GET_AR_SLC_EN(vsid, seg) \
READ_VSID_FIELD_OFFESET2(vsid, seg, 3, 0x1)
#define APUMMU_SEGMENT_GET_AW_CACHE_ALLOC(vsid, seg) \
READ_VSID_FIELD_OFFESET2(vsid, seg, 7, 0x1)
#define APUMMU_SEGMENT_GET_AW_CLR(vsid, seg) \
READ_VSID_FIELD_OFFESET2(vsid, seg, 11, 0x1)
#define APUMMU_SEGMENT_GET_AW_INVALID(vsid, seg) \
READ_VSID_FIELD_OFFESET2(vsid, seg, 10, 0x1)
#define APUMMU_SEGMENT_GET_AW_SLB_EN(vsid, seg) \
READ_VSID_FIELD_OFFESET2(vsid, seg, 5, 0x1)
#define APUMMU_SEGMENT_GET_AW_SLC_EN(vsid, seg) \
READ_VSID_FIELD_OFFESET2(vsid, seg, 6, 0x1)
#define APUMMU_SEGMENT_GET_DOMAIN(vsid, seg) \
READ_VSID_FIELD_OFFESET2(vsid, seg, 13, 0xF)
#define APUMMU_SEGMENT_GET_NS(vsid, seg) \
READ_VSID_FIELD_OFFESET2(vsid, seg, 0, 0x1)
/* Build segment data */
/* Build segment offset 0 (0x00) data */
#define APUMMU_VSID_SEGMENT_00_INPUT(input_adr) (((input_adr) & 0x3fffff) << 10)
#define APUMMU_VSID_SEGMENT_00_PAGESEL(page_sel) (((page_sel) & 0x7) << 3)
#define APUMMU_VSID_SEGMENT_00_PAGELEN(page_len) (((page_len) & 0x7) << 0)
#define APUMMU_VSID_SEGMENT_00_RESV(resv) (((resv) & 0xf) << 6)
#define APUMMU_BUILD_SEGMENT_OFFSET0(input_adr, resv, page_sel, page_len) \
(APUMMU_VSID_SEGMENT_00_INPUT(input_adr) | \
APUMMU_VSID_SEGMENT_00_RESV(resv) | \
APUMMU_VSID_SEGMENT_00_PAGESEL(page_sel) | \
APUMMU_VSID_SEGMENT_00_PAGELEN(page_len))
/* Build segment offset 1 (0x04) data */
#define APUMMU_VSID_SEGMENT_04_IOMMU_EN(iommu_en) (((iommu_en) & 0x1) << 1)
#define APUMMU_VSID_SEGMENT_04_OUTPUT(output_adr) (((output_adr) & 0x3fffff) << 10)
#define APUMMU_VSID_SEGMENT_04_RESV0(resv0) (((resv0) & 0xff) << 2)
#define APUMMU_VSID_SEGMENT_04_RESV1(resv1) (((resv1) & 0x1) << 0)
#define APUMMU_BUILD_SEGMENT_OFFSET1(output_adr, resv0, iommu_en, resv1) \
(APUMMU_VSID_SEGMENT_04_OUTPUT(output_adr) | \
APUMMU_VSID_SEGMENT_04_RESV0(resv0) | \
APUMMU_VSID_SEGMENT_04_IOMMU_EN(iommu_en) | \
APUMMU_VSID_SEGMENT_04_RESV1(resv1))
/* Build segment offset 2 (0x08) data */
#define APUMMU_VSID_SEGMENT_08_DOMAIN_MASK (0xf)
#define APUMMU_VSID_SEGMENT_08_DOMAIN_SHIFT (13)
#define APUMMU_VSID_SEGMENT_08_RESV_MASK (0x7fff)
#define APUMMU_VSID_SEGMENT_08_RESV_SHIFT (17)
#define APUMMU_VSID_SEGMENT_08_DOMAIN(domain) \
(((domain) & APUMMU_VSID_SEGMENT_08_DOMAIN_MASK) << APUMMU_VSID_SEGMENT_08_DOMAIN_SHIFT)
#define APUMMU_VSID_SEGMENT_08_RESV(resv) \
(((resv) & APUMMU_VSID_SEGMENT_08_RESV_MASK) << APUMMU_VSID_SEGMENT_08_RESV_SHIFT)
#define APUMMU_VSID_SEGMENT_08_ACP_EN(acp_en) (((acp_en) & 0x1) << 12)
#define APUMMU_VSID_SEGMENT_08_AR_EXCLU(ar_exclu) (((ar_exclu) & 0x1) << 9)
#define APUMMU_VSID_SEGMENT_08_AR_SEPCU(ar_sepcu) (((ar_sepcu) & 0x1) << 8)
#define APUMMU_VSID_SEGMENT_08_AR_SLB_EN(ar_slb_en) (((ar_slb_en) & 0x1) << 2)
#define APUMMU_VSID_SEGMENT_08_AR_SLC_EN(ar_slc_en) (((ar_slc_en) & 0x1) << 3)
#define APUMMU_VSID_SEGMENT_08_AW_CLR(aw_clr) (((aw_clr) & 0x1) << 11)
#define APUMMU_VSID_SEGMENT_08_AW_INVALID(aw_invalid) (((aw_invalid) & 0x1) << 10)
#define APUMMU_VSID_SEGMENT_08_AW_SLB_EN(aw_slb_en) (((aw_slb_en) & 0x1) << 5)
#define APUMMU_VSID_SEGMENT_08_AW_SLC_EN(aw_slc_en) (((aw_slc_en) & 0x1) << 6)
#define APUMMU_VSID_SEGMENT_08_NS(ns) (((ns) & 0x1) << 0)
#define APUMMU_VSID_SEGMENT_08_RO(ro) (((ro) & 0x1) << 1)
#define APUMMU_VSID_SEGMENT_08_AR_CACHE_ALLOCATE(ar_cache_allocate) \
(((ar_cache_allocate) & 0x1) << 4)
#define APUMMU_VSID_SEGMENT_08_AW_CACHE_ALLOCATE(aw_cache_allocate) \
(((aw_cache_allocate) & 0x1) << 7)
#define APUMMU_BUILD_SEGMENT_OFFSET2(resv, domain, acp_en, aw_clr, \
aw_invalid, ar_exclu, ar_sepcu, \
aw_cache_allocate, aw_slc_en, aw_slb_en, ar_cache_allocate, \
ar_slc_en, ar_slb_en, ro, ns) \
((APUMMU_VSID_SEGMENT_08_RESV(resv)) |\
(APUMMU_VSID_SEGMENT_08_DOMAIN(domain)) |\
(APUMMU_VSID_SEGMENT_08_ACP_EN(acp_en)) |\
(APUMMU_VSID_SEGMENT_08_AW_CLR(aw_clr)) |\
(APUMMU_VSID_SEGMENT_08_AW_INVALID(aw_invalid)) |\
(APUMMU_VSID_SEGMENT_08_AR_EXCLU(ar_exclu)) |\
(APUMMU_VSID_SEGMENT_08_AR_SEPCU(ar_sepcu)) |\
(APUMMU_VSID_SEGMENT_08_AW_CACHE_ALLOCATE(aw_cache_allocate)) |\
(APUMMU_VSID_SEGMENT_08_AW_SLC_EN(aw_slc_en)) |\
(APUMMU_VSID_SEGMENT_08_AW_SLB_EN(aw_slb_en)) |\
(APUMMU_VSID_SEGMENT_08_AR_CACHE_ALLOCATE(ar_cache_allocate)) |\
(APUMMU_VSID_SEGMENT_08_AR_SLC_EN(ar_slc_en)) |\
(APUMMU_VSID_SEGMENT_08_AR_SLB_EN(ar_slb_en)) |\
(APUMMU_VSID_SEGMENT_08_RO(ro)) | (APUMMU_VSID_SEGMENT_08_NS(ns)))
/* Build segment offset 3 (0x0c) data */
#define APUMMU_VSID_SEGMENT_0C_RESV(rsv) (((rsv) & 0x7fffffff) << 0)
#define APUMMU_VSID_SEGMENT_0C_SEG_VALID(seg_valid) (((seg_valid) & 0x1U) << 31)
#define APUMMU_BUILD_SEGMENT_OFFSET3(seg_valid, rsv) \
((uint32_t)APUMMU_VSID_SEGMENT_0C_SEG_VALID(seg_valid) | \
APUMMU_VSID_SEGMENT_0C_RESV(rsv))
#define APUMMU_INT_D2T_TBL0_OFS (0x40)
#define APUSYS_TCM (0x4d100000)
enum {
APUMMU_THD_ID_APMCU_NORMAL = 0,
APUMMU_THD_ID_TEE,
};
int rv_boot(uint32_t uP_seg_output, uint8_t uP_hw_thread,
enum apummu_page_size logger_page_size, uint32_t XPU_seg_output,
enum apummu_page_size XPU_page_size);
#endif

View file

@ -0,0 +1,337 @@
/*
* Copyright (c) 2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/debug.h>
#include <lib/utils_def.h>
#include <platform_def.h>
#include <apusys_devapc.h>
#include <apusys_devapc_def.h>
#include <mtk_mmap_pool.h>
/* AO CONTROL DEVAPC - apu_rcx_ao_infra_dapc_con */
static const struct apc_dom_16 APUSYS_CTRL_DAPC_AO[] = {
/* ctrl index = 0 */
SLAVE_RCX_BULK0("apu_ao_ctl_o-0"),
SLAVE_MD32_APB("apu_ao_ctl_o-1"),
SLAVE_ACP_TCU_SSC("apu_ao_ctl_o-2"),
SLAVE_PTP_THM("apu_ao_ctl_o-3"),
SLAVE_VCORE("apu_ao_ctl_o-4"),
SLAVE_IOMMU0_BANK0("apu_ao_ctl_o-5"),
SLAVE_IOMMU0_BANK1("apu_ao_ctl_o-6"),
SLAVE_IOMMU0_BANK2("apu_ao_ctl_o-7"),
SLAVE_IOMMU0_BANK3("apu_ao_ctl_o-8"),
SLAVE_IOMMU0_BANK4("apu_ao_ctl_o-9"),
/* ctrl index = 10 */
SLAVE_IOMMU1_BANK0("apu_ao_ctl_o-10"),
SLAVE_IOMMU1_BANK1("apu_ao_ctl_o-11"),
SLAVE_IOMMU1_BANK2("apu_ao_ctl_o-12"),
SLAVE_IOMMU1_BANK3("apu_ao_ctl_o-13"),
SLAVE_IOMMU1_BANK4("apu_ao_ctl_o-14"),
SLAVE_S0_SSC("apu_ao_ctl_o-15"),
SLAVE_N0_SSC("apu_ao_ctl_o-16"),
SLAVE_S1_SSC("apu_ao_ctl_o-17"),
SLAVE_N1_SSC("apu_ao_ctl_o-18"),
SLAVE_ACP_SSC("apu_ao_ctl_o-19"),
/* ctrl index = 20 */
SLAVE_WDEC("apu_ao_ctl_o-20"),
SLAVE_SMMU_IP_REG("apu_ao_ctl_o-21"),
SLAVE_SMMU_NSEC("apu_ao_ctl_o-22"),
SLAVE_SMMU_SEC("apu_ao_ctl_o-23"),
SLAVE_ARE0("apu_ao_ctl_o-24"),
SLAVE_ARE1("apu_ao_ctl_o-25"),
SLAVE_SONC("apu_ao_ctl_o-26"),
SLAVE_RPC("apu_ao_ctl_o-28"),
SLAVE_PCU("apu_ao_ctl_o-29"),
SLAVE_AO_CTRL("apu_ao_ctl_o-30"),
/* ctrl index = 30 */
SLAVE_AO_CTRL("apu_ao_ctl_o-31"),
SLAVE_ACC("apu_ao_ctl_o-32"),
SLAVE_SEC("apu_ao_ctl_o-33"),
SLAVE_PLL("apu_ao_ctl_o-34"),
SLAVE_RPC_MDLA("apu_ao_ctl_o-35"),
SLAVE_TOP_PMU("apu_ao_ctl_o-36"),
SLAVE_AO_BCRM("apu_ao_ctl_o-37"),
SLAVE_AO_DAPC_WRAP("apu_ao_ctl_o-38"),
SLAVE_AO_DAPC_CON("apu_ao_ctl_o-39"),
SLAVE_UNDEFINE0("apu_ao_ctl_o-40"),
/* ctrl index = 40 */
SLAVE_UNDEFINE1("apu_ao_ctl_o-41"),
SLAVE_RCX_BULK0("apu_ao_ctl_o-42"),
SLAVE_UNDEFINE2("apu_ao_ctl_o-43"),
SLAVE_UNDEFINE3("apu_ao_ctl_o-44"),
SLAVE_UNDEFINE4("apu_ao_ctl_o-45"),
SLAVE_UNDEFINE5("apu_ao_ctl_o-46"),
SLAVE_UNDEFINE6("apu_ao_ctl_o-47"),
SLAVE_UNDEFINE7("apu_ao_ctl_o-48"),
SLAVE_DATA_BULK("apu_ao_ctl_o-49"),
SLAVE_ACX0_BULK("apu_ao_ctl_o-50"),
/* ctrl index = 50 */
SLAVE_ACX0_AO("apu_ao_ctl_o-51"),
SLAVE_ACX1_BULK("apu_ao_ctl_o-52"),
SLAVE_ACX1_AO("apu_ao_ctl_o-53"),
SLAVE_NCX_BULK("apu_ao_ctl_o-54"),
SLAVE_NCX_AO("apu_ao_ctl_o-55"),
SLAVE_ACX0_BULK("apu_rcx2acx0_o-0"),
SLAVE_ACX0_AO("apu_rcx2acx0_o-1"),
SLAVE_ACX0_BULK("apu_sae2acx0_o-0"),
SLAVE_ACX0_AO("apu_sae2acx0_o-1"),
SLAVE_ACX1_BULK("apu_rcx2acx1_o-0"),
/* ctrl index = 60 */
SLAVE_ACX1_AO("apu_rcx2acx1_o-1"),
SLAVE_ACX1_BULK("apu_sae2acx1_o-0"),
SLAVE_ACX1_AO("apu_sae2acx1_o-1"),
SLAVE_NCX_BULK("apu_rcx2ncx_o-0"),
SLAVE_NCX_AO("apu_rcx2ncx_o-1"),
SLAVE_NCX_BULK("apu_sae2ncx_o-0"),
SLAVE_NCX_AO("apu_sae2ncx_o-1"),
};
/* RCX CONTROL DEVAPC - apu_rcx_infra_dapc_con */
static const struct apc_dom_16 APUSYS_CTRL_DAPC_RCX[] = {
/* ctrl index = 0 */
SLAVE_ACX0_BULK("acx0_apbs-0"),
SLAVE_ACX0_RPC("acx0_apbs-1"),
SLAVE_ACX0_AO_CTRL("acx0_apbs-2"),
SLAVE_UNDEFINE8("acx0_apbs-3"),
SLAVE_ACX1_BULK("acx1_apbs-0"),
SLAVE_ACX1_RPC("acx1_apbs-1"),
SLAVE_ACX1_AO_CTRL("acx1_apbs-2"),
SLAVE_UNDEFINE9("acx1_apbs-3"),
SLAVE_NCX_BULK("ncx_apbs-0"),
SLAVE_NCX_RPC("ncx_apbs-1"),
/* ctrl index = 10 */
SLAVE_NCX_AO_CTRL("ncx_apbs-2"),
SLAVE_UNDEFINE10("ncx_apbs-3"),
SLAVE_MD32_SYSCTRL("md32_apb_s-0"),
SLAVE_MD32_PMU("md32_apb_s-1"),
SLAVE_MD32_WDT("md32_apb_s-2"),
SLAVE_MD32_CACHE("md32_apb_s-3"),
SLAVE_ARE0("apusys_ao-0"),
SLAVE_ARE1("apusys_ao-1"),
SLAVE_SONC("apusys_ao-2"),
SLAVE_RPC("apusys_ao-3"),
/* ctrl index = 20 */
SLAVE_PCU("apusys_ao-4"),
SLAVE_AO_CTRL("apusys_ao-5"),
SLAVE_AO_CTRL("apusys_ao-6"),
SLAVE_SEC("apusys_ao-7"),
SLAVE_PLL("apusys_ao-8"),
SLAVE_RPC_MDLA("apusys_ao-9"),
SLAVE_TOP_PMU("apusys_ao-10"),
SLAVE_AO_BCRM("apusys_ao-11"),
SLAVE_AO_DAPC_WRAP("apusys_ao-12"),
SLAVE_AO_DAPC_CON("apusys_ao-13"),
/* ctrl index = 30 */
SLAVE_VCORE("apusys_ao-14"),
SLAVE_IOMMU0_BANK0("apusys_ao-15"),
SLAVE_IOMMU0_BANK1("apusys_ao-16"),
SLAVE_IOMMU0_BANK2("apusys_ao-17"),
SLAVE_IOMMU0_BANK3("apusys_ao-18"),
SLAVE_IOMMU0_BANK4("apusys_ao-19"),
SLAVE_IOMMU1_BANK0("apu_ao_ctl_o-20"),
SLAVE_IOMMU1_BANK1("apu_ao_ctl_o-21"),
SLAVE_IOMMU1_BANK2("apu_ao_ctl_o-22"),
SLAVE_IOMMU1_BANK3("apu_ao_ctl_o-23"),
/* ctrl index = 40 */
SLAVE_IOMMU1_BANK4("apu_ao_ctl_o-24"),
SLAVE_S0_SSC("apu_ao_ctl_o-25"),
SLAVE_N0_SSC("apu_ao_ctl_o-26"),
SLAVE_S1_SSC("apu_ao_ctl_o-27"),
SLAVE_N1_SSC("apu_ao_ctl_o-28"),
SLAVE_ACP_SSC("apu_ao_ctl_o-29"),
SLAVE_ACP_TCU_SSC("apu_ao_ctl_o-30"),
SLAVE_PTP_THM("apu_ao_ctl_o-31"),
SLAVE_WDEC("apu_ao_ctl_o-32"),
SLAVE_SMMU_IP_REG("apu_ao_ctl_o-33"),
/* ctrl index = 50 */
SLAVE_SMMU_NSEC("apu_ao_ctl_o-34"),
SLAVE_SMMU_SEC("apu_ao_ctl_o-35"),
SLAVE_DATA_BULK("noc_axi"),
SLAVE_MD32_DBG("md32_dbg"),
SLAVE_MDLA_DBG("mdla_dbg"),
SLAVE_INFRA_DBG("apb_infra_dbg"),
SLAVE_LOG_TOP0("apu_logtop-0"),
SLAVE_LOG_TOP1("apu_logtop-1"),
SLAVE_RCX_CFG("apu_rcx_cfg"),
SLAVE_ACX_IPS("apu_acx_ips"),
/* ctrl index = 60 */
SLAVE_SEMA_STIMER("apu_sema_stimer"),
SLAVE_EMI_CFG("apu_emi_cfg"),
SLAVE_CPE_SENSOR("apu_cpe_sensor"),
SLAVE_CPE_COEF("apu_cpe_coef"),
SLAVE_CPE_CTRL("apu_cpe_ctrl"),
SLAVE_TPPA("apu_dfd"),
SLAVE_SENSOR_ACX0_DLA0("apu_sen_acx0_dla0"),
SLAVE_SENSOR_ACX0_VPU("apu_sen_acx0_vpu"),
SLAVE_SENSOR_ACX1_DLA0("apu_sen_acx1_dla0"),
SLAVE_SENSOR_ACX1_VPU("apu_sen_acx1_vpu"),
/* ctrl index = 70 */
SLAVE_SENSOR_NCX_DLA0("apu_sen_ncx_dla0"),
SLAVE_SENSOR_NCX_NVE("apu_sen_ncx_nve"),
SLAVE_RCX_TCU0("noc_cfg-0"),
SLAVE_RCX_TCU1("noc_cfg-1"),
SLAVE_RCX_TCU2("noc_cfg-2"),
SLAVE_RCX_TCU3("noc_cfg-3"),
SLAVE_RCX_TCU4("noc_cfg-4"),
SLAVE_RCX_TCU5("noc_cfg-5"),
SLAVE_RCX_TCU6("noc_cfg-6"),
SLAVE_RCX_NOC_CFG("noc_cfg-7"),
/* ctrl index = 80 */
SLAVE_SCMDQ("apu_hse-0"),
SLAVE_HSE("apu_hse-1"),
SLAVE_MDLA_CORE_CTRL("mdla_cfg-0"),
SLAVE_MDLA_BIU("mdla_cfg-1"),
SLAVE_MDLA_PMU("mdla_cfg-2"),
SLAVE_MDLA_CMDE("mdla_cfg-3"),
SLAVE_EDPA0("apu_edpa-0"),
SLAVE_EDPA1("apu_edpa-1"),
SLAVE_RCX_BCRM("infra_bcrm"),
SLAVE_RCX_DAPC_WRAP("infra_dpac_wrap"),
/* ctrl index = 90 */
SLAVE_RCX_DAPC_CON("infra_dapc_con"),
SLAVE_RCX_CMU("rcx_cmu"),
SLAVE_RCX_ACS("apu_rcx_acs"),
SLAVE_RCX_CBFC("rcx_cbfc"),
SLAVE_ACC("acc"),
};
static enum apusys_apc_err_status set_slave_ctrl_apc(uint32_t slave,
enum apusys_apc_type type,
enum apusys_apc_domain_id domain_id,
enum apusys_apc_perm_type perm)
{
uint32_t apc_register_index;
uint32_t apc_set_index;
uint32_t base = 0;
uint32_t clr_bit;
uint32_t set_bit;
uint32_t slave_num_in_1_dom;
uint32_t slave_num, dom_num;
uint32_t dapc_base;
if (perm >= PERM_NUM) {
ERROR("%s: permission type:0x%x is not supported!\n", __func__, perm);
return APUSYS_APC_ERR_PERMISSION_NOT_SUPPORTED;
}
switch (type) {
case DAPC_AO:
slave_num_in_1_dom = APUSYS_CTRL_DAPC_AO_SLAVE_NUM_IN_1_DOM;
slave_num = APUSYS_CTRL_DAPC_AO_SLAVE_NUM;
dom_num = APUSYS_CTRL_DAPC_AO_DOM_NUM;
dapc_base = APUSYS_CTRL_DAPC_AO_BASE;
break;
case DAPC_RCX:
slave_num_in_1_dom = APUSYS_CTRL_DAPC_RCX_SLAVE_NUM_IN_1_DOM;
slave_num = APUSYS_CTRL_DAPC_RCX_SLAVE_NUM;
dom_num = APUSYS_CTRL_DAPC_RCX_DOM_NUM;
dapc_base = APUSYS_CTRL_DAPC_RCX_BASE;
break;
default:
ERROR("%s: unsupported devapc type: %u\n", __func__, type);
return APUSYS_APC_ERR_GENERIC;
}
apc_register_index = slave / slave_num_in_1_dom;
apc_set_index = slave % slave_num_in_1_dom;
clr_bit = DEVAPC_MASK << (apc_set_index * DEVAPC_DOM_SHIFT);
set_bit = (uint32_t)perm << (apc_set_index * DEVAPC_DOM_SHIFT);
if (slave < slave_num && domain_id < dom_num) {
base = dapc_base + domain_id * DEVAPC_DOM_SIZE
+ apc_register_index * DEVAPC_REG_SIZE;
} else {
ERROR("%s: out of boundary, devapc type: %d, slave: 0x%x, domain_id: 0x%x\n",
__func__, type, slave, domain_id);
return APUSYS_APC_ERR_OUT_OF_BOUNDARY;
}
if (!base)
return APUSYS_APC_ERR_GENERIC;
mmio_clrsetbits_32(base, clr_bit, set_bit);
return APUSYS_APC_OK;
}
static enum apusys_apc_err_status set_slave_ao_ctrl_apc(uint32_t slave,
enum apusys_apc_domain_id domain_id,
enum apusys_apc_perm_type perm)
{
return set_slave_ctrl_apc(slave, DAPC_AO, domain_id, perm);
}
static enum apusys_apc_err_status set_slave_rcx_ctrl_apc(uint32_t slave,
enum apusys_apc_domain_id domain_id,
enum apusys_apc_perm_type perm)
{
return set_slave_ctrl_apc(slave, DAPC_RCX, domain_id, perm);
}
static void apusys_devapc_init(uint32_t base)
{
mmio_write_32(APUSYS_DAPC_CON(base), APUSYS_DAPC_CON_VIO_MASK);
}
int apusys_devapc_ao_init(void)
{
int32_t ret = APUSYS_APC_OK;
apusys_devapc_init(APUSYS_CTRL_DAPC_AO_BASE);
ret = SET_APUSYS_DAPC_V1(APUSYS_CTRL_DAPC_AO, set_slave_ao_ctrl_apc);
if (ret) {
ERROR("[APUAPC_AO] %s: set_apusys_ao_ctrl_dapc failed\n", __func__);
return ret;
}
#ifdef DUMP_CFG
DUMP_APUSYS_DAPC_V1(APUSYS_CTRL_DAPC_AO);
#endif
INFO("[APUAPC_AO] %s done\n", __func__);
return ret;
}
int apusys_devapc_rcx_init(void)
{
int32_t ret = APUSYS_APC_OK;
apusys_devapc_init(APUSYS_CTRL_DAPC_RCX_BASE);
ret = SET_APUSYS_DAPC_V1(APUSYS_CTRL_DAPC_RCX, set_slave_rcx_ctrl_apc);
if (ret) {
ERROR("[APUAPC_RCX] %s: set_slave_rcx_ctrl_apc failed\n", __func__);
return ret;
}
#ifdef DUMP_CFG
DUMP_APUSYS_DAPC_V1(APUSYS_CTRL_DAPC_RCX);
#endif
INFO("[APUAPC_RCX] %s done\n", __func__);
return ret;
}

View file

@ -0,0 +1,18 @@
/*
* Copyright (c) 2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef APUSYS_DEVAPC_H
#define APUSYS_DEVAPC_H
enum apusys_apc_type {
DAPC_AO = 0,
DAPC_RCX
};
int apusys_devapc_ao_init(void);
int apusys_devapc_rcx_init(void);
#endif /* APUSYS_DEVAPC_H */

View file

@ -0,0 +1,144 @@
/*
* Copyright (c) 2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef APUSYS_DEVAPC_DEF_H
#define APUSYS_DEVAPC_DEF_H
#include <lib/mmio.h>
#include <devapc/apusys_dapc_v1.h>
/* Control */
#define SLAVE_RCX_BULK0 SLAVE_FORBID_EXCEPT_D0_D11_NO_PROTECT_D3_D5_D8_SEC_RW
#define SLAVE_RCX_BULK1 SLAVE_FORBID_EXCEPT_D0_NO_PROTECT_D5_D8_SEC_RW
#define SLAVE_MD32_APB SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D3_D5_SEC_RW
#define SLAVE_ACP_TCU_SSC SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_VCORE SLAVE_FORBID_EXCEPT_D0_NO_PROTECT_D3_D5_SEC_RW
#define SLAVE_WDEC SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
#define SLAVE_SMMU_IP_REG SLAVE_FORBID_EXCEPT_D3_D5_SEC_RW_D0_D4_D11_NO_PROTECT
#define SLAVE_SMMU_NSEC SLAVE_FORBID_EXCEPT_D5_SEC_RW_D0_NO_PROTECT
#define SLAVE_SMMU_SEC SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
#define SLAVE_RPC SLAVE_FORBID_EXCEPT_D3_D5_SEC_RW_D0_D11_NO_PROTECT
#define SLAVE_PCU SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D3_D5_SEC_RW
#define SLAVE_AO_CTRL SLAVE_FORBID_EXCEPT_D0_D3_D5_SEC_RW
#define SLAVE_ACC SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D3_D5_SEC_RW
#define SLAVE_PLL SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_D8_SEC_RW
#define SLAVE_SEC SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
#define SLAVE_ARE0 SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
#define SLAVE_ARE1 SLAVE_FORBID_EXCEPT_D0_D11_NO_PROTECT_D3_D5_D8_SEC_RW
#define SLAVE_RPC_MDLA SLAVE_FORBID_EXCEPT_D5_D8_SEC_RW
#define SLAVE_MDLA_DBG SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_TOP_PMU SLAVE_FORBID_EXCEPT_D5_D8_SEC_RW
#define SLAVE_UNDEFINE0 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_UNDEFINE1 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_UNDEFINE2 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_UNDEFINE3 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_UNDEFINE4 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_UNDEFINE5 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_UNDEFINE6 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_UNDEFINE7 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_UNDEFINE8 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_UNDEFINE9 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_UNDEFINE10 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_DATA_BULK SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
#define SLAVE_AO_BCRM SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_AO_DAPC_WRAP SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_AO_DAPC_CON SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
#define SLAVE_ACX0_AO SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
#define SLAVE_ACX0_BULK SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
#define SLAVE_ACX0_RPC SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
#define SLAVE_ACX0_AO_CTRL SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_ACX1_AO SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
#define SLAVE_ACX1_BULK SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
#define SLAVE_ACX1_RPC SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
#define SLAVE_ACX1_AO_CTRL SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_NCX_AO SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
#define SLAVE_NCX_BULK SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
#define SLAVE_NCX_RPC SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_NCX_AO_CTRL SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_MD32_SYSCTRL SLAVE_FORBID_EXCEPT_D0_D3_D5_SEC_RW
#define SLAVE_MD32_PMU SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D3_D5_SEC_RW
#define SLAVE_LOG_TOP0 SLAVE_FORBID_EXCEPT_D0_D5_D7_D14_NO_PROTECT
#define SLAVE_LOG_TOP1 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_RCX_CFG SLAVE_FORBID_EXCEPT_D0_NO_PROTECT_D3_D5_SEC_RW
#define SLAVE_ACX_IPS SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_RCX_TCU0 SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
#define SLAVE_RCX_TCU1 SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
#define SLAVE_RCX_TCU2 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_RCX_TCU3 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_RCX_TCU4 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_RCX_TCU5 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_RCX_TCU6 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_RCX_NOC_CFG SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
#define SLAVE_MDLA_CORE_CTRL SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
#define SLAVE_MDLA_BIU SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_MDLA_PMU SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_MDLA_CMDE SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
#define SLAVE_EDPA0 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_EDPA1 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_RCX_CMU SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
#define SLAVE_RCX_ACS SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
#define SLAVE_MD32_WDT SLAVE_FORBID_EXCEPT_D0_D3_D5_SEC_RW
#define SLAVE_MD32_CACHE SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
#define SLAVE_MD32_DBG SLAVE_FORBID_EXCEPT_D0_NO_PROTECT_D5_SEC_RW
#define SLAVE_INFRA_DBG SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
#define SLAVE_IOMMU0_BANK0 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_IOMMU0_BANK1 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_IOMMU0_BANK2 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_IOMMU0_BANK3 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_IOMMU0_BANK4 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_IOMMU1_BANK0 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_IOMMU1_BANK1 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_IOMMU1_BANK2 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_IOMMU1_BANK3 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_IOMMU1_BANK4 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_S0_SSC SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_N0_SSC SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_ACP_SSC SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_S1_SSC SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_N1_SSC SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_SEMA_STIMER SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_EMI_CFG SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_CPE_SENSOR SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_CPE_COEF SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_CPE_CTRL SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_TPPA SLAVE_FORBID_EXCEPT_D5_D8_SEC_RW
#define SLAVE_SENSOR_ACX0_DLA0 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_SENSOR_ACX0_VPU SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_SENSOR_ACX1_DLA0 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_SENSOR_ACX1_VPU SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_SENSOR_NCX_DLA0 SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_SENSOR_NCX_NVE SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_RCX_BCRM SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_RCX_DAPC_WRAP SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_RCX_DAPC_CON SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
#define SLAVE_HSE SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_RCX_CBFC SLAVE_FORBID_EXCEPT_D5_SEC_RW
#define SLAVE_SONC SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
#define SLAVE_SCMDQ SLAVE_FORBID_EXCEPT_D5_SEC_RW
#if DEBUG
#define SLAVE_PTP_THM SLAVE_FORBID_EXCEPT_D0_NO_PROTECT_D5_SEC_RW
#else
#define SLAVE_PTP_THM SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
#endif
/* Power Domain: AO */
#define APUSYS_CTRL_DAPC_AO_SLAVE_NUM_IN_1_DOM (16)
#define APUSYS_CTRL_DAPC_AO_DOM_NUM (16)
#define APUSYS_CTRL_DAPC_AO_SLAVE_NUM (67) /* 0~66 */
#define DEVAPC_MASK (0x3U)
#define DEVAPC_DOM_SHIFT (2)
/* Power Domain: RCX */
#define APUSYS_CTRL_DAPC_RCX_SLAVE_NUM_IN_1_DOM (16)
#define APUSYS_CTRL_DAPC_RCX_DOM_NUM (16)
#define APUSYS_CTRL_DAPC_RCX_SLAVE_NUM (95) /* 0~94 */
/* Dump Config */
#define DUMP_CFG
#endif

View file

@ -0,0 +1,390 @@
/*
* Copyright (c) 2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <inttypes.h>
#define SPMI_ENABLE (0)
#if SPMI_ENABLE
#include <include/drivers/spmi_api.h>
#endif
#include <common/debug.h>
#include <drivers/delay_timer.h>
#include <lib/mmio.h>
#include <lib/spinlock.h>
#include <lib/utils_def.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include "apusys_power.h"
static void apu_w_are(int entry, uint32_t reg, uint32_t data)
{
uint32_t are_entry_addr;
are_entry_addr = APUSYS_BASE + APU_ARE + ARE_REG_SIZE * ARE_ENTRY(entry);
mmio_write_32(are_entry_addr, reg);
mmio_write_32((are_entry_addr + ARE_REG_SIZE), data);
}
static void get_pll_pcw(uint32_t clk_rate, uint32_t *r1, uint32_t *r2)
{
unsigned int fvco = clk_rate;
unsigned int pcw_val;
unsigned int postdiv_val = 1;
unsigned int postdiv_reg = 0;
while (fvco <= OUT_CLK_FREQ_MIN) {
postdiv_val = postdiv_val << 1;
postdiv_reg = postdiv_reg + 1;
fvco = fvco << 1;
}
pcw_val = (fvco * (1 << DDS_SHIFT)) / BASIC_CLK_FREQ;
if (postdiv_reg == 0) {
pcw_val = pcw_val * 2;
postdiv_val = postdiv_val << 1;
postdiv_reg = postdiv_reg + 1;
}
*r1 = postdiv_reg;
*r2 = pcw_val;
}
static void buck_off_by_pcu(uint32_t ofs, uint32_t shift, uint32_t slv_id)
{
uint32_t pmif_id = 0x0;
int retry = 10;
mmio_setbits_32(APUSYS_PCU + APU_PCUTOP_CTRL_SET, PMIC_IRQ_EN);
mmio_write_32(APUSYS_PCU + APU_PCU_PMIC_TAR_BUF1,
(ofs << PMIC_OFF_ADDR_OFF) | BIT(shift));
mmio_write_32(APUSYS_PCU + APU_PCU_PMIC_TAR_BUF2,
(slv_id << PMIC_SLVID_OFF) | (pmif_id << PMIC_PMIFID_OFF) | PCU_BUCK_OFF_CMD);
mmio_write_32(APUSYS_PCU + APU_PCU_PMIC_CMD, PMIC_CMD_EN);
while ((mmio_read_32(APUSYS_PCU + APU_PCU_PMIC_IRQ) & PMIC_CMD_IRQ) == 0) {
udelay(10);
if (--retry < 0)
ERROR("%s wait APU_PCU_PMIC_IRQ timeout !\n", __func__);
}
mmio_write_32(APUSYS_PCU + APU_PCU_PMIC_IRQ, PMIC_CMD_IRQ);
}
static void apu_buck_off_cfg(void)
{
mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(10));
mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(9));
mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(12));
mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(14));
mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(10));
mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(9));
mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(12));
mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(14));
udelay(1);
mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, BUCK_PROT_REQ_SET);
udelay(1);
mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, SRAM_AOC_LHENB_SET);
udelay(1);
mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, SRAM_AOC_ISO_SET);
udelay(1);
mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, PLL_AOC_ISO_EN_SET);
udelay(1);
mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, BUCK_ELS_EN_SET);
udelay(1);
mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, BUCK_AO_RST_B_CLR);
udelay(1);
buck_off_by_pcu(BUCK_VAPU_PMIC_REG_EN_CLR_ADDR, BUCK_VAPU_PMIC_REG_EN_SHIFT,
BUCK_VAPU_PMIC_ID);
mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(6));
udelay(1);
mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(7));
udelay(1);
mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(6));
udelay(1);
mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(7));
udelay(1);
}
static void apu_acc_init(void)
{
uint32_t top_acc_base_arr[] = {MNOC_ACC_BASE, UP_ACC_BASE};
uint32_t eng_acc_base_arr[] = {MVPU_ACC_BASE, MDLA_ACC_BASE};
int acc_idx;
int are_idx = ACC_ENTRY_BEGIN;
uint32_t base_reg;
for (acc_idx = 0 ; acc_idx < ARRAY_SIZE(top_acc_base_arr) ; acc_idx++) {
base_reg = APUSYS_ACC + top_acc_base_arr[acc_idx];
#if CFG_APU_ARDCM_ENABLE
apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL1, APU_ARDCM_CTRL1_VAL_0);
apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL0, APU_ARDCM_CTRL0_VAL_0);
apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL1, APU_ARDCM_CTRL1_VAL_1);
apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL0, APU_ARDCM_CTRL0_VAL_1);
#endif
apu_w_are(are_idx++, base_reg + APU_ACC_CONFG_CLR0, CGEN_SOC);
apu_w_are(are_idx++, base_reg + APU_ACC_CONFG_SET0, HW_CTRL_EN);
}
for (acc_idx = 0 ; acc_idx < ARRAY_SIZE(eng_acc_base_arr) ; acc_idx++) {
base_reg = APUSYS_ACC + eng_acc_base_arr[acc_idx];
#if CFG_APU_ARDCM_ENABLE
apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL1, APU_ARDCM_CTRL1_VAL_0);
apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL0, APU_ARDCM_CTRL0_VAL_0);
apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL1, APU_ARDCM_CTRL1_VAL_1);
apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL0, APU_ARDCM_CTRL0_VAL_1);
#endif
apu_w_are(are_idx++, base_reg + APU_ACC_CONFG_CLR0, CGEN_SOC);
apu_w_are(are_idx++, base_reg + APU_ACC_CONFG_SET0, HW_CTRL_EN);
apu_w_are(are_idx++, base_reg + APU_ACC_AUTO_CTRL_SET0, CLK_REQ_SW_EN);
}
}
static void apu_pll_init(void)
{
uint32_t pll_base_arr[] = {MNOC_PLL_BASE, UP_PLL_BASE, MVPU_PLL_BASE, MDLA_PLL_BASE};
int32_t pll_freq_out[] = {
APUPLL0_DEFAULT_FREQ,
APUPLL1_DEFAULT_FREQ,
APUPLL2_DEFAULT_FREQ,
APUPLL3_DEFAULT_FREQ
};
uint32_t pcw_val, posdiv_val;
int pll_idx, are_idx;
uint32_t base_reg;
mmio_setbits_32(APUSYS_BASE + APU_ARE, ARE_RCX_AO_EN);
mmio_setbits_32(APUSYS_BASE + APU_ARE_REG, ARE_RCX_AO_EN);
mmio_write_32(APUSYS_BASE + APU_ARE + ARE_RCX_AO_CONFIG, ARE_ENTRY(RCX_AO_BEGIN) |
(ARE_ENTRIES(RCX_AO_BEGIN, RCX_AO_END) << ARE_RCX_AO_CONFIG_HIGH_OFF));
are_idx = PLL_ENTRY_BEGIN;
for (pll_idx = 0 ; pll_idx < ARRAY_SIZE(pll_base_arr) ; pll_idx++) {
base_reg = APUSYS_PLL + pll_base_arr[pll_idx];
apu_w_are(are_idx++, base_reg + RG_PLLGP_LVR_REFSEL, RG_PLLGP_LVR_REFSEL_VAL);
apu_w_are(are_idx++, base_reg + PLL1CPLL_FHCTL_HP_EN, FHCTL_CTRL);
apu_w_are(are_idx++, base_reg + PLL1CPLL_FHCTL_RST_CON, FHCTL_NO_RESET);
apu_w_are(are_idx++, base_reg + PLL1CPLL_FHCTL_CLK_CON, FHCTL_CLKEN);
apu_w_are(are_idx++, base_reg + PLL1CPLL_FHCTL0_CFG,
FHCTL_HOPPING_EN | FHCTL_SFSTR0_EN);
posdiv_val = 0;
pcw_val = 0;
get_pll_pcw(pll_freq_out[pll_idx], &posdiv_val, &pcw_val);
apu_w_are(are_idx++, base_reg + PLL1C_PLL1_CON1,
((0x1U << RG_PLL_SDM_PCW_CHG_OFF) |
(posdiv_val << RG_PLL_POSDIV_OFF) | pcw_val));
apu_w_are(are_idx++, base_reg + PLL1CPLL_FHCTL0_DDS,
((0x1U << FHCTL0_PLL_TGL_ORG) | pcw_val));
}
}
static void apu_are_init(void)
{
int entry = 0;
mmio_clrbits_32(APUSYS_BASE + APU_ARE, 0xFFFU << ARE_VCORE_OFF);
mmio_setbits_32(APUSYS_BASE + APU_ARE, ARE_VCORE_EN);
mmio_setbits_32(APUSYS_BASE + APU_ARE_REG, ARE_VCORE_EN);
for (entry = ARE_CONF_START; entry < ARE_CONF_END; entry += 4)
mmio_write_32(APUSYS_BASE + APU_ARE + entry, 0);
}
static void apu_rpclite_init(void)
{
uint32_t sleep_type_offset[] = {
APU_RPC_SW_TYPE1_OFF,
APU_RPC_SW_TYPE2_OFF,
APU_RPC_SW_TYPE3_OFF,
APU_RPC_SW_TYPE4_OFF
};
uint32_t rpc_lite_base[] = {
APU_ACX0_RPC_LITE,
APU_ACX1_RPC_LITE,
APU_ACX2_RPC_LITE,
};
int ofs_idx, rpc_lite_idx;
uint32_t base;
for (rpc_lite_idx = 0; rpc_lite_idx < ARRAY_SIZE(rpc_lite_base); rpc_lite_idx++) {
base = APUSYS_BASE + rpc_lite_base[rpc_lite_idx];
for (ofs_idx = 0; ofs_idx < ARRAY_SIZE(sleep_type_offset); ofs_idx++)
mmio_clrbits_32(base + sleep_type_offset[ofs_idx],
SW_TYPE_MVPU_MDLA_RV);
mmio_setbits_32(base + APU_RPC_TOP_SEL, TOP_SEL_VAL);
}
}
static void apu_rpc_mdla_init(void)
{
mmio_clrbits_32(APUSYS_BASE + APU_RPCTOP_MDLA + APU_RPC_SW_TYPE0_OFF, SW_TYPE_MVPU_MDLA_RV);
}
static void apu_rpc_init(void)
{
mmio_write_32(APUSYS_RPC + APU_RPC_SW_TYPE0_OFF, RPC_TYPE_INIT_VAL);
mmio_setbits_32(APUSYS_RPC + APU_RPC_TOP_SEL, RPC_TOP_SEL_VAL);
#if !CFG_CTL_RPC_BY_CE
mmio_clrbits_32(APUSYS_RPC + APU_RPC_TOP_SEL, CE_ENABLE);
#endif
mmio_setbits_32(APUSYS_RPC + APU_RPC_TOP_SEL_1, BUCK_PROT_SEL);
}
static int apu_pcu_init(void)
{
uint32_t pmif_id = 0x0;
uint32_t slave_id = BUCK_VAPU_PMIC_ID;
uint32_t en_set_offset = BUCK_VAPU_PMIC_REG_EN_SET_ADDR;
uint32_t en_clr_offset = BUCK_VAPU_PMIC_REG_EN_CLR_ADDR;
uint32_t en_shift = BUCK_VAPU_PMIC_REG_EN_SHIFT;
#if SPMI_ENABLE
struct spmi_device *vsram_sdev;
#endif
unsigned char vsram = 0;
mmio_write_32(APUSYS_PCU + APU_PCUTOP_CTRL_SET, AUTO_BUCK_EN);
mmio_write_32((APUSYS_PCU + APU_PCU_BUCK_STEP_SEL), BUCK_STEP_SEL_VAL);
#if SPMI_ENABLE
vsram_sdev = get_spmi_device(SPMI_MASTER_1, SPMI_SLAVE_4);
if (!vsram_sdev) {
ERROR("[APUPW] VSRAM BUCK4 get device fail\n");
return -1;
}
if (spmi_ext_register_readl(vsram_sdev, MT6363_RG_BUCK_VBUCK4_VOSEL_ADDR, &vsram, 1)) {
ERROR("[APUPW] VSRAM BUCK4 read fail\n");
return -1;
}
#endif
mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_DAT0_L,
(BUCK_VAPU_PMIC_REG_VOSEL_ADDR << PMIC_OFF_ADDR_OFF) | vsram);
mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_DAT0_H,
(slave_id << PMIC_SLVID_OFF) | (pmif_id << PMIC_PMIFID_OFF) | PCU_CMD_OP_W);
mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_DAT1_L,
(en_set_offset << PMIC_OFF_ADDR_OFF) | (0x1U << en_shift));
mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_DAT1_H,
(slave_id << PMIC_SLVID_OFF) | (pmif_id << PMIC_PMIFID_OFF) | PCU_CMD_OP_W);
mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_OFF_DAT0_L,
(en_clr_offset << PMIC_OFF_ADDR_OFF) | (0x1U << en_shift));
mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_OFF_DAT0_H,
(slave_id << PMIC_SLVID_OFF) | (pmif_id << PMIC_PMIFID_OFF) | PCU_CMD_OP_W);
mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_SLE0, 0);
mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_SLE1, VAPU_BUCK_ON_SETTLE_TIME);
return 0;
}
static void apu_aoc_init(void)
{
uint32_t reg;
mmio_setbits_32(SPM_BASE + 0xF6C, BIT(4));
mmio_clrbits_32(SPM_BASE + 0x414, BIT(1));
mmio_write_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CONFIG, APUSYS_AO_SRAM_EN);
udelay(1);
reg = APUSYS_AO_CTL + APUSYS_AO_SRAM_SET;
#if !CFG_CTL_RPC_BY_CE
mmio_setbits_32(reg, BIT(8));
udelay(1);
mmio_setbits_32(reg, BIT(11));
udelay(1);
mmio_setbits_32(reg, BIT(13));
udelay(1);
mmio_clrbits_32(reg, BIT(8));
udelay(1);
mmio_clrbits_32(reg, BIT(11));
udelay(1);
mmio_clrbits_32(reg, BIT(13));
#else
mmio_setbits_32(reg, BIT(9));
mmio_setbits_32(reg, BIT(12));
mmio_setbits_32(reg, BIT(14));
mmio_clrbits_32(reg, BIT(9));
mmio_clrbits_32(reg, BIT(12));
mmio_clrbits_32(reg, BIT(14));
udelay(1);
#endif
reg = APUSYS_RPC + APU_RPC_HW_CON;
mmio_write_32(reg, BUCK_ELS_EN_CLR);
udelay(1);
mmio_write_32(reg, BUCK_AO_RST_B_SET);
udelay(1);
mmio_write_32(reg, BUCK_PROT_REQ_CLR);
udelay(1);
mmio_write_32(reg, SRAM_AOC_ISO_CLR);
udelay(1);
mmio_write_32(reg, PLL_AOC_ISO_EN_CLR);
udelay(1);
}
static int init_hw_setting(void)
{
int ret;
apu_aoc_init();
ret = apu_pcu_init();
apu_rpc_init();
apu_rpc_mdla_init();
apu_rpclite_init();
apu_are_init();
apu_pll_init();
apu_acc_init();
apu_buck_off_cfg();
return ret;
}
int apusys_power_init(void)
{
int ret;
ret = init_hw_setting();
if (ret != 0)
ERROR("%s init HW failed\n", __func__);
else
INFO("%s init HW done\n", __func__);
mmio_write_32(APU_ACE_HW_FLAG_DIS, APU_ACE_DIS_FLAG_VAL);
return ret;
}

View file

@ -0,0 +1,225 @@
/*
* Copyright (c) 2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef APUSYS_POWER_H
#define APUSYS_POWER_H
#include <platform_def.h>
#define CFG_APU_ARDCM_ENABLE (0)
#define CFG_CTL_RPC_BY_CE (1)
#define APUPLL0_DEFAULT_FREQ (800)
#define APUPLL1_DEFAULT_FREQ (960)
#define APUPLL2_DEFAULT_FREQ (1200)
#define APUPLL3_DEFAULT_FREQ (1230)
enum t_acx_id {
D_ACX0 = 0,
ACX0,
ACX1,
ACX2,
CLUSTER_NUM,
RCX,
};
enum rcx_ao_range {
RCX_AO_BEGIN = 0,
PLL_ENTRY_BEGIN = 0,
PLL_ENTRY_END = 27,
ACC_ENTRY_BEGIN = 28,
ACC_ENTRY_END = 37,
RCX_AO_END = 37,
};
#define SYS_VLP (0x000000)
#define SYS_SPM (0x000000)
#define APU_RCX (0x020000)
#define APU_RCX_DLA (0x040000)
#define APU_ARE (0x0a0000)
#define APU_ARE_REG (0x0b0000)
#define APU_VCORE (0x0e0000)
#define APU_MD32_MBOX (0x0e1000)
#define APU_RPC (0x0f0000)
#define APU_PCU (0x0f1000)
#define APU_AO_CTL (0x0f2000)
#define APU_ACC (0x0f3000)
#define APU_PLL (0x0f6000)
#define APU_RPCTOP_MDLA (0x0F7400)
#define APU_ACX0 (0x100000)
#define APU_ACX0_RPC_LITE (0x140000)
#define APU_ACX1 (0x200000)
#define APU_ACX1_RPC_LITE (0x240000)
#define APU_ACX2 (0x300000)
#define APU_ACX2_RPC_LITE (0x340000)
/* APU GRP offset define */
#define APU_GRP_0_BASE (0x0000)
#define APU_GRP_1_BASE (0x0400)
#define APU_GRP_2_BASE (0x0800)
#define APU_GRP_3_BASE (0x0C00)
#define MDLA_PLL_BASE APU_GRP_0_BASE
#define MVPU_PLL_BASE APU_GRP_1_BASE
#define MNOC_PLL_BASE APU_GRP_2_BASE
#define UP_PLL_BASE APU_GRP_3_BASE
#define MDLA_ACC_BASE APU_GRP_0_BASE
#define MVPU_ACC_BASE APU_GRP_1_BASE
#define MNOC_ACC_BASE APU_GRP_2_BASE
#define UP_ACC_BASE APU_GRP_3_BASE
/* RPC / RPC_LITE control */
#define APU_RPC_SW_TYPE0_OFF (0x200)
#define APU_RPC_SW_TYPE1_OFF (0x204)
#define APU_RPC_SW_TYPE2_OFF (0x208)
#define APU_RPC_SW_TYPE3_OFF (0x20C)
#define APU_RPC_SW_TYPE4_OFF (0x210)
#define SW_TYPE_MVPU_MDLA_RV BIT(0)
#define CE_ENABLE BIT(10)
#define BUCK_PROT_SEL BIT(20)
#define RPC_TYPE_INIT_VAL (0x18)
#define TOP_SEL_VAL (0xB2)
#define RPC_TOP_SEL_VAL (0xB800D50F)
#define APUSYS_AO_CTL (APUSYS_BASE + APU_AO_CTL)
#define APUSYS_RPC (APUSYS_BASE + APU_RPC)
#define APUSYS_ACC (APUSYS_BASE + APU_ACC)
#define APUSYS_PLL (APUSYS_BASE + APU_PLL)
#define APUSYS_PCU (APUSYS_BASE + APU_PCU)
/* ARE control */
#define ARE_VCORE_EN BIT(20)
#define ARE_RCX_AO_EN BIT(21)
#define ARE_VCORE_OFF (20)
#define ARE_CONF_START (0x04)
#define ARE_CONF_END (0x6C)
#define ARE_REG_SIZE (4)
/* ACC offset */
#define APU_ACC_CONFG_SET0 (0x000)
#define APU_ACC_CONFG_CLR0 (0x010)
#define APU_ACC_AUTO_CTRL_SET0 (0x084)
#define APU_ARDCM_CTRL0 (0x100)
#define APU_ARDCM_CTRL1 (0x104)
/* ACC control */
#define APU_ARDCM_CTRL0_VAL_0 (0x00000016)
#define APU_ARDCM_CTRL0_VAL_1 (0x00000036)
#define APU_ARDCM_CTRL1_VAL_0 (0x00001006)
#define APU_ARDCM_CTRL1_VAL_1 (0x07F0F006)
#define CGEN_SOC BIT(2)
#define CLK_REQ_SW_EN BIT(8)
#define HW_CTRL_EN BIT(15)
/* APU PLL1C offset */
#define RG_PLLGP_LVR_REFSEL (0x204)
#define PLL1C_PLL1_CON1 (0x20C)
#define PLL1CPLL_FHCTL_HP_EN (0x300)
#define PLL1CPLL_FHCTL_CLK_CON (0x308)
#define PLL1CPLL_FHCTL_RST_CON (0x30C)
#define PLL1CPLL_FHCTL0_CFG (0x314)
#define PLL1CPLL_FHCTL0_DDS (0x31C)
/* PLL control */
#define RG_PLLGP_LVR_REFSEL_VAL (0x3)
#define FHCTL_CTRL (0x1)
#define FHCTL_NO_RESET (0x1)
#define FHCTL_CLKEN (0x1)
#define FHCTL_HOPPING_EN BIT(0)
#define FHCTL_SFSTR0_EN BIT(2)
#define RG_PLL_SDM_PCW_CHG_OFF (31)
#define RG_PLL_POSDIV_OFF (24)
#define FHCTL0_PLL_TGL_ORG (31)
/* RPC offset define */
#define APU_RPC_TOP_SEL (0x0004)
#define APU_RPC_TOP_SEL_1 (0x0018)
#define APU_RPC_HW_CON (0x001C)
#define APU_RPC_STATUS_1 (0x0034)
#define APU_RPC_INTF_PWR_RDY (0x0044)
/* RPC control */
#define SRAM_AOC_LHENB_SET BIT(4)
#define SRAM_AOC_ISO_SET BIT(6)
#define SRAM_AOC_ISO_CLR BIT(7)
#define PLL_AOC_ISO_EN_SET BIT(8)
#define PLL_AOC_ISO_EN_CLR BIT(9)
#define BUCK_ELS_EN_SET BIT(10)
#define BUCK_ELS_EN_CLR BIT(11)
#define BUCK_AO_RST_B_SET BIT(12)
#define BUCK_AO_RST_B_CLR BIT(13)
#define BUCK_PROT_REQ_SET BIT(14)
#define BUCK_PROT_REQ_CLR BIT(15)
/* mt6373_vbuck2 */
#define MT6373_SLAVE_ID (0x5)
#define MT6373_RG_BUCK_VBUCK2_SET (0x241)
#define MT6373_RG_BUCK_VBUCK2_CLR (0x242)
#define MT6373_RG_BUCK_VBUCK2_EN_SHIFT (2)
#define MT6373_RG_BUCK_VBUCK2_VOSEL_ADDR (0x24e)
/* PCU initial data */
#define APU_PCUTOP_CTRL_SET (0x0)
#define APU_PCU_BUCK_STEP_SEL (0x0030)
#define APU_PCU_BUCK_ON_DAT0_L (0x0080)
#define APU_PCU_BUCK_ON_DAT0_H (0x0084)
#define APU_PCU_BUCK_ON_DAT1_L (0x0088)
#define APU_PCU_BUCK_ON_DAT1_H (0x008C)
#define APU_PCU_BUCK_OFF_DAT0_L (0x00A0)
#define APU_PCU_BUCK_OFF_DAT0_H (0x00A4)
#define APU_PCU_BUCK_ON_SLE0 (0x00C0)
#define APU_PCU_BUCK_ON_SLE1 (0x00C4)
#define VAPU_BUCK_ON_SETTLE_TIME (0x00C8)
#define APU_PCU_PMIC_TAR_BUF1 (0x0190)
#define APU_PCU_PMIC_TAR_BUF2 (0x0194)
#define APU_PCU_PMIC_CMD (0x0184)
#define APU_PCU_PMIC_IRQ (0x0180)
/* PCU control */
#define PMIC_CMD_IRQ BIT(0)
#define PMIC_IRQ_EN BIT(2)
#define AUTO_BUCK_EN BIT(3)
#define PMIC_PMIFID_OFF (3)
#define PMIC_SLVID_OFF (4)
#define PCU_CMD_OP_W (0x7)
#define PMIC_OFF_ADDR_OFF (16)
#define PMIC_CMD_EN (0x1)
#define BUCK_STEP_SEL_VAL (0x13)
#define PCU_BUCK_OFF_CMD (0x7)
/* sram_core: mt6363_vbuck4 */
#define MT6363_RG_BUCK_VBUCK4_VOSEL_ADDR (0x250)
/* sub_pmic */
#define BUCK_VAPU_PMIC_ID MT6373_SLAVE_ID
#define BUCK_VAPU_PMIC_REG_VOSEL_ADDR MT6373_RG_BUCK_VBUCK2_VOSEL_ADDR
#define BUCK_VAPU_PMIC_REG_EN_SET_ADDR MT6373_RG_BUCK_VBUCK2_SET
#define BUCK_VAPU_PMIC_REG_EN_CLR_ADDR MT6373_RG_BUCK_VBUCK2_CLR
#define BUCK_VAPU_PMIC_REG_EN_SHIFT MT6373_RG_BUCK_VBUCK2_EN_SHIFT
/* vlp offset define */
#define APUSYS_AO_SRAM_CONFIG (0x70)
#define APUSYS_AO_SRAM_SET (0x74)
#define APUSYS_AO_SRAM_CLR (0x78)
#define APUSYS_AO_SRAM_EN (0x1)
#define ARE_ENTRIES(x, y) ((((y) - (x)) + 1) * 2)
#define ARE_ENTRY(x) (((x) * 2) + 36)
#define ARE_RCX_AO_CONFIG (0x0014)
#define ARE_RCX_AO_CONFIG_HIGH_OFF (16)
#define APU_ACE_HW_FLAG_DIS (APUSYS_CE_BASE + 0x05D4)
#define APU_ACE_DIS_FLAG_VAL (0xffff7ff8)
#define OUT_CLK_FREQ_MIN (1500)
#define DDS_SHIFT (14)
#define BASIC_CLK_FREQ (26)
int apusys_power_init(void);
#endif /* APUSYS_POWER_H */

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef APUSYS_RV_MBOX_MPU_H
#define APUSYS_RV_MBOX_MPU_H
#define MPU_EN (0)
#define MPU_DIS (1)
#define MBOX0_TX_DOMAIN (0)
#define MBOX0_TX_NS (1)
#define MBOX1_TX_DOMAIN (11)
#define MBOX1_TX_NS (1)
#define MBOX3_TX_DOMAIN (3)
#define MBOX3_TX_NS (0)
#define MBOX4_RX_DOMAIN (0)
#define MBOX4_RX_NS (0)
#define MBOX5_TX_DOMAIN (8)
#define MBOX5_TX_NS (0)
#define MBOX6_TX_DOMAIN (4)
#define MBOX6_TX_NS (1)
#define MBOX7_RX_DOMAIN (0)
#define MBOX7_RX_NS (0)
#define MBOXN_RX_DOMAIN (5)
#define MBOXN_RX_NS (0)
#define MBOXN_TX_DOMAIN (0)
#define MBOXN_TX_NS (0)
struct mbox_mpu_setting {
uint32_t no_mpu;
uint32_t rx_ns;
uint32_t rx_domain;
uint32_t tx_ns;
uint32_t tx_domain;
};
static const struct mbox_mpu_setting mbox_mpu_setting_tab[] = {
/* no_mpu, rx_ns, rx_domain, tx_ns, tx_domain */
{MPU_EN, MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOX0_TX_NS, MBOX0_TX_DOMAIN},
{MPU_EN, MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOX1_TX_NS, MBOX1_TX_DOMAIN},
{MPU_EN, MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOXN_TX_NS, MBOXN_TX_DOMAIN},
{MPU_EN, MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOX3_TX_NS, MBOX3_TX_DOMAIN},
{MPU_DIS, MBOX4_RX_NS, MBOX4_RX_DOMAIN, MBOXN_TX_NS, MBOXN_TX_DOMAIN},
{MPU_EN, MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOX5_TX_NS, MBOX5_TX_DOMAIN},
{MPU_EN, MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOX6_TX_NS, MBOX6_TX_DOMAIN},
{MPU_DIS, MBOX7_RX_NS, MBOX7_RX_DOMAIN, MBOXN_TX_NS, MBOXN_TX_DOMAIN},
{MPU_EN, MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOXN_TX_NS, MBOXN_TX_DOMAIN},
{MPU_EN, MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOXN_TX_NS, MBOXN_TX_DOMAIN},
};
#define APU_MBOX_NUM ARRAY_SIZE(mbox_mpu_setting_tab)
#endif /* APUSYS_RV_MBOX_MPU_H */

View file

@ -0,0 +1,171 @@
/*
* Copyright (c) 2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <errno.h>
#include <common/debug.h>
#include <drivers/delay_timer.h>
#include <lib/mmio.h>
#include "apusys_power.h"
#include "apusys_rv.h"
#include "apusys_rv_pwr_ctrl.h"
#define RPC_POWER_OFF_TIMEOUT_CNT (100000) /* 100ms */
static int wait_for_state_ready(uint32_t reg, uint32_t mask, uint32_t expect,
uint32_t retry_times, uint32_t set_reg, uint32_t set_val)
{
uint32_t count = 0;
while ((mmio_read_32(reg) & mask) != expect) {
if (count > retry_times) {
ERROR("%s: timed out, reg = %x, mask = %x, expect = %x\n",
__func__, reg, mask, expect);
return -EBUSY;
}
count += 1;
if (set_reg)
mmio_write_32(set_reg, set_val);
udelay(1);
}
return 0;
}
int apu_hw_sema_ctl_per_mbox(uint32_t sem_ctrl_addr, uint32_t sem_sta_addr,
uint8_t usr_bit, enum apu_hw_sem_op ctl, uint32_t timeout,
uint8_t bypass)
{
int ret;
uint8_t ctl_bit = 0;
if (ctl == HW_SEM_GET)
ctl_bit = 0x1;
else if (ctl == HW_SEM_PUT)
ctl_bit = 0x2;
else
return -EINVAL;
/* return fail if semaphore is currently not held by this user */
if (ctl == HW_SEM_PUT && ((mmio_read_32(sem_sta_addr) & BIT(usr_bit)) == 0)
&& !bypass) {
ERROR("%s release error: usr_bit:%d ctl:%d (sem_addr(0x%08x) = 0x%08x)\n",
__func__, usr_bit, ctl, sem_sta_addr, mmio_read_32(sem_sta_addr));
return -EINVAL;
}
mmio_write_32(sem_ctrl_addr, ctl_bit);
if (ctl == HW_SEM_PUT)
return 0;
ret = wait_for_state_ready(sem_sta_addr, BIT(usr_bit), BIT(usr_bit), timeout,
sem_ctrl_addr, ctl_bit);
if (ret)
return ret;
return 0;
}
int apusys_rv_pwr_ctrl(enum APU_PWR_OP op)
{
int ret;
uint32_t global_ref_cnt;
ret = apu_hw_sema_ctl_per_mbox(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA0_CTRL,
APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA0_STA,
APU_HW_SEM_SYS_APMCU, HW_SEM_GET, HW_SEM_TIMEOUT, 0);
if (ret) {
ERROR("%s(%d): sem acquire timeout\n", __func__, op);
return ret;
}
global_ref_cnt = mmio_read_32(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_DUMMY);
if (global_ref_cnt > 2) {
ERROR("%s: global_ref_cnt(%d) > 2\n", __func__, global_ref_cnt);
} else if (op == APU_PWR_OFF) {
global_ref_cnt--;
mmio_write_32(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_DUMMY, global_ref_cnt);
if (global_ref_cnt == 0)
mmio_write_32(APU_MBOX_WKUP_CFG(11), 0);
} else if (op == APU_PWR_ON) {
global_ref_cnt++;
mmio_write_32(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_DUMMY, global_ref_cnt);
if (global_ref_cnt == 1)
mmio_write_32(APU_MBOX_WKUP_CFG(11), 1);
}
ret = apu_hw_sema_ctl_per_mbox(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA0_CTRL,
APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA0_STA,
APU_HW_SEM_SYS_APMCU, HW_SEM_PUT, HW_SEM_TIMEOUT, 0);
if (ret)
ERROR("%s(%d): sem release timeout\n", __func__, op);
return ret;
}
int rv_iommu_hw_sem_trylock(void)
{
return apu_hw_sema_ctl_per_mbox(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA1_CTRL,
APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA1_STA,
APU_HW_SEM_SYS_APMCU, HW_SEM_GET, 0, 0);
}
int rv_iommu_hw_sem_unlock(void)
{
return apu_hw_sema_ctl_per_mbox(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA1_CTRL,
APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA1_STA,
APU_HW_SEM_SYS_APMCU, HW_SEM_PUT, 0, 0);
}
int apu_hw_sema_ctl(uint32_t sem_addr, uint8_t usr_bit, uint8_t ctl, uint32_t timeout,
uint8_t bypass)
{
int ret;
uint8_t ctl_bit = 0;
if (ctl == HW_SEM_GET)
ctl_bit = usr_bit;
else if (ctl == HW_SEM_PUT)
ctl_bit = usr_bit + HW_SEM_PUT_BIT_SHIFT;
else
return -EINVAL;
if (ctl == HW_SEM_PUT && ((mmio_read_32(sem_addr) & BIT(ctl_bit)) == 0) && !bypass) {
ERROR("%s release error: usr_bit:%d ctl:%d (sem_addr(0x%08x) = 0x%08x)\n",
__func__, usr_bit, ctl, sem_addr, mmio_read_32(sem_addr));
return -EINVAL;
}
mmio_write_32(sem_addr, BIT(ctl_bit));
if (ctl == HW_SEM_PUT)
goto end;
ret = wait_for_state_ready(sem_addr, BIT(ctl_bit), BIT(ctl_bit), timeout,
sem_addr, BIT(ctl_bit));
if (ret)
return ret;
end:
VERBOSE("%s: sem_addr = 0x%x, usr_bit: %d, ctl: %d, sem_addr = 0x%08x\n",
__func__, sem_addr, usr_bit, ctl, mmio_read_32(sem_addr));
return 0;
}
int apusys_infra_dcm_setup(void)
{
mmio_write_32(APU_REG_AO_GLUE_CONFG,
mmio_read_32(APU_REG_AO_GLUE_CONFG) | BIT(24) | BIT(26));
return 0;
}

View file

@ -0,0 +1,93 @@
/*
* Copyright (c) 2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef APUSYS_RV_PWR_CTL_H
#define APUSYS_RV_PWR_CTL_H
#include <platform_def.h>
#include "apusys_rv.h"
#define SUPPORT_APU_CLEAR_MBOX_DUMMY (1)
enum apu_hw_sem_sys_id {
APU_HW_SEM_SYS_APU = 0UL, /* mbox0 */
APU_HW_SEM_SYS_GZ = 1UL, /* mbox1 */
APU_HW_SEM_SYS_SCP = 3UL, /* mbox3 */
APU_HW_SEM_SYS_APMCU = 11UL, /* mbox11 */
};
int apusys_rv_pwr_ctrl(enum APU_PWR_OP op);
int rv_iommu_hw_sem_unlock(void);
int rv_iommu_hw_sem_trylock(void);
int apu_hw_sema_ctl(uint32_t sem_addr, uint8_t usr_bit, uint8_t ctl, uint32_t timeout,
uint8_t bypass);
#define HW_SEM_TIMEOUT (300) /* 300 us */
/* APU MBOX */
#define MBOX_WKUP_CFG (0x80)
#define MBOX_WKUP_MASK (0x84)
#define MBOX_FUNC_CFG (0xb0)
#define MBOX_DOMAIN_CFG (0xe0)
#define MBOX_CTRL_LOCK BIT(0)
#define MBOX_NO_MPU_SHIFT (16)
#define MBOX_RC_SHIFT (24)
#define MBOX_RX_NS_SHIFT (16)
#define MBOX_RX_DOMAIN_SHIFT (17)
#define MBOX_TX_NS_SHIFT (24)
#define MBOX_TX_DOMAIN_SHIFT (25)
#define APU_REG_AO_GLUE_CONFG (APU_AO_CTRL + 0x20)
#define ENABLE_INFRA_WA
enum apu_infra_bit_id {
APU_INFRA_SYS_APMCU = 1UL,
APU_INFRA_SYS_GZ = 2UL,
APU_INFRA_SYS_SCP = 3UL,
};
#define APU_MBOX(i) (APU_MBOX0 + 0x10000 * i)
#define APU_MBOX_FUNC_CFG(i) (APU_MBOX(i) + MBOX_FUNC_CFG)
#define APU_MBOX_DOMAIN_CFG(i) (APU_MBOX(i) + MBOX_DOMAIN_CFG)
#define APU_MBOX_WKUP_CFG(i) (APU_MBOX(i) + MBOX_WKUP_CFG)
enum apu_hw_sem_op {
HW_SEM_PUT = 0,
HW_SEM_GET = 1,
};
#define HW_SEM_PUT_BIT_SHIFT (16)
/* bypass mbox register Dump for secure master */
#define APU_MBOX_DBG_EN (0x190f2380)
/* apu_mbox register definition for mbox addr change*/
#define APU_MBOX_SEMA0_CTRL (0x090)
#define APU_MBOX_SEMA0_RST (0x094)
#define APU_MBOX_SEMA0_STA (0x098)
#define APU_MBOX_SEMA1_CTRL (0x0A0)
#define APU_MBOX_SEMA1_RST (0x0A4)
#define APU_MBOX_SEMA1_STA (0x0A8)
#define APU_MBOX_DUMMY (0x040)
#define APU_MBOX_OFFSET(i) (0x10000 * i)
/* apu infra workaround */
#define APU_INFRA_DISABLE (APU_INFRA_BASE + 0xC18)
#define APU_INFRA_ENABLE (APU_INFRA_BASE + 0xC14)
#define APU_INFRA_STATUS (APU_INFRA_BASE + 0xC10)
#define APU_INFRA_STATUS_MASK (0x1fffe)
#define APU_INFRA_HW_SEM (APUSYS_CE_BASE + 0xE00)
#define APU_RPC_STATUS (0x190f0044)
#define APU_INFRA_BIT_OFF (16)
#define APU_RPC_STATUS_BIT BIT(0)
#endif /* APUSYS_RV_PWR_CTL_H */

View file

@ -0,0 +1,115 @@
/*
* Copyright (c) 2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <errno.h>
#include <common/debug.h>
#include <lib/mmio.h>
#include "apusys_security_ctrl_perm.h"
#include "apusys_security_ctrl_perm_plat.h"
#define SEC_CTRL_APU_SEC_CON_BASE (0x190F5000)
#define SEC_CTRL_RV_DOMAIN_OFS (0x60)
#define SEC_CTRL_RV_NS_OFS (0x64)
#define SEC_CTRL_RV_DOMAIN_SHF (4)
#define SEC_CTRL_RV_NS_SHF (1)
#define SEC_LEVEL_NORMAL_DOMAIN (7)
#define SEC_LEVEL_NORMAL_NS (1)
#define SEC_LEVEL_SAPU_DOMAIN (5)
#define SEC_LEVEL_SAPU_NS (1)
#define SEC_LEVEL_AOV_DOMAIN (14)
#define SEC_LEVEL_AOV_NS (1)
#define SEC_LEVEL_UP_SECURE_DOMAIN (5)
#define SEC_LEVEL_UP_SECURE_NS (0)
#define SEC_LEVEL_MVPU_SECURE_DOMAIN (7)
#define SEC_LEVEL_MVPU_SECURE_NS (0)
#define SEC_LEVEL_MDLA_SECURE_DOMAIN (14)
#define SEC_LEVEL_MDLA_SECURE_NS (0)
#define DOMAIN(SEC_LVL) SEC_LEVEL_##SEC_LVL##_DOMAIN
#define NS(SEC_LVL) SEC_LEVEL_##SEC_LVL##_NS
int sec_get_dns(enum apusys_dev_type dev_type, enum apusys_sec_level sec_level,
uint8_t *domain, uint8_t *ns)
{
if ((dev_type < 0) || (dev_type >= APUSYS_DEVICE_NUM)) {
ERROR("invalid dev type %d\n", dev_type);
return -EINVAL;
}
if ((sec_level < 0) || (sec_level >= SEC_LEVEL_NUM)) {
ERROR("invalid sec_level %d\n", sec_level);
return -EINVAL;
}
switch (sec_level) {
case SEC_LEVEL_NORMAL:
*domain = DOMAIN(NORMAL);
*ns = NS(NORMAL);
break;
case SEC_LEVEL_SECURE:
switch (dev_type) {
case APUSYS_DEVICE_MVPU:
*domain = DOMAIN(MVPU_SECURE);
*ns = NS(MVPU_SECURE);
break;
case APUSYS_DEVICE_MDLA:
*domain = DOMAIN(MDLA_SECURE);
*ns = NS(MDLA_SECURE);
break;
case APUSYS_DEVICE_UP:
*domain = DOMAIN(UP_SECURE);
*ns = NS(UP_SECURE);
break;
default:
ERROR("invalid dev type %d\n", dev_type);
return -EINVAL;
};
break;
case SEC_LEVEL_SAPU:
*domain = DOMAIN(SAPU);
*ns = NS(SAPU);
break;
case SEC_LEVEL_AOV:
*domain = DOMAIN(AOV);
*ns = NS(AOV);
break;
default:
ERROR("invalid sec_level %d\n", sec_level);
return -EINVAL;
};
return 0;
}
int sec_set_rv_dns(void)
{
uint8_t normal_domain;
uint8_t normal_ns;
uint8_t sec_domain;
uint8_t sec_ns;
int ret;
ret = sec_get_dns(APUSYS_DEVICE_UP, SEC_LEVEL_SECURE, &sec_domain, &sec_ns);
if (ret) {
ERROR("%s failed.\n", __func__);
return ret;
}
ret = sec_get_dns(APUSYS_DEVICE_UP, SEC_LEVEL_NORMAL, &normal_domain, &normal_ns);
if (ret) {
ERROR("%s failed.\n", __func__);
return ret;
}
mmio_write_32(SEC_CTRL_APU_SEC_CON_BASE + SEC_CTRL_RV_DOMAIN_OFS,
(sec_domain << SEC_CTRL_RV_DOMAIN_SHF) | normal_domain);
mmio_write_32(SEC_CTRL_APU_SEC_CON_BASE + SEC_CTRL_RV_NS_OFS,
(sec_ns << SEC_CTRL_RV_NS_SHF) | normal_ns);
return 0;
}

View file

@ -0,0 +1,18 @@
/*
* Copyright (c) 2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef APUSYS_SECURITY_CTRL_PERM_PLAT_H
#define APUSYS_SECURITY_CTRL_PERM_PLAT_H
enum apusys_dev_type {
APUSYS_DEVICE_MDLA,
APUSYS_DEVICE_EDPA,
APUSYS_DEVICE_MVPU,
APUSYS_DEVICE_UP,
APUSYS_DEVICE_NUM,
};
#endif /* APUSYS_SECURITY_CTRL_PERM_PLAT_H */

View file

@ -0,0 +1,82 @@
/*
* Copyright (c) 2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define ENABLE_SMPU_PROTECT (0)
#if ENABLE_SMPU_PROTECT
#include "emi.h"
#include "mt_emi.h"
#endif
#include <common/debug.h>
#include <lib/mmio.h>
#include <apusys_security_ctrl_plat.h>
#define APUSYS_SEC_FW_EMI_REGION (23)
#define bits_clr(x, m, o) (x & (~(m << o)))
#define bits_set(x, v, m, o) ((bits_clr(x, m, o)) | ((v & m) << o))
static void sec_sideband_init(void)
{
uint32_t value = mmio_read_32(SEC_CTRL_SIDE_BAND);
value = bits_set(value, SEC_CTRL_NARE_DOMAIN, SEC_CTRL_DOMAIN_MASK,
SEC_CTRL_NARE_DOMAIN_SHF);
value = bits_set(value, SEC_CTRL_NARE_NS, SEC_CTRL_NS_MASK, SEC_CTRL_NARE_NS_SHF);
value = bits_set(value, SEC_CTRL_SARE0_DOMAIN, SEC_CTRL_DOMAIN_MASK,
SEC_CTRL_SARE0_DOMAIN_SHF);
value = bits_set(value, SEC_CTRL_SARE0_NS, SEC_CTRL_NS_MASK, SEC_CTRL_SARE0_NS_SHF);
value = bits_set(value, SEC_CTRL_SARE1_DOMAIN, SEC_CTRL_DOMAIN_MASK,
SEC_CTRL_SARE1_DOMAIN_SHF);
value = bits_set(value, SEC_CTRL_SARE1_NS, SEC_CTRL_NS_MASK, SEC_CTRL_SARE1_NS_SHF);
mmio_write_32(SEC_CTRL_SIDE_BAND, value);
}
static void domain_remap_init(void)
{
const uint32_t remap_domains[] = {
D0_REMAP_DOMAIN, D1_REMAP_DOMAIN, D2_REMAP_DOMAIN, D3_REMAP_DOMAIN,
D4_REMAP_DOMAIN, D5_REMAP_DOMAIN, D6_REMAP_DOMAIN, D7_REMAP_DOMAIN,
D8_REMAP_DOMAIN, D9_REMAP_DOMAIN, D10_REMAP_DOMAIN, D11_REMAP_DOMAIN,
D12_REMAP_DOMAIN, D13_REMAP_DOMAIN, D14_REMAP_DOMAIN, D15_REMAP_DOMAIN,
};
uint32_t lower_domain = 0;
uint32_t higher_domain = 0;
int i;
for (i = 0; i < ARRAY_SIZE(remap_domains); i++) {
if (i < SEC_CTRL_REG_DOMAIN_NUM)
lower_domain |= (remap_domains[i] << (i * REG_DOMAIN_BITS));
else
higher_domain |= (remap_domains[i] <<
((i - SEC_CTRL_REG_DOMAIN_NUM) * REG_DOMAIN_BITS));
}
mmio_write_32(SEC_CTRL_SOC2APU_SET1_0, lower_domain);
mmio_write_32(SEC_CTRL_SOC2APU_SET1_1, higher_domain);
mmio_setbits_32(APU_SEC_CON, SEC_CTRL_DOMAIN_REMAP_SEL);
}
void apusys_security_ctrl_init(void)
{
domain_remap_init();
sec_sideband_init();
}
int apusys_plat_setup_sec_mem(void)
{
#if ENABLE_SMPU_PROTECT
return sip_emi_mpu_set_protection(APU_RESERVE_MEMORY >> EMI_MPU_ALIGN_BITS,
(APU_RESERVE_MEMORY + APU_RESERVE_SIZE) >> EMI_MPU_ALIGN_BITS,
APUSYS_SEC_FW_EMI_REGION);
#else
INFO("%s: Bypass SMPU protection setup.\n", __func__);
return 0;
#endif
}

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef APUSYS_SECURITY_CTRL_PLAT_H
#define APUSYS_SECURITY_CTRL_PLAT_H
#include <lib/utils_def.h>
#include <platform_def.h>
#define SEC_CTRL_SOC2APU_SET1_0 (APU_SEC_CON + 0xC)
#define SEC_CTRL_SOC2APU_SET1_1 (APU_SEC_CON + 0x10)
#define SEC_CTRL_SIDE_BAND (APU_SEC_CON + 0x24)
#define SEC_CTRL_REG_DOMAIN_NUM (8)
#define SEC_CTRL_DOMAIN_REMAP_SEL BIT(6)
#define SEC_CTRL_DOMAIN_MASK (0xF)
#define SEC_CTRL_NS_MASK (0x1)
#define SEC_CTRL_NARE_DOMAIN (5)
#define SEC_CTRL_NARE_NS (0)
#define SEC_CTRL_NARE_DOMAIN_SHF (0)
#define SEC_CTRL_NARE_NS_SHF (4)
#define SEC_CTRL_SARE0_DOMAIN (5)
#define SEC_CTRL_SARE0_NS (0)
#define SEC_CTRL_SARE0_DOMAIN_SHF (5)
#define SEC_CTRL_SARE0_NS_SHF (9)
#define SEC_CTRL_SARE1_DOMAIN (5)
#define SEC_CTRL_SARE1_NS (0)
#define SEC_CTRL_SARE1_DOMAIN_SHF (10)
#define SEC_CTRL_SARE1_NS_SHF (14)
#define REG_DOMAIN_BITS (4)
#define D0_REMAP_DOMAIN (0)
#define D1_REMAP_DOMAIN (1)
#define D2_REMAP_DOMAIN (2)
#define D3_REMAP_DOMAIN (3)
#define D4_REMAP_DOMAIN (4)
#define D5_REMAP_DOMAIN (6)
#define D6_REMAP_DOMAIN (6)
#define D7_REMAP_DOMAIN (6)
#define D8_REMAP_DOMAIN (8)
#define D9_REMAP_DOMAIN (9)
#define D10_REMAP_DOMAIN (10)
#define D11_REMAP_DOMAIN (11)
#define D12_REMAP_DOMAIN (12)
#define D13_REMAP_DOMAIN (13)
#define D14_REMAP_DOMAIN (6)
#define D15_REMAP_DOMAIN (15)
void apusys_security_ctrl_init(void);
int apusys_plat_setup_sec_mem(void);
#endif /* APUSYS_SECURITY_CTRL_PLAT_H */

View file

@ -0,0 +1,23 @@
#
# Copyright (c) 2024, MediaTek Inc. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
LOCAL_DIR := $(call GET_LOCAL_DIR)
MODULE := apusys_${MTK_SOC}
ifeq (${CONFIG_MTK_APUSYS_EMI_SUPPORT}, y)
PLAT_INCLUDES += -I${MTK_PLAT}/drivers/emi/common
PLAT_INCLUDES += -I${MTK_PLAT}/drivers/emi/${MTK_SOC}
endif
LOCAL_SRCS-y := ${LOCAL_DIR}/apusys_ammu.c
LOCAL_SRCS-y += ${LOCAL_DIR}/apusys_devapc.c
LOCAL_SRCS-y += ${LOCAL_DIR}/apusys_power.c
LOCAL_SRCS-y += ${LOCAL_DIR}/apusys_rv_pwr_ctrl.c
LOCAL_SRCS-y += ${LOCAL_DIR}/apusys_security_ctrl_plat.c
LOCAL_SRCS-y += ${LOCAL_DIR}/apusys_security_ctrl_perm_plat.c
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))

View file

@ -1,5 +1,5 @@
#
# Copyright (c) 2023, MediaTek Inc. All rights reserved.
# Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@ -12,10 +12,19 @@ LOCAL_SRCS-y:= ${LOCAL_DIR}/apusys.c
PLAT_INCLUDES += -I${LOCAL_DIR} -I${LOCAL_DIR}/${MTK_SOC} -I${LOCAL_DIR}/apusys_rv/2.0
$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_CE_SUPPORT))
$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_EMI_SUPPORT))
$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_LOGTOP_SUPPORT))
$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT))
$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_RV_COREDUMP_WA_SUPPORT))
$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_RV_IOMMU_HW_SEM_SUPPORT))
$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_SEC_CTRL))
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
SUB_RULES-y := ${LOCAL_DIR}/${MTK_SOC}
SUB_RULES-y += ${LOCAL_DIR}/devapc
SUB_RULES-y += ${LOCAL_DIR}/apusys_rv/2.0
SUB_RULES-${CONFIG_MTK_APUSYS_SEC_CTRL} += $(LOCAL_DIR)/security_ctrl
$(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES-y)))

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef SECURITY_CTRL_PERM_H
#define SECURITY_CTRL_PERM_H
#include "apusys_security_ctrl_perm_plat.h"
enum apusys_sec_level {
SEC_LEVEL_NORMAL,
SEC_LEVEL_SECURE,
SEC_LEVEL_SAPU,
SEC_LEVEL_AOV,
SEC_LEVEL_NUM,
};
int sec_set_rv_dns(void);
int sec_get_dns(enum apusys_dev_type dev_type, enum apusys_sec_level sec_level,
uint8_t *domain, uint8_t *ns);
#endif

View file

@ -0,0 +1,8 @@
#
# Copyright (c) 2024, MediaTek Inc. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
PLAT_INCLUDES += -I${MTK_PLAT}/drivers/apusys/security_ctrl
PLAT_INCLUDES += -I${MTK_PLAT}/drivers/apusys/${MTK_SOC}

View file

@ -0,0 +1,18 @@
/*
* Copyright (c) 2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef APUSYS_RV_PUBLIC_H
#define APUSYS_RV_PUBLIC_H
#ifdef CONFIG_MTK_APUSYS_RV_IOMMU_HW_SEM_SUPPORT
int apusys_rv_iommu_hw_sem_trylock(void);
int apusys_rv_iommu_hw_sem_unlock(void);
#else
#define apusys_rv_iommu_hw_sem_trylock() 0
#define apusys_rv_iommu_hw_sem_unlock() 0
#endif /* CONFIG_MTK_APUSYS_RV_IOMMU_HW_SEM_SUPPORT */
#endif /* APUSYS_RV_PUBLIC_H */

View file

@ -30,6 +30,37 @@
******************************************************************************/
#define AUDIO_BASE (IO_PHYS + 0x0a110000)
/*******************************************************************************
* APUSYS related constants
******************************************************************************/
#define APUSYS_BASE (IO_PHYS + 0x09000000)
#define APU_MD32_SYSCTRL (IO_PHYS + 0x09001000)
#define APU_MD32_WDT (IO_PHYS + 0x09002000)
#define APU_LOGTOP (IO_PHYS + 0x09024000)
#define APUSYS_CTRL_DAPC_RCX_BASE (IO_PHYS + 0x09030000)
#define APU_REVISER (IO_PHYS + 0x0903C000)
#define APU_RCX_UPRV_TCU (IO_PHYS + 0x09060000)
#define APU_RCX_EXTM_TCU (IO_PHYS + 0x09061000)
#define APU_CMU_TOP (IO_PHYS + 0x09067000)
#define APUSYS_CE_BASE (IO_PHYS + 0x090B0000)
#define APU_ARE_REG_BASE (IO_PHYS + 0x090B0000)
#define APU_RCX_VCORE_CONFIG (IO_PHYS + 0x090E0000)
#define APU_AO_CTRL (IO_PHYS + 0x090F2000)
#define APU_SEC_CON (IO_PHYS + 0x090F5000)
#define APUSYS_CTRL_DAPC_AO_BASE (IO_PHYS + 0x090FC000)
#define APU_MBOX0 (0x4C200000)
#define APU_MD32_TCM (0x4D000000)
#define APU_MD32_TCM_SZ (0x50000)
#define APU_MBOX0_SZ (0x100000)
#define APU_INFRA_BASE (0x1002C000)
#define APU_INFRA_SZ (0x1000)
#define APU_RESERVE_MEMORY (0x95000000)
#define APU_SEC_INFO_OFFSET (0x100000)
#define APU_RESERVE_SIZE (0x1400000)
/*******************************************************************************
* SPM related constants
******************************************************************************/

View file

@ -26,6 +26,14 @@ USE_PMIC_WRAP_INIT_V2 := 1
CTX_INCLUDE_AARCH32_REGS := 0
CONFIG_ARCH_ARM_V9 := y
CONFIG_MTK_APUSYS_CE_SUPPORT := y
CONFIG_MTK_APUSYS_EMI_SUPPORT := n
CONFIG_MTK_APUSYS_LOGTOP_SUPPORT := y
CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT := y
CONFIG_MTK_APUSYS_RV_COREDUMP_WA_SUPPORT := y
CONFIG_MTK_APUSYS_RV_IOMMU_HW_SEM_SUPPORT := y
CONFIG_MTK_APUSYS_SEC_CTRL := y
CONFIG_MTK_APUSYS_SETUP_CE := y
CONFIG_MTK_MCUSYS := y
MCUSYS_VERSION := v1
CONFIG_MTK_PM_SUPPORT := y

View file

@ -21,6 +21,8 @@ static const mmap_region_t plat_mmap[] = {
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(EDP_SEC_BASE, EDP_SEC_SIZE,
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(APU_MBOX0, APU_MBOX0_SZ,
MT_DEVICE | MT_RW | MT_SECURE),
{ 0 }
};
DECLARE_MTK_MMAP_REGIONS(plat_mmap);

View file

@ -25,6 +25,7 @@ PLAT_INCLUDES := -I${MTK_PLAT}/common \
MODULES-y += $(MTK_PLAT)/common
MODULES-y += $(MTK_PLAT)/lib/mtk_init
MODULES-y += $(MTK_PLAT)/lib/pm
MODULES-y += $(MTK_PLAT)/drivers/apusys
MODULES-y += $(MTK_PLAT)/drivers/dp
MODULES-y += $(MTK_PLAT)/drivers/mcusys
MODULES-y += $(MTK_PLAT)/drivers/timer