diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 17:43:51 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 17:43:51 +0000 |
commit | be58c81aff4cd4c0ccf43dbd7998da4a6a08c03b (patch) | |
tree | 779c248fb61c83f65d1f0dc867f2053d76b4e03a /plat/mediatek/drivers/apusys/mt8188 | |
parent | Initial commit. (diff) | |
download | arm-trusted-firmware-be58c81aff4cd4c0ccf43dbd7998da4a6a08c03b.tar.xz arm-trusted-firmware-be58c81aff4cd4c0ccf43dbd7998da4a6a08c03b.zip |
Adding upstream version 2.10.0+dfsg.upstream/2.10.0+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'plat/mediatek/drivers/apusys/mt8188')
-rw-r--r-- | plat/mediatek/drivers/apusys/mt8188/apusys_devapc.c | 307 | ||||
-rw-r--r-- | plat/mediatek/drivers/apusys/mt8188/apusys_devapc.h | 13 | ||||
-rw-r--r-- | plat/mediatek/drivers/apusys/mt8188/apusys_devapc_def.h | 109 | ||||
-rw-r--r-- | plat/mediatek/drivers/apusys/mt8188/apusys_power.c | 483 | ||||
-rw-r--r-- | plat/mediatek/drivers/apusys/mt8188/apusys_power.h | 248 | ||||
-rw-r--r-- | plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.c | 43 | ||||
-rw-r--r-- | plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.h | 38 | ||||
-rw-r--r-- | plat/mediatek/drivers/apusys/mt8188/rules.mk | 15 |
8 files changed, 1256 insertions, 0 deletions
diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_devapc.c b/plat/mediatek/drivers/apusys/mt8188/apusys_devapc.c new file mode 100644 index 0000000..da5242a --- /dev/null +++ b/plat/mediatek/drivers/apusys/mt8188/apusys_devapc.c @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* TF-A system header */ +#include <common/debug.h> +#include <lib/utils_def.h> + +/* Vendor header */ +#include "apusys.h" +#include "apusys_devapc.h" +#include "apusys_devapc_def.h" +#include <platform_def.h> + +#define DUMP_APUSYS_DAPC (0) + +static const struct apc_dom_16 APU_NOC_DAPC_RCX[] = { + /* ctrl index = 0 */ + SLAVE_MD32_SRAM("slv16-0"), + SLAVE_MD32_SRAM("slv16-1"), + SLAVE_MD32_SRAM("slv16-2"), + SLAVE_MD32_SRAM("slv16-3"), + SLAVE_MD32_SRAM("slv16-4"), +}; + +static const struct apc_dom_16 APU_CTRL_DAPC_AO[] = { + /* ctrl index = 0 */ + SLAVE_VCORE("apu_ao_ctl_o-0"), + SLAVE_RPC("apu_ao_ctl_o-2"), + SLAVE_PCU("apu_ao_ctl_o-3"), + SLAVE_AO_CTRL("apu_ao_ctl_o-4"), + SLAVE_PLL("apu_ao_ctl_o-5"), + SLAVE_ACC("apu_ao_ctl_o-6"), + SLAVE_SEC("apu_ao_ctl_o-7"), + SLAVE_ARE0("apu_ao_ctl_o-8"), + SLAVE_ARE1("apu_ao_ctl_o-9"), + SLAVE_ARE2("apu_ao_ctl_o-10"), + + /* ctrl index = 10 */ + SLAVE_UNKNOWN("apu_ao_ctl_o-11"), + SLAVE_AO_BCRM("apu_ao_ctl_o-12"), + SLAVE_AO_DAPC_WRAP("apu_ao_ctl_o-13"), + SLAVE_AO_DAPC_CON("apu_ao_ctl_o-14"), + SLAVE_RCX_ACX_BULK("apu_ao_ctl_o-15"), + SLAVE_UNKNOWN("apu_ao_ctl_o-16"), + SLAVE_UNKNOWN("apu_ao_ctl_o-17"), + SLAVE_APU_BULK("apu_ao_ctl_o-18"), + SLAVE_ACX0_BCRM("apu_ao_ctl_o-20"), + SLAVE_RPCTOP_LITE_ACX0("apu_ao_ctl_o-21"), + + /* ctrl index = 20 */ + SLAVE_ACX1_BCRM("apu_ao_ctl_o-22"), + SLAVE_RPCTOP_LITE_ACX1("apu_ao_ctl_o-23"), + SLAVE_RCX_TO_ACX0_0("apu_rcx2acx0_o-0"), + SLAVE_RCX_TO_ACX0_1("apu_rcx2acx0_o-1"), + SLAVE_SAE_TO_ACX0_0("apu_sae2acx0_o-0"), + SLAVE_SAE_TO_ACX0_1("apu_sae2acx0_o-1"), + SLAVE_RCX_TO_ACX1_0("apu_rcx2acx1_o-0"), + SLAVE_RCX_TO_ACX1_1("apu_rcx2acx1_o-1"), + SLAVE_SAE_TO_ACX1_0("apu_sae2acx1_o-0"), + SLAVE_SAE_TO_ACX1_1("apu_sae2acx1_o-1"), +}; + +static const struct apc_dom_16 APU_CTRL_DAPC_RCX[] = { + /* ctrl index = 0 */ + SLAVE_MD32_SYSCTRL0("md32_apb_s-0"), + SLAVE_MD32_SYSCTRL1("md32_apb_s-1"), + SLAVE_MD32_WDT("md32_apb_s-2"), + SLAVE_MD32_CACHE("md32_apb_s-3"), + SLAVE_RPC("apusys_ao-0"), + SLAVE_PCU("apusys_ao-1"), + SLAVE_AO_CTRL("apusys_ao-2"), + SLAVE_PLL("apusys_ao-3"), + SLAVE_ACC("apusys_ao-4"), + SLAVE_SEC("apusys_ao-5"), + + /* ctrl index = 10 */ + SLAVE_ARE0("apusys_ao-6"), + SLAVE_ARE1("apusys_ao-7"), + SLAVE_ARE2("apusys_ao-8"), + SLAVE_UNKNOWN("apusys_ao-9"), + SLAVE_AO_BCRM("apusys_ao-10"), + SLAVE_AO_DAPC_WRAP("apusys_ao-11"), + SLAVE_AO_DAPC_CON("apusys_ao-12"), + SLAVE_VCORE("apusys_ao-13"), + SLAVE_ACX0_BCRM("apusys_ao-15"), + SLAVE_ACX1_BCRM("apusys_ao-16"), + + /* ctrl index = 20 */ + SLAVE_NOC_AXI("noc_axi"), + SLAVE_MD32_DBG("md32_dbg"), + SLAVE_DBG_CRTL("apb_infra_dbg"), + SLAVE_IOMMU0_BANK0("apu_n_mmu_r0"), + SLAVE_IOMMU0_BANK1("apu_n_mmu_r1"), + SLAVE_IOMMU0_BANK2("apu_n_mmu_r2"), + SLAVE_IOMMU0_BANK3("apu_n_mmu_r3"), + SLAVE_IOMMU0_BANK4("apu_n_mmu_r4"), + SLAVE_IOMMU1_BANK0("apu_s_mmu_r0"), + SLAVE_IOMMU1_BANK1("apu_s_mmu_r1"), + + /* ctrl index = 30 */ + SLAVE_IOMMU1_BANK2("apu_s_mmu_r2"), + SLAVE_IOMMU1_BANK3("apu_s_mmu_r3"), + SLAVE_IOMMU1_BANK4("apu_s_mmu_r4"), + SLAVE_S0_SSC("apu_s0_ssc_cfg"), + SLAVE_N0_SSC("apu_n0_ssc_cfg"), + SLAVE_ACP_SSC("apu_acp_ssc_cfg"), + SLAVE_S1_SSC("apu_s1_ssc_cfg"), + SLAVE_N1_SSC("apu_n1_ssc_cfg"), + SLAVE_CFG("apu_rcx_cfg"), + SLAVE_SEMA_STIMER("apu_sema_stimer"), + + /* ctrl index = 40 */ + SLAVE_EMI_CFG("apu_emi_cfg"), + SLAVE_LOG("apu_logtop"), + SLAVE_CPE_SENSOR("apu_cpe_sensor"), + SLAVE_CPE_COEF("apu_cpe_coef"), + SLAVE_CPE_CTRL("apu_cpe_ctrl"), + SLAVE_UNKNOWN("apu_xpu_rsi"), + SLAVE_DFD_REG_SOC("apu_dfd"), + SLAVE_SENSOR_WRAP_ACX0_DLA0("apu_sen_ac0_dla0"), + SLAVE_SENSOR_WRAP_ACX0_DLA1("apu_sen_ac0_dla1"), + SLAVE_SENSOR_WRAP_ACX0_VPU0("apu_sen_ac0_vpu"), + + /* ctrl index = 50 */ + SLAVE_SENSOR_WRAP_ACX1_DLA0("apu_sen_ac1_dla0"), + SLAVE_SENSOR_WRAP_ACX1_DLA1("apu_sen_ac1_dla1"), + SLAVE_SENSOR_WRAP_ACX1_VPU0("apu_sen_ac1_vpu"), + SLAVE_REVISER("noc_cfg-0"), + SLAVE_NOC("noc_cfg-1"), + SLAVE_BCRM("infra_bcrm"), + SLAVE_DAPC_WRAP("infra_dapc_wrap"), + SLAVE_DAPC_CON("infra_dapc_con"), + SLAVE_NOC_DAPC_WRAP("noc_dapc_wrap"), + SLAVE_NOC_DAPC_CON("noc_dapc_con"), + + /* ctrl index = 60 */ + SLAVE_NOC_BCRM("noc_bcrm"), + SLAVE_ACS("apu_rcx_acs"), + SLAVE_HSE("apu_hse"), +}; + +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) +{ + uint32_t apc_register_index; + uint32_t apc_set_index; + uint32_t base; + uint32_t clr_bit; + uint32_t set_bit; + + if ((perm < 0) || (perm >= PERM_NUM)) { + ERROR(MODULE_TAG "%s: permission type:0x%x is not supported!\n", __func__, perm); + return APUSYS_APC_ERR_GENERIC; + } + + if ((slave >= APU_CTRL_DAPC_AO_SLAVE_NUM) || + ((domain_id < 0) || (domain_id >= APU_CTRL_DAPC_AO_DOM_NUM))) { + ERROR(MODULE_TAG "%s: out of boundary, slave:0x%x, domain_id:0x%x\n", + __func__, slave, domain_id); + return APUSYS_APC_ERR_GENERIC; + } + + apc_register_index = slave / APU_CTRL_DAPC_AO_SLAVE_NUM_IN_1_DOM; + apc_set_index = slave % APU_CTRL_DAPC_AO_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); + + base = (APU_CTRL_DAPC_AO_BASE + domain_id * DEVAPC_DOM_SIZE + + apc_register_index * DEVAPC_REG_SIZE); + + mmio_clrsetbits_32(base, clr_bit, set_bit); + return APUSYS_APC_OK; +} + +static enum apusys_apc_err_status set_slave_noc_dapc_rcx(uint32_t slave, + 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; + uint32_t clr_bit; + uint32_t set_bit; + + if ((perm >= PERM_NUM) || (perm < 0)) { + ERROR(MODULE_TAG "%s: permission type:0x%x is not supported!\n", __func__, perm); + return APUSYS_APC_ERR_GENERIC; + } + + if ((slave >= APU_NOC_DAPC_RCX_SLAVE_NUM) || + ((domain_id < 0) || (domain_id >= APU_NOC_DAPC_RCX_DOM_NUM))) { + ERROR(MODULE_TAG "%s: out of boundary, slave:0x%x, domain_id:0x%x\n", + __func__, slave, domain_id); + return APUSYS_APC_ERR_GENERIC; + } + + apc_register_index = slave / APU_NOC_DAPC_RCX_SLAVE_NUM_IN_1_DOM; + apc_set_index = slave % APU_NOC_DAPC_RCX_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); + base = (APU_NOC_DAPC_RCX_BASE + domain_id * DEVAPC_DOM_SIZE + + apc_register_index * DEVAPC_REG_SIZE); + + mmio_clrsetbits_32(base, clr_bit, set_bit); + return APUSYS_APC_OK; +} + +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) +{ + uint32_t apc_register_index; + uint32_t apc_set_index; + uint32_t base; + uint32_t clr_bit; + uint32_t set_bit; + + if ((perm < 0) || (perm >= PERM_NUM)) { + ERROR(MODULE_TAG "%s: permission type:0x%x is not supported!\n", __func__, perm); + return APUSYS_APC_ERR_GENERIC; + } + + if ((slave >= APU_CTRL_DAPC_RCX_SLAVE_NUM) || + ((domain_id < 0) || (domain_id >= APU_CTRL_DAPC_RCX_DOM_NUM))) { + ERROR(MODULE_TAG "%s: out of boundary, slave:0x%x, domain_id:0x%x\n", + __func__, slave, domain_id); + return APUSYS_APC_ERR_GENERIC; + } + + apc_register_index = slave / APU_CTRL_DAPC_RCX_SLAVE_NUM_IN_1_DOM; + apc_set_index = slave % APU_CTRL_DAPC_RCX_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); + base = (APU_CTRL_DAPC_RCX_BASE + domain_id * DEVAPC_DOM_SIZE + + apc_register_index * DEVAPC_REG_SIZE); + + mmio_clrsetbits_32(base, clr_bit, set_bit); + return APUSYS_APC_OK; +} + +static void apusys_devapc_init(const char *name, uint32_t base) +{ + mmio_write_32(APUSYS_DAPC_CON(base), APUSYS_DAPC_CON_VIO_MASK); +} + +int apusys_devapc_ao_init(void) +{ + enum apusys_apc_err_status ret; + + apusys_devapc_init("APUAPC_CTRL_AO", APU_CTRL_DAPC_AO_BASE); + + ret = SET_APUSYS_DAPC_V1(APU_CTRL_DAPC_AO, set_slave_ao_ctrl_apc); + if (ret != APUSYS_APC_OK) { + ERROR(MODULE_TAG "%s: set_apusys_ao_ctrl_dap FAILED!\n", __func__); + return -1; + } + +#if DUMP_APUSYS_DAPC + DUMP_APUSYS_DAPC_V1(APU_CTRL_DAPC_AO); +#endif + + return 0; +} + +int apusys_devapc_rcx_init(void) +{ + static bool apusys_devapc_rcx_init_called; + enum apusys_apc_err_status ret; + + if (apusys_devapc_rcx_init_called == true) { + INFO(MODULE_TAG "%s: init more than once!\n", __func__); + return -1; + } + apusys_devapc_rcx_init_called = true; + + apusys_devapc_init("APUAPC_CTRL_RCX", APU_CTRL_DAPC_RCX_BASE); + apusys_devapc_init("APUAPC_NOC_RCX", APU_NOC_DAPC_RCX_BASE); + + ret = SET_APUSYS_DAPC_V1(APU_CTRL_DAPC_RCX, set_slave_rcx_ctrl_apc); + if (ret != APUSYS_APC_OK) { + ERROR(MODULE_TAG "%s: set_slave_rcx_ctrl_apc FAILED!\n", __func__); + return -1; + } + +#if DUMP_APUSYS_DAPC + DUMP_APUSYS_DAPC_V1(APU_CTRL_DAPC_RCX); +#endif + + ret = SET_APUSYS_DAPC_V1(APU_NOC_DAPC_RCX, set_slave_noc_dapc_rcx); + if (ret != APUSYS_APC_OK) { + ERROR(MODULE_TAG "%s: set_slave_noc_dapc_rcx FAILED\n", __func__); + return -1; + } + +#if DUMP_APUSYS_DAPC + DUMP_APUSYS_DAPC_V1(APU_NOC_DAPC_RCX); +#endif + + return 0; +} diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_devapc.h b/plat/mediatek/drivers/apusys/mt8188/apusys_devapc.h new file mode 100644 index 0000000..de76459 --- /dev/null +++ b/plat/mediatek/drivers/apusys/mt8188/apusys_devapc.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef APUSYS_DEVAPC_H +#define APUSYS_DEVAPC_H + +int apusys_devapc_ao_init(void); +int apusys_devapc_rcx_init(void); + +#endif /* APUSYS_DEVAPC_H */ diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_devapc_def.h b/plat/mediatek/drivers/apusys/mt8188/apusys_devapc_def.h new file mode 100644 index 0000000..47a2a94 --- /dev/null +++ b/plat/mediatek/drivers/apusys/mt8188/apusys_devapc_def.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2023, 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" + +/* NoC */ +#define SLAVE_MD32_SRAM SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT + +/* Control */ +#define SLAVE_VCORE SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT +#define SLAVE_RPC SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_NO_PROTECT +#define SLAVE_PCU SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT +#define SLAVE_AO_CTRL SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT +#define SLAVE_PLL SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_NO_PROTECT +#define SLAVE_ACC SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT +#define SLAVE_SEC SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT +#define SLAVE_ARE0 SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT +#define SLAVE_ARE1 SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT +#define SLAVE_ARE2 SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT +#define SLAVE_UNKNOWN SLAVE_FORBID_EXCEPT_D5_NO_PROTECT +#define SLAVE_APU_BULK SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT +#define SLAVE_AO_BCRM SLAVE_FORBID_EXCEPT_D5_NO_PROTECT +#define SLAVE_AO_DAPC_WRAP SLAVE_FORBID_EXCEPT_D5_NO_PROTECT +#define SLAVE_AO_DAPC_CON SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT +#define SLAVE_RCX_ACX_BULK SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT +#define SLAVE_ACX0_BCRM SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT +#define SLAVE_RPCTOP_LITE_ACX0 SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT +#define SLAVE_ACX1_BCRM SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT +#define SLAVE_RPCTOP_LITE_ACX1 SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT +#define SLAVE_RCX_TO_ACX0_0 SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT +#define SLAVE_RCX_TO_ACX0_1 SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT +#define SLAVE_SAE_TO_ACX0_0 SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT +#define SLAVE_SAE_TO_ACX0_1 SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT +#define SLAVE_RCX_TO_ACX1_0 SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT +#define SLAVE_RCX_TO_ACX1_1 SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT +#define SLAVE_SAE_TO_ACX1_0 SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT +#define SLAVE_SAE_TO_ACX1_1 SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT +#define SLAVE_MD32_SYSCTRL0 SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT +#define SLAVE_MD32_SYSCTRL1 SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_NO_PROTECT +#define SLAVE_MD32_WDT SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT +#define SLAVE_MD32_CACHE SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT +#define SLAVE_NOC_AXI SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT +#define SLAVE_MD32_DBG SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT +#define SLAVE_DBG_CRTL SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT +#define SLAVE_IOMMU0_BANK0 SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT +#define SLAVE_IOMMU0_BANK1 SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT +#define SLAVE_IOMMU0_BANK2 SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT +#define SLAVE_IOMMU0_BANK3 SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT +#define SLAVE_IOMMU0_BANK4 SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT +#define SLAVE_IOMMU1_BANK0 SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT +#define SLAVE_IOMMU1_BANK1 SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT +#define SLAVE_IOMMU1_BANK2 SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT +#define SLAVE_IOMMU1_BANK3 SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT +#define SLAVE_IOMMU1_BANK4 SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT +#define SLAVE_S0_SSC SLAVE_FORBID_EXCEPT_D5_NO_PROTECT +#define SLAVE_N0_SSC SLAVE_FORBID_EXCEPT_D5_NO_PROTECT +#define SLAVE_ACP_SSC SLAVE_FORBID_EXCEPT_D5_NO_PROTECT +#define SLAVE_S1_SSC SLAVE_FORBID_EXCEPT_D5_NO_PROTECT +#define SLAVE_N1_SSC SLAVE_FORBID_EXCEPT_D5_NO_PROTECT +#define SLAVE_CFG SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_NO_PROTECT +#define SLAVE_SEMA_STIMER SLAVE_FORBID_EXCEPT_D5_NO_PROTECT +#define SLAVE_EMI_CFG SLAVE_FORBID_EXCEPT_D5_NO_PROTECT +#define SLAVE_LOG SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_NO_PROTECT +#define SLAVE_CPE_SENSOR SLAVE_FORBID_EXCEPT_D5_NO_PROTECT +#define SLAVE_CPE_COEF SLAVE_FORBID_EXCEPT_D5_NO_PROTECT +#define SLAVE_CPE_CTRL SLAVE_FORBID_EXCEPT_D5_NO_PROTECT +#define SLAVE_DFD_REG_SOC SLAVE_FORBID_EXCEPT_D5_NO_PROTECT +#define SLAVE_SENSOR_WRAP_ACX0_DLA0 SLAVE_FORBID_EXCEPT_D5_NO_PROTECT +#define SLAVE_SENSOR_WRAP_ACX0_DLA1 SLAVE_FORBID_EXCEPT_D5_NO_PROTECT +#define SLAVE_SENSOR_WRAP_ACX0_VPU0 SLAVE_FORBID_EXCEPT_D5_NO_PROTECT +#define SLAVE_SENSOR_WRAP_ACX1_DLA0 SLAVE_FORBID_EXCEPT_D5_NO_PROTECT +#define SLAVE_SENSOR_WRAP_ACX1_DLA1 SLAVE_FORBID_EXCEPT_D5_NO_PROTECT +#define SLAVE_SENSOR_WRAP_ACX1_VPU0 SLAVE_FORBID_EXCEPT_D5_NO_PROTECT +#define SLAVE_REVISER SLAVE_FORBID_EXCEPT_D0_SEC_RW +#define SLAVE_NOC SLAVE_FORBID_EXCEPT_D0_SEC_RW +#define SLAVE_BCRM SLAVE_FORBID_EXCEPT_D5_NO_PROTECT +#define SLAVE_DAPC_WRAP SLAVE_FORBID_EXCEPT_D5_NO_PROTECT +#define SLAVE_DAPC_CON SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT +#define SLAVE_NOC_DAPC_WRAP SLAVE_FORBID_EXCEPT_D5_NO_PROTECT +#define SLAVE_NOC_DAPC_CON SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT +#define SLAVE_NOC_BCRM SLAVE_FORBID_EXCEPT_D5_NO_PROTECT +#define SLAVE_ACS SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT +#define SLAVE_HSE SLAVE_FORBID_EXCEPT_D5_NO_PROTECT + + +/* Power Domain: AO */ +#define APU_CTRL_DAPC_AO_SLAVE_NUM_IN_1_DOM (16) +#define APU_CTRL_DAPC_AO_DOM_NUM (16) +#define APU_CTRL_DAPC_AO_SLAVE_NUM (30) +#define DEVAPC_MASK (0x3U) +#define DEVAPC_DOM_SHIFT (2) + +/* Power Domain: RCX */ +#define APU_CTRL_DAPC_RCX_SLAVE_NUM_IN_1_DOM (16) +#define APU_CTRL_DAPC_RCX_DOM_NUM (16) +#define APU_CTRL_DAPC_RCX_SLAVE_NUM (63) + +#define APU_NOC_DAPC_RCX_SLAVE_NUM_IN_1_DOM (16) +#define APU_NOC_DAPC_RCX_DOM_NUM (16) +#define APU_NOC_DAPC_RCX_SLAVE_NUM (5) + +#endif /* APUSYS_DEVAPC_DEF_H */ diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_power.c b/plat/mediatek/drivers/apusys/mt8188/apusys_power.c new file mode 100644 index 0000000..0a2781b --- /dev/null +++ b/plat/mediatek/drivers/apusys/mt8188/apusys_power.c @@ -0,0 +1,483 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <inttypes.h> + +/* TF-A system header */ +#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> + +/* Vendor header */ +#include "apusys.h" +#include "apusys_power.h" +#include "apusys_rv.h" +#include <mtk_mmap_pool.h> + +static spinlock_t apu_lock; +static bool apusys_top_on; + +static int apu_poll(uintptr_t reg, uint32_t mask, uint32_t value, uint32_t timeout_us) +{ + uint32_t reg_val, count; + + count = timeout_us / APU_POLL_STEP_US; + if (count == 0) { + count = 1; + } + + do { + reg_val = mmio_read_32(reg); + if ((reg_val & mask) == value) { + return 0; + } + udelay(APU_POLL_STEP_US); + } while (--count); + + ERROR(MODULE_TAG "Timeout polling APU register %#" PRIxPTR "\n", reg); + ERROR(MODULE_TAG "Read value 0x%x, expected 0x%x\n", reg_val, + (value == 0U) ? (reg_val & ~mask) : (reg_val | mask)); + + return -1; +} + +static void apu_backup_restore(enum APU_BACKUP_RESTORE_CTRL ctrl) +{ + int i; + static struct apu_restore_data apu_restore_data[] = { + { UP_NORMAL_DOMAIN_NS, 0 }, + { UP_PRI_DOMAIN_NS, 0 }, + { UP_IOMMU_CTRL, 0 }, + { UP_CORE0_VABASE0, 0 }, + { UP_CORE0_MVABASE0, 0 }, + { UP_CORE0_VABASE1, 0 }, + { UP_CORE0_MVABASE1, 0 }, + { UP_CORE0_VABASE2, 0 }, + { UP_CORE0_MVABASE2, 0 }, + { UP_CORE0_VABASE3, 0 }, + { UP_CORE0_MVABASE3, 0 }, + { MD32_SYS_CTRL, 0 }, + { MD32_CLK_CTRL, 0 }, + { UP_WAKE_HOST_MASK0, 0 } + }; + + switch (ctrl) { + case APU_CTRL_BACKUP: + for (i = 0; i < ARRAY_SIZE(apu_restore_data); i++) { + apu_restore_data[i].data = mmio_read_32(apu_restore_data[i].reg); + } + break; + case APU_CTRL_RESTORE: + for (i = 0; i < ARRAY_SIZE(apu_restore_data); i++) { + mmio_write_32(apu_restore_data[i].reg, apu_restore_data[i].data); + } + break; + default: + ERROR(MODULE_TAG "%s invalid op: %d\n", __func__, ctrl); + break; + } +} + +static void apu_xpu2apusys_d4_slv_en(enum APU_D4_SLV_CTRL en) +{ + switch (en) { + case D4_SLV_OFF: + mmio_setbits_32(BCRM_FMEM_PDN_BASE + INFRA_FMEM_BUS_u_SI21_CTRL_0, + INFRA_FMEM_BUS_u_SI21_CTRL_EN); + mmio_setbits_32(BCRM_FMEM_PDN_BASE + INFRA_FMEM_BUS_u_SI22_CTRL_0, + INFRA_FMEM_BUS_u_SI22_CTRL_EN); + mmio_setbits_32(BCRM_FMEM_PDN_BASE + INFRA_FMEM_BUS_u_SI11_CTRL_0, + INFRA_FMEM_BUS_u_SI11_CTRL_EN); + mmio_setbits_32(BCRM_FMEM_PDN_BASE + INFRA_FMEM_M6M7_BUS_u_SI24_CTRL_0, + INFRA_FMEM_M6M7_BUS_u_SI24_CTRL_EN); + break; + case D4_SLV_ON: + mmio_clrbits_32(BCRM_FMEM_PDN_BASE + INFRA_FMEM_BUS_u_SI21_CTRL_0, + INFRA_FMEM_BUS_u_SI21_CTRL_EN); + mmio_clrbits_32(BCRM_FMEM_PDN_BASE + INFRA_FMEM_BUS_u_SI22_CTRL_0, + INFRA_FMEM_BUS_u_SI22_CTRL_EN); + mmio_clrbits_32(BCRM_FMEM_PDN_BASE + INFRA_FMEM_BUS_u_SI11_CTRL_0, + INFRA_FMEM_BUS_u_SI11_CTRL_EN); + mmio_clrbits_32(BCRM_FMEM_PDN_BASE + INFRA_FMEM_M6M7_BUS_u_SI24_CTRL_0, + INFRA_FMEM_M6M7_BUS_u_SI24_CTRL_EN); + break; + default: + ERROR(MODULE_TAG "%s invalid op: %d\n", __func__, en); + break; + } +} + +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) +{ + int ret; + + spin_lock(&apu_lock); + + if (apusys_top_on == true) { + INFO(MODULE_TAG "%s: APUSYS already powered on!\n", __func__); + spin_unlock(&apu_lock); + return 0; + } + + apu_pwr_flow_remote_sync(1); + + mmio_setbits_32(APU_RPC_BASE + APU_RPC_TOP_SEL_1, AFC_ENA); + + mmio_write_32(APU_RPC_BASE + APU_RPC_TOP_CON, REG_WAKEUP_SET); + + ret = apu_poll(APU_RPC_BASE + APU_RPC_INTF_PWR_RDY, + PWR_RDY, PWR_RDY, APU_TOP_ON_POLLING_TIMEOUT_US); + if (ret != 0) { + ERROR(MODULE_TAG "%s polling RPC RDY timeout, ret %d\n", __func__, ret); + spin_unlock(&apu_lock); + return ret; + } + + ret = apu_poll(APU_RPC_BASE + APU_RPC_STATUS, + RPC_STATUS_RDY, RPC_STATUS_RDY, APU_TOP_ON_POLLING_TIMEOUT_US); + if (ret != 0) { + ERROR(MODULE_TAG "%s polling ARE FSM timeout, ret %d\n", __func__, ret); + spin_unlock(&apu_lock); + return ret; + } + + mmio_write_32(APU_VCORE_BASE + APUSYS_VCORE_CG_CLR, CG_CLR); + mmio_write_32(APU_RCX_BASE + APU_RCX_CG_CLR, CG_CLR); + + apu_xpu2apusys_d4_slv_en(D4_SLV_OFF); + + apu_backup_restore(APU_CTRL_RESTORE); + + apusys_top_on = true; + + spin_unlock(&apu_lock); + return ret; +} + +static void apu_sleep_rpc_rcx(void) +{ + mmio_write_32(APU_RPC_BASE + APU_RPC_TOP_CON, REG_WAKEUP_CLR); + dsb(); + udelay(10); + + mmio_setbits_32(APU_RPC_BASE + APU_RPC_TOP_SEL, (RPC_CTRL | RSV10)); + dsb(); + udelay(10); + + mmio_setbits_32(APU_RPC_BASE + APU_RPC_TOP_CON, CLR_IRQ); + dsb(); + udelay(10); + + mmio_setbits_32(APU_RPC_BASE + APU_RPC_TOP_CON, SLEEP_REQ); + dsb(); + udelay(100); +} + +int apusys_kernel_apusys_pwr_top_off(void) +{ + int ret; + + spin_lock(&apu_lock); + + if (apusys_top_on == false) { + INFO(MODULE_TAG "%s: APUSYS already powered off!\n", __func__); + spin_unlock(&apu_lock); + return 0; + } + + apu_backup_restore(APU_CTRL_BACKUP); + + apu_xpu2apusys_d4_slv_en(D4_SLV_ON); + + if (mmio_read_32(APU_MBOX0_BASE + PWR_FLOW_SYNC_REG) == 0) { + apu_pwr_flow_remote_sync(1); + } else { + apu_sleep_rpc_rcx(); + } + + ret = apu_poll(APU_RPC_BASE + APU_RPC_INTF_PWR_RDY, + PWR_RDY, PWR_OFF, APU_TOP_OFF_POLLING_TIMEOUT_US); + if (ret != 0) { + ERROR(MODULE_TAG "%s timeout to wait RPC sleep (val:%d), ret %d\n", + __func__, APU_TOP_OFF_POLLING_TIMEOUT_US, ret); + spin_unlock(&apu_lock); + return ret; + } + + apusys_top_on = false; + + spin_unlock(&apu_lock); + return ret; +} + +static void get_pll_pcw(const 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 apu_pll_init(void) +{ + const uint32_t pll_hfctl_cfg[PLL_NUM] = { + PLL4HPLL_FHCTL0_CFG, + PLL4HPLL_FHCTL1_CFG, + PLL4HPLL_FHCTL2_CFG, + PLL4HPLL_FHCTL3_CFG + }; + const uint32_t pll_con1[PLL_NUM] = { + PLL4H_PLL1_CON1, + PLL4H_PLL2_CON1, + PLL4H_PLL3_CON1, + PLL4H_PLL4_CON1 + }; + const uint32_t pll_fhctl_dds[PLL_NUM] = { + PLL4HPLL_FHCTL0_DDS, + PLL4HPLL_FHCTL1_DDS, + PLL4HPLL_FHCTL2_DDS, + PLL4HPLL_FHCTL3_DDS + }; + const uint32_t pll_freq_out[PLL_NUM] = { + APUPLL0_DEFAULT_FREQ, + APUPLL1_DEFAULT_FREQ, + APUPLL2_DEFAULT_FREQ, + APUPLL3_DEFAULT_FREQ + }; + uint32_t pcw_val, posdiv_val; + int pll_idx; + + mmio_setbits_32(APU_PLL_BASE + PLL4HPLL_FHCTL_RST_CON, PLL4H_PLL_HP_SWRSTB); + mmio_setbits_32(APU_PLL_BASE + PLL4HPLL_FHCTL_HP_EN, PLL4H_PLL_HP_EN); + mmio_setbits_32(APU_PLL_BASE + PLL4HPLL_FHCTL_CLK_CON, PLL4H_PLL_HP_CLKEN); + + for (pll_idx = 0; pll_idx < PLL_NUM; pll_idx++) { + mmio_setbits_32(APU_PLL_BASE + pll_hfctl_cfg[pll_idx], (FHCTL0_EN | SFSTR0_EN)); + + posdiv_val = 0; + pcw_val = 0; + get_pll_pcw(pll_freq_out[pll_idx], &posdiv_val, &pcw_val); + + mmio_clrsetbits_32(APU_PLL_BASE + pll_con1[pll_idx], + (RG_PLL_POSDIV_MASK << RG_PLL_POSDIV_SFT), + (posdiv_val << RG_PLL_POSDIV_SFT)); + mmio_write_32(APU_PLL_BASE + pll_fhctl_dds[pll_idx], + (FHCTL_PLL_TGL_ORG | pcw_val)); + } +} + +static void apu_acc_init(void) +{ + mmio_write_32(APU_ACC_BASE + APU_ACC_CONFG_CLR0, CGEN_SOC); + mmio_write_32(APU_ACC_BASE + APU_ACC_CONFG_SET0, HW_CTRL_EN); + + mmio_write_32(APU_ACC_BASE + APU_ACC_CONFG_CLR1, CGEN_SOC); + mmio_write_32(APU_ACC_BASE + APU_ACC_CONFG_SET1, HW_CTRL_EN); + + mmio_write_32(APU_ACC_BASE + APU_ACC_CONFG_CLR2, CGEN_SOC); + mmio_write_32(APU_ACC_BASE + APU_ACC_CONFG_SET2, HW_CTRL_EN); + mmio_write_32(APU_ACC_BASE + APU_ACC_AUTO_CTRL_SET2, CLK_REQ_SW_EN); + + mmio_write_32(APU_ACC_BASE + APU_ACC_CONFG_CLR3, CGEN_SOC); + mmio_write_32(APU_ACC_BASE + APU_ACC_CONFG_SET3, HW_CTRL_EN); + mmio_write_32(APU_ACC_BASE + APU_ACC_AUTO_CTRL_SET3, CLK_REQ_SW_EN); + + mmio_write_32(APU_ACC_BASE + APU_ACC_CLK_INV_EN_SET, CLK_INV_EN); +} + +static void apu_buck_off_cfg(void) +{ + mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, BUCK_PROT_REQ_SET); + dsb(); + udelay(10); + + mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, BUCK_ELS_EN_SET); + dsb(); + udelay(10); + + mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, BUCK_AO_RST_B_CLR); + dsb(); + udelay(10); +} + +static void apu_pcu_init(void) +{ + uint32_t vapu_en_offset = BUCK_VAPU_PMIC_REG_EN_ADDR; + uint32_t vapu_sram_en_offset = BUCK_VAPU_SRAM_PMIC_REG_EN_ADDR; + + mmio_write_32(APU_PCU_BASE + APU_PCU_CTRL_SET, AUTO_BUCK_EN); + + mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_STEP_SEL, BUCK_ON_OFF_CMD_EN); + + mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_ON_DAT0_L, + ((vapu_sram_en_offset << BUCK_OFFSET_SFT) + BUCK_ON_CMD)); + mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_ON_DAT0_H, CMD_OP); + + mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_ON_DAT1_L, + ((vapu_en_offset << BUCK_OFFSET_SFT) + BUCK_ON_CMD)); + mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_ON_DAT1_H, CMD_OP); + + mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_OFF_DAT0_L, + ((vapu_en_offset << BUCK_OFFSET_SFT) + BUCK_OFF_CMD)); + mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_OFF_DAT0_H, CMD_OP); + + mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_OFF_DAT1_L, + ((vapu_sram_en_offset << BUCK_OFFSET_SFT) + BUCK_OFF_CMD)); + mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_OFF_DAT1_H, CMD_OP); + + mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_ON_SLE0, APU_PCU_BUCK_ON_SETTLE_TIME); + mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_ON_SLE1, APU_PCU_BUCK_ON_SETTLE_TIME); +} + +static void apu_rpclite_init(void) +{ + const uint32_t sleep_type_offset[] = { + APU_RPC_SW_TYPE2, + APU_RPC_SW_TYPE3, + APU_RPC_SW_TYPE4, + APU_RPC_SW_TYPE5, + APU_RPC_SW_TYPE6, + APU_RPC_SW_TYPE7, + APU_RPC_SW_TYPE8, + APU_RPC_SW_TYPE9 + }; + int ofs_arr_size = ARRAY_SIZE(sleep_type_offset); + int ofs_idx; + + for (ofs_idx = 0 ; ofs_idx < ofs_arr_size ; ofs_idx++) { + mmio_clrbits_32(APU_ACX0_RPC_LITE_BASE + sleep_type_offset[ofs_idx], + SW_TYPE); + } + + mmio_setbits_32(APU_ACX0_RPC_LITE_BASE + APU_RPC_TOP_SEL, RPC_CTRL); +} + +static void apu_rpc_init(void) +{ + mmio_clrbits_32(APU_RPC_BASE + APU_RPC_SW_TYPE0, SW_TYPE); + mmio_setbits_32(APU_RPC_BASE + APU_RPC_TOP_SEL, RPC_TOP_CTRL); + mmio_setbits_32(APU_RPC_BASE + APU_RPC_TOP_SEL_1, RPC_TOP_CTRL1); +} + +static int apu_are_init(void) +{ + int ret; + int are_id = 0; + const uint32_t are_base[APU_ARE_NUM] = { APU_ARE0_BASE, APU_ARE1_BASE, APU_ARE2_BASE }; + const uint32_t are_entry2_cfg_l[APU_ARE_NUM] = { + ARE0_ENTRY2_CFG_L, + ARE1_ENTRY2_CFG_L, + ARE2_ENTRY2_CFG_L + }; + + mmio_setbits_32(APU_AO_CTL_BASE + CSR_DUMMY_0_ADDR, VCORE_ARE_REQ); + + ret = apu_poll(APU_ARE2_BASE + APU_ARE_GLO_FSM, ARE_GLO_FSM_IDLE, ARE_GLO_FSM_IDLE, + APU_ARE_POLLING_TIMEOUT_US); + if (ret != 0) { + ERROR(MODULE_TAG "[%s][%d] ARE init timeout\n", + __func__, __LINE__); + return ret; + } + + for (are_id = APU_ARE0; are_id < APU_ARE_NUM; are_id++) { + mmio_write_32(are_base[are_id] + APU_ARE_ENTRY0_SRAM_H, ARE_ENTRY0_SRAM_H_INIT); + mmio_write_32(are_base[are_id] + APU_ARE_ENTRY0_SRAM_L, ARE_ENTRY0_SRAM_L_INIT); + + mmio_write_32(are_base[are_id] + APU_ARE_ENTRY1_SRAM_H, ARE_ENTRY1_SRAM_H_INIT); + mmio_write_32(are_base[are_id] + APU_ARE_ENTRY1_SRAM_L, ARE_ENTRY1_SRAM_L_INIT); + + mmio_write_32(are_base[are_id] + APU_ARE_ENTRY2_SRAM_H, ARE_ENTRY_CFG_H); + mmio_write_32(are_base[are_id] + APU_ARE_ENTRY2_SRAM_L, are_entry2_cfg_l[are_id]); + + mmio_read_32(are_base[are_id] + APU_ARE_ENTRY2_SRAM_H); + mmio_read_32(are_base[are_id] + APU_ARE_ENTRY2_SRAM_L); + + mmio_write_32(are_base[are_id] + APU_ARE_INI_CTRL, ARE_CONFG_INI); + } + + return ret; +} + +static void apu_aoc_init(void) +{ + mmio_clrbits_32(SPM_BASE + APUSYS_BUCK_ISOLATION, IPU_EXT_BUCK_ISO); + mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, BUCK_ELS_EN_CLR); + dsb(); + udelay(10); + + mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, BUCK_AO_RST_B_SET); + dsb(); + udelay(10); + + mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, BUCK_PROT_REQ_CLR); + dsb(); + udelay(10); + + mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, SRAM_AOC_ISO_CLR); + dsb(); + udelay(10); +} + +static int init_hw_setting(void) +{ + int ret; + + apu_aoc_init(); + apu_pcu_init(); + apu_rpc_init(); + apu_rpclite_init(); + + ret = apu_are_init(); + if (ret != 0) { + return ret; + } + + 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(MODULE_TAG "%s initial fail\n", __func__); + } else { + INFO(MODULE_TAG "%s initial done\n", __func__); + } + + return ret; +} diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_power.h b/plat/mediatek/drivers/apusys/mt8188/apusys_power.h new file mode 100644 index 0000000..460cc50 --- /dev/null +++ b/plat/mediatek/drivers/apusys/mt8188/apusys_power.h @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef APUSYS_POWER_H +#define APUSYS_POWER_H + +#include <platform_def.h> + +enum APU_CLKSRC_ID { + PLL_CONN = 0, /* MNOC */ + PLL_UP, + PLL_VPU, + PLL_DLA, + PLL_NUM, +}; + +enum APU_ARE_ID { + APU_ARE0 = 0, + APU_ARE1, + APU_ARE2, + APU_ARE_NUM, +}; + +enum APU_D4_SLV_CTRL { + D4_SLV_OFF = 0, + D4_SLV_ON, +}; + +enum APU_BACKUP_RESTORE_CTRL { + APU_CTRL_BACKUP = 0, + APU_CTRL_RESTORE = 1, +}; + +struct apu_restore_data { + uint32_t reg; + uint32_t data; +}; + +#define APU_POLL_STEP_US (5) + +#define OUT_CLK_FREQ_MIN (1500) +#define BASIC_CLK_FREQ (26) +#define DDS_SHIFT (14) + +#define APUPLL0_DEFAULT_FREQ (900) +#define APUPLL1_DEFAULT_FREQ (832) +#define APUPLL2_DEFAULT_FREQ (700) +#define APUPLL3_DEFAULT_FREQ (700) + +#define APU_TOP_ON_POLLING_TIMEOUT_US (10000) +#define APU_TOP_OFF_POLLING_TIMEOUT_US (5 * APU_TOP_ON_POLLING_TIMEOUT_US) +#define APU_ARE_POLLING_TIMEOUT_US (10000) + +/* APU related reg */ +#define APU_VCORE_BASE (APU_RCX_VCORE_CONFIG) +#define APU_RCX_BASE (APU_RCX_CONFIG) +#define APU_RPC_BASE (APU_RPCTOP) +#define APU_PCU_BASE (APU_PCUTOP) +#define APU_ARE0_BASE (APU_ARETOP_ARE0) +#define APU_ARE1_BASE (APU_ARETOP_ARE1) +#define APU_ARE2_BASE (APU_ARETOP_ARE2) +#define APU_MBOX0_BASE (APU_MBOX0) +#define APU_AO_CTL_BASE (APU_AO_CTRL) +#define APU_PLL_BASE (APU_PLL) +#define APU_ACC_BASE (APU_ACC) +#define APU_ACX0_RPC_LITE_BASE (APU_ACX0_RPC_LITE) + +/* RPC offset define */ +#define APU_RPC_TOP_CON (0x0000) +#define APU_RPC_TOP_SEL (0x0004) +#define APU_RPC_STATUS (0x0014) +#define APU_RPC_TOP_SEL_1 (0x0018) +#define APU_RPC_HW_CON (0x001c) +#define APU_RPC_INTF_PWR_RDY (0x0044) +#define APU_RPC_SW_TYPE0 (0x0200) + +/* RPC control */ +#define SRAM_AOC_ISO_CLR BIT(7) +#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) +#define SW_TYPE BIT(1) +#define RPC_CTRL (0x0000009e) +#define RPC_TOP_CTRL (0x0800501e) +#define RPC_TOP_CTRL1 BIT(20) +#define AFC_ENA BIT(16) +#define REG_WAKEUP_SET BIT(8) +#define REG_WAKEUP_CLR BIT(12) +#define PWR_RDY BIT(0) +#define PWR_OFF (0) +#define RPC_STATUS_RDY BIT(29) +#define RSV10 BIT(10) +#define CLR_IRQ (0x6) +#define SLEEP_REQ BIT(0) + +/* PLL offset define */ +#define PLL4H_PLL1_CON1 (0x000c) +#define PLL4H_PLL2_CON1 (0x001c) +#define PLL4H_PLL3_CON1 (0x002c) +#define PLL4H_PLL4_CON1 (0x003c) +#define PLL4HPLL_FHCTL_HP_EN (0x0e00) +#define PLL4HPLL_FHCTL_CLK_CON (0x0e08) +#define PLL4HPLL_FHCTL_RST_CON (0x0e0c) +#define PLL4HPLL_FHCTL0_CFG (0x0e3c) +#define PLL4HPLL_FHCTL0_DDS (0x0e44) +#define PLL4HPLL_FHCTL1_CFG (0x0e50) +#define PLL4HPLL_FHCTL1_DDS (0x0e58) +#define PLL4HPLL_FHCTL2_CFG (0x0e64) +#define PLL4HPLL_FHCTL2_DDS (0x0e6c) +#define PLL4HPLL_FHCTL3_CFG (0x0e78) +#define PLL4HPLL_FHCTL3_DDS (0x0e80) + +/* PLL control */ +#define PLL4H_PLL_HP_EN (0xf) +#define PLL4H_PLL_HP_CLKEN (0xf) +#define PLL4H_PLL_HP_SWRSTB (0xf) +#define FHCTL0_EN BIT(0) +#define SFSTR0_EN BIT(2) +#define RG_PLL_POSDIV_MASK (0x7) +#define RG_PLL_POSDIV_SFT (24) +#define FHCTL_PLL_TGL_ORG BIT(31) + +/* ACC offset define */ +#define APU_ACC_CONFG_SET0 (0x0000) +#define APU_ACC_CONFG_SET1 (0x0004) +#define APU_ACC_CONFG_SET2 (0x0008) +#define APU_ACC_CONFG_SET3 (0x000c) +#define APU_ACC_CONFG_CLR0 (0x0040) +#define APU_ACC_CONFG_CLR1 (0x0044) +#define APU_ACC_CONFG_CLR2 (0x0048) +#define APU_ACC_CONFG_CLR3 (0x004c) +#define APU_ACC_CLK_INV_EN_SET (0x00e8) +#define APU_ACC_AUTO_CTRL_SET2 (0x0128) +#define APU_ACC_AUTO_CTRL_SET3 (0x012c) + +/* ACC control */ +#define CGEN_SOC BIT(2) +#define HW_CTRL_EN BIT(15) +#define CLK_REQ_SW_EN BIT(8) +#define CLK_INV_EN (0xaaa8) + +/* ARE offset define */ +#define APU_ARE_INI_CTRL (0x0000) +#define APU_ARE_GLO_FSM (0x0048) +#define APU_ARE_ENTRY0_SRAM_H (0x0c00) +#define APU_ARE_ENTRY0_SRAM_L (0x0800) +#define APU_ARE_ENTRY1_SRAM_H (0x0c04) +#define APU_ARE_ENTRY1_SRAM_L (0x0804) +#define APU_ARE_ENTRY2_SRAM_H (0x0c08) +#define APU_ARE_ENTRY2_SRAM_L (0x0808) + +/* ARE control */ +#define ARE_ENTRY_CFG_H (0x00140000) +#define ARE0_ENTRY2_CFG_L (0x004e0804) +#define ARE1_ENTRY2_CFG_L (0x004e0806) +#define ARE2_ENTRY2_CFG_L (0x004e0807) +#define ARE_GLO_FSM_IDLE BIT(0) +#define ARE_ENTRY0_SRAM_H_INIT (0x12345678) +#define ARE_ENTRY0_SRAM_L_INIT (0x89abcdef) +#define ARE_ENTRY1_SRAM_H_INIT (0xfedcba98) +#define ARE_ENTRY1_SRAM_L_INIT (0x76543210) +#define ARE_CONFG_INI BIT(2) + +/* VCORE offset define */ +#define APUSYS_VCORE_CG_CLR (0x0008) + +/* RCX offset define */ +#define APU_RCX_CG_CLR (0x0008) + +/* SPM offset define */ +#define APUSYS_BUCK_ISOLATION (0x03ec) + +/* SPM control*/ +#define IPU_EXT_BUCK_ISO (0x21) + +/* apu_rcx_ao_ctrl */ +#define CSR_DUMMY_0_ADDR (0x0024) + +/* apu_rcx_ao_ctrl control */ +#define VCORE_ARE_REQ BIT(2) + +/* xpu2apusys */ +#define INFRA_FMEM_BUS_u_SI21_CTRL_0 (0x002c) +#define INFRA_FMEM_BUS_u_SI22_CTRL_0 (0x0044) +#define INFRA_FMEM_BUS_u_SI11_CTRL_0 (0x0048) +#define INFRA_FMEM_M6M7_BUS_u_SI24_CTRL_0 (0x01d0) + +/* xpu2apusys */ +#define INFRA_FMEM_BUS_u_SI21_CTRL_EN BIT(12) +#define INFRA_FMEM_BUS_u_SI22_CTRL_EN BIT(13) +#define INFRA_FMEM_BUS_u_SI11_CTRL_EN BIT(11) +#define INFRA_FMEM_M6M7_BUS_u_SI24_CTRL_EN BIT(15) + +/* PCU offset define */ +#define APU_PCU_CTRL_SET (0x0000) +#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_OFF_DAT1_L (0x00a8) +#define APU_PCU_BUCK_OFF_DAT1_H (0x00ac) +#define APU_PCU_BUCK_ON_SLE0 (0x00c0) +#define APU_PCU_BUCK_ON_SLE1 (0x00c4) +#define APU_PCU_BUCK_ON_SETTLE_TIME (0x012c) + +/* PCU initial data */ +#define MT6359P_RG_BUCK_VMODEM_EN_ADDR (0x1688) +#define MT6359P_RG_LDO_VSRAM_MD_EN_ADDR (0x1f2e) +#define BUCK_VAPU_PMIC_REG_EN_ADDR MT6359P_RG_BUCK_VMODEM_EN_ADDR +#define BUCK_VAPU_SRAM_PMIC_REG_EN_ADDR MT6359P_RG_LDO_VSRAM_MD_EN_ADDR + +/* PCU control */ +#define AUTO_BUCK_EN BIT(16) +#define BUCK_ON_OFF_CMD_EN (0x33) +#define BUCK_OFFSET_SFT (16) +#define BUCK_ON_CMD (0x1) +#define BUCK_OFF_CMD (0x0) +#define CMD_OP (0x4) + +/* RPC lite offset define */ +#define APU_RPC_SW_TYPE2 (0x0208) +#define APU_RPC_SW_TYPE3 (0x020c) +#define APU_RPC_SW_TYPE4 (0x0210) +#define APU_RPC_SW_TYPE5 (0x0214) +#define APU_RPC_SW_TYPE6 (0x0218) +#define APU_RPC_SW_TYPE7 (0x021c) +#define APU_RPC_SW_TYPE8 (0x0220) +#define APU_RPC_SW_TYPE9 (0x0224) + +/* power flow sync */ +#define PWR_FLOW_SYNC_REG (0x0440) + +#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 */ diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.c b/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.c new file mode 100644 index 0000000..86bebe5 --- /dev/null +++ b/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* TF-A system header */ +#include <common/debug.h> +#include <lib/mmio.h> + +/* Vendor header */ +#include "apusys_security_ctrl_plat.h" + +static void apusys_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 < REG_DOMAIN_NUM) { + lower_domain |= (remap_domains[i] << (i * REG_DOMAIN_BITS)); + } else { + higher_domain |= (remap_domains[i] << + ((i - REG_DOMAIN_NUM) * REG_DOMAIN_BITS)); + } + } + + mmio_write_32(SOC2APU_SET1_0, lower_domain); + mmio_write_32(SOC2APU_SET1_1, higher_domain); + mmio_setbits_32(APU_SEC_CON, DOMAIN_REMAP_SEL); +} + +void apusys_security_ctrl_init(void) +{ + apusys_domain_remap_init(); +} diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.h b/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.h new file mode 100644 index 0000000..f9181ae --- /dev/null +++ b/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef APUSYS_SECURITY_CTRL_PLAT_H +#define APUSYS_SECURITY_CTRL_PLAT_H + +#include <platform_def.h> + +#define SOC2APU_SET1_0 (APU_SEC_CON + 0x0c) +#define SOC2APU_SET1_1 (APU_SEC_CON + 0x10) + +#define REG_DOMAIN_NUM (8) +#define REG_DOMAIN_BITS (4) +#define DOMAIN_REMAP_SEL BIT(6) + +#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 (14) +#define D6_REMAP_DOMAIN (6) +#define D7_REMAP_DOMAIN (14) +#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 (14) +#define D15_REMAP_DOMAIN (15) + +void apusys_security_ctrl_init(void); + +#endif /* APUSYS_SECURITY_CTRL_PLAT_H */ diff --git a/plat/mediatek/drivers/apusys/mt8188/rules.mk b/plat/mediatek/drivers/apusys/mt8188/rules.mk new file mode 100644 index 0000000..c358067 --- /dev/null +++ b/plat/mediatek/drivers/apusys/mt8188/rules.mk @@ -0,0 +1,15 @@ +# +# Copyright (c) 2023, MediaTek Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +LOCAL_DIR := $(call GET_LOCAL_DIR) + +MODULE := apusys_${MTK_SOC} + +LOCAL_SRCS-y := ${LOCAL_DIR}/apusys_devapc.c +LOCAL_SRCS-y += ${LOCAL_DIR}/apusys_power.c +LOCAL_SRCS-y += ${LOCAL_DIR}/apusys_security_ctrl_plat.c + +$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL))) |