diff options
Diffstat (limited to 'plat/mediatek/drivers')
130 files changed, 16113 insertions, 0 deletions
diff --git a/plat/mediatek/drivers/apusys/apusys.c b/plat/mediatek/drivers/apusys/apusys.c new file mode 100644 index 0000000..dfe1dcf --- /dev/null +++ b/plat/mediatek/drivers/apusys/apusys.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* TF-A system header */ +#include <common/debug.h> + +/* Vendor header */ +#include "apusys.h" +#include "apusys_devapc.h" +#include "apusys_power.h" +#include "apusys_rv.h" +#include "apusys_security_ctrl_plat.h" +#include <lib/mtk_init/mtk_init.h> +#include <mtk_sip_svc.h> + +static u_register_t apusys_kernel_handler(u_register_t x1, + u_register_t x2, + u_register_t x3, + u_register_t x4, + void *handle, + struct smccc_res *smccc_ret) +{ + uint32_t request_ops; + int32_t ret = -1; + + request_ops = (uint32_t)x1; + + switch (request_ops) { + case MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_ON: + ret = apusys_kernel_apusys_pwr_top_on(); + break; + case MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_OFF: + ret = apusys_kernel_apusys_pwr_top_off(); + break; + case MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_REVISER: + ret = apusys_kernel_apusys_rv_setup_reviser(); + break; + case MTK_APUSYS_KERNEL_OP_APUSYS_RV_RESET_MP: + ret = apusys_kernel_apusys_rv_reset_mp(); + break; + case MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_BOOT: + ret = apusys_kernel_apusys_rv_setup_boot(); + break; + case MTK_APUSYS_KERNEL_OP_APUSYS_RV_START_MP: + ret = apusys_kernel_apusys_rv_start_mp(); + break; + case MTK_APUSYS_KERNEL_OP_APUSYS_RV_STOP_MP: + ret = apusys_kernel_apusys_rv_stop_mp(); + break; + case MTK_APUSYS_KERNEL_OP_DEVAPC_INIT_RCX: + ret = apusys_devapc_rcx_init(); + break; + case MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_SEC_MEM: + ret = apusys_kernel_apusys_rv_setup_sec_mem(); + break; + case MTK_APUSYS_KERNEL_OP_APUSYS_RV_DISABLE_WDT_ISR: + ret = apusys_kernel_apusys_rv_disable_wdt_isr(); + break; + case MTK_APUSYS_KERNEL_OP_APUSYS_RV_CLEAR_WDT_ISR: + ret = apusys_kernel_apusys_rv_clear_wdt_isr(); + break; + case MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_GATING: + ret = apusys_kernel_apusys_rv_cg_gating(); + break; + case MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_UNGATING: + ret = apusys_kernel_apusys_rv_cg_ungating(); + break; + default: + ERROR(MODULE_TAG "%s unknown request_ops = %x\n", MODULE_TAG, request_ops); + break; + } + + return ret; +} +DECLARE_SMC_HANDLER(MTK_SIP_APUSYS_CONTROL, apusys_kernel_handler); + +int apusys_init(void) +{ + if (apusys_power_init() != 0) { + return -1; + } + + if (apusys_devapc_ao_init() != 0) { + return -1; + } + + apusys_security_ctrl_init(); + apusys_rv_mbox_mpu_init(); + + return 0; +} +MTK_PLAT_SETUP_1_INIT(apusys_init); diff --git a/plat/mediatek/drivers/apusys/apusys.h b/plat/mediatek/drivers/apusys/apusys.h new file mode 100644 index 0000000..ed4e195 --- /dev/null +++ b/plat/mediatek/drivers/apusys/apusys.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef APUSYS_H +#define APUSYS_H + +#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_NUM, +}; + +#endif diff --git a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c new file mode 100644 index 0000000..86c4b81 --- /dev/null +++ b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* TF-A system header */ +#include <common/debug.h> +#include <drivers/delay_timer.h> +#include <lib/mmio.h> +#include <lib/spinlock.h> + +/* Vendor header */ +#include "apusys.h" +#include "apusys_rv.h" +#include "apusys_rv_mbox_mpu.h" +#include "emi_mpu.h" + +static spinlock_t apusys_rv_lock; + +void apusys_rv_mbox_mpu_init(void) +{ + int i; + + for (i = 0; i < APU_MBOX_NUM; i++) { + mmio_write_32(APU_MBOX_FUNC_CFG(i), + (MBOX_CTRL_LOCK | + (mbox_mpu_setting_tab[i].no_mpu << MBOX_NO_MPU_SHIFT))); + mmio_write_32(APU_MBOX_DOMAIN_CFG(i), + (MBOX_CTRL_LOCK | + (mbox_mpu_setting_tab[i].rx_ns << MBOX_RX_NS_SHIFT) | + (mbox_mpu_setting_tab[i].rx_domain << MBOX_RX_DOMAIN_SHIFT) | + (mbox_mpu_setting_tab[i].tx_ns << MBOX_TX_NS_SHIFT) | + (mbox_mpu_setting_tab[i].tx_domain << MBOX_TX_DOMAIN_SHIFT))); + } +} + +int apusys_kernel_apusys_rv_setup_reviser(void) +{ + static bool apusys_rv_setup_reviser_called; + + spin_lock(&apusys_rv_lock); + + if (apusys_rv_setup_reviser_called) { + WARN(MODULE_TAG "%s: already initialized\n", __func__); + spin_unlock(&apusys_rv_lock); + return -1; + } + + apusys_rv_setup_reviser_called = true; + + mmio_write_32(USERFW_CTXT, CFG_4GB_SEL_EN | CFG_4GB_SEL); + mmio_write_32(SECUREFW_CTXT, CFG_4GB_SEL_EN | CFG_4GB_SEL); + + mmio_write_32(UP_IOMMU_CTRL, MMU_CTRL_LOCK | MMU_CTRL | MMU_EN); + + mmio_write_32(UP_NORMAL_DOMAIN_NS, + (UP_NORMAL_DOMAIN << UP_DOMAIN_SHIFT) | (UP_NORMAL_NS << UP_NS_SHIFT)); + mmio_write_32(UP_PRI_DOMAIN_NS, + (UP_PRI_DOMAIN << UP_DOMAIN_SHIFT) | (UP_PRI_NS << UP_NS_SHIFT)); + + mmio_write_32(UP_CORE0_VABASE0, + VLD | PARTIAL_ENABLE | (THREAD_NUM_PRI << THREAD_NUM_SHIFT)); + mmio_write_32(UP_CORE0_MVABASE0, VASIZE_1MB | (APU_SEC_FW_IOVA >> MVA_34BIT_SHIFT)); + + mmio_write_32(UP_CORE0_VABASE1, + VLD | PARTIAL_ENABLE | (THREAD_NUM_NORMAL << THREAD_NUM_SHIFT)); + mmio_write_32(UP_CORE0_MVABASE1, VASIZE_1MB | (APU_SEC_FW_IOVA >> MVA_34BIT_SHIFT)); + + spin_unlock(&apusys_rv_lock); + + return 0; +} + +int apusys_kernel_apusys_rv_reset_mp(void) +{ + static bool apusys_rv_reset_mp_called; + + spin_lock(&apusys_rv_lock); + + if (apusys_rv_reset_mp_called) { + WARN(MODULE_TAG "%s: already initialized\n", __func__); + spin_unlock(&apusys_rv_lock); + return -1; + } + + apusys_rv_reset_mp_called = true; + + mmio_write_32(MD32_SYS_CTRL, MD32_SYS_CTRL_RST); + + dsb(); + udelay(RESET_DEALY_US); + + mmio_write_32(MD32_SYS_CTRL, MD32_G2B_CG_EN | MD32_DBG_EN | MD32_DM_AWUSER_IOMMU_EN | + MD32_DM_ARUSER_IOMMU_EN | MD32_PM_AWUSER_IOMMU_EN | MD32_PM_ARUSER_IOMMU_EN | + MD32_SOFT_RSTN); + + mmio_write_32(MD32_CLK_CTRL, MD32_CLK_EN); + mmio_write_32(UP_WAKE_HOST_MASK0, WDT_IRQ_EN); + mmio_write_32(UP_WAKE_HOST_MASK1, MBOX0_IRQ_EN | MBOX1_IRQ_EN | MBOX2_IRQ_EN); + + spin_unlock(&apusys_rv_lock); + + return 0; +} + +int apusys_kernel_apusys_rv_setup_boot(void) +{ + static bool apusys_rv_setup_boot_called; + + spin_lock(&apusys_rv_lock); + + if (apusys_rv_setup_boot_called) { + WARN(MODULE_TAG "%s: already initialized\n", __func__); + spin_unlock(&apusys_rv_lock); + return -1; + } + + apusys_rv_setup_boot_called = true; + + mmio_write_32(MD32_BOOT_CTRL, APU_SEC_FW_IOVA); + + mmio_write_32(MD32_PRE_DEFINE, (PREDEFINE_CACHE_TCM << PREDEF_1G_OFS) | + (PREDEFINE_CACHE << PREDEF_2G_OFS) | (PREDEFINE_CACHE << PREDEF_3G_OFS) | + (PREDEFINE_CACHE << PREDEF_4G_OFS)); + + spin_unlock(&apusys_rv_lock); + return 0; +} + +int apusys_kernel_apusys_rv_start_mp(void) +{ + static bool apusys_rv_start_mp_called; + + spin_lock(&apusys_rv_lock); + + if (apusys_rv_start_mp_called) { + WARN(MODULE_TAG "%s: already initialized\n", __func__); + spin_unlock(&apusys_rv_lock); + return -1; + } + + apusys_rv_start_mp_called = true; + + mmio_write_32(MD32_RUNSTALL, MD32_RUN); + + spin_unlock(&apusys_rv_lock); + + return 0; +} + +static bool watch_dog_is_timeout(void) +{ + if (mmio_read_32(WDT_INT) != WDT_INT_W1C) { + ERROR(MODULE_TAG "%s: WDT does not timeout\n", __func__); + return false; + } + return true; +} + +int apusys_kernel_apusys_rv_stop_mp(void) +{ + static bool apusys_rv_stop_mp_called; + + spin_lock(&apusys_rv_lock); + + if (apusys_rv_stop_mp_called) { + WARN(MODULE_TAG "%s: already initialized\n", __func__); + spin_unlock(&apusys_rv_lock); + return -1; + } + + if (watch_dog_is_timeout() == false) { + spin_unlock(&apusys_rv_lock); + return -1; + } + + apusys_rv_stop_mp_called = true; + + mmio_write_32(MD32_RUNSTALL, MD32_STALL); + + spin_unlock(&apusys_rv_lock); + + return 0; +} + +int apusys_kernel_apusys_rv_setup_sec_mem(void) +{ + static bool apusys_rv_setup_sec_mem_called; + int ret; + + spin_lock(&apusys_rv_lock); + + if (apusys_rv_setup_sec_mem_called) { + WARN(MODULE_TAG "%s: already initialized\n", __func__); + spin_unlock(&apusys_rv_lock); + return -1; + } + + apusys_rv_setup_sec_mem_called = true; + + ret = set_apu_emi_mpu_region(); + if (ret != 0) { + ERROR(MODULE_TAG "%s: set emimpu protection failed\n", __func__); + } + + spin_unlock(&apusys_rv_lock); + return ret; +} + +int apusys_kernel_apusys_rv_disable_wdt_isr(void) +{ + spin_lock(&apusys_rv_lock); + mmio_clrbits_32(WDT_CTRL0, WDT_EN); + spin_unlock(&apusys_rv_lock); + + return 0; +} + +int apusys_kernel_apusys_rv_clear_wdt_isr(void) +{ + 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; +} + +int apusys_kernel_apusys_rv_cg_gating(void) +{ + spin_lock(&apusys_rv_lock); + + if (watch_dog_is_timeout() == false) { + spin_unlock(&apusys_rv_lock); + return -1; + } + + mmio_write_32(MD32_CLK_CTRL, MD32_CLK_DIS); + spin_unlock(&apusys_rv_lock); + + return 0; +} + +int apusys_kernel_apusys_rv_cg_ungating(void) +{ + spin_lock(&apusys_rv_lock); + + if (watch_dog_is_timeout() == false) { + spin_unlock(&apusys_rv_lock); + return -1; + } + + mmio_write_32(MD32_CLK_CTRL, MD32_CLK_EN); + spin_unlock(&apusys_rv_lock); + + return 0; +} diff --git a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.h b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.h new file mode 100644 index 0000000..8a43890 --- /dev/null +++ b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef APUSYS_RV_H +#define APUSYS_RV_H + +#include <platform_def.h> + +#define APU_SEC_FW_IOVA (0x200000UL) + +/* APU_SCTRL_REVISER */ +#define UP_NORMAL_DOMAIN_NS (APU_REVISER + 0x0000) +#define UP_PRI_DOMAIN_NS (APU_REVISER + 0x0004) +#define UP_IOMMU_CTRL (APU_REVISER + 0x0008) +#define UP_CORE0_VABASE0 (APU_REVISER + 0x000c) +#define UP_CORE0_MVABASE0 (APU_REVISER + 0x0010) +#define UP_CORE0_VABASE1 (APU_REVISER + 0x0014) +#define UP_CORE0_MVABASE1 (APU_REVISER + 0x0018) +#define UP_CORE0_VABASE2 (APU_REVISER + 0x001c) +#define UP_CORE0_MVABASE2 (APU_REVISER + 0x0020) +#define UP_CORE0_VABASE3 (APU_REVISER + 0x0024) +#define UP_CORE0_MVABASE3 (APU_REVISER + 0x0028) +#define USERFW_CTXT (APU_REVISER + 0x1000) +#define SECUREFW_CTXT (APU_REVISER + 0x1004) +#define UP_NORMAL_DOMAIN (7) +#define UP_NORMAL_NS (1) +#define UP_PRI_DOMAIN (5) +#define UP_PRI_NS (1) +#define UP_DOMAIN_SHIFT (0) +#define UP_NS_SHIFT (4) +#define MMU_EN BIT(0) +#define MMU_CTRL BIT(1) +#define MMU_CTRL_LOCK BIT(2) +#define VLD BIT(0) +#define PARTIAL_ENABLE BIT(1) +#define THREAD_NUM_PRI (1) +#define THREAD_NUM_NORMAL (0) +#define THREAD_NUM_SHIFT (2) +#define VASIZE_1MB BIT(0) +#define CFG_4GB_SEL_EN BIT(2) +#define CFG_4GB_SEL (0) +#define MVA_34BIT_SHIFT (2) + +/* APU_MD32_SYSCTRL */ +#define MD32_SYS_CTRL (APU_MD32_SYSCTRL + 0x0000) +#define UP_INT_EN2 (APU_MD32_SYSCTRL + 0x000c) +#define MD32_CLK_CTRL (APU_MD32_SYSCTRL + 0x00b8) +#define UP_WAKE_HOST_MASK0 (APU_MD32_SYSCTRL + 0x00bc) +#define UP_WAKE_HOST_MASK1 (APU_MD32_SYSCTRL + 0x00c0) +#define MD32_SYS_CTRL_RST (0) +#define MD32_G2B_CG_EN BIT(11) +#define MD32_DBG_EN BIT(10) +#define MD32_DM_AWUSER_IOMMU_EN BIT(9) +#define MD32_DM_ARUSER_IOMMU_EN BIT(7) +#define MD32_PM_AWUSER_IOMMU_EN BIT(5) +#define MD32_PM_ARUSER_IOMMU_EN BIT(3) +#define MD32_SOFT_RSTN BIT(0) +#define MD32_CLK_EN (1) +#define MD32_CLK_DIS (0) +#define WDT_IRQ_EN BIT(0) +#define MBOX0_IRQ_EN BIT(21) +#define MBOX1_IRQ_EN BIT(22) +#define MBOX2_IRQ_EN BIT(23) +#define RESET_DEALY_US (10) +#define DBG_APB_EN BIT(31) + +/* APU_AO_CTRL */ +#define MD32_PRE_DEFINE (APU_AO_CTRL + 0x0000) +#define MD32_BOOT_CTRL (APU_AO_CTRL + 0x0004) +#define MD32_RUNSTALL (APU_AO_CTRL + 0x0008) +#define PREDEFINE_NON_CACHE (0) +#define PREDEFINE_TCM (1) +#define PREDEFINE_CACHE (2) +#define PREDEFINE_CACHE_TCM (3) +#define PREDEF_1G_OFS (0) +#define PREDEF_2G_OFS (2) +#define PREDEF_3G_OFS (4) +#define PREDEF_4G_OFS (6) +#define MD32_RUN (0) +#define MD32_STALL (1) + +/* APU_MD32_WDT */ +#define WDT_INT (APU_MD32_WDT + 0x0) +#define WDT_CTRL0 (APU_MD32_WDT + 0x4) +#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) + +#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) + +void apusys_rv_mbox_mpu_init(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); +int apusys_kernel_apusys_rv_start_mp(void); +int apusys_kernel_apusys_rv_stop_mp(void); +int apusys_kernel_apusys_rv_setup_sec_mem(void); +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); + +#endif /* APUSYS_RV_H */ diff --git a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv_mbox_mpu.h b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv_mbox_mpu.h new file mode 100644 index 0000000..0ee4878 --- /dev/null +++ b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv_mbox_mpu.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2023, 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 MBOX4_RX_DOMAIN (0) +#define MBOX4_RX_NS (0) +#define MBOX5_TX_DOMAIN (3) +#define MBOX5_TX_NS (0) +#define MBOXN_RX_DOMAIN (5) +#define MBOXN_RX_NS (1) +#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[] = { + { MPU_EN, MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOX0_TX_NS, MBOX0_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 }, + { MPU_EN, MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOXN_TX_NS, MBOXN_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, 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 }, + { 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 */ diff --git a/plat/mediatek/drivers/apusys/apusys_rv/2.0/rules.mk b/plat/mediatek/drivers/apusys/apusys_rv/2.0/rules.mk new file mode 100644 index 0000000..031264d --- /dev/null +++ b/plat/mediatek/drivers/apusys/apusys_rv/2.0/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_rv_${MTK_SOC} + +PLAT_INCLUDES += -I${MTK_PLAT}/drivers/apusys/${MTK_SOC} + +LOCAL_SRCS-y := ${LOCAL_DIR}/apusys_rv.c + +$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL))) diff --git a/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.c b/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.c new file mode 100644 index 0000000..4bd4272 --- /dev/null +++ b/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.c @@ -0,0 +1,68 @@ +/* + * 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_dapc_v1.h" +#include <platform_def.h> + +enum apusys_apc_err_status set_apusys_dapc_v1(const struct apc_dom_16 *dapc, + uint32_t size, dapc_cfg_func cfg) +{ + enum apusys_apc_err_status ret = APUSYS_APC_OK; + uint32_t i; + + if ((dapc == NULL) || (cfg == NULL)) { + return APUSYS_APC_ERR_GENERIC; + } + + for (i = 0; i < size; i++) { + ret += cfg(i, DOMAIN_0, dapc[i].d0_permission); + ret += cfg(i, DOMAIN_1, dapc[i].d1_permission); + ret += cfg(i, DOMAIN_2, dapc[i].d2_permission); + ret += cfg(i, DOMAIN_3, dapc[i].d3_permission); + ret += cfg(i, DOMAIN_4, dapc[i].d4_permission); + ret += cfg(i, DOMAIN_5, dapc[i].d5_permission); + ret += cfg(i, DOMAIN_6, dapc[i].d6_permission); + ret += cfg(i, DOMAIN_7, dapc[i].d7_permission); + ret += cfg(i, DOMAIN_8, dapc[i].d8_permission); + ret += cfg(i, DOMAIN_9, dapc[i].d9_permission); + ret += cfg(i, DOMAIN_10, dapc[i].d10_permission); + ret += cfg(i, DOMAIN_11, dapc[i].d11_permission); + ret += cfg(i, DOMAIN_12, dapc[i].d12_permission); + ret += cfg(i, DOMAIN_13, dapc[i].d13_permission); + ret += cfg(i, DOMAIN_14, dapc[i].d14_permission); + ret += cfg(i, DOMAIN_15, dapc[i].d15_permission); + } + + if (ret != APUSYS_APC_OK) { + ret = APUSYS_APC_ERR_GENERIC; + } + + return ret; +} + +void dump_apusys_dapc_v1(const char *name, uintptr_t base, uint32_t reg_num, uint32_t dom_num) +{ + uint32_t d, i; + + if ((name == NULL) || (base == 0)) { + return; + } + + for (d = 0; d < dom_num; d++) { + for (i = 0; i <= reg_num; i++) { + INFO(MODULE_TAG "[%s] D%d_APC_%d: 0x%x\n", name, d, i, + mmio_read_32(base + d * DEVAPC_DOM_SIZE + i * DEVAPC_REG_SIZE)); + } + } + + INFO(MODULE_TAG "[%s] APC_CON: 0x%x\n", name, mmio_read_32(APUSYS_DAPC_CON(base))); +} diff --git a/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.h b/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.h new file mode 100644 index 0000000..1b77942 --- /dev/null +++ b/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.h @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef APUSYS_DAPC_V1_H +#define APUSYS_DAPC_V1_H + +#include <lib/mmio.h> + +/****************************************************************************** + * STRUCTURE DEFINITION + ******************************************************************************/ +enum apusys_apc_err_status { + APUSYS_APC_OK = 0x0, + APUSYS_APC_ERR_GENERIC = 0x1, +}; + +enum apusys_apc_perm_type { + NO_PROTECTION = 0, + SEC_RW_ONLY = 1, + SEC_RW_NS_R = 2, + FORBIDDEN = 3, + PERM_NUM = 4, +}; + +enum apusys_apc_domain_id { + DOMAIN_0 = 0, + DOMAIN_1 = 1, + DOMAIN_2 = 2, + DOMAIN_3 = 3, + DOMAIN_4 = 4, + DOMAIN_5 = 5, + DOMAIN_6 = 6, + DOMAIN_7 = 7, + DOMAIN_8 = 8, + DOMAIN_9 = 9, + DOMAIN_10 = 10, + DOMAIN_11 = 11, + DOMAIN_12 = 12, + DOMAIN_13 = 13, + DOMAIN_14 = 14, + DOMAIN_15 = 15, +}; + +struct apc_dom_16 { + unsigned char d0_permission; + unsigned char d1_permission; + unsigned char d2_permission; + unsigned char d3_permission; + unsigned char d4_permission; + unsigned char d5_permission; + unsigned char d6_permission; + unsigned char d7_permission; + unsigned char d8_permission; + unsigned char d9_permission; + unsigned char d10_permission; + unsigned char d11_permission; + unsigned char d12_permission; + unsigned char d13_permission; + unsigned char d14_permission; + unsigned char d15_permission; +}; + +#define APUSYS_APC_AO_ATTR(DEV_NAME, \ + PERM_ATTR0, PERM_ATTR1, PERM_ATTR2, PERM_ATTR3, \ + PERM_ATTR4, PERM_ATTR5, PERM_ATTR6, PERM_ATTR7, \ + PERM_ATTR8, PERM_ATTR9, PERM_ATTR10, PERM_ATTR11, \ + PERM_ATTR12, PERM_ATTR13, PERM_ATTR14, PERM_ATTR15) \ + {(unsigned char)PERM_ATTR0, (unsigned char)PERM_ATTR1, \ + (unsigned char)PERM_ATTR2, (unsigned char)PERM_ATTR3, \ + (unsigned char)PERM_ATTR4, (unsigned char)PERM_ATTR5, \ + (unsigned char)PERM_ATTR6, (unsigned char)PERM_ATTR7, \ + (unsigned char)PERM_ATTR8, (unsigned char)PERM_ATTR9, \ + (unsigned char)PERM_ATTR10, (unsigned char)PERM_ATTR11, \ + (unsigned char)PERM_ATTR12, (unsigned char)PERM_ATTR13, \ + (unsigned char)PERM_ATTR14, (unsigned char)PERM_ATTR15} + +typedef enum apusys_apc_err_status (*dapc_cfg_func)(uint32_t slave, + enum apusys_apc_domain_id domain_id, + enum apusys_apc_perm_type perm); + +/* Register */ +#define DEVAPC_DOM_SIZE (0x40) +#define DEVAPC_REG_SIZE (4) + +/* APUSYS APC offsets */ +#define APUSYS_DAPC_CON_VIO_MASK (0x80000000) +#define APUSYS_DAPC_CON(base) ((base) + 0x00f00) + +/****************************************************************************** + * DAPC Common Function + ******************************************************************************/ +#define SET_APUSYS_DAPC_V1(dapc, cfg) \ + set_apusys_dapc_v1(dapc, ARRAY_SIZE(dapc), cfg) + +#define DUMP_APUSYS_DAPC_V1(apc) \ + dump_apusys_dapc_v1(#apc, apc##_BASE, \ + (apc##_SLAVE_NUM / apc##_SLAVE_NUM_IN_1_DOM), apc##_DOM_NUM) + +enum apusys_apc_err_status set_apusys_dapc_v1(const struct apc_dom_16 *dapc, + uint32_t size, dapc_cfg_func cfg); + +void dump_apusys_dapc_v1(const char *name, uintptr_t base, uint32_t reg_num, uint32_t dom_num); + +/****************************************************************************** + * DAPC Permission Policy + ******************************************************************************/ +#define SLAVE_FORBID_EXCEPT_D0_SEC_RW(domain) \ + APUSYS_APC_AO_ATTR(domain, \ + SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, FORBIDDEN, \ + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \ + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \ + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN) + +#define SLAVE_FORBID_EXCEPT_D0_SEC_RW_D5_NO_PROTECT(domain) \ + APUSYS_APC_AO_ATTR(domain, \ + SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, FORBIDDEN, \ + FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN, \ + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \ + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN) + +#define SLAVE_FORBID_EXCEPT_D5_NO_PROTECT(domain) \ + APUSYS_APC_AO_ATTR(domain, \ + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \ + FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN, \ + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \ + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN) + +#define SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_NO_PROTECT(domain) \ + APUSYS_APC_AO_ATTR(domain, \ + SEC_RW_NS_R, FORBIDDEN, FORBIDDEN, FORBIDDEN, \ + FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN, \ + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \ + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN) + +#define SLAVE_FORBID_EXCEPT_D7_NO_PROTECT(domain) \ + APUSYS_APC_AO_ATTR(domain, \ + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \ + FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION, \ + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \ + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN) + +#define SLAVE_FORBID_EXCEPT_D5_D7_NO_PROTECT(domain) \ + APUSYS_APC_AO_ATTR(domain, \ + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \ + FORBIDDEN, NO_PROTECTION, FORBIDDEN, NO_PROTECTION, \ + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \ + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN) + +#define SLAVE_FORBID_EXCEPT_D0_D5_NO_PROTECT(domain) \ + APUSYS_APC_AO_ATTR(domain, \ + NO_PROTECTION, FORBIDDEN, FORBIDDEN, FORBIDDEN, \ + FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN, \ + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \ + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN) +#endif /* APUSYS_DAPC_V1_H */ diff --git a/plat/mediatek/drivers/apusys/devapc/rules.mk b/plat/mediatek/drivers/apusys/devapc/rules.mk new file mode 100644 index 0000000..6153b31 --- /dev/null +++ b/plat/mediatek/drivers/apusys/devapc/rules.mk @@ -0,0 +1,13 @@ +# +# Copyright (c) 2023, MediaTek Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +LOCAL_DIR := $(call GET_LOCAL_DIR) + +MODULE := apusys_devapc + +LOCAL_SRCS-y := ${LOCAL_DIR}/apusys_dapc_v1.c + +$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL))) 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))) diff --git a/plat/mediatek/drivers/apusys/rules.mk b/plat/mediatek/drivers/apusys/rules.mk new file mode 100644 index 0000000..498925c --- /dev/null +++ b/plat/mediatek/drivers/apusys/rules.mk @@ -0,0 +1,21 @@ +# +# Copyright (c) 2023, MediaTek Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +LOCAL_DIR := $(call GET_LOCAL_DIR) + +MODULE := apusys + +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 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 + +$(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES-y))) diff --git a/plat/mediatek/drivers/audio/audio.c b/plat/mediatek/drivers/audio/audio.c new file mode 100644 index 0000000..285c565 --- /dev/null +++ b/plat/mediatek/drivers/audio/audio.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <errno.h> +#include <stdbool.h> + +#include <common/debug.h> + +#include <audio.h> + +#include <mtk_sip_svc.h> + +#define MODULE_TAG "[AUDIO]" + +static u_register_t audio_smc_handler(u_register_t x1, u_register_t x2, + u_register_t x3, u_register_t x4, + void *handle, struct smccc_res *smccc_ret) +{ + uint32_t request_ops; + int ret; + + request_ops = (uint32_t)x1; + + switch (request_ops) { + case MTK_AUDIO_SMC_OP_DOMAIN_SIDEBANDS: + ret = set_audio_domain_sidebands(); + break; + default: + ERROR("%s: %s: Unsupported request_ops %x\n", + MODULE_TAG, __func__, request_ops); + ret = -EIO; + break; + } + + VERBOSE("%s: %s, request_ops = %x, ret = %d\n", + MODULE_TAG, __func__, request_ops, ret); + return ret; +} +/* Register SiP SMC service */ +DECLARE_SMC_HANDLER(MTK_SIP_AUDIO_CONTROL, audio_smc_handler); diff --git a/plat/mediatek/drivers/audio/audio.h b/plat/mediatek/drivers/audio/audio.h new file mode 100644 index 0000000..1598a92 --- /dev/null +++ b/plat/mediatek/drivers/audio/audio.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef AUDIO_H +#define AUDIO_H + +#include <stdint.h> +#include <lib/mmio.h> + +enum mtk_audio_smc_call_op { + MTK_AUDIO_SMC_OP_INIT = 0, + MTK_AUDIO_SMC_OP_DRAM_REQUEST, + MTK_AUDIO_SMC_OP_DRAM_RELEASE, + MTK_AUDIO_SMC_OP_SRAM_REQUEST, + MTK_AUDIO_SMC_OP_SRAM_RELEASE, + MTK_AUDIO_SMC_OP_ADSP_REQUEST, + MTK_AUDIO_SMC_OP_ADSP_RELEASE, + MTK_AUDIO_SMC_OP_DOMAIN_SIDEBANDS, + MTK_AUDIO_SMC_OP_BTCVSD_WRITE, + MTK_AUDIO_SMC_OP_BTCVSD_UPDATE_CTRL_CLEAR, + MTK_AUDIO_SMC_OP_BTCVSD_UPDATE_CTRL_UNDERFLOW, + MTK_AUDIO_SMC_OP_NUM, +}; + +int32_t set_audio_domain_sidebands(void); + +#endif /* AUDIO_H */ diff --git a/plat/mediatek/drivers/audio/mt8188/audio_domain.c b/plat/mediatek/drivers/audio/mt8188/audio_domain.c new file mode 100644 index 0000000..cbafd19 --- /dev/null +++ b/plat/mediatek/drivers/audio/mt8188/audio_domain.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022, Mediatek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <errno.h> +#include <common/debug.h> + +#include <audio.h> +#include <mt_audio_private.h> +#include <mtk_mmap_pool.h> +#include <platform_def.h> +#include <spm_reg.h> + +#define MODULE_TAG "[AUDIO_DOMAIN]" + +int32_t set_audio_domain_sidebands(void) +{ + uint32_t val = mmio_read_32(PWR_STATUS); + + if ((val & BIT(SPM_PWR_STATUS_AUDIO_BIT)) == 0) { + ERROR("%s: %s, pwr_status=0x%x, w/o [%d]AUDIO!\n", + MODULE_TAG, __func__, val, SPM_PWR_STATUS_AUDIO_BIT); + return -EIO; + } + + mmio_write_32(AFE_SE_SECURE_CON, 0x0); + + mmio_write_32(AFE_SECURE_SIDEBAND0, 0x0); + mmio_write_32(AFE_SECURE_SIDEBAND1, 0x0); + mmio_write_32(AFE_SECURE_SIDEBAND2, 0x0); + mmio_write_32(AFE_SECURE_SIDEBAND3, 0x0); + + VERBOSE("%s: %s, SE_SECURE_CON=0x%x, SIDEBAND0/1/2/3=0x%x/0x%x/0x%x/0x%x\n", + MODULE_TAG, __func__, + mmio_read_32(AFE_SE_SECURE_CON), + mmio_read_32(AFE_SECURE_SIDEBAND0), + mmio_read_32(AFE_SECURE_SIDEBAND1), + mmio_read_32(AFE_SECURE_SIDEBAND2), + mmio_read_32(AFE_SECURE_SIDEBAND3)); + + return 0; +} diff --git a/plat/mediatek/drivers/audio/mt8188/mt_audio_private.h b/plat/mediatek/drivers/audio/mt8188/mt_audio_private.h new file mode 100644 index 0000000..bcb1abc --- /dev/null +++ b/plat/mediatek/drivers/audio/mt8188/mt_audio_private.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_AUDIO_PRIVATE_H +#define MT_AUDIO_PRIVATE_H + +#include <platform_def.h> + +#define AFE_SE_SECURE_CON (AUDIO_BASE + 0x17a8) +#define AFE_SECURE_SIDEBAND0 (AUDIO_BASE + 0x1908) +#define AFE_SECURE_SIDEBAND1 (AUDIO_BASE + 0x190c) +#define AFE_SECURE_SIDEBAND2 (AUDIO_BASE + 0x1910) +#define AFE_SECURE_SIDEBAND3 (AUDIO_BASE + 0x1914) + +#define SPM_PWR_STATUS_AUDIO_BIT (6) + +#endif /* MT_AUDIO_PRIVATE_H */ diff --git a/plat/mediatek/drivers/audio/mt8188/rules.mk b/plat/mediatek/drivers/audio/mt8188/rules.mk new file mode 100644 index 0000000..82acbfc --- /dev/null +++ b/plat/mediatek/drivers/audio/mt8188/rules.mk @@ -0,0 +1,13 @@ +# +# Copyright (c) 2022, MediaTek Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +LOCAL_DIR := $(call GET_LOCAL_DIR) + +MODULE := audio_${MTK_SOC} + +LOCAL_SRCS-y := ${LOCAL_DIR}/audio_domain.c + +$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL))) diff --git a/plat/mediatek/drivers/audio/rules.mk b/plat/mediatek/drivers/audio/rules.mk new file mode 100644 index 0000000..8538a64 --- /dev/null +++ b/plat/mediatek/drivers/audio/rules.mk @@ -0,0 +1,19 @@ +# +# Copyright (c) 2022, MediaTek Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +LOCAL_DIR := $(call GET_LOCAL_DIR) + +MODULE := audio + +LOCAL_SRCS-y := ${LOCAL_DIR}/audio.c + +PLAT_INCLUDES += -I${LOCAL_DIR} +PLAT_INCLUDES += -I${LOCAL_DIR}/$(MTK_SOC) + +SUB_RULES-y:= ${LOCAL_DIR}/${MTK_SOC} + +$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL))) +$(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES-y))) diff --git a/plat/mediatek/drivers/cirq/mt_cirq.c b/plat/mediatek/drivers/cirq/mt_cirq.c new file mode 100644 index 0000000..60534a2 --- /dev/null +++ b/plat/mediatek/drivers/cirq/mt_cirq.c @@ -0,0 +1,549 @@ +/* + * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch_helpers.h> +#include <common/debug.h> +#include <drivers/arm/gic_common.h> +#include <lib/mmio.h> + +#include <mt_cirq.h> +#include <mt_gic_v3.h> + +static struct cirq_events cirq_all_events = { + .spi_start = CIRQ_SPI_START, +}; +static uint32_t already_cloned; +/* + * mt_irq_mask_restore: restore all interrupts + * @mask: pointer to struct mtk_irq_mask for storing the original mask value. + * Return 0 for success; return negative values for failure. + * (This is ONLY used for the idle current measurement by the factory mode.) + */ +int mt_irq_mask_restore(struct mtk_irq_mask *mask) +{ + if (mask == NULL) { + return -1; + } + if (mask->header != IRQ_MASK_HEADER) { + return -1; + } + if (mask->footer != IRQ_MASK_FOOTER) { + return -1; + } + + mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x4), + mask->mask1); + mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x8), + mask->mask2); + mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0xc), + mask->mask3); + mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x10), + mask->mask4); + mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x14), + mask->mask5); + mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x18), + mask->mask6); + mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x1c), + mask->mask7); + mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x20), + mask->mask8); + mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x24), + mask->mask9); + mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x28), + mask->mask10); + mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x2c), + mask->mask11); + mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x30), + mask->mask12); + /* make sure dist changes happen */ + dsb(); + + return 0; +} + +/* + * mt_irq_mask_all: disable all interrupts + * @mask: pointer to struct mtk_irq_mask for storing the original mask value. + * Return 0 for success; return negative values for failure. + * (This is ONLY used for the idle current measurement by the factory mode.) + */ +int mt_irq_mask_all(struct mtk_irq_mask *mask) +{ + if (mask != NULL) { + /* for SPI */ + mask->mask1 = mmio_read_32((BASE_GICD_BASE + + GICD_ISENABLER + 0x4)); + mask->mask2 = mmio_read_32((BASE_GICD_BASE + + GICD_ISENABLER + 0x8)); + mask->mask3 = mmio_read_32((BASE_GICD_BASE + + GICD_ISENABLER + 0xc)); + mask->mask4 = mmio_read_32((BASE_GICD_BASE + + GICD_ISENABLER + 0x10)); + mask->mask5 = mmio_read_32((BASE_GICD_BASE + + GICD_ISENABLER + 0x14)); + mask->mask6 = mmio_read_32((BASE_GICD_BASE + + GICD_ISENABLER + 0x18)); + mask->mask7 = mmio_read_32((BASE_GICD_BASE + + GICD_ISENABLER + 0x1c)); + mask->mask8 = mmio_read_32((BASE_GICD_BASE + + GICD_ISENABLER + 0x20)); + mask->mask9 = mmio_read_32((BASE_GICD_BASE + + GICD_ISENABLER + 0x24)); + mask->mask10 = mmio_read_32((BASE_GICD_BASE + + GICD_ISENABLER + 0x28)); + mask->mask11 = mmio_read_32((BASE_GICD_BASE + + GICD_ISENABLER + 0x2c)); + mask->mask12 = mmio_read_32((BASE_GICD_BASE + + GICD_ISENABLER + 0x30)); + + /* for SPI */ + mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x4), + 0xFFFFFFFF); + mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x8), + 0xFFFFFFFF); + mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0xC), + 0xFFFFFFFF); + mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x10), + 0xFFFFFFFF); + mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x14), + 0xFFFFFFFF); + mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x18), + 0xFFFFFFFF); + mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x1C), + 0xFFFFFFFF); + mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x20), + 0xFFFFFFFF); + mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x24), + 0xFFFFFFFF); + mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x28), + 0xFFFFFFFF); + mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x2c), + 0xFFFFFFFF); + mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x30), + 0xFFFFFFFF); + /* make sure distributor changes happen */ + dsb(); + + mask->header = IRQ_MASK_HEADER; + mask->footer = IRQ_MASK_FOOTER; + + return 0; + } else { + return -1; + } +} + +static uint32_t mt_irq_get_pol(uint32_t irq) +{ +#ifdef CIRQ_WITH_POLARITY + uint32_t reg; + uint32_t base = INT_POL_CTL0; + + if (irq < 32U) { + return 0; + } + + reg = ((irq - 32U) / 32U); + + return mmio_read_32(base + reg * 4U); +#else + return 0; +#endif +} + +unsigned int mt_irq_get_sens(unsigned int irq) +{ + unsigned int config; + + /* + * 2'b10 edge + * 2'b01 level + */ + config = mmio_read_32(MT_GIC_BASE + GICD_ICFGR + (irq / 16U) * 4U); + config = (config >> (irq % 16U) * 2U) & 0x3; + + return config; +} + +static void collect_all_wakeup_events(void) +{ + unsigned int i; + uint32_t gic_irq; + uint32_t cirq; + uint32_t cirq_reg; + uint32_t cirq_offset; + uint32_t mask; + uint32_t pol_mask; + uint32_t irq_offset; + uint32_t irq_mask; + + if ((cirq_all_events.wakeup_events == NULL) || + cirq_all_events.num_of_events == 0U) { + return; + } + + for (i = 0U; i < cirq_all_events.num_of_events; i++) { + if (cirq_all_events.wakeup_events[i] > 0U) { + gic_irq = cirq_all_events.wakeup_events[i]; + cirq = gic_irq - cirq_all_events.spi_start - 32U; + cirq_reg = cirq / 32U; + cirq_offset = cirq % 32U; + mask = 0x1 << cirq_offset; + irq_offset = gic_irq % 32U; + irq_mask = 0x1 << irq_offset; + /* + * CIRQ default masks all + */ + cirq_all_events.table[cirq_reg].mask |= mask; + /* + * CIRQ default pol is low + */ + pol_mask = mt_irq_get_pol( + cirq_all_events.wakeup_events[i]) + & irq_mask; + /* + * 0 means rising + */ + if (pol_mask == 0U) { + cirq_all_events.table[cirq_reg].pol |= mask; + } + /* + * CIRQ could monitor edge/level trigger + * cirq register (0: edge, 1: level) + */ + if (mt_irq_get_sens(cirq_all_events.wakeup_events[i]) + == SENS_EDGE) { + cirq_all_events.table[cirq_reg].sen |= mask; + } + + cirq_all_events.table[cirq_reg].used = 1U; + cirq_all_events.table[cirq_reg].reg_num = cirq_reg; + } + } +} + +/* + * mt_cirq_set_pol: Set the polarity for the specified SYS_CIRQ number. + * @cirq_num: the SYS_CIRQ number to set + * @pol: polarity to set + * @return: + * 0: set pol success + * -1: cirq num is out of range + */ +#ifdef CIRQ_WITH_POLARITY +static int mt_cirq_set_pol(uint32_t cirq_num, uint32_t pol) +{ + uint32_t base; + uint32_t bit = 1U << (cirq_num % 32U); + + if (cirq_num >= CIRQ_IRQ_NUM) { + return -1; + } + + if (pol == MT_CIRQ_POL_NEG) { + base = (cirq_num / 32U) * 4U + CIRQ_POL_CLR_BASE; + } else if (pol == MT_CIRQ_POL_POS) { + base = (cirq_num / 32U) * 4U + CIRQ_POL_SET_BASE; + } else { + return -1; + } + + mmio_write_32(base, bit); + return 0; +} +#endif + +/* + * mt_cirq_mask: Mask the specified SYS_CIRQ. + * @cirq_num: the SYS_CIRQ number to mask + * @return: + * 0: mask success + * -1: cirq num is out of range + */ +static int mt_cirq_mask(uint32_t cirq_num) +{ + uint32_t bit = 1U << (cirq_num % 32U); + + if (cirq_num >= CIRQ_IRQ_NUM) { + return -1; + } + + mmio_write_32((cirq_num / 32U) * 4U + CIRQ_MASK_SET_BASE, bit); + + return 0; +} + +/* + * mt_cirq_unmask: Unmask the specified SYS_CIRQ. + * @cirq_num: the SYS_CIRQ number to unmask + * @return: + * 0: umask success + * -1: cirq num is out of range + */ +static int mt_cirq_unmask(uint32_t cirq_num) +{ + uint32_t bit = 1U << (cirq_num % 32U); + + if (cirq_num >= CIRQ_IRQ_NUM) { + return -1; + } + + mmio_write_32((cirq_num / 32U) * 4U + CIRQ_MASK_CLR_BASE, bit); + + return 0; +} + +uint32_t mt_irq_get_en(uint32_t irq) +{ + uint32_t addr, st, val; + + addr = BASE_GICD_BASE + GICD_ISENABLER + (irq / 32U) * 4U; + st = mmio_read_32(addr); + + val = (st >> (irq % 32U)) & 1U; + + return val; +} + +static void __cirq_fast_clone(void) +{ + struct cirq_reg *reg; + unsigned int i; + + for (i = 0U; i < CIRQ_REG_NUM ; ++i) { + uint32_t cirq_bit; + + reg = &cirq_all_events.table[i]; + + if (reg->used == 0U) { + continue; + } + + mmio_write_32(CIRQ_SENS_CLR_BASE + (reg->reg_num * 4U), + reg->sen); + + for (cirq_bit = 0U; cirq_bit < 32U; ++cirq_bit) { + uint32_t val, cirq_id; + uint32_t gic_id; +#ifdef CIRQ_WITH_POLARITY + uint32_t gic_bit, pol; +#endif + uint32_t en; + + val = ((1U << cirq_bit) & reg->mask); + + if (val == 0U) { + continue; + } + + cirq_id = (reg->reg_num << 5U) + cirq_bit; + gic_id = CIRQ_TO_IRQ_NUM(cirq_id); +#ifdef CIRQ_WITH_POLARITY + gic_bit = (0x1U << ((gic_id - 32U) % 32U)); + pol = mt_irq_get_pol(gic_id) & gic_bit; + if (pol != 0U) { + mt_cirq_set_pol(cirq_id, MT_CIRQ_POL_NEG); + } else { + mt_cirq_set_pol(cirq_id, MT_CIRQ_POL_POS); + } +#endif + en = mt_irq_get_en(gic_id); + if (en == 1U) { + mt_cirq_unmask(cirq_id); + } else { + mt_cirq_mask(cirq_id); + } + } + } +} + +static void cirq_fast_clone(void) +{ + if (already_cloned == 0U) { + collect_all_wakeup_events(); + already_cloned = 1U; + } + __cirq_fast_clone(); +} + +void set_wakeup_sources(uint32_t *list, uint32_t num_of_events) +{ + cirq_all_events.num_of_events = num_of_events; + cirq_all_events.wakeup_events = list; +} +/* + * mt_cirq_clone_gic: Copy the setting from GIC to SYS_CIRQ + */ +void mt_cirq_clone_gic(void) +{ + cirq_fast_clone(); +} + +uint32_t mt_irq_get_pending_vec(uint32_t start_irq) +{ + uint32_t base = 0U; + uint32_t pending_vec = 0U; + uint32_t reg = start_irq / 32U; + uint32_t LSB_num, MSB_num; + uint32_t LSB_vec, MSB_vec; + + base = BASE_GICD_BASE; + + /* if start_irq is not aligned 32, do some assembling */ + MSB_num = start_irq % 32U; + if (MSB_num != 0U) { + LSB_num = 32U - MSB_num; + LSB_vec = mmio_read_32(base + GICD_ISPENDR + + reg * 4U) >> MSB_num; + MSB_vec = mmio_read_32(base + GICD_ISPENDR + + (reg + 1U) * 4U) << LSB_num; + pending_vec = MSB_vec | LSB_vec; + } else { + pending_vec = mmio_read_32(base + GICD_ISPENDR + reg * 4); + } + + return pending_vec; +} + +static int mt_cirq_get_mask_vec(unsigned int i) +{ + return mmio_read_32((i * 4U) + CIRQ_MASK_BASE); +} + +/* + * mt_cirq_ack_all: Ack all the interrupt on SYS_CIRQ + */ +void mt_cirq_ack_all(void) +{ + uint32_t ack_vec, pend_vec, mask_vec; + unsigned int i; + + for (i = 0; i < CIRQ_CTRL_REG_NUM; i++) { + /* + * if a irq is pending & not masked, don't ack it + * , since cirq start irq might not be 32 aligned with gic, + * need an exotic API to get proper vector of pending irq + */ + pend_vec = mt_irq_get_pending_vec(CIRQ_SPI_START + + (i + 1U) * 32U); + mask_vec = mt_cirq_get_mask_vec(i); + /* those should be acked are: "not (pending & not masked)", + */ + ack_vec = (~pend_vec) | mask_vec; + mmio_write_32(CIRQ_ACK_BASE + (i * 4U), ack_vec); + } + + /* + * make sure all cirq setting take effect + * before doing other things + */ + dsb(); +} +/* + * mt_cirq_enable: Enable SYS_CIRQ + */ +void mt_cirq_enable(void) +{ + uint32_t st; + + /* level only */ + mt_cirq_ack_all(); + + st = mmio_read_32(CIRQ_CON); + /* + * CIRQ could monitor edge/level trigger + */ + st |= (CIRQ_CON_EN << CIRQ_CON_EN_BITS); + + mmio_write_32(CIRQ_CON, (st & CIRQ_CON_BITS_MASK)); +} + +/* + * mt_cirq_disable: Disable SYS_CIRQ + */ +void mt_cirq_disable(void) +{ + uint32_t st; + + st = mmio_read_32(CIRQ_CON); + st &= ~(CIRQ_CON_EN << CIRQ_CON_EN_BITS); + mmio_write_32(CIRQ_CON, (st & CIRQ_CON_BITS_MASK)); +} + +void mt_irq_unmask_for_sleep_ex(uint32_t irq) +{ + uint32_t mask; + + mask = 1U << (irq % 32U); + + mmio_write_32(BASE_GICD_BASE + GICD_ISENABLER + + ((irq / 32U) * 4U), mask); +} + +void mt_cirq_mask_all(void) +{ + unsigned int i; + + for (i = 0U; i < CIRQ_CTRL_REG_NUM; i++) { + mmio_write_32(CIRQ_MASK_SET_BASE + (i * 4U), 0xFFFFFFFF); + } + dsb(); +} + +static void cirq_fast_sw_flush(void) +{ + struct cirq_reg *reg; + unsigned int i; + + for (i = 0U; i < CIRQ_REG_NUM ; ++i) { + uint32_t cirq_bit; + + reg = &cirq_all_events.table[i]; + + if (reg->used == 0U) { + continue; + } + + reg->pending = mmio_read_32(CIRQ_STA_BASE + + (reg->reg_num << 2U)); + reg->pending &= reg->mask; + + for (cirq_bit = 0U; cirq_bit < 32U; ++cirq_bit) { + uint32_t val, cirq_id; + + val = (1U << cirq_bit) & reg->pending; + if (val == 0U) { + continue; + } + + cirq_id = (reg->reg_num << 5U) + cirq_bit; + mt_irq_set_pending(CIRQ_TO_IRQ_NUM(cirq_id)); + if (CIRQ_TO_IRQ_NUM(cirq_id) == MD_WDT_IRQ_BIT_ID) { + INFO("Set MD_WDT_IRQ pending in %s\n", + __func__); + } + } + } +} + +/* + * mt_cirq_disable: Flush interrupt from SYS_CIRQ to GIC + */ +void mt_cirq_flush(void) +{ + cirq_fast_sw_flush(); + mt_cirq_mask_all(); + mt_cirq_ack_all(); +} + +void mt_cirq_sw_reset(void) +{ + uint32_t st; + + st = mmio_read_32(CIRQ_CON); + st |= (CIRQ_SW_RESET << CIRQ_CON_SW_RST_BITS); + mmio_write_32(CIRQ_CON, st); +} diff --git a/plat/mediatek/drivers/cirq/mt_cirq.h b/plat/mediatek/drivers/cirq/mt_cirq.h new file mode 100644 index 0000000..cb96295 --- /dev/null +++ b/plat/mediatek/drivers/cirq/mt_cirq.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_MT_CIRQ_H +#define PLAT_MT_CIRQ_H + +#include <stdint.h> +#include <platform_def.h> + +enum { + IRQ_MASK_HEADER = 0xF1F1F1F1, + IRQ_MASK_FOOTER = 0xF2F2F2F2 +}; + +struct mtk_irq_mask { + uint32_t header; /* for error checking */ + uint32_t mask0; + uint32_t mask1; + uint32_t mask2; + uint32_t mask3; + uint32_t mask4; + uint32_t mask5; + uint32_t mask6; + uint32_t mask7; + uint32_t mask8; + uint32_t mask9; + uint32_t mask10; + uint32_t mask11; + uint32_t mask12; + uint32_t footer; /* for error checking */ +}; + +/* + * Define hardware register + */ +#define CIRQ_STA_BASE (SYS_CIRQ_BASE + U(0x000)) +#define CIRQ_ACK_BASE (SYS_CIRQ_BASE + U(0x080)) +#define CIRQ_MASK_BASE (SYS_CIRQ_BASE + U(0x100)) +#define CIRQ_MASK_SET_BASE (SYS_CIRQ_BASE + U(0x180)) +#define CIRQ_MASK_CLR_BASE (SYS_CIRQ_BASE + U(0x200)) +#define CIRQ_SENS_BASE (SYS_CIRQ_BASE + U(0x280)) +#define CIRQ_SENS_SET_BASE (SYS_CIRQ_BASE + U(0x300)) +#define CIRQ_SENS_CLR_BASE (SYS_CIRQ_BASE + U(0x380)) +#define CIRQ_POL_BASE (SYS_CIRQ_BASE + U(0x400)) +#define CIRQ_POL_SET_BASE (SYS_CIRQ_BASE + U(0x480)) +#define CIRQ_POL_CLR_BASE (SYS_CIRQ_BASE + U(0x500)) +#define CIRQ_CON (SYS_CIRQ_BASE + U(0x600)) + +/* + * Register placement + */ +#define CIRQ_CON_EN_BITS U(0) +#define CIRQ_CON_EDGE_ONLY_BITS U(1) +#define CIRQ_CON_FLUSH_BITS U(2) +#define CIRQ_CON_SW_RST_BITS U(20) +#define CIRQ_CON_EVENT_BITS U(31) +#define CIRQ_CON_BITS_MASK U(0x7) + +/* + * Register setting + */ +#define CIRQ_CON_EN U(0x1) +#define CIRQ_CON_EDGE_ONLY U(0x1) +#define CIRQ_CON_FLUSH U(0x1) +#define CIRQ_SW_RESET U(0x1) + +/* + * Define constant + */ +#define CIRQ_CTRL_REG_NUM ((CIRQ_IRQ_NUM + 31U) / 32U) + +#define MT_CIRQ_POL_NEG U(0) +#define MT_CIRQ_POL_POS U(1) + +#define IRQ_TO_CIRQ_NUM(irq) ((irq) - (32U + CIRQ_SPI_START)) +#define CIRQ_TO_IRQ_NUM(cirq) ((cirq) + (32U + CIRQ_SPI_START)) + +/* GIC sensitive */ +#define SENS_EDGE U(0x2) +#define SENS_LEVEL U(0x1) + + +/* + * Define function prototypes. + */ +int mt_cirq_test(void); +void mt_cirq_dump_reg(void); +int mt_irq_mask_restore(struct mtk_irq_mask *mask); +int mt_irq_mask_all(struct mtk_irq_mask *mask); +void mt_cirq_clone_gic(void); +void mt_cirq_enable(void); +void mt_cirq_flush(void); +void mt_cirq_disable(void); +void mt_irq_unmask_for_sleep_ex(uint32_t irq); +void set_wakeup_sources(uint32_t *list, uint32_t num_of_events); +void mt_cirq_sw_reset(void); + +struct cirq_reg { + uint32_t reg_num; + uint32_t used; + uint32_t mask; + uint32_t pol; + uint32_t sen; + uint32_t pending; + uint32_t the_link; +}; + +struct cirq_events { + uint32_t num_reg; + uint32_t spi_start; + uint32_t num_of_events; + uint32_t *wakeup_events; + struct cirq_reg table[CIRQ_REG_NUM]; + uint32_t dist_base; + uint32_t cirq_base; + uint32_t used_reg_head; +}; + +#endif /* PLAT_MT_CIRQ_H */ diff --git a/plat/mediatek/drivers/cirq/rules.mk b/plat/mediatek/drivers/cirq/rules.mk new file mode 100644 index 0000000..710eae0 --- /dev/null +++ b/plat/mediatek/drivers/cirq/rules.mk @@ -0,0 +1,14 @@ +# +# Copyright (c) 2022, MediaTek Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +LOCAL_DIR := $(call GET_LOCAL_DIR) + +MODULE := cirq +LOCAL_SRCS-y := $(LOCAL_DIR)/mt_cirq.c + +PLAT_INCLUDES += -I${LOCAL_DIR} + +$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL))) diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm.c b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm.c new file mode 100644 index 0000000..6281cc0 --- /dev/null +++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm.c @@ -0,0 +1,466 @@ +/* + * Copyright (c) 2022-2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <stdint.h> + +#include <lib/spinlock.h> + +#include <lib/mtk_init/mtk_init.h> +#include <lib/pm/mtk_pm.h> +#include <lpm/mt_lp_rm.h> +#include "mt_cpu_pm.h" +#include "mt_cpu_pm_cpc.h" +#include "mt_cpu_pm_mbox.h" +#include "mt_smp.h" +#include <mtk_mmap_pool.h> +#include <platform_def.h> + +/* + * The locker must use the bakery locker when cache turns off. + * Using spin_lock will gain better performance. + */ +#ifdef MT_CPU_PM_USING_BAKERY_LOCK +DEFINE_BAKERY_LOCK(mt_cpu_pm_lock); +#define plat_cpu_pm_lock_init() bakery_lock_init(&mt_cpu_pm_lock) +#define plat_cpu_pm_lock() bakery_lock_get(&mt_cpu_pm_lock) +#define plat_cpu_pm_unlock() bakery_lock_release(&mt_cpu_pm_lock) +#else +spinlock_t mt_cpu_pm_lock; +#define plat_cpu_pm_lock_init() +#define plat_cpu_pm_lock() spin_lock(&mt_cpu_pm_lock) +#define plat_cpu_pm_unlock() spin_unlock(&mt_cpu_pm_lock) +#endif + +enum mt_pwr_node { + MT_PWR_NONMCUSYS = 0, + MT_PWR_MCUSYS_PDN, + MT_PWR_SUSPEND, + MT_PWR_SYSTEM_MEM, + MT_PWR_SYSTEM_PLL, + MT_PWR_SYSTEM_BUS, + MT_PWR_MAX, +}; + +#define CPU_PM_DEPD_INIT BIT(0) +#define CPU_PM_DEPD_READY BIT(1) +#define CPU_PM_PLAT_READY BIT(2) + +#ifdef CPU_PM_TINYSYS_SUPPORT +#define CPU_PM_INIT_READY (CPU_PM_DEPD_INIT | CPU_PM_DEPD_READY) +#define CPU_PM_LP_READY (CPU_PM_INIT_READY | CPU_PM_PLAT_READY) +#else +#define CPU_PM_LP_READY (CPU_PM_PLAT_READY) +#endif + +#if CONFIG_MTK_PM_SUPPORT + +#if CONFIG_MTK_CPU_SUSPEND_EN || CONFIG_MTK_SMP_EN +static void cpupm_cpu_resume_common(const struct mtk_cpupm_pwrstate *state) +{ + CPU_PM_ASSERT(state != NULL); + mtk_cpc_core_on_hint_clr(state->info.cpuid); +} +#endif + +#if CONFIG_MTK_SMP_EN +static int cpupm_cpu_pwr_on_prepare(unsigned int cpu, uintptr_t entry) +{ + struct cpu_pwr_ctrl pwr_ctrl; + + PER_CPU_PWR_CTRL(pwr_ctrl, cpu); + mt_smp_core_bootup_address_set(&pwr_ctrl, entry); + mt_smp_core_init_arch(0, cpu, 1, &pwr_ctrl); + + return mt_smp_power_core_on(cpu, &pwr_ctrl); +} + +static void cpupm_cpu_resume_smp(const struct mtk_cpupm_pwrstate *state) +{ + CPU_PM_ASSERT(state != NULL); + + plat_cpu_pm_lock(); + mmio_clrbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG, + GIC_WAKEUP_IGNORE(state->info.cpuid)); + plat_cpu_pm_unlock(); + cpupm_cpu_resume_common(state); +} + +static void cpupm_cpu_suspend_smp(const struct mtk_cpupm_pwrstate *state) +{ + struct cpu_pwr_ctrl pwr_ctrl; + + CPU_PM_ASSERT(state != NULL); + + PER_CPU_PWR_CTRL(pwr_ctrl, state->info.cpuid); + mt_smp_power_core_off(&pwr_ctrl); + mmio_setbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG, + GIC_WAKEUP_IGNORE(state->info.cpuid)); +} + +static void cpupm_smp_init(unsigned int cpu, uintptr_t sec_entrypoint) +{ + unsigned int reg; + struct mtk_cpupm_pwrstate state = { + .info = { + .cpuid = cpu, + .mode = MTK_CPU_PM_SMP, + }, + .pwr = { + .afflv = 0, + .state_id = 0, + }, + }; + + reg = mmio_read_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG); + if ((reg & CPC_MCUSYS_CPC_RESET_PWR_ON_EN) != 0) { + INFO("[%s:%d][CPU_PM] reset pwr on is enabled then clear it!\n", + __func__, __LINE__); + mmio_clrbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG, CPC_MCUSYS_CPC_RESET_PWR_ON_EN); + } + + cpupm_cpu_pwr_on_prepare(cpu, sec_entrypoint); + cpupm_cpu_resume_smp(&state); +} + +static struct mtk_cpu_smp_ops cpcv3_2_cpu_smp = { + .init = cpupm_smp_init, + .cpu_pwr_on_prepare = cpupm_cpu_pwr_on_prepare, + .cpu_on = cpupm_cpu_resume_smp, + .cpu_off = cpupm_cpu_suspend_smp, +}; + +#endif /* CONFIG_MTK_SMP_EN */ + +#if CONFIG_MTK_CPU_SUSPEND_EN +#define CPUPM_READY_MS (40000) +#define CPUPM_ARCH_TIME_MS(ms) (ms * 1000 * SYS_COUNTER_FREQ_IN_MHZ) +#define CPUPM_BOOTUP_TIME_THR CPUPM_ARCH_TIME_MS(CPUPM_READY_MS) + +static int mt_pwr_nodes[MT_PWR_MAX]; +static int plat_mt_lp_cpu_rc; +static unsigned int cpu_pm_status; +static unsigned int plat_prev_stateid; + +static int mcusys_prepare_suspend(const struct mtk_cpupm_pwrstate *state) +{ + unsigned int stateid = state->pwr.state_id; + + if (mtk_cpc_mcusys_off_prepare() != CPC_SUCCESS) { + goto mt_pwr_mcusysoff_break; + } + + if (!IS_PLAT_SUSPEND_ID(stateid)) { + if (mt_pwr_nodes[MT_PWR_SYSTEM_MEM] != 0) { + stateid = MT_PLAT_PWR_STATE_SYSTEM_MEM; + } else if (mt_pwr_nodes[MT_PWR_SYSTEM_PLL] != 0) { + stateid = MT_PLAT_PWR_STATE_SYSTEM_PLL; + } else if (mt_pwr_nodes[MT_PWR_SYSTEM_BUS] != 0) { + stateid = MT_PLAT_PWR_STATE_SYSTEM_BUS; + } else if (mt_pwr_nodes[MT_PWR_SUSPEND] != 0) { + stateid = MT_PLAT_PWR_STATE_SUSPEND; + } else { + stateid = MT_PLAT_PWR_STATE_MCUSYS; + } + } + + plat_prev_stateid = stateid; + plat_mt_lp_cpu_rc = mt_lp_rm_find_and_run_constraint(0, state->info.cpuid, stateid, NULL); + + if (plat_mt_lp_cpu_rc < 0) { + goto mt_pwr_mcusysoff_reflect; + } + +#ifdef CPU_PM_TINYSYS_SUPPORT + mtk_set_cpu_pm_preffered_cpu(state->info.cpuid); +#endif + return MTK_CPUPM_E_OK; + +mt_pwr_mcusysoff_reflect: + mtk_cpc_mcusys_off_reflect(); +mt_pwr_mcusysoff_break: + plat_mt_lp_cpu_rc = -1; + + return MTK_CPUPM_E_FAIL; +} + +static int mcusys_prepare_resume(const struct mtk_cpupm_pwrstate *state) +{ + if (plat_mt_lp_cpu_rc < 0) { + return MTK_CPUPM_E_FAIL; + } + + mt_lp_rm_reset_constraint(plat_mt_lp_cpu_rc, state->info.cpuid, plat_prev_stateid); + mtk_cpc_mcusys_off_reflect(); + return MTK_CPUPM_E_OK; +} + +static unsigned int cpupm_do_pstate_off(const mtk_pstate_type psci_state, + const struct mtk_cpupm_pwrstate *state) +{ + unsigned int pstate = MT_CPUPM_PWR_DOMAIN_CORE; + + if (!state || (state->pwr.afflv > PLAT_MAX_PWR_LVL)) { + CPU_PM_ASSERT(0); + } + + switch (state->pwr.state_id) { + case MT_PLAT_PWR_STATE_SYSTEM_MEM: + mt_pwr_nodes[MT_PWR_SYSTEM_MEM] += 1; + break; + case MT_PLAT_PWR_STATE_SYSTEM_PLL: + mt_pwr_nodes[MT_PWR_SYSTEM_PLL] += 1; + break; + case MT_PLAT_PWR_STATE_SYSTEM_BUS: + mt_pwr_nodes[MT_PWR_SYSTEM_BUS] += 1; + break; + case MT_PLAT_PWR_STATE_SUSPEND: + mt_pwr_nodes[MT_PWR_SUSPEND] += 1; + break; + default: + if (!IS_MT_PLAT_PWR_STATE_MCUSYS(state->pwr.state_id) && + !IS_PLAT_SYSTEM_SUSPEND(state->pwr.afflv)) { + plat_cpu_pm_lock(); + mt_pwr_nodes[MT_PWR_NONMCUSYS] += 1; + flush_dcache_range((uintptr_t)&mt_pwr_nodes[MT_PWR_NONMCUSYS], + sizeof(mt_pwr_nodes[MT_PWR_NONMCUSYS])); + plat_cpu_pm_unlock(); + } + break; + } + + if ((mt_pwr_nodes[MT_PWR_NONMCUSYS] == 0) && IS_PLAT_MCUSYSOFF_AFFLV(state->pwr.afflv)) { + /* Prepare to power down mcusys */ + if (mcusys_prepare_suspend(state) == MTK_CPUPM_E_OK) { + mt_pwr_nodes[MT_PWR_MCUSYS_PDN] += 1; + flush_dcache_range((uintptr_t)&mt_pwr_nodes[MT_PWR_MCUSYS_PDN], + sizeof(mt_pwr_nodes[MT_PWR_MCUSYS_PDN])); + pstate |= (MT_CPUPM_PWR_DOMAIN_MCUSYS | MT_CPUPM_PWR_DOMAIN_CLUSTER); + } + } + + if (state->pwr.afflv >= PLAT_MT_CPU_SUSPEND_CLUSTER) { + pstate |= MT_CPUPM_PWR_DOMAIN_CLUSTER; + } + + if (psci_get_pstate_pwrlvl(psci_state) >= PLAT_MT_CPU_SUSPEND_CLUSTER) { + pstate |= MT_CPUPM_PWR_DOMAIN_PERCORE_DSU; + } + + return pstate; +} + +static unsigned int cpupm_do_pstate_on(const mtk_pstate_type psci_state, + const struct mtk_cpupm_pwrstate *state) +{ + unsigned int pstate = MT_CPUPM_PWR_DOMAIN_CORE; + + CPU_PM_ASSERT(state != NULL); + + if (state->pwr.afflv > PLAT_MAX_PWR_LVL) { + CPU_PM_ASSERT(0); + } + + if (mt_pwr_nodes[MT_PWR_MCUSYS_PDN] != 0) { + mt_pwr_nodes[MT_PWR_MCUSYS_PDN] = 0; + flush_dcache_range((uintptr_t)&mt_pwr_nodes[MT_PWR_MCUSYS_PDN], + sizeof(mt_pwr_nodes[MT_PWR_MCUSYS_PDN])); + pstate |= (MT_CPUPM_PWR_DOMAIN_MCUSYS | MT_CPUPM_PWR_DOMAIN_CLUSTER); + mcusys_prepare_resume(state); + } + + if (state->pwr.afflv >= PLAT_MT_CPU_SUSPEND_CLUSTER) { + pstate |= MT_CPUPM_PWR_DOMAIN_CLUSTER; + } + + switch (state->pwr.state_id) { + case MT_PLAT_PWR_STATE_SYSTEM_MEM: + mt_pwr_nodes[MT_PWR_SYSTEM_MEM] -= 1; + CPU_PM_ASSERT(mt_pwr_nodes[MT_PWR_SYSTEM_MEM] >= 0); + break; + case MT_PLAT_PWR_STATE_SYSTEM_PLL: + mt_pwr_nodes[MT_PWR_SYSTEM_PLL] -= 1; + CPU_PM_ASSERT(mt_pwr_nodes[MT_PWR_SYSTEM_PLL] >= 0); + break; + case MT_PLAT_PWR_STATE_SYSTEM_BUS: + mt_pwr_nodes[MT_PWR_SYSTEM_BUS] -= 1; + CPU_PM_ASSERT(mt_pwr_nodes[MT_PWR_SYSTEM_BUS] >= 0); + break; + case MT_PLAT_PWR_STATE_SUSPEND: + mt_pwr_nodes[MT_PWR_SUSPEND] -= 1; + CPU_PM_ASSERT(mt_pwr_nodes[MT_PWR_SUSPEND] >= 0); + break; + default: + if (!IS_MT_PLAT_PWR_STATE_MCUSYS(state->pwr.state_id) && + !IS_PLAT_SYSTEM_SUSPEND(state->pwr.afflv)) { + plat_cpu_pm_lock(); + mt_pwr_nodes[MT_PWR_NONMCUSYS] -= 1; + flush_dcache_range((uintptr_t)&mt_pwr_nodes[MT_PWR_NONMCUSYS], + sizeof(mt_pwr_nodes[MT_PWR_NONMCUSYS])); + plat_cpu_pm_unlock(); + } + break; + } + + if (IS_PLAT_SYSTEM_SUSPEND(state->pwr.afflv) || + (IS_PLAT_SYSTEM_RETENTION(state->pwr.afflv) && (mt_pwr_nodes[MT_PWR_SUSPEND] > 0))) { + mtk_cpc_time_sync(); + } + + if (mt_pwr_nodes[MT_PWR_NONMCUSYS] < 0) { + CPU_PM_ASSERT(0); + } + + pstate |= MT_CPUPM_PWR_DOMAIN_PERCORE_DSU; + + return pstate; +} + +static void cpupm_cpu_resume(const struct mtk_cpupm_pwrstate *state) +{ + cpupm_cpu_resume_common(state); +} + +static void cpupm_mcusys_resume(const struct mtk_cpupm_pwrstate *state) +{ + assert(state != NULL); +} + +static void cpupm_mcusys_suspend(const struct mtk_cpupm_pwrstate *state) +{ + assert(state != NULL); +} + +static unsigned int cpupm_get_pstate(enum mt_cpupm_pwr_domain domain, + const mtk_pstate_type psci_state, + const struct mtk_cpupm_pwrstate *state) +{ + unsigned int pstate = 0; + + if (state == NULL) { + return 0; + } + + if (state->info.mode == MTK_CPU_PM_SMP) { + pstate = MT_CPUPM_PWR_DOMAIN_CORE; + } else { + if (domain == CPUPM_PWR_OFF) { + pstate = cpupm_do_pstate_off(psci_state, state); + } else if (domain == CPUPM_PWR_ON) { + pstate = cpupm_do_pstate_on(psci_state, state); + } else { + INFO("[%s:%d][CPU_PM] unknown pwr domain :%d\n", + __func__, __LINE__, domain); + assert(0); + } + } + return pstate; +} + +static int cpupm_init(void) +{ + int ret = MTK_CPUPM_E_OK; + +#ifdef CPU_PM_TINYSYS_SUPPORT + int status; + + if ((cpu_pm_status & CPU_PM_INIT_READY) == CPU_PM_INIT_READY) { + return MTK_CPUPM_E_OK; + } + + if (!(cpu_pm_status & CPU_PM_DEPD_INIT)) { + status = mtk_lp_depd_condition(CPUPM_MBOX_WAIT_DEV_INIT); + if (status == 0) { + plat_cpu_pm_lock(); + cpu_pm_status |= CPU_PM_DEPD_INIT; + plat_cpu_pm_unlock(); + } + } + + if ((cpu_pm_status & CPU_PM_DEPD_INIT) && !(cpu_pm_status & CPU_PM_DEPD_READY)) { + status = mtk_lp_depd_condition(CPUPM_MBOX_WAIT_TASK_READY); + if (status == 0) { + plat_cpu_pm_lock(); + cpu_pm_status |= CPU_PM_DEPD_READY; + plat_cpu_pm_unlock(); + } + } + + ret = ((cpu_pm_status & CPU_PM_INIT_READY) == CPU_PM_INIT_READY) ? + MTK_CPUPM_E_OK : MTK_CPUPM_E_FAIL; +#endif + return ret; +} + +static int cpupm_pwr_state_valid(unsigned int afflv, unsigned int state) +{ + if (cpu_pm_status == CPU_PM_LP_READY) { + return MTK_CPUPM_E_OK; + } + + if (cpupm_init() != MTK_CPUPM_E_OK) { + return MTK_CPUPM_E_FAIL; + } + + if (read_cntpct_el0() >= (uint64_t)CPUPM_BOOTUP_TIME_THR) { + plat_cpu_pm_lock(); + cpu_pm_status |= CPU_PM_PLAT_READY; + plat_cpu_pm_unlock(); + } + + if (!IS_PLAT_SYSTEM_SUSPEND(afflv) && (cpu_pm_status & CPU_PM_PLAT_READY) == 0) { + return MTK_CPUPM_E_FAIL; + } + + return MTK_CPUPM_E_OK; +} + +static struct mtk_cpu_pm_ops cpcv3_2_mcdi = { + .get_pstate = cpupm_get_pstate, + .pwr_state_valid = cpupm_pwr_state_valid, + .cpu_resume = cpupm_cpu_resume, + .mcusys_suspend = cpupm_mcusys_suspend, + .mcusys_resume = cpupm_mcusys_resume, +}; +#endif /* CONFIG_MTK_CPU_SUSPEND_EN */ + +#endif /* CONFIG_MTK_PM_SUPPORT */ + +/* + * Depend on mtk pm methodology, the psci op init must + * be invoked after cpu pm to avoid initialization fail. + */ +int mt_plat_cpu_pm_init(void) +{ + plat_cpu_pm_lock_init(); + + mtk_cpc_init(); +#if CONFIG_MTK_PM_SUPPORT + +#if CONFIG_MTK_CPU_SUSPEND_EN + register_cpu_pm_ops(CPU_PM_FN, &cpcv3_2_mcdi); +#endif /* CONFIG_MTK_CPU_SUSPEND_EN */ + +#if CONFIG_MTK_SMP_EN + register_cpu_smp_ops(CPU_PM_FN, &cpcv3_2_cpu_smp); +#endif /* CONFIG_MTK_SMP_EN */ + +#endif /* CONFIG_MTK_PM_SUPPORT */ + + INFO("[%s:%d] - CPU PM INIT finished\n", __func__, __LINE__); + return 0; +} +MTK_ARCH_INIT(mt_plat_cpu_pm_init); + +static const mmap_region_t cpu_pm_mmap[] MTK_MMAP_SECTION = { +#ifdef CPU_PM_TINYSYS_SUPPORT +#if CONFIG_MTK_PM_SUPPORT && CONFIG_MTK_CPU_SUSPEND_EN + MAP_REGION_FLAT(CPU_EB_TCM_BASE, CPU_EB_TCM_SIZE, MT_DEVICE | MT_RW | MT_SECURE), +#endif +#endif + {0} +}; +DECLARE_MTK_MMAP_REGIONS(cpu_pm_mmap); diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm.h b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm.h new file mode 100644 index 0000000..4d99df1 --- /dev/null +++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_CPU_PM_H +#define MT_CPU_PM_H + +#include <assert.h> +#include <mcucfg.h> +#include <platform_def.h> + +/* + * After ARM v8.2, the cache will turn off automatically when powering down CPU. Therefore, there + * is no doubt to use the spin_lock here. + */ +#if !HW_ASSISTED_COHERENCY +#define MT_CPU_PM_USING_BAKERY_LOCK +#endif + +#define CPU_PM_FN (MTK_CPUPM_FN_CPUPM_GET_PWR_STATE | \ + MTK_CPUPM_FN_PWR_STATE_VALID | \ + MTK_CPUPM_FN_PWR_ON_CORE_PREPARE | \ + MTK_CPUPM_FN_RESUME_CORE | \ + MTK_CPUPM_FN_SUSPEND_MCUSYS | \ + MTK_CPUPM_FN_RESUME_MCUSYS | \ + MTK_CPUPM_FN_SMP_INIT | \ + MTK_CPUPM_FN_SMP_CORE_ON | \ + MTK_CPUPM_FN_SMP_CORE_OFF) + +#define CPU_PM_ASSERT(_cond) ({ \ + if (!(_cond)) { \ + INFO("[%s:%d] - %s\n", __func__, __LINE__, #_cond); \ + panic(); \ + } }) + +#define CPC_PWR_MASK_MCUSYS_MP0 (0xC001) + +#define PER_CPU_PWR_DATA(ctrl, cluster, core) \ + do { \ + ctrl.rvbaraddr_l = CORE_RVBRADDR_##cluster##_##core##_L; \ + ctrl.arch_addr = MCUCFG_MP0_CLUSTER_CFG5; \ + ctrl.pwpr = SPM_MP##cluster##_CPU##core##_PWR_CON; \ + } while (0) + +#define PER_CPU_PWR_CTRL(ctrl, cpu) ({ \ + switch (cpu) { \ + case 0: \ + PER_CPU_PWR_DATA(ctrl, 0, 0); \ + break; \ + case 1: \ + PER_CPU_PWR_DATA(ctrl, 0, 1); \ + break; \ + case 2: \ + PER_CPU_PWR_DATA(ctrl, 0, 2); \ + break; \ + case 3: \ + PER_CPU_PWR_DATA(ctrl, 0, 3); \ + break; \ + case 4: \ + PER_CPU_PWR_DATA(ctrl, 0, 4); \ + break; \ + case 5: \ + PER_CPU_PWR_DATA(ctrl, 0, 5); \ + break; \ + case 6: \ + PER_CPU_PWR_DATA(ctrl, 0, 6); \ + break; \ + case 7: \ + PER_CPU_PWR_DATA(ctrl, 0, 7); \ + break; \ + default: \ + assert(0); \ + break; \ + } }) + + +/* MCUSYS DREQ BIG VPROC ISO control */ +#define DREQ20_BIG_VPROC_ISO (MCUCFG_BASE + 0xad8c) + +/* Definition about bootup address for each core CORE_RVBRADDR_clusterid_cpuid */ +#define CORE_RVBRADDR_0_0_L (MCUCFG_BASE + 0xc900) +#define CORE_RVBRADDR_0_1_L (MCUCFG_BASE + 0xc908) +#define CORE_RVBRADDR_0_2_L (MCUCFG_BASE + 0xc910) +#define CORE_RVBRADDR_0_3_L (MCUCFG_BASE + 0xc918) +#define CORE_RVBRADDR_0_4_L (MCUCFG_BASE + 0xc920) +#define CORE_RVBRADDR_0_5_L (MCUCFG_BASE + 0xc928) +#define CORE_RVBRADDR_0_6_L (MCUCFG_BASE + 0xc930) +#define CORE_RVBRADDR_0_7_L (MCUCFG_BASE + 0xc938) +#define MCUCFG_MP0_CLUSTER_CFG5 (MCUCFG_BASE + 0xc8e4) + +struct cpu_pwr_ctrl { + unsigned int rvbaraddr_l; + unsigned int arch_addr; + unsigned int pwpr; +}; + +#define MCUSYS_STATUS_PDN BIT(0) +#define MCUSYS_STATUS_CPUSYS_PROTECT BIT(8) +#define MCUSYS_STATUS_MCUSYS_PROTECT BIT(9) + +/* cpu_pm function ID */ +enum mt_cpu_pm_user_id { + MCUSYS_STATUS, + CPC_COMMAND, +}; + +/* cpu_pm lp function ID */ +enum mt_cpu_pm_lp_smc_id { + LP_CPC_COMMAND, + IRQS_REMAIN_ALLOC, + IRQS_REMAIN_CTRL, + IRQS_REMAIN_IRQ, + IRQS_REMAIN_WAKEUP_CAT, + IRQS_REMAIN_WAKEUP_SRC, +}; + +#endif /* MT_CPU_PM_H */ diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_cpc.c b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_cpc.c new file mode 100644 index 0000000..4cc2203 --- /dev/null +++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_cpc.c @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <string.h> + +#include <drivers/delay_timer.h> + +#include "mt_cpu_pm.h" +#include "mt_cpu_pm_cpc.h" +#include "mt_smp.h" +#include <mt_timer.h> + +struct mtk_cpc_dev { + int auto_off; + unsigned int auto_thres_tick; +}; + +static struct mtk_cpc_dev cpc; + +static int mtk_cpc_last_core_prot(int prot_req, int resp_reg, int resp_ofs) +{ + unsigned int staus; + unsigned int retry = 0; + + while (retry < RETRY_CNT_MAX) { + retry++; + + mmio_write_32(CPC_MCUSYS_LAST_CORE_REQ, prot_req); + + udelay(1); + + staus = (mmio_read_32(resp_reg) >> resp_ofs) & CPC_PROT_RESP_MASK; + + if (staus == PROT_SUCCESS) { + return CPC_SUCCESS; + } else if (staus == PROT_GIVEUP) { + return CPC_ERR_FAIL; + } + } + + return CPC_ERR_TIMEOUT; +} + +static int mtk_cpu_pm_mcusys_prot_aquire(void) +{ + return mtk_cpc_last_core_prot(MCUSYS_PROT_SET, CPC_MCUSYS_LAST_CORE_RESP, MCUSYS_RESP_OFS); +} + +static void mtk_cpu_pm_mcusys_prot_release(void) +{ + mmio_write_32(CPC_MCUSYS_PWR_ON_MASK, MCUSYS_PROT_CLR); +} + +int mtk_cpu_pm_cluster_prot_aquire(void) +{ + return mtk_cpc_last_core_prot(CPUSYS_PROT_SET, CPC_MCUSYS_MP_LAST_CORE_RESP, + CPUSYS_RESP_OFS); +} + +void mtk_cpu_pm_cluster_prot_release(void) +{ + mmio_write_32(CPC_MCUSYS_PWR_ON_MASK, CPUSYS_PROT_CLR); +} + +static void mtk_cpc_cluster_cnt_backup(void) +{ + /* single cluster */ + uint32_t backup_cnt = mmio_read_32(CPC_CLUSTER_CNT_BACKUP); + uint32_t curr_cnt = mmio_read_32(CPC_MCUSYS_CLUSTER_COUNTER); + + if ((curr_cnt & 0x7fff) == 0) { + curr_cnt = (curr_cnt >> 16) & 0x7fff; + } else { + curr_cnt = curr_cnt & 0x7fff; + } + + mmio_write_32(CPC_CLUSTER_CNT_BACKUP, backup_cnt + curr_cnt); + mmio_write_32(CPC_MCUSYS_CLUSTER_COUNTER_CLR, 0x3); +} + +static inline void mtk_cpc_mcusys_off_enable(bool enable) +{ + mmio_write_32(CPC_MCUSYS_PWR_CTRL, enable ? 1 : 0); +} + +void mtk_cpc_mcusys_off_reflect(void) +{ + mtk_cpc_mcusys_off_enable(false); + mtk_cpu_pm_mcusys_prot_release(); +} + +int mtk_cpc_mcusys_off_prepare(void) +{ + if (mtk_cpu_pm_mcusys_prot_aquire() != CPC_SUCCESS) { + return CPC_ERR_FAIL; + } + + mtk_cpc_cluster_cnt_backup(); + mtk_cpc_mcusys_off_enable(true); + + return CPC_SUCCESS; +} + +void mtk_cpc_core_on_hint_set(int cpu) +{ + mmio_write_32(CPC_MCUSYS_CPU_ON_SW_HINT_SET, BIT(cpu)); +} + +void mtk_cpc_core_on_hint_clr(int cpu) +{ + mmio_write_32(CPC_MCUSYS_CPU_ON_SW_HINT_CLR, BIT(cpu)); +} + +static void mtk_cpc_dump_timestamp(void) +{ + unsigned int id; + + for (id = 0; id < CPC_TRACE_ID_NUM; id++) { + mmio_write_32(CPC_MCUSYS_TRACE_SEL, id); + + memcpy((void *)(uintptr_t)CPC_TRACE_SRAM(id), + (const void *)(uintptr_t)CPC_MCUSYS_TRACE_DATA, + CPC_TRACE_SIZE); + } +} + +void mtk_cpc_time_sync(void) +{ + uint64_t kt; + uint32_t systime_l, systime_h; + + kt = sched_clock(); + systime_l = mmio_read_32(CNTSYS_L_REG); + systime_h = mmio_read_32(CNTSYS_H_REG); + + /* sync kernel timer to cpc */ + mmio_write_32(CPC_MCUSYS_CPC_KERNEL_TIME_L_BASE, (uint32_t)kt); + mmio_write_32(CPC_MCUSYS_CPC_KERNEL_TIME_H_BASE, (uint32_t)(kt >> 32)); + + /* sync system timer to cpc */ + mmio_write_32(CPC_MCUSYS_CPC_SYSTEM_TIME_L_BASE, systime_l); + mmio_write_32(CPC_MCUSYS_CPC_SYSTEM_TIME_H_BASE, systime_h); +} + +static void mtk_cpc_config(unsigned int cfg, unsigned int data) +{ + switch (cfg) { + case CPC_SMC_CONFIG_PROF: + if (data) { + mmio_setbits_32(CPC_MCUSYS_CPC_DBG_SETTING, CPC_PROF_EN); + } else { + mmio_clrbits_32(CPC_MCUSYS_CPC_DBG_SETTING, CPC_PROF_EN); + } + break; + case CPC_SMC_CONFIG_AUTO_OFF: + if (data) { + mmio_setbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG, CPC_AUTO_OFF_EN); + cpc.auto_off = 1; + } else { + mmio_setbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG, CPC_AUTO_OFF_EN); + cpc.auto_off = 0; + } + break; + case CPC_SMC_CONFIG_AUTO_OFF_THRES: + cpc.auto_thres_tick = US_TO_TICKS(data); + mmio_write_32(CPC_MCUSYS_CPC_OFF_THRES, cpc.auto_thres_tick); + break; + case CPC_SMC_CONFIG_CNT_CLR: + mmio_write_32(CPC_MCUSYS_CLUSTER_COUNTER_CLR, 0x3); + break; + case CPC_SMC_CONFIG_TIME_SYNC: + mtk_cpc_time_sync(); + break; + default: + break; + } +} + +static unsigned int mtk_cpc_read_config(unsigned int cfg) +{ + unsigned int res = 0; + + switch (cfg) { + case CPC_SMC_CONFIG_PROF: + res = (mmio_read_32(CPC_MCUSYS_CPC_DBG_SETTING) & CPC_PROF_EN) ? 1 : 0; + break; + case CPC_SMC_CONFIG_AUTO_OFF: + res = cpc.auto_off; + break; + case CPC_SMC_CONFIG_AUTO_OFF_THRES: + res = TICKS_TO_US(cpc.auto_thres_tick); + break; + case CPC_SMC_CONFIG_CNT_CLR: + default: + break; + } + + return res; +} + +uint64_t mtk_cpc_handler(uint64_t act, uint64_t arg1, uint64_t arg2) +{ + uint64_t res = 0; + + switch (act) { + case CPC_SMC_EVENT_CPC_CONFIG: + mtk_cpc_config((unsigned int)arg1, (unsigned int)arg2); + break; + case CPC_SMC_EVENT_READ_CONFIG: + res = mtk_cpc_read_config((unsigned int)arg1); + break; + case CPC_SMC_EVENT_GIC_DPG_SET: + /* isolated_status = x2; */ + default: + break; + } + + return res; +} + +uint64_t mtk_cpc_trace_dump(uint64_t act, uint64_t arg1, uint64_t arg2) +{ + switch (act) { + case CPC_SMC_EVENT_DUMP_TRACE_DATA: + mtk_cpc_dump_timestamp(); + break; + default: + break; + } + + return 0; +} + +void mtk_cpc_init(void) +{ +#if CONFIG_MTK_SMP_EN + mt_smp_init(); +#endif + mmio_setbits_32(CPC_MCUSYS_CPC_DBG_SETTING, (CPC_DBG_EN | CPC_CALC_EN)); + + cpc.auto_off = 1; + mmio_setbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG, (CPC_OFF_PRE_EN | + ((cpc.auto_off > 0) ? CPC_AUTO_OFF_EN : 0))); + + mtk_cpc_config(CPC_SMC_CONFIG_AUTO_OFF_THRES, 8000); + + /* enable CPC */ + mmio_setbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG, CPC_CTRL_ENABLE); + mmio_setbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG, SSPM_CORE_PWR_ON_EN); +} diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_cpc.h b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_cpc.h new file mode 100644 index 0000000..3004f41 --- /dev/null +++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_cpc.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_CPU_PM_CPC_H +#define MT_CPU_PM_CPC_H + +#include <lib/mmio.h> + +#include <mcucfg.h> +#include <platform_def.h> + +#define NEED_CPUSYS_PROT_WORKAROUND (1) + +/* system sram registers */ +#define CPUIDLE_SRAM_REG(r) (CPU_IDLE_SRAM_BASE + (r)) + +/* db dump */ +#define CPC_TRACE_SIZE (0x20) +#define CPC_TRACE_ID_NUM (10) +#define CPC_TRACE_SRAM(id) (CPUIDLE_SRAM_REG(0x10) + (id) * CPC_TRACE_SIZE) + +/* buckup off count */ +#define CPC_CLUSTER_CNT_BACKUP CPUIDLE_SRAM_REG(0x1f0) +#define CPC_MCUSYS_CNT CPUIDLE_SRAM_REG(0x1f4) + +/* CPC_MCUSYS_CPC_FLOW_CTRL_CFG (0xA814): debug setting */ +#define CPC_PWR_ON_SEQ_DIS BIT(1) +#define CPC_PWR_ON_PRIORITY BIT(2) +#define CPC_AUTO_OFF_EN BIT(5) +#define CPC_DORMANT_WAIT_EN BIT(14) +#define CPC_CTRL_EN BIT(16) +#define CPC_OFF_PRE_EN BIT(29) + +/* CPC_MCUSYS_LAST_CORE_REQ (0xA818) : last core protection */ +#define CPUSYS_PROT_SET BIT(0) +#define MCUSYS_PROT_SET BIT(8) +#define CPUSYS_PROT_CLR BIT(8) +#define MCUSYS_PROT_CLR BIT(9) + +#define CPC_PROT_RESP_MASK (0x3) +#define CPUSYS_RESP_OFS (16) +#define MCUSYS_RESP_OFS (30) + +#define RETRY_CNT_MAX (1000) + +#define PROT_RETRY (0) +#define PROT_SUCCESS (1) +#define PROT_GIVEUP (2) + +/* CPC_MCUSYS_CPC_DBG_SETTING (0xAB00): debug setting */ +#define CPC_PROF_EN BIT(0) +#define CPC_DBG_EN BIT(1) +#define CPC_FREEZE BIT(2) +#define CPC_CALC_EN BIT(3) + +enum mcusys_cpc_lastcore_prot_status { + CPC_SUCCESS = 0, + CPC_ERR_FAIL, + CPC_ERR_TIMEOUT, + NF_CPC_ERR, +}; + +enum mcusys_cpc_smc_events { + CPC_SMC_EVENT_DUMP_TRACE_DATA, + CPC_SMC_EVENT_GIC_DPG_SET, + CPC_SMC_EVENT_CPC_CONFIG, + CPC_SMC_EVENT_READ_CONFIG, + NF_CPC_SMC_EVENT, +}; + +enum mcusys_cpc_smc_config { + CPC_SMC_CONFIG_PROF, + CPC_SMC_CONFIG_AUTO_OFF, + CPC_SMC_CONFIG_AUTO_OFF_THRES, + CPC_SMC_CONFIG_CNT_CLR, + CPC_SMC_CONFIG_TIME_SYNC, + NF_CPC_SMC_CONFIG, +}; + +#define US_TO_TICKS(us) ((us) * 13) +#define TICKS_TO_US(tick) ((tick) / 13) + +int mtk_cpu_pm_cluster_prot_aquire(void); +void mtk_cpu_pm_cluster_prot_release(void); + +void mtk_cpc_mcusys_off_reflect(void); +int mtk_cpc_mcusys_off_prepare(void); + +void mtk_cpc_core_on_hint_set(int cpu); +void mtk_cpc_core_on_hint_clr(int cpu); +void mtk_cpc_time_sync(void); + +uint64_t mtk_cpc_handler(uint64_t act, uint64_t arg1, uint64_t arg2); +uint64_t mtk_cpc_trace_dump(uint64_t act, uint64_t arg1, uint64_t arg2); +void mtk_cpc_init(void); + +#endif /* MT_CPU_PM_CPC_H */ diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_mbox.c b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_mbox.c new file mode 100644 index 0000000..4d67e7b --- /dev/null +++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_mbox.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <errno.h> + +#include <lib/mmio.h> + +#include "mt_cpu_pm_mbox.h" +#include <platform_def.h> + +#ifdef __GNUC__ +#define MCDI_LIKELY(x) __builtin_expect(!!(x), 1) +#define MCDI_UNLIKELY(x) __builtin_expect(!!(x), 0) +#else +#define MCDI_LIKELY(x) (x) +#define MCDI_UNLIKELY(x) (x) +#endif + +#define MCUPM_MBOX_3_BASE (CPU_EB_TCM_BASE + CPU_EB_MBOX3_OFFSET) +#define MCUPM_MBOX_WRITE(id, val) mmio_write_32(MCUPM_MBOX_3_BASE + 4 * (id), val) +#define MCUPM_MBOX_READ(id) mmio_read_32(MCUPM_MBOX_3_BASE + 4 * (id)) + +void mtk_set_mcupm_pll_mode(unsigned int mode) +{ + if (mode < NF_MCUPM_ARMPLL_MODE) { + MCUPM_MBOX_WRITE(MCUPM_MBOX_ARMPLL_MODE, mode); + } +} + +int mtk_get_mcupm_pll_mode(void) +{ + return MCUPM_MBOX_READ(MCUPM_MBOX_ARMPLL_MODE); +} + +void mtk_set_mcupm_buck_mode(unsigned int mode) +{ + if (mode < NF_MCUPM_BUCK_MODE) { + MCUPM_MBOX_WRITE(MCUPM_MBOX_BUCK_MODE, mode); + } +} + +int mtk_get_mcupm_buck_mode(void) +{ + return MCUPM_MBOX_READ(MCUPM_MBOX_BUCK_MODE); +} + +void mtk_set_cpu_pm_preffered_cpu(unsigned int cpuid) +{ + return MCUPM_MBOX_WRITE(MCUPM_MBOX_WAKEUP_CPU, cpuid); +} + +unsigned int mtk_get_cpu_pm_preffered_cpu(void) +{ + return MCUPM_MBOX_READ(MCUPM_MBOX_WAKEUP_CPU); +} + +static int mtk_wait_mbox_init_done(void) +{ + int status = MCUPM_MBOX_READ(MCUPM_MBOX_TASK_STA); + + if (status != MCUPM_TASK_INIT) { + return status; + } + + mtk_set_mcupm_pll_mode(MCUPM_ARMPLL_OFF); + mtk_set_mcupm_buck_mode(MCUPM_BUCK_OFF_MODE); + + MCUPM_MBOX_WRITE(MCUPM_MBOX_PWR_CTRL_EN, (MCUPM_MCUSYS_CTRL | MCUPM_CM_CTRL | + MCUPM_BUCK_CTRL | MCUPM_ARMPLL_CTRL)); + + return status; +} + +int mtk_lp_depd_condition(enum cpupm_mbox_depd_type type) +{ + int status; + + if (type == CPUPM_MBOX_WAIT_DEV_INIT) { + status = mtk_wait_mbox_init_done(); + if (MCDI_UNLIKELY(status != MCUPM_TASK_INIT)) { + return -ENXIO; + } + MCUPM_MBOX_WRITE(MCUPM_MBOX_AP_READY, 1); + } else if (type == CPUPM_MBOX_WAIT_TASK_READY) { + status = MCUPM_MBOX_READ(MCUPM_MBOX_TASK_STA); + if (MCDI_UNLIKELY((status != MCUPM_TASK_WAIT) && + (status != MCUPM_TASK_INIT_FINISH))) { + return -ENXIO; + } + } + return 0; +} diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_mbox.h b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_mbox.h new file mode 100644 index 0000000..72be6bd --- /dev/null +++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_mbox.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_CPU_PM_MBOX_H +#define MT_CPU_PM_MBOX_H + +#include <lib/utils_def.h> + +/* MCUPM Mbox */ +/* AP Write */ +#define MCUPM_MBOX_AP_READY (0) +#define MCUPM_MBOX_RESERVED_1 (1) +#define MCUPM_MBOX_RESERVED_2 (2) +#define MCUPM_MBOX_RESERVED_3 (3) +#define MCUPM_MBOX_PWR_CTRL_EN (4) +#define MCUPM_MBOX_L3_CACHE_MODE (5) +#define MCUPM_MBOX_BUCK_MODE (6) +#define MCUPM_MBOX_ARMPLL_MODE (7) +/* AP Read */ +#define MCUPM_MBOX_TASK_STA (8) +#define MCUPM_MBOX_RESERVED_9 (9) +#define MCUPM_MBOX_RESERVED_10 (10) +#define MCUPM_MBOX_RESERVED_11 (11) +#define MCUPM_MBOX_WAKEUP_CPU (12) + +/* Mbox Slot: APMCU_MCUPM_MBOX_PWR_CTRL_EN (4) */ +#define MCUPM_MCUSYS_CTRL BIT(0) +#define MCUPM_BUCK_CTRL BIT(1) +#define MCUPM_ARMPLL_CTRL BIT(2) +#define MCUPM_CM_CTRL BIT(3) +#define MCUPM_PWR_CTRL_MASK (BIT(3) - 1) + +/* Mbox Slot: APMCU_MCUPM_MBOX_L3_CACHE_MODE (5) */ +#define MCUPM_L3_OFF_MODE (0) /* default */ +#define MCUPM_L3_DORMANT_MODE (1) +#define NF_MCUPM_L3_MODE (2) + +/* Mbox Slot: APMCU_MCUPM_MBOX_BUCK_MODE (6) */ +#define MCUPM_BUCK_NORMAL_MODE (0) /* default */ +#define MCUPM_BUCK_LP_MODE (1) +#define MCUPM_BUCK_OFF_MODE (2) +#define NF_MCUPM_BUCK_MODE (3) + +/* Mbox Slot: APMCU_MCUPM_MBOX_ARMPLL_MODE (7) */ +#define MCUPM_ARMPLL_ON (0) /* default */ +#define MCUPM_ARMPLL_GATING (1) +#define MCUPM_ARMPLL_OFF (2) +#define NF_MCUPM_ARMPLL_MODE (3) + +/* Mbox Slot: APMCU_MCUPM_MBOX_TASK_STA (9) */ +#define MCUPM_TASK_UNINIT (0) +#define MCUPM_TASK_INIT (1) +#define MCUPM_TASK_INIT_FINISH (2) +#define MCUPM_TASK_WAIT (3) +#define MCUPM_TASK_RUN (4) +#define MCUPM_TASK_PAUSE (5) + + +void mtk_set_mcupm_pll_mode(unsigned int mode); +int mtk_get_mcupm_pll_mode(void); + +void mtk_set_mcupm_buck_mode(unsigned int mode); +int mtk_get_mcupm_buck_mode(void); + +void mtk_set_cpu_pm_preffered_cpu(unsigned int cpuid); +unsigned int mtk_get_cpu_pm_preffered_cpu(void); + +enum cpupm_mbox_depd_type { + CPUPM_MBOX_WAIT_DEV_INIT, + CPUPM_MBOX_WAIT_TASK_READY, +}; + +int mtk_lp_depd_condition(enum cpupm_mbox_depd_type type); + +#endif /* MT_CPU_PM_MBOX_H */ diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_smp.c b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_smp.c new file mode 100644 index 0000000..a1d9c31 --- /dev/null +++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_smp.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> + +#include <arch_helpers.h> +#include <common/debug.h> +#include <drivers/delay_timer.h> +#include <plat/common/platform.h> + +#include <lib/pm/mtk_pm.h> +#include <mcucfg.h> +#include "mt_cpu_pm.h" +#include "mt_smp.h" + +static inline int is_core_power_status_on(unsigned int cpuid) +{ + return !!(mmio_read_32(CPU_PWR_STATUS) & BIT(cpuid)); +} + +void mt_smp_core_init_arch(unsigned int cluster, unsigned int cpu, int arm64, + struct cpu_pwr_ctrl *pwr_ctrl) +{ + CPU_PM_ASSERT(cluster == 0); + CPU_PM_ASSERT(pwr_ctrl != NULL); + + /* aa64naa32 in bits[16:23] */ + if (arm64 != 0) { + mmio_setbits_32(pwr_ctrl->arch_addr, 1 << (16 + cpu)); + } else { + mmio_clrbits_32(pwr_ctrl->arch_addr, 1 << (16 + cpu)); + } +} + +void mt_smp_core_bootup_address_set(struct cpu_pwr_ctrl *pwr_ctrl, uintptr_t entry) +{ + CPU_PM_ASSERT(pwr_ctrl != NULL); + + /* Set bootup address */ + mmio_write_32(pwr_ctrl->rvbaraddr_l, entry); +} + +int mt_smp_power_core_on(unsigned int cpu_id, struct cpu_pwr_ctrl *pwr_ctrl) +{ + unsigned int val = is_core_power_status_on(cpu_id); + + CPU_PM_ASSERT(pwr_ctrl); + + mmio_clrbits_32(pwr_ctrl->pwpr, RESETPWRON_CONFIG); + if (val == 0) { + /* + * Set to 0 after BIG VPROC bulk powered on (configure in MCUPM) and + * before big core power-on sequence. + */ + if (cpu_id >= PLAT_CPU_PM_B_BUCK_ISO_ID) { + mmio_write_32(DREQ20_BIG_VPROC_ISO, 0); + } + + mmio_setbits_32(pwr_ctrl->pwpr, PWR_RST_B); + dsbsy(); + + /* set mp0_spmc_pwr_on_cpuX = 1 */ + mmio_setbits_32(pwr_ctrl->pwpr, PWR_ON); + + val = 0; + while (is_core_power_status_on(cpu_id) == 0) { + DO_SMP_CORE_ON_WAIT_TIMEOUT(val); + mmio_clrbits_32(pwr_ctrl->pwpr, PWR_ON); + mmio_setbits_32(pwr_ctrl->pwpr, PWR_ON); + } + } else { + INFO("[%s:%d] - core_%u haven been power on\n", __func__, __LINE__, cpu_id); + } + + return MTK_CPUPM_E_OK; +} + +int mt_smp_power_core_off(struct cpu_pwr_ctrl *pwr_ctrl) +{ + /* set mp0_spmc_pwr_on_cpuX = 1 */ + mmio_clrbits_32(pwr_ctrl->pwpr, PWR_ON); + return MTK_CPUPM_E_OK; +} + +void mt_smp_init(void) +{ + /* clear RESETPWRON_CONFIG of mcusys/cluster/core0 */ + mmio_clrbits_32(SPM_MCUSYS_PWR_CON, RESETPWRON_CONFIG); + mmio_clrbits_32(SPM_MP0_CPUTOP_PWR_CON, RESETPWRON_CONFIG); +} diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_smp.h b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_smp.h new file mode 100644 index 0000000..4c2f8d2 --- /dev/null +++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_smp.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_SMP_H +#define MT_SMP_H + +#include <lib/mmio.h> +#include <platform_def.h> + +#define CPU_PWR_STATUS (MCUCFG_BASE + 0xA840) + +#define SMP_CORE_TIMEOUT_MAX (50000) +#define DO_SMP_CORE_ON_WAIT_TIMEOUT(k_cnt) ({ \ + CPU_PM_ASSERT(k_cnt < SMP_CORE_TIMEOUT_MAX); \ + k_cnt++; udelay(1); }) + +void mt_smp_core_init_arch(unsigned int cluster, unsigned int cpu, int arm64, + struct cpu_pwr_ctrl *pwr_ctrl); +void mt_smp_core_bootup_address_set(struct cpu_pwr_ctrl *pwr_ctrl, uintptr_t entry); +int mt_smp_power_core_on(unsigned int cpu_id, struct cpu_pwr_ctrl *pwr_ctrl); +int mt_smp_power_core_off(struct cpu_pwr_ctrl *pwr_ctrl); +void mt_smp_init(void); + +#endif /* MT_SMP_H */ diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/rules.mk b/plat/mediatek/drivers/cpu_pm/cpcv3_2/rules.mk new file mode 100644 index 0000000..858cf38 --- /dev/null +++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/rules.mk @@ -0,0 +1,19 @@ +# +# Copyright (c) 2022, MediaTek Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +LOCAL_DIR := $(call GET_LOCAL_DIR) + +MODULE := cpcv${CONFIG_MTK_CPU_PM_ARCH} + +LOCAL_SRCS-y := ${LOCAL_DIR}/mt_cpu_pm.c ${LOCAL_DIR}/mt_cpu_pm_cpc.c + +LOCAL_SRCS-$(CPU_PM_TINYSYS_SUPPORT) += ${LOCAL_DIR}/mt_cpu_pm_mbox.c +LOCAL_SRCS-$(CONFIG_MTK_SMP_EN) += ${LOCAL_DIR}/mt_smp.c + +$(eval $(call add_defined_option,CPU_PM_TINYSYS_SUPPORT)) + +$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL))) + diff --git a/plat/mediatek/drivers/cpu_pm/rules.mk b/plat/mediatek/drivers/cpu_pm/rules.mk new file mode 100644 index 0000000..8df4f21 --- /dev/null +++ b/plat/mediatek/drivers/cpu_pm/rules.mk @@ -0,0 +1,13 @@ +# +# Copyright (c) 2022, MediaTek Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +LOCAL_DIR := $(call GET_LOCAL_DIR) + +MODULE := cpu_pm + +SUB_RULES-${CONFIG_MTK_CPU_PM_SUPPORT} := $(LOCAL_DIR)/cpcv${CONFIG_MTK_CPU_PM_ARCH} + +$(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES-y))) diff --git a/plat/mediatek/drivers/dcm/mt8188/mtk_dcm_utils.c b/plat/mediatek/drivers/dcm/mt8188/mtk_dcm_utils.c new file mode 100644 index 0000000..c054de9 --- /dev/null +++ b/plat/mediatek/drivers/dcm/mt8188/mtk_dcm_utils.c @@ -0,0 +1,402 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <lib/mmio.h> +#include <lib/utils_def.h> +#include <mtk_dcm_utils.h> + +#define MP_CPUSYS_TOP_ADB_DCM_REG0_MASK BIT(17) +#define MP_CPUSYS_TOP_ADB_DCM_REG1_MASK (BIT(15) | BIT(16) | BIT(17) | \ + BIT(18) | BIT(21)) +#define MP_CPUSYS_TOP_ADB_DCM_REG2_MASK (BIT(15) | BIT(16) | BIT(17) | BIT(18)) +#define MP_CPUSYS_TOP_ADB_DCM_REG0_ON BIT(17) +#define MP_CPUSYS_TOP_ADB_DCM_REG1_ON (BIT(15) | BIT(16) | BIT(17) | \ + BIT(18) | BIT(21)) +#define MP_CPUSYS_TOP_ADB_DCM_REG2_ON (BIT(15) | BIT(16) | BIT(17) | BIT(18)) +#define MP_CPUSYS_TOP_ADB_DCM_REG0_OFF (0x0 << 17) +#define MP_CPUSYS_TOP_ADB_DCM_REG1_OFF ((0x0 << 15) | (0x0 << 16) | \ + (0x0 << 17) | (0x0 << 18) | \ + (0x0 << 21)) +#define MP_CPUSYS_TOP_ADB_DCM_REG2_OFF ((0x0 << 15) | (0x0 << 16) | \ + (0x0 << 17) | (0x0 << 18)) + +bool dcm_mp_cpusys_top_adb_dcm_is_on(void) +{ + bool ret = true; + + ret &= dcm_check_state(MP_CPUSYS_TOP_MP_ADB_DCM_CFG0, + MP_CPUSYS_TOP_ADB_DCM_REG0_MASK, + MP_CPUSYS_TOP_ADB_DCM_REG0_ON); + ret &= dcm_check_state(MP_CPUSYS_TOP_MP_ADB_DCM_CFG4, + MP_CPUSYS_TOP_ADB_DCM_REG1_MASK, + MP_CPUSYS_TOP_ADB_DCM_REG1_ON); + ret &= dcm_check_state(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0, + MP_CPUSYS_TOP_ADB_DCM_REG2_MASK, + MP_CPUSYS_TOP_ADB_DCM_REG2_ON); + + return ret; +} + +void dcm_mp_cpusys_top_adb_dcm(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'mp_cpusys_top_adb_dcm'" */ + mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_ADB_DCM_CFG0, + MP_CPUSYS_TOP_ADB_DCM_REG0_MASK, + MP_CPUSYS_TOP_ADB_DCM_REG0_ON); + mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_ADB_DCM_CFG4, + MP_CPUSYS_TOP_ADB_DCM_REG1_MASK, + MP_CPUSYS_TOP_ADB_DCM_REG1_ON); + mmio_clrsetbits_32(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0, + MP_CPUSYS_TOP_ADB_DCM_REG2_MASK, + MP_CPUSYS_TOP_ADB_DCM_REG2_ON); + } else { + /* TINFO = "Turn OFF DCM 'mp_cpusys_top_adb_dcm'" */ + mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_ADB_DCM_CFG0, + MP_CPUSYS_TOP_ADB_DCM_REG0_MASK, + MP_CPUSYS_TOP_ADB_DCM_REG0_OFF); + mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_ADB_DCM_CFG4, + MP_CPUSYS_TOP_ADB_DCM_REG1_MASK, + MP_CPUSYS_TOP_ADB_DCM_REG1_OFF); + mmio_clrsetbits_32(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0, + MP_CPUSYS_TOP_ADB_DCM_REG2_MASK, + MP_CPUSYS_TOP_ADB_DCM_REG2_OFF); + } +} + +#define MP_CPUSYS_TOP_APB_DCM_REG0_MASK BIT(5) +#define MP_CPUSYS_TOP_APB_DCM_REG1_MASK BIT(8) +#define MP_CPUSYS_TOP_APB_DCM_REG2_MASK BIT(16) +#define MP_CPUSYS_TOP_APB_DCM_REG0_ON BIT(5) +#define MP_CPUSYS_TOP_APB_DCM_REG1_ON BIT(8) +#define MP_CPUSYS_TOP_APB_DCM_REG2_ON BIT(16) +#define MP_CPUSYS_TOP_APB_DCM_REG0_OFF (0x0 << 5) +#define MP_CPUSYS_TOP_APB_DCM_REG1_OFF (0x0 << 8) +#define MP_CPUSYS_TOP_APB_DCM_REG2_OFF (0x0 << 16) + +bool dcm_mp_cpusys_top_apb_dcm_is_on(void) +{ + bool ret = true; + + ret &= dcm_check_state(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0, + MP_CPUSYS_TOP_APB_DCM_REG0_MASK, + MP_CPUSYS_TOP_APB_DCM_REG0_ON); + ret &= dcm_check_state(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0, + MP_CPUSYS_TOP_APB_DCM_REG1_MASK, + MP_CPUSYS_TOP_APB_DCM_REG1_ON); + ret &= dcm_check_state(MP_CPUSYS_TOP_MP0_DCM_CFG0, + MP_CPUSYS_TOP_APB_DCM_REG2_MASK, + MP_CPUSYS_TOP_APB_DCM_REG2_ON); + + return ret; +} + +void dcm_mp_cpusys_top_apb_dcm(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'mp_cpusys_top_apb_dcm'" */ + mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0, + MP_CPUSYS_TOP_APB_DCM_REG0_MASK, + MP_CPUSYS_TOP_APB_DCM_REG0_ON); + mmio_clrsetbits_32(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0, + MP_CPUSYS_TOP_APB_DCM_REG1_MASK, + MP_CPUSYS_TOP_APB_DCM_REG1_ON); + mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG0, + MP_CPUSYS_TOP_APB_DCM_REG2_MASK, + MP_CPUSYS_TOP_APB_DCM_REG2_ON); + } else { + /* TINFO = "Turn OFF DCM 'mp_cpusys_top_apb_dcm'" */ + mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0, + MP_CPUSYS_TOP_APB_DCM_REG0_MASK, + MP_CPUSYS_TOP_APB_DCM_REG0_OFF); + mmio_clrsetbits_32(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0, + MP_CPUSYS_TOP_APB_DCM_REG1_MASK, + MP_CPUSYS_TOP_APB_DCM_REG1_OFF); + mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG0, + MP_CPUSYS_TOP_APB_DCM_REG2_MASK, + MP_CPUSYS_TOP_APB_DCM_REG2_OFF); + } +} + +#define MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_MASK (BIT(11) | BIT(24) | BIT(25)) +#define MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_ON (BIT(11) | BIT(24) | BIT(25)) +#define MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_OFF ((0x0 << 11) | \ + (0x0 << 24) | \ + (0x0 << 25)) + +bool dcm_mp_cpusys_top_bus_pll_div_dcm_is_on(void) +{ + return dcm_check_state(MP_CPUSYS_TOP_BUS_PLLDIV_CFG, + MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_MASK, + MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_ON); +} + +void dcm_mp_cpusys_top_bus_pll_div_dcm(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'mp_cpusys_top_bus_pll_div_dcm'" */ + mmio_clrsetbits_32(MP_CPUSYS_TOP_BUS_PLLDIV_CFG, + MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_MASK, + MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_ON); + } else { + /* TINFO = "Turn OFF DCM 'mp_cpusys_top_bus_pll_div_dcm'" */ + mmio_clrsetbits_32(MP_CPUSYS_TOP_BUS_PLLDIV_CFG, + MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_MASK, + MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_OFF); + } +} + +#define MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_MASK BIT(0) +#define MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_ON BIT(0) +#define MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_OFF (0x0 << 0) + +bool dcm_mp_cpusys_top_core_stall_dcm_is_on(void) +{ + return dcm_check_state(MP_CPUSYS_TOP_MP0_DCM_CFG7, + MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_MASK, + MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_ON); +} + +void dcm_mp_cpusys_top_core_stall_dcm(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'mp_cpusys_top_core_stall_dcm'" */ + mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG7, + MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_MASK, + MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_ON); + } else { + /* TINFO = "Turn OFF DCM 'mp_cpusys_top_core_stall_dcm'" */ + mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG7, + MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_MASK, + MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_OFF); + } +} + +#define MP_CPUSYS_TOP_CPUBIU_DCM_REG0_MASK (0xffff << 0) +#define MP_CPUSYS_TOP_CPUBIU_DCM_REG0_ON (0xffff << 0) +#define MP_CPUSYS_TOP_CPUBIU_DCM_REG0_OFF (0x0 << 0) + +bool dcm_mp_cpusys_top_cpubiu_dcm_is_on(void) +{ + return dcm_check_state(MP_CPUSYS_TOP_MCSIC_DCM0, + MP_CPUSYS_TOP_CPUBIU_DCM_REG0_MASK, + MP_CPUSYS_TOP_CPUBIU_DCM_REG0_ON); +} + +void dcm_mp_cpusys_top_cpubiu_dcm(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'mp_cpusys_top_cpubiu_dcm'" */ + mmio_clrsetbits_32(MP_CPUSYS_TOP_MCSIC_DCM0, + MP_CPUSYS_TOP_CPUBIU_DCM_REG0_MASK, + MP_CPUSYS_TOP_CPUBIU_DCM_REG0_ON); + } else { + /* TINFO = "Turn OFF DCM 'mp_cpusys_top_cpubiu_dcm'" */ + mmio_clrsetbits_32(MP_CPUSYS_TOP_MCSIC_DCM0, + MP_CPUSYS_TOP_CPUBIU_DCM_REG0_MASK, + MP_CPUSYS_TOP_CPUBIU_DCM_REG0_OFF); + } +} + +#define MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_MASK (BIT(24) | BIT(25)) +#define MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_ON (BIT(24) | BIT(25)) +#define MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_OFF ((0x0 << 24) | (0x0 << 25)) + +bool dcm_mp_cpusys_top_cpu_pll_div_0_dcm_is_on(void) +{ + return dcm_check_state(MP_CPUSYS_TOP_CPU_PLLDIV_CFG0, + MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_MASK, + MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_ON); +} + +void dcm_mp_cpusys_top_cpu_pll_div_0_dcm(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'mp_cpusys_top_cpu_pll_div_0_dcm'" */ + mmio_clrsetbits_32(MP_CPUSYS_TOP_CPU_PLLDIV_CFG0, + MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_MASK, + MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_ON); + } else { + /* TINFO = "Turn OFF DCM 'mp_cpusys_top_cpu_pll_div_0_dcm'" */ + mmio_clrsetbits_32(MP_CPUSYS_TOP_CPU_PLLDIV_CFG0, + MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_MASK, + MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_OFF); + } +} + +#define MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_MASK (BIT(24) | BIT(25)) +#define MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_ON (BIT(24) | BIT(25)) +#define MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_OFF ((0x0 << 24) | (0x0 << 25)) + +bool dcm_mp_cpusys_top_cpu_pll_div_1_dcm_is_on(void) +{ + return dcm_check_state(MP_CPUSYS_TOP_CPU_PLLDIV_CFG1, + MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_MASK, + MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_ON); +} + +void dcm_mp_cpusys_top_cpu_pll_div_1_dcm(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'mp_cpusys_top_cpu_pll_div_1_dcm'" */ + mmio_clrsetbits_32(MP_CPUSYS_TOP_CPU_PLLDIV_CFG1, + MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_MASK, + MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_ON); + } else { + /* TINFO = "Turn OFF DCM 'mp_cpusys_top_cpu_pll_div_1_dcm'" */ + mmio_clrsetbits_32(MP_CPUSYS_TOP_CPU_PLLDIV_CFG1, + MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_MASK, + MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_OFF); + } +} + +#define MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_MASK BIT(4) +#define MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_ON BIT(4) +#define MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_OFF (0x0 << 4) + +bool dcm_mp_cpusys_top_fcm_stall_dcm_is_on(void) +{ + return dcm_check_state(MP_CPUSYS_TOP_MP0_DCM_CFG7, + MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_MASK, + MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_ON); +} + +void dcm_mp_cpusys_top_fcm_stall_dcm(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'mp_cpusys_top_fcm_stall_dcm'" */ + mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG7, + MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_MASK, + MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_ON); + } else { + /* TINFO = "Turn OFF DCM 'mp_cpusys_top_fcm_stall_dcm'" */ + mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG7, + MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_MASK, + MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_OFF); + } +} + +#define MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_MASK BIT(31) +#define MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_ON BIT(31) +#define MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_OFF (0x0U << 31) + +bool dcm_mp_cpusys_top_last_cor_idle_dcm_is_on(void) +{ + return dcm_check_state(MP_CPUSYS_TOP_BUS_PLLDIV_CFG, + MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_MASK, + MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_ON); +} + +void dcm_mp_cpusys_top_last_cor_idle_dcm(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'mp_cpusys_top_last_cor_idle_dcm'" */ + mmio_clrsetbits_32(MP_CPUSYS_TOP_BUS_PLLDIV_CFG, + MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_MASK, + MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_ON); + } else { + /* TINFO = "Turn OFF DCM 'mp_cpusys_top_last_cor_idle_dcm'" */ + mmio_clrsetbits_32(MP_CPUSYS_TOP_BUS_PLLDIV_CFG, + MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_MASK, + MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_OFF); + } +} + +#define MP_CPUSYS_TOP_MISC_DCM_REG0_MASK (BIT(1) | BIT(4)) +#define MP_CPUSYS_TOP_MISC_DCM_REG0_ON (BIT(1) | BIT(4)) +#define MP_CPUSYS_TOP_MISC_DCM_REG0_OFF ((0x0 << 1) | (0x0 << 4)) + +bool dcm_mp_cpusys_top_misc_dcm_is_on(void) +{ + return dcm_check_state(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0, + MP_CPUSYS_TOP_MISC_DCM_REG0_MASK, + MP_CPUSYS_TOP_MISC_DCM_REG0_ON); +} + +void dcm_mp_cpusys_top_misc_dcm(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'mp_cpusys_top_misc_dcm'" */ + mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0, + MP_CPUSYS_TOP_MISC_DCM_REG0_MASK, + MP_CPUSYS_TOP_MISC_DCM_REG0_ON); + } else { + /* TINFO = "Turn OFF DCM 'mp_cpusys_top_misc_dcm'" */ + mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0, + MP_CPUSYS_TOP_MISC_DCM_REG0_MASK, + MP_CPUSYS_TOP_MISC_DCM_REG0_OFF); + } +} + +#define MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK BIT(3) +#define MP_CPUSYS_TOP_MP0_QDCM_REG1_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3)) +#define MP_CPUSYS_TOP_MP0_QDCM_REG0_ON BIT(3) +#define MP_CPUSYS_TOP_MP0_QDCM_REG1_ON (BIT(0) | BIT(1) | BIT(2) | BIT(3)) +#define MP_CPUSYS_TOP_MP0_QDCM_REG0_OFF ((0x0 << 3)) +#define MP_CPUSYS_TOP_MP0_QDCM_REG1_OFF ((0x0 << 0) | (0x0 << 1) | \ + (0x0 << 2) | (0x0 << 3)) + +bool dcm_mp_cpusys_top_mp0_qdcm_is_on(void) +{ + bool ret = true; + + ret &= dcm_check_state(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0, + MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK, + MP_CPUSYS_TOP_MP0_QDCM_REG0_ON); + ret &= dcm_check_state(MP_CPUSYS_TOP_MP0_DCM_CFG0, + MP_CPUSYS_TOP_MP0_QDCM_REG1_MASK, + MP_CPUSYS_TOP_MP0_QDCM_REG1_ON); + + return ret; +} + +void dcm_mp_cpusys_top_mp0_qdcm(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'mp_cpusys_top_mp0_qdcm'" */ + mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0, + MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK, + MP_CPUSYS_TOP_MP0_QDCM_REG0_ON); + mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG0, + MP_CPUSYS_TOP_MP0_QDCM_REG1_MASK, + MP_CPUSYS_TOP_MP0_QDCM_REG1_ON); + } else { + /* TINFO = "Turn OFF DCM 'mp_cpusys_top_mp0_qdcm'" */ + mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0, + MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK, + MP_CPUSYS_TOP_MP0_QDCM_REG0_OFF); + mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG0, + MP_CPUSYS_TOP_MP0_QDCM_REG1_MASK, + MP_CPUSYS_TOP_MP0_QDCM_REG1_OFF); + } +} + +#define CPCCFG_REG_EMI_WFIFO_REG0_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3)) +#define CPCCFG_REG_EMI_WFIFO_REG0_ON (BIT(0) | BIT(1) | BIT(2) | BIT(3)) +#define CPCCFG_REG_EMI_WFIFO_REG0_OFF ((0x0 << 0) | (0x0 << 1) | \ + (0x0 << 2) | (0x0 << 3)) + +bool dcm_cpccfg_reg_emi_wfifo_is_on(void) +{ + return dcm_check_state(CPCCFG_REG_EMI_WFIFO, + CPCCFG_REG_EMI_WFIFO_REG0_MASK, + CPCCFG_REG_EMI_WFIFO_REG0_ON); +} + +void dcm_cpccfg_reg_emi_wfifo(bool on) +{ + if (on) { + /* TINFO = "Turn ON DCM 'cpccfg_reg_emi_wfifo'" */ + mmio_clrsetbits_32(CPCCFG_REG_EMI_WFIFO, + CPCCFG_REG_EMI_WFIFO_REG0_MASK, + CPCCFG_REG_EMI_WFIFO_REG0_ON); + } else { + /* TINFO = "Turn OFF DCM 'cpccfg_reg_emi_wfifo'" */ + mmio_clrsetbits_32(CPCCFG_REG_EMI_WFIFO, + CPCCFG_REG_EMI_WFIFO_REG0_MASK, + CPCCFG_REG_EMI_WFIFO_REG0_OFF); + } +} diff --git a/plat/mediatek/drivers/dcm/mt8188/mtk_dcm_utils.h b/plat/mediatek/drivers/dcm/mt8188/mtk_dcm_utils.h new file mode 100644 index 0000000..5d758dd --- /dev/null +++ b/plat/mediatek/drivers/dcm/mt8188/mtk_dcm_utils.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MTK_DCM_UTILS_H +#define MTK_DCM_UTILS_H + +#include <stdbool.h> + +#include <mtk_dcm.h> +#include <platform_def.h> + +/* Base */ +#define MP_CPUSYS_TOP_BASE (MCUCFG_BASE + 0x8000) +#define CPCCFG_REG_BASE (MCUCFG_BASE + 0xA800) + +/* Register Definition */ +#define CPCCFG_REG_EMI_WFIFO (CPCCFG_REG_BASE + 0x100) +#define MP_CPUSYS_TOP_CPU_PLLDIV_CFG0 (MP_CPUSYS_TOP_BASE + 0x22a0) +#define MP_CPUSYS_TOP_CPU_PLLDIV_CFG1 (MP_CPUSYS_TOP_BASE + 0x22a4) +#define MP_CPUSYS_TOP_BUS_PLLDIV_CFG (MP_CPUSYS_TOP_BASE + 0x22e0) +#define MP_CPUSYS_TOP_MCSIC_DCM0 (MP_CPUSYS_TOP_BASE + 0x2440) +#define MP_CPUSYS_TOP_MP_ADB_DCM_CFG0 (MP_CPUSYS_TOP_BASE + 0x2500) +#define MP_CPUSYS_TOP_MP_ADB_DCM_CFG4 (MP_CPUSYS_TOP_BASE + 0x2510) +#define MP_CPUSYS_TOP_MP_MISC_DCM_CFG0 (MP_CPUSYS_TOP_BASE + 0x2518) +#define MP_CPUSYS_TOP_MCUSYS_DCM_CFG0 (MP_CPUSYS_TOP_BASE + 0x25c0) +#define MP_CPUSYS_TOP_MP0_DCM_CFG0 (MP_CPUSYS_TOP_BASE + 0x4880) +#define MP_CPUSYS_TOP_MP0_DCM_CFG7 (MP_CPUSYS_TOP_BASE + 0x489c) + +/* MP_CPUSYS_TOP */ +bool dcm_mp_cpusys_top_adb_dcm_is_on(void); +void dcm_mp_cpusys_top_adb_dcm(bool on); +bool dcm_mp_cpusys_top_apb_dcm_is_on(void); +void dcm_mp_cpusys_top_apb_dcm(bool on); +bool dcm_mp_cpusys_top_bus_pll_div_dcm_is_on(void); +void dcm_mp_cpusys_top_bus_pll_div_dcm(bool on); +bool dcm_mp_cpusys_top_core_stall_dcm_is_on(void); +void dcm_mp_cpusys_top_core_stall_dcm(bool on); +bool dcm_mp_cpusys_top_cpubiu_dcm_is_on(void); +void dcm_mp_cpusys_top_cpubiu_dcm(bool on); +bool dcm_mp_cpusys_top_cpu_pll_div_0_dcm_is_on(void); +void dcm_mp_cpusys_top_cpu_pll_div_0_dcm(bool on); +bool dcm_mp_cpusys_top_cpu_pll_div_1_dcm_is_on(void); +void dcm_mp_cpusys_top_cpu_pll_div_1_dcm(bool on); +bool dcm_mp_cpusys_top_fcm_stall_dcm_is_on(void); +void dcm_mp_cpusys_top_fcm_stall_dcm(bool on); +bool dcm_mp_cpusys_top_last_cor_idle_dcm_is_on(void); +void dcm_mp_cpusys_top_last_cor_idle_dcm(bool on); +bool dcm_mp_cpusys_top_misc_dcm_is_on(void); +void dcm_mp_cpusys_top_misc_dcm(bool on); +bool dcm_mp_cpusys_top_mp0_qdcm_is_on(void); +void dcm_mp_cpusys_top_mp0_qdcm(bool on); +/* CPCCFG_REG */ +bool dcm_cpccfg_reg_emi_wfifo_is_on(void); +void dcm_cpccfg_reg_emi_wfifo(bool on); + +#endif diff --git a/plat/mediatek/drivers/dcm/mtk_dcm.c b/plat/mediatek/drivers/dcm/mtk_dcm.c new file mode 100644 index 0000000..ca79a20 --- /dev/null +++ b/plat/mediatek/drivers/dcm/mtk_dcm.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#include <lib/mmio.h> +#include <lib/mtk_init/mtk_init.h> +#include <mtk_dcm.h> +#include <mtk_dcm_utils.h> + +static void dcm_armcore(bool mode) +{ + dcm_mp_cpusys_top_bus_pll_div_dcm(mode); + dcm_mp_cpusys_top_cpu_pll_div_0_dcm(mode); + dcm_mp_cpusys_top_cpu_pll_div_1_dcm(mode); +} + +static void dcm_mcusys(bool on) +{ + dcm_mp_cpusys_top_adb_dcm(on); + dcm_mp_cpusys_top_apb_dcm(on); + dcm_mp_cpusys_top_cpubiu_dcm(on); + dcm_mp_cpusys_top_misc_dcm(on); + dcm_mp_cpusys_top_mp0_qdcm(on); + + /* CPCCFG_REG */ + dcm_cpccfg_reg_emi_wfifo(on); + dcm_mp_cpusys_top_last_cor_idle_dcm(on); +} + +static void dcm_stall(bool on) +{ + dcm_mp_cpusys_top_core_stall_dcm(on); + dcm_mp_cpusys_top_fcm_stall_dcm(on); +} + +static bool check_dcm_state(void) +{ + bool ret = true; + + ret &= dcm_mp_cpusys_top_bus_pll_div_dcm_is_on(); + ret &= dcm_mp_cpusys_top_cpu_pll_div_0_dcm_is_on(); + ret &= dcm_mp_cpusys_top_cpu_pll_div_1_dcm_is_on(); + + ret &= dcm_mp_cpusys_top_adb_dcm_is_on(); + ret &= dcm_mp_cpusys_top_apb_dcm_is_on(); + ret &= dcm_mp_cpusys_top_cpubiu_dcm_is_on(); + ret &= dcm_mp_cpusys_top_misc_dcm_is_on(); + ret &= dcm_mp_cpusys_top_mp0_qdcm_is_on(); + ret &= dcm_cpccfg_reg_emi_wfifo_is_on(); + ret &= dcm_mp_cpusys_top_last_cor_idle_dcm_is_on(); + + ret &= dcm_mp_cpusys_top_core_stall_dcm_is_on(); + ret &= dcm_mp_cpusys_top_fcm_stall_dcm_is_on(); + + return ret; +} + +bool dcm_check_state(uintptr_t addr, unsigned int mask, unsigned int compare) +{ + return ((mmio_read_32(addr) & mask) == compare); +} + +int dcm_set_init(void) +{ + int ret; + + dcm_armcore(true); + dcm_mcusys(true); + dcm_stall(true); + + if (check_dcm_state() == false) { + ERROR("Failed to set default dcm on!!\n"); + ret = -1; + } else { + INFO("%s, dcm pass\n", __func__); + ret = 0; + } + + return ret; +} +MTK_PLAT_SETUP_0_INIT(dcm_set_init); diff --git a/plat/mediatek/drivers/dcm/mtk_dcm.h b/plat/mediatek/drivers/dcm/mtk_dcm.h new file mode 100644 index 0000000..05f8d45 --- /dev/null +++ b/plat/mediatek/drivers/dcm/mtk_dcm.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MTK_DCM_H +#define MTK_DCM_H + +#include <stdbool.h> + +bool dcm_check_state(uintptr_t addr, unsigned int mask, unsigned int compare); +int dcm_set_init(void); + +#endif /* #ifndef MTK_DCM_H */ diff --git a/plat/mediatek/drivers/dcm/rules.mk b/plat/mediatek/drivers/dcm/rules.mk new file mode 100644 index 0000000..a8ee05e --- /dev/null +++ b/plat/mediatek/drivers/dcm/rules.mk @@ -0,0 +1,17 @@ +# +# Copyright (c) 2022, MediaTek Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +LOCAL_DIR := $(call GET_LOCAL_DIR) + +MODULE := mtk_dcm + +LOCAL_SRCS-y := ${LOCAL_DIR}/mtk_dcm.c +LOCAL_SRCS-y += ${LOCAL_DIR}/${MTK_SOC}/mtk_dcm_utils.c + +PLAT_INCLUDES += -I${LOCAL_DIR} +PLAT_INCLUDES += -I${LOCAL_DIR}/${MTK_SOC} + +$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL))) diff --git a/plat/mediatek/drivers/dfd/dfd.c b/plat/mediatek/drivers/dfd/dfd.c new file mode 100644 index 0000000..5770d50 --- /dev/null +++ b/plat/mediatek/drivers/dfd/dfd.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include <arch_helpers.h> +#include <common/debug.h> +#include <lib/mmio.h> +#include <dfd.h> +#include <mtk_sip_svc.h> +#include <plat_dfd.h> + +static u_register_t dfd_smc_dispatcher(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3, + void *handle, struct smccc_res *smccc_ret) +{ + int ret = MTK_SIP_E_SUCCESS; + + switch (arg0) { + case PLAT_MTK_DFD_SETUP_MAGIC: + INFO("[%s] DFD setup call from kernel\n", __func__); + dfd_setup(arg1, arg2, arg3); + break; + case PLAT_MTK_DFD_READ_MAGIC: + /* only allow to access DFD register base + 0x200 */ + if (arg1 <= 0x200) { + ret = mmio_read_32(MISC1_CFG_BASE + arg1); + } + break; + case PLAT_MTK_DFD_WRITE_MAGIC: + /* only allow to access DFD register base + 0x200 */ + if (arg1 <= 0x200) { + sync_writel(MISC1_CFG_BASE + arg1, arg2); + } + break; + default: + ret = MTK_SIP_E_INVALID_PARAM; + break; + } + + return ret; +} +DECLARE_SMC_HANDLER(MTK_SIP_KERNEL_DFD, dfd_smc_dispatcher); diff --git a/plat/mediatek/drivers/dfd/dfd.h b/plat/mediatek/drivers/dfd/dfd.h new file mode 100644 index 0000000..c088bd0 --- /dev/null +++ b/plat/mediatek/drivers/dfd/dfd.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef DFD_H +#define DFD_H + +#include <arch_helpers.h> +#include <lib/mmio.h> + +void dfd_resume(void); +void dfd_setup(uint64_t base_addr, uint64_t chain_length, uint64_t cache_dump); + +#endif /* DFD_H */ diff --git a/plat/mediatek/drivers/dfd/mt8188/plat_dfd.c b/plat/mediatek/drivers/dfd/mt8188/plat_dfd.c new file mode 100644 index 0000000..1aa68f5 --- /dev/null +++ b/plat/mediatek/drivers/dfd/mt8188/plat_dfd.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include <arch_helpers.h> +#include <common/debug.h> +#include <lib/mmio.h> +#include <dfd.h> +#include <plat_dfd.h> + +static uint64_t dfd_cache_dump; +static bool dfd_enabled; +static uint64_t dfd_base_addr; +static uint64_t dfd_chain_length; + +void dfd_setup(uint64_t base_addr, uint64_t chain_length, uint64_t cache_dump) +{ + mmio_write_32(MTK_DRM_LATCH_CTL1, MTK_DRM_LATCH_CTL1_VAL); + mmio_write_32(MTK_DRM_LATCH_CTL2, MTK_DRM_LATCH_CTL2_VAL); + mmio_write_32(MTK_WDT_LATCH_CTL2, MTK_WDT_LATCH_CTL2_VAL); + + mmio_clrbits_32(DFD_O_INTRF_MCU_PWR_CTL_MASK, BIT(2)); + mmio_setbits_32(DFD_V50_GROUP_0_63_DIFF, 0x1); + sync_writel(DFD_INTERNAL_CTL, 0x5); + mmio_setbits_32(DFD_INTERNAL_CTL, BIT(13)); + mmio_setbits_32(DFD_INTERNAL_CTL, 0x1F << 3); + mmio_setbits_32(DFD_INTERNAL_CTL, 0x3 << 9); + mmio_setbits_32(DFD_INTERNAL_CTL, 0x3 << 19); + + mmio_write_32(DFD_INTERNAL_PWR_ON, 0xB); + mmio_write_32(DFD_CHAIN_LENGTH0, chain_length); + mmio_write_32(DFD_INTERNAL_SHIFT_CLK_RATIO, 0x0); + mmio_write_32(DFD_INTERNAL_TEST_SO_OVER_64, 0x1); + + mmio_write_32(DFD_TEST_SI_0, 0x0); + mmio_write_32(DFD_TEST_SI_1, 0x0); + mmio_write_32(DFD_TEST_SI_2, 0x0); + mmio_write_32(DFD_TEST_SI_3, 0x0); + + sync_writel(DFD_POWER_CTL, 0xF9); + sync_writel(DFD_READ_ADDR, DFD_READ_ADDR_VAL); + sync_writel(DFD_V30_CTL, 0xD); + + mmio_write_32(DFD_O_SET_BASEADDR_REG, base_addr >> 24); + mmio_write_32(DFD_O_REG_0, 0); + + /* setup global variables for suspend and resume */ + dfd_enabled = true; + dfd_base_addr = base_addr; + dfd_chain_length = chain_length; + dfd_cache_dump = cache_dump; + + if ((cache_dump & DFD_CACHE_DUMP_ENABLE) != 0UL) { + mmio_write_32(MTK_DRM_LATCH_CTL2, MTK_DRM_LATCH_CTL2_CACHE_VAL); + sync_writel(DFD_V35_ENABLE, 0x1); + sync_writel(DFD_V35_TAP_NUMBER, 0xB); + sync_writel(DFD_V35_TAP_EN, DFD_V35_TAP_EN_VAL); + sync_writel(DFD_V35_SEQ0_0, DFD_V35_SEQ0_0_VAL); + + /* Cache dump only mode */ + sync_writel(DFD_V35_CTL, 0x1); + mmio_write_32(DFD_INTERNAL_NUM_OF_TEST_SO_GROUP, 0xF); + mmio_write_32(DFD_CHAIN_LENGTH0, DFD_CHAIN_LENGTH_VAL); + mmio_write_32(DFD_CHAIN_LENGTH1, DFD_CHAIN_LENGTH_VAL); + mmio_write_32(DFD_CHAIN_LENGTH2, DFD_CHAIN_LENGTH_VAL); + mmio_write_32(DFD_CHAIN_LENGTH3, DFD_CHAIN_LENGTH_VAL); + + if ((cache_dump & DFD_PARITY_ERR_TRIGGER) != 0UL) { + sync_writel(DFD_HW_TRIGGER_MASK, 0xC); + mmio_setbits_32(DFD_INTERNAL_CTL, 0x1 << 4); + } + } + dsbsy(); +} + +void dfd_resume(void) +{ + if (dfd_enabled == true) { + dfd_setup(dfd_base_addr, dfd_chain_length, dfd_cache_dump); + } +} diff --git a/plat/mediatek/drivers/dfd/mt8188/plat_dfd.h b/plat/mediatek/drivers/dfd/mt8188/plat_dfd.h new file mode 100644 index 0000000..5b98024 --- /dev/null +++ b/plat/mediatek/drivers/dfd/mt8188/plat_dfd.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_DFD_H +#define PLAT_DFD_H + +#include <lib/mmio.h> +#include <platform_def.h> + +#define sync_writel(addr, val) do { mmio_write_32((addr), (val)); dsbsy(); } while (0) + +#define PLAT_MTK_DFD_SETUP_MAGIC (0x99716150) +#define PLAT_MTK_DFD_READ_MAGIC (0x99716151) +#define PLAT_MTK_DFD_WRITE_MAGIC (0x99716152) + +#define MTK_DRM_LATCH_CTL1 (DRM_BASE + 0x40) +#define MTK_DRM_LATCH_CTL2 (DRM_BASE + 0x44) + +#define MTK_WDT_BASE (RGU_BASE) +#define MTK_WDT_INTERVAL (MTK_WDT_BASE + 0x10) +#define MTK_WDT_LATCH_CTL2 (MTK_WDT_BASE + 0x48) + +#define MCU_BIU_BASE (MCUCFG_BASE) +#define MISC1_CFG_BASE (MCU_BIU_BASE + 0xE040) +#define DFD_INTERNAL_CTL (MISC1_CFG_BASE + 0x00) +#define DFD_INTERNAL_PWR_ON (MISC1_CFG_BASE + 0x08) +#define DFD_CHAIN_LENGTH0 (MISC1_CFG_BASE + 0x0C) +#define DFD_INTERNAL_SHIFT_CLK_RATIO (MISC1_CFG_BASE + 0x10) +#define DFD_CHAIN_LENGTH1 (MISC1_CFG_BASE + 0x1C) +#define DFD_CHAIN_LENGTH2 (MISC1_CFG_BASE + 0x20) +#define DFD_CHAIN_LENGTH3 (MISC1_CFG_BASE + 0x24) +#define DFD_INTERNAL_TEST_SO_0 (MISC1_CFG_BASE + 0x28) +#define DFD_INTERNAL_NUM_OF_TEST_SO_GROUP (MISC1_CFG_BASE + 0x30) +#define DFD_INTERNAL_TEST_SO_OVER_64 (MISC1_CFG_BASE + 0x34) +#define DFD_INTERNAL_SW_NS_TRIGGER (MISC1_CFG_BASE + 0x3c) +#define DFD_V30_CTL (MISC1_CFG_BASE + 0x48) +#define DFD_V30_BASE_ADDR (MISC1_CFG_BASE + 0x4C) +#define DFD_POWER_CTL (MISC1_CFG_BASE + 0x50) +#define DFD_TEST_SI_0 (MISC1_CFG_BASE + 0x58) +#define DFD_TEST_SI_1 (MISC1_CFG_BASE + 0x5C) +#define DFD_CLEAN_STATUS (MISC1_CFG_BASE + 0x60) +#define DFD_TEST_SI_2 (MISC1_CFG_BASE + 0x1D8) +#define DFD_TEST_SI_3 (MISC1_CFG_BASE + 0x1DC) +#define DFD_READ_ADDR (MISC1_CFG_BASE + 0x1E8) +#define DFD_HW_TRIGGER_MASK (MISC1_CFG_BASE + 0xBC) + +#define DFD_V35_ENABLE (MCU_BIU_BASE + 0xE0A8) +#define DFD_V35_TAP_NUMBER (MCU_BIU_BASE + 0xE0AC) +#define DFD_V35_TAP_EN (MCU_BIU_BASE + 0xE0B0) +#define DFD_V35_CTL (MCU_BIU_BASE + 0xE0B4) +#define DFD_V35_SEQ0_0 (MCU_BIU_BASE + 0xE0C0) +#define DFD_V35_SEQ0_1 (MCU_BIU_BASE + 0xE0C4) +#define DFD_V50_GROUP_0_63_DIFF (MCU_BIU_BASE + 0xE2AC) + +#define DFD_O_PROTECT_EN_REG (0x10001220) +#define DFD_O_INTRF_MCU_PWR_CTL_MASK (0x10001A3C) +#define DFD_O_SET_BASEADDR_REG (0x10043000) +#define DFD_O_REG_0 (0x10001390) + +#define DFD_CACHE_DUMP_ENABLE (1U) +#define DFD_PARITY_ERR_TRIGGER (2U) + +#define DFD_V35_TAP_EN_VAL (0x43FF) +#define DFD_V35_SEQ0_0_VAL (0x63668820) +#define DFD_READ_ADDR_VAL (0x40000008) +#define DFD_CHAIN_LENGTH_VAL (0xFFFFFFFF) + +#define MTK_WDT_LATCH_CTL2_VAL (0x9507FFFF) +#define MTK_WDT_INTERVAL_VAL (0x6600000A) +#define MTK_DRM_LATCH_CTL2_VAL (0x950607D0) +#define MTK_DRM_LATCH_CTL2_CACHE_VAL (0x95065DC0) + +#define MTK_DRM_LATCH_CTL1_VAL (0x95000013) + +#endif /* PLAT_DFD_H */ diff --git a/plat/mediatek/drivers/dfd/rules.mk b/plat/mediatek/drivers/dfd/rules.mk new file mode 100644 index 0000000..60fbc88 --- /dev/null +++ b/plat/mediatek/drivers/dfd/rules.mk @@ -0,0 +1,17 @@ +# +# Copyright (c) 2022, MediaTek Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +LOCAL_DIR := $(call GET_LOCAL_DIR) + +MODULE := mtk_dfd + +LOCAL_SRCS-y := ${LOCAL_DIR}/dfd.c +LOCAL_SRCS-y += ${LOCAL_DIR}/$(MTK_SOC)/plat_dfd.c + +PLAT_INCLUDES += -I${LOCAL_DIR} +PLAT_INCLUDES += -I${LOCAL_DIR}/$(MTK_SOC) + +$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL))) diff --git a/plat/mediatek/drivers/dp/mt_dp.c b/plat/mediatek/drivers/dp/mt_dp.c new file mode 100644 index 0000000..8aa246f --- /dev/null +++ b/plat/mediatek/drivers/dp/mt_dp.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <inttypes.h> + +#include <common/debug.h> +#include <lib/mmio.h> +#include <mt_dp.h> +#include <mtk_sip_svc.h> +#include <platform_def.h> + +static uint32_t dp_write_sec_reg(uint32_t is_edp, uint32_t offset, + uint32_t value, uint32_t mask) +{ + uint32_t reg = (is_edp != 0U) ? EDP_SEC_BASE : DP_SEC_BASE; + + mmio_clrsetbits_32(reg + offset, mask, value); + + return mmio_read_32(reg + offset); +} + +int32_t dp_secure_handler(uint64_t cmd, uint64_t para, uint32_t *val) +{ + int32_t ret = 0L; + uint32_t is_edp = 0UL; + uint32_t regval = 0UL; + uint32_t regmsk = 0UL; + uint32_t fldmask = 0UL; + + if ((cmd > DP_ATF_CMD_COUNT) || (val == NULL)) { + INFO("dp_secure_handler error cmd 0x%" PRIx64 "\n", cmd); + return MTK_SIP_E_INVALID_PARAM; + } + + switch (cmd) { + case DP_ATF_DP_VIDEO_UNMUTE: + INFO("[%s] DP_ATF_DP_VIDEO_UNMUTE\n", __func__); + is_edp = DP_ATF_TYPE_DP; + ret = MTK_SIP_E_SUCCESS; + break; + case DP_ATF_EDP_VIDEO_UNMUTE: + INFO("[%s] DP_ATF_EDP_VIDEO_UNMUTE\n", __func__); + is_edp = DP_ATF_TYPE_EDP; + ret = MTK_SIP_E_SUCCESS; + break; + default: + ret = MTK_SIP_E_INVALID_PARAM; + break; + } + + if (ret == MTK_SIP_E_SUCCESS) { + regmsk = (VIDEO_MUTE_SEL_SECURE_FLDMASK | + VIDEO_MUTE_SW_SECURE_FLDMASK); + if (para > 0U) { + fldmask = VIDEO_MUTE_SW_SECURE_FLDMASK; + } else { + fldmask = 0; + } + + regval = (VIDEO_MUTE_SEL_SECURE_FLDMASK | fldmask); + *val = dp_write_sec_reg(is_edp, DP_TX_SECURE_REG11, + regval, regmsk); + } + + return ret; +} + +u_register_t mtk_dp_sip_handler(u_register_t x1, u_register_t x2, + u_register_t x3, u_register_t x4, + void *handle, struct smccc_res *smccc_ret) +{ + uint32_t ret_val; + + return dp_secure_handler(x1, x2, &ret_val); +} +DECLARE_SMC_HANDLER(MTK_SIP_DP_CONTROL, mtk_dp_sip_handler); diff --git a/plat/mediatek/drivers/dp/mt_dp.h b/plat/mediatek/drivers/dp/mt_dp.h new file mode 100644 index 0000000..d5dad29 --- /dev/null +++ b/plat/mediatek/drivers/dp/mt_dp.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_DP_H +#define MT_DP_H + +#define DP_TX_SECURE_REG11 (0x2c) + +#define VIDEO_MUTE_SEL_SECURE_FLDMASK (0x10) +#define VIDEO_MUTE_SW_SECURE_FLDMASK (0x8) + +enum DP_ATF_HW_TYPE { + DP_ATF_TYPE_DP = 0, + DP_ATF_TYPE_EDP = 1 +}; + +enum DP_ATF_CMD { + DP_ATF_DP_VIDEO_UNMUTE = 0x20, + DP_ATF_EDP_VIDEO_UNMUTE, + DP_ATF_CMD_COUNT +}; + +int32_t dp_secure_handler(uint64_t cmd, uint64_t para, uint32_t *val); + +#endif diff --git a/plat/mediatek/drivers/dp/rules.mk b/plat/mediatek/drivers/dp/rules.mk new file mode 100644 index 0000000..786d514 --- /dev/null +++ b/plat/mediatek/drivers/dp/rules.mk @@ -0,0 +1,14 @@ +# +# Copyright (c) 2022, MediaTek Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +LOCAL_DIR := $(call GET_LOCAL_DIR) + +MODULE := dp +LOCAL_SRCS-y := $(LOCAL_DIR)/mt_dp.c + +PLAT_INCLUDES += -I${LOCAL_DIR} + +$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL))) diff --git a/plat/mediatek/drivers/emi_mpu/emi_mpu.h b/plat/mediatek/drivers/emi_mpu/emi_mpu.h new file mode 100644 index 0000000..ef7134c --- /dev/null +++ b/plat/mediatek/drivers/emi_mpu/emi_mpu.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2022-2023, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef EMI_MPU_H +#define EMI_MPU_H + +#include <emi_mpu_priv.h> +#include <platform_def.h> + +#define NO_PROTECTION (0) +#define SEC_RW (1) +#define SEC_RW_NSEC_R (2) +#define SEC_RW_NSEC_W (3) +#define SEC_R_NSEC_R (4) +#define FORBIDDEN (5) +#define SEC_R_NSEC_RW (6) + +#define LOCK (1) +#define UNLOCK (0) + +#if (EMI_MPU_DGROUP_NUM == 1) +#define SET_ACCESS_PERMISSION(apc_ary, lock, d7, d6, d5, d4, d3, d2, d1, d0) \ +do { \ + apc_ary[1] = 0; \ + apc_ary[0] = \ + (((unsigned int) d7) << 21) | (((unsigned int) d6) << 18) | \ + (((unsigned int) d5) << 15) | (((unsigned int) d4) << 12) | \ + (((unsigned int) d3) << 9) | (((unsigned int) d2) << 6) | \ + (((unsigned int) d1) << 3) | ((unsigned int) d0) | \ + ((unsigned int) lock << 31); \ +} while (0) +#elif (EMI_MPU_DGROUP_NUM == 2) +#define SET_ACCESS_PERMISSION(apc_ary, lock, d15, d14, d13, d12, d11, d10, \ + d9, d8, d7, d6, d5, d4, d3, d2, d1, d0) \ +do { \ + apc_ary[1] = \ + (((unsigned int) d15) << 21) | (((unsigned int) d14) << 18) | \ + (((unsigned int) d13) << 15) | (((unsigned int) d12) << 12) | \ + (((unsigned int) d11) << 9) | (((unsigned int) d10) << 6) | \ + (((unsigned int) d9) << 3) | ((unsigned int) d8); \ + apc_ary[0] = \ + (((unsigned int) d7) << 21) | (((unsigned int) d6) << 18) | \ + (((unsigned int) d5) << 15) | (((unsigned int) d4) << 12) | \ + (((unsigned int) d3) << 9) | (((unsigned int) d2) << 6) | \ + (((unsigned int) d1) << 3) | ((unsigned int) d0) | \ + ((unsigned int) lock << 31); \ +} while (0) +#endif + +struct emi_region_info_t { + unsigned long long start; + unsigned long long end; + unsigned int region; + unsigned int apc[EMI_MPU_DGROUP_NUM]; +}; + +enum MPU_REQ_ORIGIN_ZONE_ID { + MPU_REQ_ORIGIN_TEE_ZONE_SVP = 0, + MPU_REQ_ORIGIN_TEE_ZONE_TUI = 1, + MPU_REQ_ORIGIN_TEE_ZONE_WFD = 2, + MPU_REQ_ORIGIN_TEE_ZONE_MAX = 3, + MPU_REQ_ORIGIN_ZONE_INVALID = 0x7FFFFFFF, +}; + +int emi_mpu_init(void); +int emi_mpu_optee_handler(uint64_t encoded_addr, uint64_t zone_size, + uint64_t zone_info); +int emi_mpu_set_protection(struct emi_region_info_t *region_info); +void set_emi_mpu_regions(void); +int set_apu_emi_mpu_region(void); +#endif diff --git a/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c b/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c new file mode 100644 index 0000000..8810be3 --- /dev/null +++ b/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2022-2023, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <string.h> +#include <common/debug.h> +#include <lib/mmio.h> +#include <smccc_helpers.h> + +#include <emi_mpu.h> +#include <lib/mtk_init/mtk_init.h> +#include <mtk_sip_svc.h> + +#if ENABLE_EMI_MPU_SW_LOCK +static unsigned char region_lock_state[EMI_MPU_REGION_NUM]; +#endif + +#define EMI_MPU_START_MASK (0x00FFFFFF) +#define EMI_MPU_END_MASK (0x00FFFFFF) +#define EMI_MPU_APC_SW_LOCK_MASK (0x00FFFFFF) +#define EMI_MPU_APC_HW_LOCK_MASK (0x80FFFFFF) + +static int _emi_mpu_set_protection(unsigned int start, unsigned int end, + unsigned int apc) +{ + unsigned int dgroup; + unsigned int region; + + region = (start >> 24) & 0xFF; + start &= EMI_MPU_START_MASK; + dgroup = (end >> 24) & 0xFF; + end &= EMI_MPU_END_MASK; + + if ((region >= EMI_MPU_REGION_NUM) || (dgroup > EMI_MPU_DGROUP_NUM)) { + WARN("invalid region, domain\n"); + return -1; + } + +#if ENABLE_EMI_MPU_SW_LOCK + if (region_lock_state[region] == 1) { + WARN("invalid region\n"); + return -1; + } + + if ((dgroup == 0) && ((apc >> 31) & 0x1)) { + region_lock_state[region] = 1; + } + + apc &= EMI_MPU_APC_SW_LOCK_MASK; +#else + apc &= EMI_MPU_APC_HW_LOCK_MASK; +#endif + + if ((start >= DRAM_OFFSET) && (end >= start)) { + start -= DRAM_OFFSET; + end -= DRAM_OFFSET; + } else { + WARN("invalid range\n"); + return -1; + } + + mmio_write_32(EMI_MPU_SA(region), start); + mmio_write_32(EMI_MPU_EA(region), end); + mmio_write_32(EMI_MPU_APC(region, dgroup), apc); + +#if defined(SUB_EMI_MPU_BASE) + mmio_write_32(SUB_EMI_MPU_SA(region), start); + mmio_write_32(SUB_EMI_MPU_EA(region), end); + mmio_write_32(SUB_EMI_MPU_APC(region, dgroup), apc); +#endif + return 0; +} + +static void dump_emi_mpu_regions(void) +{ + int region, i; + + /* Only dump 8 regions(max: EMI_MPU_REGION_NUM --> 32) */ + for (region = 0; region < 8; ++region) { + INFO("region %d:\n", region); + INFO("\tsa: 0x%x, ea: 0x%x\n", + mmio_read_32(EMI_MPU_SA(region)), mmio_read_32(EMI_MPU_EA(region))); + + for (i = 0; i < EMI_MPU_DGROUP_NUM; ++i) { + INFO("\tapc%d: 0x%x\n", i, mmio_read_32(EMI_MPU_APC(region, i))); + } + } +} + +int emi_mpu_set_protection(struct emi_region_info_t *region_info) +{ + unsigned int start, end; + int i; + + if (region_info->region >= EMI_MPU_REGION_NUM) { + WARN("invalid region\n"); + return -1; + } + + start = (unsigned int)(region_info->start >> EMI_MPU_ALIGN_BITS) | + (region_info->region << 24); + + for (i = EMI_MPU_DGROUP_NUM - 1; i >= 0; i--) { + end = (unsigned int)(region_info->end >> EMI_MPU_ALIGN_BITS) | (i << 24); + + if (_emi_mpu_set_protection(start, end, region_info->apc[i]) < 0) { + WARN("Failed to set emi mpu protection(%d, %d, %d)\n", + start, end, region_info->apc[i]); + } + } + + return 0; +} + +u_register_t mtk_emi_mpu_sip_handler(u_register_t x1, u_register_t x2, + u_register_t x3, u_register_t x4, + void *handle, struct smccc_res *smccc_ret) +{ + return (u_register_t) emi_mpu_optee_handler(x1, x2, x3); +} +DECLARE_SMC_HANDLER(MTK_SIP_TEE_MPU_PERM_SET, mtk_emi_mpu_sip_handler); + +int emi_mpu_init(void) +{ + INFO("[%s] emi mpu initialization\n", __func__); + + set_emi_mpu_regions(); + dump_emi_mpu_regions(); + + return 0; +} +MTK_PLAT_SETUP_0_INIT(emi_mpu_init); diff --git a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c new file mode 100644 index 0000000..e8882f0 --- /dev/null +++ b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2022-2023, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#include <emi_mpu.h> +#include <mtk_sip_svc.h> + +#define MPU_PHYSICAL_ADDR_SHIFT_BITS (16) + +void set_emi_mpu_regions(void) +{ + struct emi_region_info_t region_info; + + /* SCP core0 DRAM */ + region_info.start = 0x50000000ULL; + region_info.end = 0x528FFFFFULL; + region_info.region = 2; + SET_ACCESS_PERMISSION(region_info.apc, 1, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION); + emi_mpu_set_protection(®ion_info); + + /* SCP core1 DRAM */ + region_info.start = 0x70000000ULL; + region_info.end = 0x729FFFFFULL; + region_info.region = 3; + SET_ACCESS_PERMISSION(region_info.apc, 1, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION); + emi_mpu_set_protection(®ion_info); + + /* DSP protect address */ + region_info.start = 0x60000000ULL; + region_info.end = 0x610FFFFFULL; + region_info.region = 4; + SET_ACCESS_PERMISSION(region_info.apc, 1, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION, + FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION); + emi_mpu_set_protection(®ion_info); + + /* All default settings */ + region_info.start = 0x40000000ULL; + region_info.end = 0x1FFFF0000ULL; + region_info.region = 31; + SET_ACCESS_PERMISSION(region_info.apc, 1, + FORBIDDEN, FORBIDDEN, NO_PROTECTION, NO_PROTECTION, + NO_PROTECTION, FORBIDDEN, NO_PROTECTION, NO_PROTECTION, + NO_PROTECTION, SEC_R_NSEC_RW, NO_PROTECTION, FORBIDDEN, + NO_PROTECTION, NO_PROTECTION, NO_PROTECTION, NO_PROTECTION); + emi_mpu_set_protection(®ion_info); +} + +int set_apu_emi_mpu_region(void) +{ + struct emi_region_info_t region_info; + + region_info.start = (unsigned long long)APUSYS_SEC_BUF_PA; + region_info.end = (unsigned long long)(APUSYS_SEC_BUF_PA + APUSYS_SEC_BUF_SZ) - 1; + region_info.region = APUSYS_SEC_BUF_EMI_REGION; + + SET_ACCESS_PERMISSION(region_info.apc, UNLOCK, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + NO_PROTECTION, FORBIDDEN, NO_PROTECTION, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, SEC_RW); + + return emi_mpu_set_protection(®ion_info); +} + +static inline uint64_t get_decoded_phys_addr(uint64_t addr) +{ + return (addr << MPU_PHYSICAL_ADDR_SHIFT_BITS); +} + +static inline uint32_t get_decoded_zone_id(uint32_t info) +{ + return ((info & 0xFFFF0000) >> MPU_PHYSICAL_ADDR_SHIFT_BITS); +} + +int emi_mpu_optee_handler(uint64_t encoded_addr, uint64_t zone_size, + uint64_t zone_info) +{ + uint64_t phys_addr = get_decoded_phys_addr(encoded_addr); + struct emi_region_info_t region_info; + enum MPU_REQ_ORIGIN_ZONE_ID zone_id = get_decoded_zone_id(zone_info); + + INFO("encoded_addr = 0x%lx, zone_size = 0x%lx, zone_info = 0x%lx\n", + encoded_addr, zone_size, zone_info); + + if (zone_id != MPU_REQ_ORIGIN_TEE_ZONE_SVP) { + ERROR("Invalid param %s, %d\n", __func__, __LINE__); + return MTK_SIP_E_INVALID_PARAM; + } + + /* SVP DRAM */ + region_info.start = phys_addr; + region_info.end = phys_addr + zone_size; + region_info.region = 4; + SET_ACCESS_PERMISSION(region_info.apc, 1, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, + FORBIDDEN, FORBIDDEN, FORBIDDEN, SEC_RW); + + emi_mpu_set_protection(®ion_info); + + return 0; +}
\ No newline at end of file diff --git a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h new file mode 100644 index 0000000..cc7f7f1 --- /dev/null +++ b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022-2023, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef EMI_MPU_PRIV_H +#define EMI_MPU_PRIV_H + +#define ENABLE_EMI_MPU_SW_LOCK (1) + +#define EMI_MPU_CTRL (EMI_MPU_BASE + 0x000) +#define EMI_MPU_DBG (EMI_MPU_BASE + 0x004) +#define EMI_MPU_SA0 (EMI_MPU_BASE + 0x100) +#define EMI_MPU_EA0 (EMI_MPU_BASE + 0x200) +#define EMI_MPU_SA(region) (EMI_MPU_SA0 + (region * 4)) +#define EMI_MPU_EA(region) (EMI_MPU_EA0 + (region * 4)) +#define EMI_MPU_APC0 (EMI_MPU_BASE + 0x300) +#define EMI_MPU_APC(region, dgroup) (EMI_MPU_APC0 + (region * 4) + (dgroup * 0x100)) +#define EMI_MPU_CTRL_D0 (EMI_MPU_BASE + 0x800) +#define EMI_MPU_CTRL_D(domain) (EMI_MPU_CTRL_D0 + (domain * 4)) +#define EMI_RG_MASK_D0 (EMI_MPU_BASE + 0x900) +#define EMI_RG_MASK_D(domain) (EMI_RG_MASK_D0 + (domain * 4)) + +#define SUB_EMI_MPU_CTRL (SUB_EMI_MPU_BASE + 0x000) +#define SUB_EMI_MPU_DBG (SUB_EMI_MPU_BASE + 0x004) +#define SUB_EMI_MPU_SA0 (SUB_EMI_MPU_BASE + 0x100) +#define SUB_EMI_MPU_EA0 (SUB_EMI_MPU_BASE + 0x200) +#define SUB_EMI_MPU_SA(region) (SUB_EMI_MPU_SA0 + (region * 4)) +#define SUB_EMI_MPU_EA(region) (SUB_EMI_MPU_EA0 + (region * 4)) +#define SUB_EMI_MPU_APC0 (SUB_EMI_MPU_BASE + 0x300) +#define SUB_EMI_MPU_APC(region, dgroup) (SUB_EMI_MPU_APC0 + (region * 4) + (dgroup * 0x100)) +#define SUB_EMI_MPU_CTRL_D0 (SUB_EMI_MPU_BASE + 0x800) +#define SUB_EMI_MPU_CTRL_D(domain) (SUB_EMI_MPU_CTRL_D0 + (domain * 4)) +#define SUB_EMI_RG_MASK_D0 (SUB_EMI_MPU_BASE + 0x900) +#define SUB_EMI_RG_MASK_D(domain) (SUB_EMI_RG_MASK_D0 + (domain * 4)) + +#define EMI_MPU_DOMAIN_NUM (16) +#define EMI_MPU_REGION_NUM (32) +#define EMI_MPU_ALIGN_BITS (16) +#define DRAM_OFFSET (0x40000000 >> EMI_MPU_ALIGN_BITS) + +#define EMI_MPU_DGROUP_NUM (EMI_MPU_DOMAIN_NUM / 8) + +/* APU EMI MPU Setting */ +#define APUSYS_SEC_BUF_EMI_REGION (21) +#define APUSYS_SEC_BUF_PA (0x55000000) +#define APUSYS_SEC_BUF_SZ (0x100000) + +#endif diff --git a/plat/mediatek/drivers/emi_mpu/rules.mk b/plat/mediatek/drivers/emi_mpu/rules.mk new file mode 100644 index 0000000..ed3d777 --- /dev/null +++ b/plat/mediatek/drivers/emi_mpu/rules.mk @@ -0,0 +1,16 @@ +# +# Copyright (c) 2022, MediaTek Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +LOCAL_DIR := $(call GET_LOCAL_DIR) + +MODULE := emi_mpu +LOCAL_SRCS-y := $(LOCAL_DIR)/emi_mpu_common.c +LOCAL_SRCS-y += ${LOCAL_DIR}/${MTK_SOC}/emi_mpu.c + +PLAT_INCLUDES += -I${LOCAL_DIR} +PLAT_INCLUDES += -I${LOCAL_DIR}/${MTK_SOC} + +$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL))) diff --git a/plat/mediatek/drivers/gic600/mt_gic_v3.c b/plat/mediatek/drivers/gic600/mt_gic_v3.c new file mode 100644 index 0000000..85f9e37 --- /dev/null +++ b/plat/mediatek/drivers/gic600/mt_gic_v3.c @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <stdint.h> +#include <stdio.h> + +#include "../drivers/arm/gic/v3/gicv3_private.h" +#include <bl31/interrupt_mgmt.h> +#include <common/bl_common.h> +#include <common/debug.h> +#include <lib/mtk_init/mtk_init.h> +#include <mt_gic_v3.h> +#include <mtk_plat_common.h> +#include <plat/common/platform.h> +#include <plat_private.h> +#include <platform_def.h> + +#define SGI_MASK 0xffff + +uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT]; +static uint32_t rdist_has_saved[PLATFORM_CORE_COUNT]; + +/* we save and restore the GICv3 context on system suspend */ +gicv3_dist_ctx_t dist_ctx; + +static unsigned int mt_mpidr_to_core_pos(u_register_t mpidr) +{ + return plat_core_pos_by_mpidr(mpidr); +} + +gicv3_driver_data_t mt_gicv3_data = { + .gicd_base = MT_GIC_BASE, + .gicr_base = MT_GIC_RDIST_BASE, + .rdistif_num = PLATFORM_CORE_COUNT, + .rdistif_base_addrs = rdistif_base_addrs, + .mpidr_to_core_pos = mt_mpidr_to_core_pos, +}; + +struct gic_chip_data { + /* All cores share the same configuration */ + unsigned int saved_ctlr; + unsigned int saved_group; + unsigned int saved_enable; + unsigned int saved_conf0; + unsigned int saved_conf1; + unsigned int saved_grpmod; + unsigned int saved_ispendr; + unsigned int saved_isactiver; + unsigned int saved_nsacr; + /* Per-core sgi */ + unsigned int saved_sgi[PLATFORM_CORE_COUNT]; + /* Per-core priority */ + unsigned int saved_prio[PLATFORM_CORE_COUNT][GICR_NUM_REGS(IPRIORITYR)]; +}; + +static struct gic_chip_data gic_data; + +void mt_gic_driver_init(void) +{ + gicv3_driver_init(&mt_gicv3_data); +} + +void mt_gic_set_pending(uint32_t irq) +{ + gicv3_set_interrupt_pending(irq, plat_my_core_pos()); +} + +void mt_gic_distif_save(void) +{ + gicv3_distif_save(&dist_ctx); +} + +void mt_gic_distif_restore(void) +{ + gicv3_distif_init_restore(&dist_ctx); +} + +void mt_gic_rdistif_init(void) +{ + unsigned int proc_num; + unsigned int index; + uintptr_t gicr_base; + + proc_num = plat_my_core_pos(); + gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; + + /* set all SGI/PPI as non-secure GROUP1 by default */ + mmio_write_32(gicr_base + GICR_IGROUPR0, ~0U); + mmio_write_32(gicr_base + GICR_IGRPMODR0, 0x0); + + /* setup the default PPI/SGI priorities */ + for (index = 0; index < TOTAL_PCPU_INTR_NUM; index += 4U) + gicr_write_ipriorityr(gicr_base, index, + GICD_IPRIORITYR_DEF_VAL); +} + +void mt_gic_rdistif_save(void) +{ + unsigned int i, proc_num; + uintptr_t gicr_base; + + proc_num = plat_my_core_pos(); + gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; + + /* + * Wait for any write to GICR_CTLR to complete before trying to save any + * state. + */ + gicr_wait_for_pending_write(gicr_base); + + gic_data.saved_ctlr = mmio_read_32(gicr_base + GICR_CTLR); + gic_data.saved_group = mmio_read_32(gicr_base + GICR_IGROUPR0); + gic_data.saved_enable = mmio_read_32(gicr_base + GICR_ISENABLER0); + gic_data.saved_conf0 = mmio_read_32(gicr_base + GICR_ICFGR0); + gic_data.saved_conf1 = mmio_read_32(gicr_base + GICR_ICFGR1); + gic_data.saved_grpmod = mmio_read_32(gicr_base + GICR_IGRPMODR0); + gic_data.saved_ispendr = mmio_read_32(gicr_base + GICR_ISPENDR0); + gic_data.saved_isactiver = mmio_read_32(gicr_base + GICR_ISACTIVER0); + gic_data.saved_nsacr = mmio_read_32(gicr_base + GICR_NSACR); + + for (i = 0U; i < 8U; ++i) + gic_data.saved_prio[proc_num][i] = gicr_ipriorityr_read(gicr_base, i); + + rdist_has_saved[proc_num] = 1; +} + +void mt_gic_rdistif_restore(void) +{ + unsigned int i, proc_num; + uintptr_t gicr_base; + + proc_num = plat_my_core_pos(); + if (rdist_has_saved[proc_num] == 1) { + gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; + + mmio_write_32(gicr_base + GICR_IGROUPR0, gic_data.saved_group); + mmio_write_32(gicr_base + GICR_IGRPMODR0, gic_data.saved_grpmod); + mmio_write_32(gicr_base + GICR_NSACR, gic_data.saved_nsacr); + mmio_write_32(gicr_base + GICR_ICFGR0, gic_data.saved_conf0); + mmio_write_32(gicr_base + GICR_ICFGR1, gic_data.saved_conf1); + + for (i = 0U; i < 8U; ++i) + gicr_ipriorityr_write(gicr_base, i, gic_data.saved_prio[proc_num][i]); + + mmio_write_32(gicr_base + GICR_ISPENDR0, gic_data.saved_ispendr); + mmio_write_32(gicr_base + GICR_ISACTIVER0, gic_data.saved_isactiver); + mmio_write_32(gicr_base + GICR_ISENABLER0, gic_data.saved_enable); + mmio_write_32(gicr_base + GICR_CTLR, gic_data.saved_ctlr); + + gicr_wait_for_pending_write(gicr_base); + } +} + +void mt_gic_rdistif_restore_all(void) +{ + unsigned int i, proc_num; + uintptr_t gicr_base; + + for (proc_num = 0; proc_num < PLATFORM_CORE_COUNT; proc_num++) { + gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; + + mmio_write_32(gicr_base + GICR_IGROUPR0, gic_data.saved_group); + mmio_write_32(gicr_base + GICR_IGRPMODR0, gic_data.saved_grpmod); + mmio_write_32(gicr_base + GICR_NSACR, gic_data.saved_nsacr); + mmio_write_32(gicr_base + GICR_ICFGR0, gic_data.saved_conf0); + mmio_write_32(gicr_base + GICR_ICFGR1, gic_data.saved_conf1); + + for (i = 0U; i < 8U; ++i) + gicr_ipriorityr_write(gicr_base, i, gic_data.saved_prio[proc_num][i]); + + mmio_write_32(gicr_base + GICR_ISPENDR0, gic_data.saved_ispendr); + mmio_write_32(gicr_base + GICR_ISACTIVER0, gic_data.saved_isactiver); + mmio_write_32(gicr_base + GICR_ISENABLER0, gic_data.saved_enable); + mmio_write_32(gicr_base + GICR_CTLR, gic_data.saved_ctlr); + + gicr_wait_for_pending_write(gicr_base); + } +} + +void gic_sgi_save_all(void) +{ + unsigned int proc_num; + uintptr_t gicr_base; + + for (proc_num = 0; proc_num < PLATFORM_CORE_COUNT; proc_num++) { + gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; + gic_data.saved_sgi[proc_num] = + mmio_read_32(gicr_base + GICR_ISPENDR0) & SGI_MASK; + } +} + +void gic_sgi_restore_all(void) +{ + unsigned int proc_num; + uintptr_t gicr_base; + + for (proc_num = 0; proc_num < PLATFORM_CORE_COUNT; proc_num++) { + gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; + mmio_write_32(gicr_base + GICR_ICPENDR0, SGI_MASK); + mmio_write_32(gicr_base + GICR_ISPENDR0, + gic_data.saved_sgi[proc_num] & SGI_MASK); + } +} + +void mt_gic_init(void) +{ + gicv3_distif_init(); + gicv3_rdistif_init(plat_my_core_pos()); + gicv3_cpuif_enable(plat_my_core_pos()); +} + +uint32_t mt_irq_get_pending(uint32_t irq) +{ + uint32_t val; + + val = mmio_read_32(BASE_GICD_BASE + GICD_ISPENDR + + irq / 32 * 4); + val = (val >> (irq % 32)) & 1U; + return val; +} + + +void mt_irq_set_pending(uint32_t irq) +{ + uint32_t bit = 1U << (irq % 32); + + mmio_write_32(BASE_GICD_BASE + GICD_ISPENDR + + irq / 32 * 4, bit); +} + +int mt_gic_one_init(void) +{ + INFO("[%s] GIC initialization\n", __func__); + + /* Initialize the GIC driver, CPU and distributor interfaces */ + mt_gic_driver_init(); + mt_gic_init(); + + return 0; +} +MTK_PLAT_SETUP_0_INIT(mt_gic_one_init); diff --git a/plat/mediatek/drivers/gic600/mt_gic_v3.h b/plat/mediatek/drivers/gic600/mt_gic_v3.h new file mode 100644 index 0000000..31513ef --- /dev/null +++ b/plat/mediatek/drivers/gic600/mt_gic_v3.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_GIC_V3_H +#define MT_GIC_V3_H + +#include <drivers/arm/gicv3.h> +#include <lib/mmio.h> + +void mt_gic_driver_init(void); +void mt_gic_init(void); +void mt_gic_set_pending(uint32_t irq); +void mt_gic_distif_save(void); +void mt_gic_distif_restore(void); +void mt_gic_rdistif_init(void); +void mt_gic_rdistif_save(void); +void mt_gic_rdistif_restore(void); +void mt_gic_rdistif_restore_all(void); +void gic_sgi_save_all(void); +void gic_sgi_restore_all(void); +uint32_t mt_irq_get_pending(uint32_t irq); +void mt_irq_set_pending(uint32_t irq); +int mt_gic_one_init(void); + +#endif /* MT_GIC_V3_H */ diff --git a/plat/mediatek/drivers/gic600/rules.mk b/plat/mediatek/drivers/gic600/rules.mk new file mode 100644 index 0000000..3070591 --- /dev/null +++ b/plat/mediatek/drivers/gic600/rules.mk @@ -0,0 +1,14 @@ +# +# Copyright (c) 2022, MediaTek Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +LOCAL_DIR := $(call GET_LOCAL_DIR) + +MODULE := gic600 +LOCAL_SRCS-y := $(LOCAL_DIR)/mt_gic_v3.c + +PLAT_INCLUDES += -I${LOCAL_DIR} + +$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL))) diff --git a/plat/mediatek/drivers/gpio/mt8188/mtgpio.c b/plat/mediatek/drivers/gpio/mt8188/mtgpio.c new file mode 100644 index 0000000..9e9fc5d --- /dev/null +++ b/plat/mediatek/drivers/gpio/mt8188/mtgpio.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <mtgpio.h> +#include <platform_def.h> + +uintptr_t mt_gpio_find_reg_addr(uint32_t pin) +{ + uintptr_t reg_addr = 0U; + struct mt_pin_info gpio_info; + + assert(pin < MAX_GPIO_PIN); + + gpio_info = mt_pin_infos[pin]; + + switch (gpio_info.base & 0x0f) { + case 0: + reg_addr = IOCFG_RM_BASE; + break; + case 1: + reg_addr = IOCFG_LT_BASE; + break; + case 2: + reg_addr = IOCFG_LM_BASE; + break; + case 3: + reg_addr = IOCFG_RT_BASE; + break; + default: + break; + } + + return reg_addr; +} diff --git a/plat/mediatek/drivers/gpio/mt8188/mtgpio.h b/plat/mediatek/drivers/gpio/mt8188/mtgpio.h new file mode 100644 index 0000000..32a4608 --- /dev/null +++ b/plat/mediatek/drivers/gpio/mt8188/mtgpio.h @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_GPIO_H +#define MT_GPIO_H + +#include <mtgpio_common.h> + +/* Enumeration for GPIO pin */ +typedef enum GPIO_PIN { + GPIO_UNSUPPORTED = -1, + GPIO0, GPIO1, GPIO2, GPIO3, GPIO4, GPIO5, GPIO6, + GPIO7, GPIO8, GPIO9, GPIO10, GPIO11, GPIO12, GPIO13, GPIO14, + GPIO15, GPIO16, GPIO17, GPIO18, GPIO19, GPIO20, GPIO21, GPIO22, + GPIO23, GPIO24, GPIO25, GPIO26, GPIO27, GPIO28, GPIO29, GPIO30, + GPIO31, GPIO32, GPIO33, GPIO34, GPIO35, GPIO36, GPIO37, GPIO38, + GPIO39, GPIO40, GPIO41, GPIO42, GPIO43, GPIO44, GPIO45, GPIO46, + GPIO47, GPIO48, GPIO49, GPIO50, GPIO51, GPIO52, GPIO53, GPIO54, + GPIO55, GPIO56, GPIO57, GPIO58, GPIO59, GPIO60, GPIO61, GPIO62, + GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70, + GPIO71, GPIO72, GPIO73, GPIO74, GPIO75, GPIO76, GPIO77, GPIO78, + GPIO79, GPIO80, GPIO81, GPIO82, GPIO83, GPIO84, GPIO85, GPIO86, + GPIO87, GPIO88, GPIO89, GPIO90, GPIO91, GPIO92, GPIO93, GPIO94, + GPIO95, GPIO96, GPIO97, GPIO98, GPIO99, GPIO100, GPIO101, GPIO102, + GPIO103, GPIO104, GPIO105, GPIO106, GPIO107, GPIO108, GPIO109, GPIO110, + GPIO111, GPIO112, GPIO113, GPIO114, GPIO115, GPIO116, GPIO117, GPIO118, + GPIO119, GPIO120, GPIO121, GPIO122, GPIO123, GPIO124, GPIO125, GPIO126, + GPIO127, GPIO128, GPIO129, GPIO130, GPIO131, GPIO132, GPIO133, GPIO134, + GPIO135, GPIO136, GPIO137, GPIO138, GPIO139, GPIO140, GPIO141, GPIO142, + GPIO143, GPIO144, GPIO145, GPIO146, GPIO147, GPIO148, GPIO149, GPIO150, + GPIO151, GPIO152, GPIO153, GPIO154, GPIO155, GPIO156, GPIO157, GPIO158, + GPIO159, GPIO160, GPIO161, GPIO162, GPIO163, GPIO164, GPIO165, GPIO166, + GPIO167, GPIO168, GPIO169, GPIO170, GPIO171, GPIO172, GPIO173, GPIO174, + GPIO175, GPIO176, + MT_GPIO_BASE_MAX +} GPIO_PIN; + +static const struct mt_pin_info mt_pin_infos[] = { + PIN(0, 0, 6, 0x30, 0xb0), + PIN(1, 0, 7, 0x30, 0xb0), + PIN(2, 0, 8, 0x30, 0xb0), + PIN(3, 0, 9, 0x30, 0xb0), + PIN(4, 0, 10, 0x30, 0xb0), + PIN(5, 0, 11, 0x30, 0xb0), + PIN(6, 0, 12, 0x30, 0xb0), + PIN(7, 0, 13, 0x30, 0xb0), + PIN(8, 0, 14, 0x30, 0xb0), + PIN(9, 0, 15, 0x30, 0xb0), + PIN(10, 0, 16, 0x30, 0xb0), + PIN(11, 0, 17, 0x30, 0xb0), + PIN(12, 0, 12, 0x31, 0xa0), + PIN(13, 0, 13, 0x31, 0xa0), + PIN(14, 0, 14, 0x31, 0xa0), + PIN(15, 0, 15, 0x31, 0xa0), + PIN(16, 0, 1, 0x22, 0x50), + PIN(17, 0, 2, 0x22, 0x50), + PIN(18, 0, 3, 0x23, 0x60), + PIN(19, 0, 4, 0x23, 0x60), + PIN(20, 0, 5, 0x23, 0x60), + PIN(21, 0, 6, 0x23, 0x60), + PIN(22, 0, 0, 0x23, 0x60), + PIN(23, 0, 1, 0x23, 0x60), + PIN(24, 0, 2, 0x23, 0x60), + PIN(25, 0, 3, 0x30, 0xb0), + PIN(26, 0, 2, 0x30, 0xb0), + PIN(27, 0, 5, 0x30, 0xb0), + PIN(28, 0, 4, 0x30, 0xb0), + PIN(29, 0, 0, 0x30, 0xb0), + PIN(30, 0, 1, 0x30, 0xb0), + PIN(31, 0, 11, 0x30, 0xc0), + PIN(32, 0, 10, 0x30, 0xc0), + PIN(33, 0, 13, 0x30, 0xc0), + PIN(34, 0, 12, 0x30, 0xc0), + PIN(35, 0, 15, 0x30, 0xc0), + PIN(36, 0, 14, 0x30, 0xc0), + PIN(37, 0, 21, 0x30, 0xb0), + PIN(38, 0, 18, 0x30, 0xb0), + PIN(39, 0, 19, 0x30, 0xb0), + PIN(40, 0, 20, 0x30, 0xb0), + PIN(41, 0, 22, 0x30, 0xb0), + PIN(42, 1, 12, 0x31, 0xc0), + PIN(43, 1, 13, 0x31, 0xc0), + PIN(44, 1, 14, 0x31, 0xc0), + PIN(45, 1, 15, 0x31, 0xc0), + PIN(46, 0, 0, 0x22, 0x50), + PIN(47, 0, 25, 0x30, 0xb0), + PIN(48, 0, 24, 0x30, 0xb0), + PIN(49, 0, 23, 0x30, 0xb0), + PIN(50, 0, 5, 0x22, 0x50), + PIN(51, 0, 4, 0x22, 0x50), + PIN(52, 0, 3, 0x22, 0x50), + PIN(53, 0, 6, 0x22, 0x50), + PIN(54, 0, 7, 0x22, 0x50), + PIN(55, 0, 26, 0x30, 0xb0), + PIN(56, 0, 29, 0x30, 0xb0), + PIN(57, 0, 6, 0x31, 0xb0), + PIN(58, 0, 9, 0x31, 0xb0), + PIN(59, 0, 27, 0x30, 0xb0), + PIN(60, 0, 30, 0x30, 0xb0), + PIN(61, 0, 28, 0x30, 0xb0), + PIN(62, 0, 31, 0x30, 0xb0), + PIN(63, 0, 7, 0x31, 0xb0), + PIN(64, 0, 10, 0x31, 0xb0), + PIN(65, 0, 7, 0x23, 0x60), + PIN(66, 0, 9, 0x23, 0x60), + PIN(67, 0, 8, 0x23, 0x60), + PIN(68, 0, 10, 0x23, 0x60), + PIN(69, 0, 1, 0x30, 0xc0), + PIN(70, 0, 0, 0x30, 0xc0), + PIN(71, 0, 5, 0x30, 0xc0), + PIN(72, 0, 4, 0x30, 0xc0), + PIN(73, 0, 2, 0x30, 0xc0), + PIN(74, 0, 3, 0x30, 0xc0), + PIN(75, 0, 7, 0x30, 0xc0), + PIN(76, 0, 6, 0x30, 0xc0), + PIN(77, 0, 9, 0x30, 0xc0), + PIN(78, 0, 8, 0x30, 0xc0), + PIN(79, 0, 12, 0x23, 0x60), + PIN(80, 0, 11, 0x23, 0x60), + PIN(81, 0, 14, 0x23, 0x60), + PIN(82, 0, 13, 0x23, 0x60), + PIN(83, 0, 16, 0x31, 0xb0), + PIN(84, 0, 15, 0x31, 0xb0), + PIN(85, 0, 17, 0x31, 0xb0), + PIN(86, 0, 19, 0x31, 0xb0), + PIN(87, 0, 18, 0x31, 0xb0), + PIN(88, 0, 20, 0x31, 0xb0), + PIN(89, 0, 22, 0x31, 0xb0), + PIN(90, 0, 21, 0x31, 0xb0), + PIN(91, 0, 23, 0x31, 0xb0), + PIN(92, 0, 3, 0x31, 0xb0), + PIN(93, 0, 2, 0x31, 0xb0), + PIN(94, 0, 5, 0x31, 0xb0), + PIN(95, 0, 4, 0x31, 0xb0), + PIN(96, 0, 31, 0x31, 0xa0), + PIN(97, 0, 0, 0x31, 0xb0), + PIN(98, 0, 8, 0x31, 0xb0), + PIN(99, 0, 30, 0x31, 0xa0), + PIN(100, 0, 1, 0x31, 0xb0), + PIN(101, 0, 0, 0x31, 0xa0), + PIN(102, 0, 5, 0x31, 0xa0), + PIN(103, 0, 3, 0x31, 0xa0), + PIN(104, 0, 4, 0x31, 0xa0), + PIN(105, 0, 1, 0x31, 0xa0), + PIN(106, 0, 2, 0x31, 0xa0), + PIN(107, 0, 21, 0x31, 0xa0), + PIN(108, 0, 16, 0x31, 0xa0), + PIN(109, 0, 22, 0x31, 0xa0), + PIN(110, 0, 17, 0x31, 0xa0), + PIN(111, 0, 18, 0x31, 0xa0), + PIN(112, 0, 19, 0x31, 0xa0), + PIN(113, 0, 20, 0x31, 0xa0), + PIN(114, 0, 28, 0x31, 0xa0), + PIN(115, 0, 23, 0x31, 0xa0), + PIN(116, 0, 29, 0x31, 0xa0), + PIN(117, 0, 24, 0x31, 0xa0), + PIN(118, 0, 25, 0x31, 0xa0), + PIN(119, 0, 26, 0x31, 0xa0), + PIN(120, 0, 27, 0x31, 0xa0), + PIN(121, 0, 8, 0x22, 0x50), + PIN(122, 0, 11, 0x22, 0x50), + PIN(123, 0, 10, 0x22, 0x50), + PIN(124, 0, 9, 0x22, 0x50), + PIN(125, 0, 6, 0x31, 0xa0), + PIN(126, 0, 7, 0x31, 0xa0), + PIN(127, 0, 8, 0x31, 0xa0), + PIN(128, 0, 9, 0x31, 0xa0), + PIN(129, 0, 10, 0x31, 0xa0), + PIN(130, 0, 11, 0x31, 0xa0), + PIN(131, 1, 1, 0x30, 0xd0), + PIN(132, 1, 2, 0x30, 0xd0), + PIN(133, 1, 9, 0x30, 0xd0), + PIN(134, 1, 10, 0x30, 0xd0), + PIN(135, 1, 11, 0x30, 0xd0), + PIN(136, 1, 12, 0x30, 0xd0), + PIN(137, 1, 13, 0x30, 0xd0), + PIN(138, 1, 14, 0x30, 0xd0), + PIN(139, 1, 15, 0x30, 0xd0), + PIN(140, 1, 16, 0x30, 0xd0), + PIN(141, 1, 3, 0x30, 0xd0), + PIN(142, 1, 4, 0x30, 0xd0), + PIN(143, 1, 5, 0x30, 0xd0), + PIN(144, 1, 6, 0x30, 0xd0), + PIN(145, 1, 7, 0x30, 0xd0), + PIN(146, 1, 8, 0x30, 0xd0), + PIN(147, 1, 18, 0x30, 0xd0), + PIN(148, 1, 19, 0x30, 0xd0), + PIN(149, 1, 17, 0x30, 0xd0), + PIN(150, 1, 0, 0x30, 0xd0), + PIN(151, 1, 9, 0x31, 0xc0), + PIN(152, 1, 8, 0x31, 0xc0), + PIN(153, 1, 7, 0x31, 0xc0), + PIN(154, 1, 6, 0x31, 0xc0), + PIN(155, 1, 11, 0x31, 0xc0), + PIN(156, 1, 1, 0x31, 0xc0), + PIN(157, 1, 0, 0x31, 0xc0), + PIN(158, 1, 5, 0x31, 0xc0), + PIN(159, 1, 4, 0x31, 0xc0), + PIN(160, 1, 3, 0x31, 0xc0), + PIN(161, 1, 2, 0x31, 0xc0), + PIN(162, 1, 10, 0x31, 0xc0), + PIN(163, 1, 1, 0x23, 0x70), + PIN(164, 1, 0, 0x23, 0x70), + PIN(165, 1, 2, 0x23, 0x70), + PIN(166, 1, 3, 0x23, 0x70), + PIN(167, 1, 4, 0x23, 0x70), + PIN(168, 1, 5, 0x23, 0x70), + PIN(169, 1, 1, 0x22, 0x60), + PIN(170, 1, 0, 0x22, 0x60), + PIN(171, 1, 2, 0x22, 0x60), + PIN(172, 1, 3, 0x22, 0x60), + PIN(173, 1, 4, 0x22, 0x60), + PIN(174, 1, 5, 0x22, 0x60), + PIN(175, 0, 11, 0x31, 0xb0), + PIN(176, 0, 12, 0x31, 0xb0), +}; + +#endif /* MT_GPIO_H */ diff --git a/plat/mediatek/drivers/gpio/mtgpio_common.c b/plat/mediatek/drivers/gpio/mtgpio_common.c new file mode 100644 index 0000000..bad0190 --- /dev/null +++ b/plat/mediatek/drivers/gpio/mtgpio_common.c @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <common/debug.h> +#include <drivers/delay_timer.h> +#include <drivers/gpio.h> +#include <lib/mmio.h> +#include <lib/mtk_init/mtk_init.h> +#include <mtgpio.h> +#include <platform_def.h> + +/****************************************************************************** + *Macro Definition + ******************************************************************************/ +#define GPIO_MODE_BITS 4 +#define MAX_GPIO_MODE_PER_REG 8 +#define MAX_GPIO_REG_BITS 32 +#define DIR_BASE (GPIO_BASE + 0x000) +#define DOUT_BASE (GPIO_BASE + 0x100) +#define DIN_BASE (GPIO_BASE + 0x200) +#define MODE_BASE (GPIO_BASE + 0x300) +#define SET 0x4 +#define CLR 0x8 + +static void mt_set_gpio_dir_chip(uint32_t pin, int dir) +{ + uint32_t pos, bit; + + assert(pin < MAX_GPIO_PIN); + assert(dir < MT_GPIO_DIR_MAX); + + pos = pin / MAX_GPIO_REG_BITS; + bit = pin % MAX_GPIO_REG_BITS; + + if (dir == MT_GPIO_DIR_IN) { + mmio_write_32(DIR_BASE + 0x10U * pos + CLR, 1U << bit); + } else { + mmio_write_32(DIR_BASE + 0x10U * pos + SET, 1U << bit); + } +} + +static int mt_get_gpio_dir_chip(uint32_t pin) +{ + uint32_t pos, bit; + uint32_t reg; + + assert(pin < MAX_GPIO_PIN); + + pos = pin / MAX_GPIO_REG_BITS; + bit = pin % MAX_GPIO_REG_BITS; + + reg = mmio_read_32(DIR_BASE + 0x10U * pos); + return (((reg & (1U << bit)) != 0U) ? MT_GPIO_DIR_OUT : MT_GPIO_DIR_IN); +} + +static void mt_set_gpio_out_chip(uint32_t pin, int output) +{ + uint32_t pos, bit; + + assert(pin < MAX_GPIO_PIN); + assert(output < MT_GPIO_OUT_MAX); + + pos = pin / MAX_GPIO_REG_BITS; + bit = pin % MAX_GPIO_REG_BITS; + + if (output == MT_GPIO_OUT_ZERO) { + mmio_write_32(DOUT_BASE + 0x10U * pos + CLR, 1U << bit); + } else { + mmio_write_32(DOUT_BASE + 0x10U * pos + SET, 1U << bit); + } +} + +static int mt_get_gpio_in_chip(uint32_t pin) +{ + uint32_t pos, bit; + uint32_t reg; + + assert(pin < MAX_GPIO_PIN); + + pos = pin / MAX_GPIO_REG_BITS; + bit = pin % MAX_GPIO_REG_BITS; + + reg = mmio_read_32(DIN_BASE + 0x10U * pos); + return (((reg & (1U << bit)) != 0U) ? 1 : 0); +} + +static void mt_gpio_set_spec_pull_pupd(uint32_t pin, int enable, + int select) +{ + uintptr_t reg1; + uintptr_t reg2; + struct mt_pin_info gpio_info; + + gpio_info = mt_pin_infos[pin]; + uint32_t bit = gpio_info.bit; + + reg1 = mt_gpio_find_reg_addr(pin) + gpio_info.offset; + reg2 = reg1 + (gpio_info.base & 0xf0); + if (enable == MT_GPIO_PULL_ENABLE) { + mmio_write_32(reg2 + SET, (1U << bit)); + if (select == MT_GPIO_PULL_DOWN) { + mmio_write_32(reg1 + SET, (1U << bit)); + } else { + mmio_write_32(reg1 + CLR, (1U << bit)); + } + } else { + mmio_write_32(reg2 + CLR, (1U << bit)); + mmio_write_32((reg2 + 0x010U) + CLR, (1U << bit)); + } +} + +static void mt_gpio_set_pull_pu_pd(uint32_t pin, int enable, + int select) +{ + uintptr_t reg1; + uintptr_t reg2; + struct mt_pin_info gpio_info; + + gpio_info = mt_pin_infos[pin]; + uint32_t bit = gpio_info.bit; + + reg1 = mt_gpio_find_reg_addr(pin) + gpio_info.offset; + reg2 = reg1 - (gpio_info.base & 0xf0); + + if (enable == MT_GPIO_PULL_ENABLE) { + if (select == MT_GPIO_PULL_DOWN) { + mmio_write_32(reg1 + CLR, (1U << bit)); + mmio_write_32(reg2 + SET, (1U << bit)); + } else { + mmio_write_32(reg2 + CLR, (1U << bit)); + mmio_write_32(reg1 + SET, (1U << bit)); + } + } else { + mmio_write_32(reg1 + CLR, (1U << bit)); + mmio_write_32(reg2 + CLR, (1U << bit)); + } +} + +static void mt_gpio_set_pull_chip(uint32_t pin, int enable, + int select) +{ + struct mt_pin_info gpio_info; + + gpio_info = mt_pin_infos[pin]; + if (gpio_info.flag) { + mt_gpio_set_spec_pull_pupd(pin, enable, select); + } else { + mt_gpio_set_pull_pu_pd(pin, enable, select); + } +} + +static int mt_gpio_get_spec_pull_pupd(uint32_t pin) +{ + uintptr_t reg1; + uintptr_t reg2; + uint32_t r0; + uint32_t r1; + + struct mt_pin_info gpio_info; + + gpio_info = mt_pin_infos[pin]; + uint32_t bit = gpio_info.bit; + + reg1 = mt_gpio_find_reg_addr(pin) + gpio_info.offset; + reg2 = reg1 + (gpio_info.base & 0xf0); + + r0 = (mmio_read_32(reg2) >> bit) & 1U; + r1 = (mmio_read_32(reg2 + 0x010) >> bit) & 1U; + if (r0 == 0U && r1 == 0U) { + return MT_GPIO_PULL_NONE; + } else { + if (mmio_read_32(reg1) & (1U << bit)) { + return MT_GPIO_PULL_DOWN; + } else { + return MT_GPIO_PULL_UP; + } + } +} + +static int mt_gpio_get_pull_pu_pd(uint32_t pin) +{ + uintptr_t reg1; + uintptr_t reg2; + uint32_t pu; + uint32_t pd; + + struct mt_pin_info gpio_info; + + gpio_info = mt_pin_infos[pin]; + uint32_t bit = gpio_info.bit; + + reg1 = mt_gpio_find_reg_addr(pin) + gpio_info.offset; + reg2 = reg1 - (gpio_info.base & 0xf0); + pu = (mmio_read_32(reg1) >> bit) & 1U; + pd = (mmio_read_32(reg2) >> bit) & 1U; + if (pu == 1U) { + return MT_GPIO_PULL_UP; + } else if (pd == 1U) { + return MT_GPIO_PULL_DOWN; + } else { + return MT_GPIO_PULL_NONE; + } +} + +static int mt_gpio_get_pull_chip(uint32_t pin) +{ + struct mt_pin_info gpio_info; + + gpio_info = mt_pin_infos[pin]; + if (gpio_info.flag) { + return mt_gpio_get_spec_pull_pupd(pin); + } else { + return mt_gpio_get_pull_pu_pd(pin); + } +} + +static void mt_set_gpio_pull_select_chip(uint32_t pin, int sel) +{ + assert(pin < MAX_GPIO_PIN); + + if (sel == MT_GPIO_PULL_NONE) { + mt_gpio_set_pull_chip(pin, MT_GPIO_PULL_DISABLE, MT_GPIO_PULL_DOWN); + } else if (sel == MT_GPIO_PULL_UP) { + mt_gpio_set_pull_chip(pin, MT_GPIO_PULL_ENABLE, MT_GPIO_PULL_UP); + } else if (sel == MT_GPIO_PULL_DOWN) { + mt_gpio_set_pull_chip(pin, MT_GPIO_PULL_ENABLE, MT_GPIO_PULL_DOWN); + } +} + +/* get pull-up or pull-down, regardless of resistor value */ +static int mt_get_gpio_pull_select_chip(uint32_t pin) +{ + assert(pin < MAX_GPIO_PIN); + + return mt_gpio_get_pull_chip(pin); +} + +static void mt_set_gpio_dir(int gpio, int direction) +{ + mt_set_gpio_dir_chip((uint32_t)gpio, direction); +} + +static int mt_get_gpio_dir(int gpio) +{ + uint32_t pin; + + pin = (uint32_t)gpio; + return mt_get_gpio_dir_chip(pin); +} + +static void mt_set_gpio_pull(int gpio, int pull) +{ + uint32_t pin; + + pin = (uint32_t)gpio; + mt_set_gpio_pull_select_chip(pin, pull); +} + +static int mt_get_gpio_pull(int gpio) +{ + uint32_t pin; + + pin = (uint32_t)gpio; + return mt_get_gpio_pull_select_chip(pin); +} + +static void mt_set_gpio_out(int gpio, int value) +{ + uint32_t pin; + + pin = (uint32_t)gpio; + mt_set_gpio_out_chip(pin, value); +} + +static int mt_get_gpio_in(int gpio) +{ + uint32_t pin; + + pin = (uint32_t)gpio; + return mt_get_gpio_in_chip(pin); +} + +const gpio_ops_t mtgpio_ops = { + .get_direction = mt_get_gpio_dir, + .set_direction = mt_set_gpio_dir, + .get_value = mt_get_gpio_in, + .set_value = mt_set_gpio_out, + .set_pull = mt_set_gpio_pull, + .get_pull = mt_get_gpio_pull, +}; + +int mt_gpio_init(void) +{ + gpio_init(&mtgpio_ops); + + return 0; +} +MTK_PLAT_SETUP_0_INIT(mt_gpio_init); diff --git a/plat/mediatek/drivers/gpio/mtgpio_common.h b/plat/mediatek/drivers/gpio/mtgpio_common.h new file mode 100644 index 0000000..d6b858c --- /dev/null +++ b/plat/mediatek/drivers/gpio/mtgpio_common.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_GPIO_COMMON_H +#define MT_GPIO_COMMON_H + +#include <stdbool.h> +#include <stdint.h> + +#include <plat/common/common_def.h> + +/* Error Code No. */ +#define RSUCCESS 0 +#define ERACCESS 1 +#define ERINVAL 2 +#define ERWRAPPER 3 +#define MAX_GPIO_PIN MT_GPIO_BASE_MAX + +/* GPIO MODE CONTROL VALUE*/ +typedef enum { + GPIO_MODE_UNSUPPORTED = -1, + GPIO_MODE_GPIO = 0, + GPIO_MODE_00 = 0, + GPIO_MODE_01, + GPIO_MODE_02, + GPIO_MODE_03, + GPIO_MODE_04, + GPIO_MODE_05, + GPIO_MODE_06, + GPIO_MODE_07, + + GPIO_MODE_MAX, + GPIO_MODE_DEFAULT = GPIO_MODE_00, +} GPIO_MODE; + +/* GPIO DIRECTION */ +typedef enum { + MT_GPIO_DIR_UNSUPPORTED = -1, + MT_GPIO_DIR_OUT = 0, + MT_GPIO_DIR_IN = 1, + MT_GPIO_DIR_MAX, + MT_GPIO_DIR_DEFAULT = MT_GPIO_DIR_IN, +} GPIO_DIR; + +/* GPIO PULL ENABLE*/ +typedef enum { + MT_GPIO_PULL_EN_UNSUPPORTED = -1, + MT_GPIO_PULL_DISABLE = 0, + MT_GPIO_PULL_ENABLE = 1, + MT_GPIO_PULL_ENABLE_R0 = 2, + MT_GPIO_PULL_ENABLE_R1 = 3, + MT_GPIO_PULL_ENABLE_R0R1 = 4, + + MT_GPIO_PULL_EN_MAX, + MT_GPIO_PULL_EN_DEFAULT = MT_GPIO_PULL_ENABLE, +} GPIO_PULL_EN; + +/* GPIO PULL-UP/PULL-DOWN*/ +typedef enum { + MT_GPIO_PULL_UNSUPPORTED = -1, + MT_GPIO_PULL_NONE = 0, + MT_GPIO_PULL_UP = 1, + MT_GPIO_PULL_DOWN = 2, + MT_GPIO_PULL_MAX, + MT_GPIO_PULL_DEFAULT = MT_GPIO_PULL_DOWN +} GPIO_PULL; + +/* GPIO OUTPUT */ +typedef enum { + MT_GPIO_OUT_UNSUPPORTED = -1, + MT_GPIO_OUT_ZERO = 0, + MT_GPIO_OUT_ONE = 1, + + MT_GPIO_OUT_MAX, + MT_GPIO_OUT_DEFAULT = MT_GPIO_OUT_ZERO, + MT_GPIO_DATA_OUT_DEFAULT = MT_GPIO_OUT_ZERO, /*compatible with DCT*/ +} GPIO_OUT; + +/* GPIO INPUT */ +typedef enum { + MT_GPIO_IN_UNSUPPORTED = -1, + MT_GPIO_IN_ZERO = 0, + MT_GPIO_IN_ONE = 1, + + MT_GPIO_IN_MAX, +} GPIO_IN; + +#define PIN(_id, _flag, _bit, _base, _offset) { \ + .id = _id, \ + .flag = _flag, \ + .bit = _bit, \ + .base = _base, \ + .offset = _offset, \ + } + +struct mt_pin_info { + uint8_t id; + uint8_t flag; + uint8_t bit; + uint16_t base; + uint16_t offset; +}; + +int mt_gpio_init(void); +uintptr_t mt_gpio_find_reg_addr(uint32_t pin); +#endif /* MT_GPIO_COMMON_H */ diff --git a/plat/mediatek/drivers/gpio/rules.mk b/plat/mediatek/drivers/gpio/rules.mk new file mode 100644 index 0000000..78061a8 --- /dev/null +++ b/plat/mediatek/drivers/gpio/rules.mk @@ -0,0 +1,18 @@ +# +# Copyright (c) 2022, MediaTek Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +LOCAL_DIR := $(call GET_LOCAL_DIR) + +MODULE := gpio + +LOCAL_SRCS-y := drivers/gpio/gpio.c +LOCAL_SRCS-y += ${LOCAL_DIR}/mtgpio_common.c +LOCAL_SRCS-y += ${LOCAL_DIR}/${MTK_SOC}/mtgpio.c + +PLAT_INCLUDES += -I${LOCAL_DIR} +PLAT_INCLUDES += -I${LOCAL_DIR}/${MTK_SOC} + +$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL))) diff --git a/plat/mediatek/drivers/iommu/mt8188/mtk_iommu_plat.c b/plat/mediatek/drivers/iommu/mt8188/mtk_iommu_plat.c new file mode 100644 index 0000000..1d6863f --- /dev/null +++ b/plat/mediatek/drivers/iommu/mt8188/mtk_iommu_plat.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <mtk_iommu_plat.h> +#include <mtk_mmap_pool.h> +#include <platform_def.h> + +/* mm iommu */ +#define SMI_L0_ID (0) +#define SMI_L1_ID (1) +#define SMI_L2_ID (2) +#define SMI_L3_ID (3) +#define SMI_L4_ID (4) +#define SMI_L5_ID (5) +#define SMI_L6_ID (6) +#define SMI_L7_ID (7) +#define SMI_L9_ID (8) +#define SMI_L10_ID (9) +#define SMI_L11A_ID (10) +#define SMI_L11B_ID (11) +#define SMI_L11C_ID (12) +#define SMI_L12_ID (13) +#define SMI_L13_ID (14) +#define SMI_L14_ID (15) +#define SMI_L15_ID (16) +#define SMI_L16A_ID (17) +#define SMI_L16B_ID (18) +#define SMI_L17A_ID (19) +#define SMI_L17B_ID (20) +#define SMI_L19_ID (21) +#define SMI_L21_ID (22) +#define SMI_L23_ID (23) +#define SMI_L27_ID (24) +#define SMI_L28_ID (25) + +/* infra iommu */ +#define PERI_MST_PROT (0x710) +#define PERICFG_AO_IOMMU_1 (0x714) +#define MMU_DEV_PCIE_0 (0) +#define IFR_CFG_GROUP_NUM (1) + +static struct mtk_smi_larb_config mt8188_larb_cfg[SMI_LARB_NUM] = { + [SMI_L0_ID] = LARB_CFG_ENTRY(SMI_LARB_0_BASE, 7, 0), + [SMI_L1_ID] = LARB_CFG_ENTRY(SMI_LARB_1_BASE, 7, 0), + [SMI_L2_ID] = LARB_CFG_ENTRY(SMI_LARB_2_BASE, 5, 0), + [SMI_L3_ID] = LARB_CFG_ENTRY(SMI_LARB_3_BASE, 7, 0), + [SMI_L4_ID] = LARB_CFG_ENTRY(SMI_LARB_4_BASE, 7, 0), + [SMI_L5_ID] = LARB_CFG_ENTRY(SMI_LARB_5_BASE, 8, 0), + [SMI_L6_ID] = LARB_CFG_ENTRY(SMI_LARB_6_BASE, 4, 0), + [SMI_L7_ID] = LARB_CFG_ENTRY(SMI_LARB_7_BASE, 3, 0), + [SMI_L9_ID] = LARB_CFG_ENTRY(SMI_LARB_9_BASE, 25, 0), + [SMI_L10_ID] = LARB_CFG_ENTRY(SMI_LARB_10_BASE, 20, 0), + [SMI_L11A_ID] = LARB_CFG_ENTRY(SMI_LARB_11A_BASE, 30, 0), + [SMI_L11B_ID] = LARB_CFG_ENTRY(SMI_LARB_11B_BASE, 30, 0), + [SMI_L11C_ID] = LARB_CFG_ENTRY(SMI_LARB_11C_BASE, 30, 0), + [SMI_L12_ID] = LARB_CFG_ENTRY(SMI_LARB_12_BASE, 16, 0), + [SMI_L13_ID] = LARB_CFG_ENTRY(SMI_LARB_13_BASE, 24, 0), + [SMI_L14_ID] = LARB_CFG_ENTRY(SMI_LARB_14_BASE, 23, 0), + [SMI_L15_ID] = LARB_CFG_ENTRY(SMI_LARB_15_BASE, 19, 0), + [SMI_L16A_ID] = LARB_CFG_ENTRY(SMI_LARB_16A_BASE, 17, 0), + [SMI_L16B_ID] = LARB_CFG_ENTRY(SMI_LARB_16B_BASE, 17, 0), + [SMI_L17A_ID] = LARB_CFG_ENTRY(SMI_LARB_17A_BASE, 7, 0), + [SMI_L17B_ID] = LARB_CFG_ENTRY(SMI_LARB_17B_BASE, 7, 0), + /* venc nbm ports (5/6/11/15/16/17) to sram */ + [SMI_L19_ID] = LARB_CFG_ENTRY_WITH_PATH(SMI_LARB_19_BASE, 27, 0, 0x38860), + [SMI_L21_ID] = LARB_CFG_ENTRY(SMI_LARB_21_BASE, 11, 0), + [SMI_L23_ID] = LARB_CFG_ENTRY(SMI_LARB_23_BASE, 9, 0), + [SMI_L27_ID] = LARB_CFG_ENTRY(SMI_LARB_27_BASE, 4, 0), + [SMI_L28_ID] = LARB_CFG_ENTRY(SMI_LARB_28_BASE, 0, 0), +}; + +static bool is_protected; + +static uint32_t mt8188_ifr_mst_cfg_base[IFR_CFG_GROUP_NUM] = { + PERICFG_AO_BASE, +}; +static uint32_t mt8188_ifr_mst_cfg_offs[IFR_CFG_GROUP_NUM] = { + PERICFG_AO_IOMMU_1, +}; +static struct mtk_ifr_mst_config mt8188_ifr_mst_cfg[MMU_DEV_NUM] = { + [MMU_DEV_PCIE_0] = IFR_MST_CFG_ENTRY(0, 18), +}; + +struct mtk_smi_larb_config *g_larb_cfg = &mt8188_larb_cfg[0]; +struct mtk_ifr_mst_config *g_ifr_mst_cfg = &mt8188_ifr_mst_cfg[0]; +uint32_t *g_ifr_mst_cfg_base = &mt8188_ifr_mst_cfg_base[0]; +uint32_t *g_ifr_mst_cfg_offs = &mt8188_ifr_mst_cfg_offs[0]; + +/* Protect infra iommu enable setting registers as secure access. */ +void mtk_infra_iommu_enable_protect(void) +{ + if (!is_protected) { + mmio_write_32(PERICFG_AO_BASE + PERI_MST_PROT, 0xffffffff); + is_protected = true; + } +} diff --git a/plat/mediatek/drivers/iommu/mt8188/mtk_iommu_plat.h b/plat/mediatek/drivers/iommu/mt8188/mtk_iommu_plat.h new file mode 100644 index 0000000..a59e0c7 --- /dev/null +++ b/plat/mediatek/drivers/iommu/mt8188/mtk_iommu_plat.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef IOMMU_PLAT_H +#define IOMMU_PLAT_H + +#include <mtk_iommu_priv.h> + +/* mm iommu */ +#define SMI_LARB_NUM (26) +extern struct mtk_smi_larb_config *g_larb_cfg; + +/* infra iommu */ +#define MMU_DEV_NUM (1) +extern struct mtk_ifr_mst_config *g_ifr_mst_cfg; +extern uint32_t *g_ifr_mst_cfg_base; +extern uint32_t *g_ifr_mst_cfg_offs; + +extern void mtk_infra_iommu_enable_protect(void); + +#endif /* IOMMU_PLAT_H */ diff --git a/plat/mediatek/drivers/iommu/mtk_iommu_priv.h b/plat/mediatek/drivers/iommu/mtk_iommu_priv.h new file mode 100644 index 0000000..3404d31 --- /dev/null +++ b/plat/mediatek/drivers/iommu/mtk_iommu_priv.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef IOMMU_PRIV_H +#define IOMMU_PRIV_H + +#include <common/debug.h> +#include <lib/mmio.h> +#include <mtk_sip_svc.h> + +#define LARB_CFG_ENTRY(bs, p_nr, dom) \ + { .base = (bs), .port_nr = (p_nr), \ + .dom_id = (dom), .to_sram = 0, } + +#define LARB_CFG_ENTRY_WITH_PATH(bs, p_nr, dom, sram) \ + { .base = (bs), .port_nr = (p_nr), \ + .dom_id = (dom), .to_sram = (sram), } + +#define IFR_MST_CFG_ENTRY(idx, bit) \ + { .cfg_addr_idx = (idx), .r_mmu_en_bit = (bit), } + +enum IOMMU_ATF_CMD { + IOMMU_ATF_CMD_CONFIG_SMI_LARB, /* For mm master to enable iommu */ + IOMMU_ATF_CMD_CONFIG_INFRA_IOMMU, /* For infra master to enable iommu */ + IOMMU_ATF_CMD_COUNT, +}; + +struct mtk_smi_larb_config { + uint32_t base; + uint32_t port_nr; + uint32_t dom_id; + uint32_t to_sram; + uint32_t sec_en_msk; +}; + +struct mtk_ifr_mst_config { + uint8_t cfg_addr_idx; + uint8_t r_mmu_en_bit; +}; + +#endif /* IOMMU_PRIV_H */ diff --git a/plat/mediatek/drivers/iommu/mtk_iommu_smc.c b/plat/mediatek/drivers/iommu/mtk_iommu_smc.c new file mode 100644 index 0000000..e998725 --- /dev/null +++ b/plat/mediatek/drivers/iommu/mtk_iommu_smc.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2022-2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stddef.h> +#include <mtk_iommu_plat.h> + +/* defination */ +/* smi larb */ +#define SMI_LARB_NON_SEC_CON(port) (0x380 + ((port) << 2)) +#define PATH_SEL_MASK (0xf0000) /* to sram (INT) */ +#define SMI_LARB_SEC_CON_INT(port) (0xf00 + ((port) << 2)) +#define SMI_LARB_SEC_CON(port) (0xf80 + ((port) << 2)) +#define MMU_MASK BIT(0) +#define MMU_EN(en) ((!!(en)) << 0) +#define SEC_MASK BIT(1) +#define SEC_EN(en) ((!!(en)) << 1) +#define DOMAIN_MASK (0x1f << 4) +#define SMI_MMU_EN(port) (0x1 << (port)) + +/* infra master */ +#define IFR_CFG_MMU_EN_MSK(r_bit) (0x3 << (r_bit)) + +/* smi larb configure */ +/* + * If multimedia security config is enabled, the SMI config register must be + * configurated in security world. + * And the SRAM path is also configurated here to enhance security. + */ +static void mtk_smi_larb_port_config_to_sram( + const struct mtk_smi_larb_config *larb, + uint32_t port_id) +{ + mmio_clrbits_32(larb->base + SMI_LARB_SEC_CON_INT(port_id), + MMU_MASK | SEC_MASK | DOMAIN_MASK); + + mmio_setbits_32(larb->base + SMI_LARB_NON_SEC_CON(port_id), + PATH_SEL_MASK); +} + +static void mtk_smi_port_config(const struct mtk_smi_larb_config *larb, + uint32_t port_id, uint8_t mmu_en, uint8_t sec_en) +{ + mmio_clrsetbits_32(larb->base + SMI_LARB_SEC_CON(port_id), + MMU_MASK | SEC_MASK | DOMAIN_MASK, + MMU_EN(mmu_en) | SEC_EN(sec_en)); +} + +static int mtk_smi_larb_port_config_sec(uint32_t larb_id, uint32_t mmu_en_msk) +{ + uint32_t port_id, port_nr; + const struct mtk_smi_larb_config *larb; + uint32_t to_sram; + uint8_t mmu_en; + + if (larb_id >= SMI_LARB_NUM) { + return MTK_SIP_E_INVALID_PARAM; + } + + larb = &g_larb_cfg[larb_id]; + port_nr = larb->port_nr; + to_sram = larb->to_sram; + + for (port_id = 0; port_id < port_nr; port_id++) { + if ((to_sram & BIT(port_id)) > 0U) { + mtk_smi_larb_port_config_to_sram(larb, port_id); + continue; + } + mmu_en = !!(mmu_en_msk & SMI_MMU_EN(port_id)); + mtk_smi_port_config(larb, port_id, mmu_en, 0); + } + + return MTK_SIP_E_SUCCESS; +} + +static int mtk_infra_master_config_sec(uint32_t dev_id_msk, uint32_t enable) +{ + const struct mtk_ifr_mst_config *ifr_cfg; + uint32_t dev_id, reg_addr, reg_mask; + + mtk_infra_iommu_enable_protect(); + + if (dev_id_msk >= BIT(MMU_DEV_NUM)) { + return MTK_SIP_E_INVALID_PARAM; + } + + for (dev_id = 0U; dev_id < MMU_DEV_NUM; dev_id++) { + if ((dev_id_msk & BIT(dev_id)) == 0U) { + continue; + } + + ifr_cfg = &g_ifr_mst_cfg[dev_id]; + reg_addr = g_ifr_mst_cfg_base[(ifr_cfg->cfg_addr_idx)] + + g_ifr_mst_cfg_offs[(ifr_cfg->cfg_addr_idx)]; + reg_mask = IFR_CFG_MMU_EN_MSK(ifr_cfg->r_mmu_en_bit); + + if (enable > 0U) { + mmio_setbits_32(reg_addr, reg_mask); + } else { + mmio_clrbits_32(reg_addr, reg_mask); + } + } + + return MTK_SIP_E_SUCCESS; +} + +static u_register_t mtk_iommu_handler(u_register_t x1, u_register_t x2, + u_register_t x3, u_register_t x4, + void *handle, struct smccc_res *smccc_ret) +{ + uint32_t cmd_id = x1, mdl_id = x2, val = x3; + int ret = MTK_SIP_E_NOT_SUPPORTED; + + (void)x4; + (void)handle; + + switch (cmd_id) { + case IOMMU_ATF_CMD_CONFIG_SMI_LARB: + ret = mtk_smi_larb_port_config_sec(mdl_id, val); + break; + case IOMMU_ATF_CMD_CONFIG_INFRA_IOMMU: + ret = mtk_infra_master_config_sec(mdl_id, val); + break; + default: + break; + } + + return ret; +} +DECLARE_SMC_HANDLER(MTK_SIP_IOMMU_CONTROL, mtk_iommu_handler); diff --git a/plat/mediatek/drivers/iommu/rules.mk b/plat/mediatek/drivers/iommu/rules.mk new file mode 100644 index 0000000..5490f41 --- /dev/null +++ b/plat/mediatek/drivers/iommu/rules.mk @@ -0,0 +1,17 @@ +# +# Copyright (c) 2022, MediaTek Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +LOCAL_DIR := $(call GET_LOCAL_DIR) + +MODULE := mtk_iommu + +LOCAL_SRCS-y := ${LOCAL_DIR}/mtk_iommu_smc.c +LOCAL_SRCS-y += ${LOCAL_DIR}/${MTK_SOC}/mtk_iommu_plat.c + +PLAT_INCLUDES += -I${LOCAL_DIR} +PLAT_INCLUDES += -I${LOCAL_DIR}/${MTK_SOC} + +$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL))) diff --git a/plat/mediatek/drivers/mcusys/mcusys.c b/plat/mediatek/drivers/mcusys/mcusys.c new file mode 100644 index 0000000..63edb23 --- /dev/null +++ b/plat/mediatek/drivers/mcusys/mcusys.c @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdint.h> +#include <mtk_mmap_pool.h> +#include <platform_def.h> + +static const mmap_region_t mcusys_mmap[] MTK_MMAP_SECTION = { + MAP_REGION_FLAT(MCUCFG_BASE, MCUCFG_REG_SIZE, MT_DEVICE | MT_RW | MT_SECURE), + {0} +}; +DECLARE_MTK_MMAP_REGIONS(mcusys_mmap); diff --git a/plat/mediatek/drivers/mcusys/rules.mk b/plat/mediatek/drivers/mcusys/rules.mk new file mode 100644 index 0000000..5438998 --- /dev/null +++ b/plat/mediatek/drivers/mcusys/rules.mk @@ -0,0 +1,15 @@ +# +# Copyright (c) 2022, MediaTek Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +LOCAL_DIR := $(call GET_LOCAL_DIR) + +MODULE := mcusys + +PLAT_INCLUDES += -I$(LOCAL_DIR)/$(MCUSYS_VERSION) + +LOCAL_SRCS-y := $(LOCAL_DIR)/mcusys.c + +$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL))) diff --git a/plat/mediatek/drivers/mcusys/v1/mcucfg.h b/plat/mediatek/drivers/mcusys/v1/mcucfg.h new file mode 100644 index 0000000..7aced5a --- /dev/null +++ b/plat/mediatek/drivers/mcusys/v1/mcucfg.h @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MCUCFG_V1_H +#define MCUCFG_V1_H + +#ifndef __ASSEMBLER__ +#include <stdint.h> +#endif /*__ASSEMBLER__*/ + +#include <platform_def.h> + +#define MP2_MISC_CONFIG_BOOT_ADDR_L(cpu) (MCUCFG_BASE + 0x2290 + ((cpu) * 8)) +#define MP2_MISC_CONFIG_BOOT_ADDR_H(cpu) (MCUCFG_BASE + 0x2294 + ((cpu) * 8)) + +#define MP2_CPUCFG (MCUCFG_BASE + 0x2208) + +#define MP0_CPUTOP_SPMC_CTL (MCUCFG_BASE + 0x788) +#define MP1_CPUTOP_SPMC_CTL (MCUCFG_BASE + 0x78C) +#define MP1_CPUTOP_SPMC_SRAM_CTL (MCUCFG_BASE + 0x790) + +#define CPUSYSx_CPUx_SPMC_CTL(cluster, cpu) (MCUCFG_BASE + 0x1C30 + \ + (cluster) * 0x2000 + (cpu) * 4) + +#define CPUSYS0_CPU0_SPMC_CTL (MCUCFG_BASE + 0x1C30) +#define CPUSYS0_CPU1_SPMC_CTL (MCUCFG_BASE + 0x1C34) +#define CPUSYS0_CPU2_SPMC_CTL (MCUCFG_BASE + 0x1C38) +#define CPUSYS0_CPU3_SPMC_CTL (MCUCFG_BASE + 0x1C3C) + +#define CPUSYS1_CPU0_SPMC_CTL (MCUCFG_BASE + 0x3C30) +#define CPUSYS1_CPU1_SPMC_CTL (MCUCFG_BASE + 0x3C34) +#define CPUSYS1_CPU2_SPMC_CTL (MCUCFG_BASE + 0x3C38) +#define CPUSYS1_CPU3_SPMC_CTL (MCUCFG_BASE + 0x3C3C) + +/* CPC related registers */ +#define CPC_MCUSYS_CPC_OFF_THRES (MCUCFG_BASE + 0xA714) +#define CPC_MCUSYS_PWR_CTRL (MCUCFG_BASE + 0xA804) +#define CPC_MCUSYS_CPC_FLOW_CTRL_CFG (MCUCFG_BASE + 0xA814) +#define CPC_MCUSYS_LAST_CORE_REQ (MCUCFG_BASE + 0xA818) +#define CPC_MCUSYS_MP_LAST_CORE_RESP (MCUCFG_BASE + 0xA81C) +#define CPC_MCUSYS_LAST_CORE_RESP (MCUCFG_BASE + 0xA824) +#define CPC_MCUSYS_PWR_ON_MASK (MCUCFG_BASE + 0xA828) +#define CPC_SPMC_PWR_STATUS (MCUCFG_BASE + 0xA840) +#define CPC_MCUSYS_CPU_ON_SW_HINT_SET (MCUCFG_BASE + 0xA8A8) +#define CPC_MCUSYS_CPU_ON_SW_HINT_CLR (MCUCFG_BASE + 0xA8AC) +#define CPC_MCUSYS_CPC_DBG_SETTING (MCUCFG_BASE + 0xAB00) +#define CPC_MCUSYS_CPC_KERNEL_TIME_L_BASE (MCUCFG_BASE + 0xAB04) +#define CPC_MCUSYS_CPC_KERNEL_TIME_H_BASE (MCUCFG_BASE + 0xAB08) +#define CPC_MCUSYS_CPC_SYSTEM_TIME_L_BASE (MCUCFG_BASE + 0xAB0C) +#define CPC_MCUSYS_CPC_SYSTEM_TIME_H_BASE (MCUCFG_BASE + 0xAB10) +#define CPC_MCUSYS_TRACE_SEL (MCUCFG_BASE + 0xAB14) +#define CPC_MCUSYS_TRACE_DATA (MCUCFG_BASE + 0xAB20) +#define CPC_MCUSYS_CLUSTER_COUNTER (MCUCFG_BASE + 0xAB70) +#define CPC_MCUSYS_CLUSTER_COUNTER_CLR (MCUCFG_BASE + 0xAB74) + +/* CPC_MCUSYS_CPC_FLOW_CTRL_CFG bit control */ +#define CPC_CTRL_ENABLE BIT(16) +#define SSPM_CORE_PWR_ON_EN BIT(7) /* for cpu-hotplug */ +#define SSPM_ALL_PWR_CTRL_EN BIT(13) /* for cpu-hotplug */ +#define GIC_WAKEUP_IGNORE(cpu) BIT(21 + cpu) + +#define CPC_MCUSYS_CPC_RESET_ON_KEEP_ON BIT(17) +#define CPC_MCUSYS_CPC_RESET_PWR_ON_EN BIT(20) + +/* SPMC related registers */ +#define SPM_MCUSYS_PWR_CON (MCUCFG_BASE + 0xD200) +#define SPM_MP0_CPUTOP_PWR_CON (MCUCFG_BASE + 0xD204) +#define SPM_MP0_CPU0_PWR_CON (MCUCFG_BASE + 0xD208) +#define SPM_MP0_CPU1_PWR_CON (MCUCFG_BASE + 0xD20C) +#define SPM_MP0_CPU2_PWR_CON (MCUCFG_BASE + 0xD210) +#define SPM_MP0_CPU3_PWR_CON (MCUCFG_BASE + 0xD214) +#define SPM_MP0_CPU4_PWR_CON (MCUCFG_BASE + 0xD218) +#define SPM_MP0_CPU5_PWR_CON (MCUCFG_BASE + 0xD21C) +#define SPM_MP0_CPU6_PWR_CON (MCUCFG_BASE + 0xD220) +#define SPM_MP0_CPU7_PWR_CON (MCUCFG_BASE + 0xD224) + +/* bit fields of SPM_*_PWR_CON */ +#define PWR_ON_ACK BIT(31) +#define VPROC_EXT_OFF BIT(7) +#define DORMANT_EN BIT(6) +#define RESETPWRON_CONFIG BIT(5) +#define PWR_CLK_DIS BIT(4) +#define PWR_ON BIT(2) +#define PWR_RST_B BIT(0) + +#define SPARK2LDO (MCUCFG_BASE + 0x2700) +/* APB Module mcucfg */ +#define MP0_CA7_CACHE_CONFIG (MCUCFG_BASE + 0x000) +#define MP0_AXI_CONFIG (MCUCFG_BASE + 0x02C) +#define MP0_MISC_CONFIG0 (MCUCFG_BASE + 0x030) +#define MP0_MISC_CONFIG1 (MCUCFG_BASE + 0x034) +#define MP0_MISC_CONFIG2 (MCUCFG_BASE + 0x038) +#define MP0_MISC_CONFIG_BOOT_ADDR(cpu) (MCUCFG_BASE + 0x038 + ((cpu) * 8)) +#define MP0_MISC_CONFIG3 (MCUCFG_BASE + 0x03C) +#define MP0_MISC_CONFIG9 (MCUCFG_BASE + 0x054) +#define MP0_CA7_MISC_CONFIG (MCUCFG_BASE + 0x064) + +#define MP0_RW_RSVD0 (MCUCFG_BASE + 0x06C) +#define MP1_CA7_CACHE_CONFIG (MCUCFG_BASE + 0x200) +#define MP1_AXI_CONFIG (MCUCFG_BASE + 0x22C) +#define MP1_MISC_CONFIG0 (MCUCFG_BASE + 0x230) +#define MP1_MISC_CONFIG1 (MCUCFG_BASE + 0x234) +#define MP1_MISC_CONFIG2 (MCUCFG_BASE + 0x238) +#define MP1_MISC_CONFIG_BOOT_ADDR(cpu) (MCUCFG_BASE + 0x238 + ((cpu) * 8)) +#define MP1_MISC_CONFIG3 (MCUCFG_BASE + 0x23C) +#define MP1_MISC_CONFIG9 (MCUCFG_BASE + 0x254) +#define MP1_CA7_MISC_CONFIG (MCUCFG_BASE + 0x264) + +#define CCI_ADB400_DCM_CONFIG (MCUCFG_BASE + 0x740) +#define SYNC_DCM_CONFIG (MCUCFG_BASE + 0x744) + +#define MP0_CLUSTER_CFG0 (MCUCFG_BASE + 0xC8D0) + +#define MP0_SPMC (MCUCFG_BASE + 0x788) +#define MP1_SPMC (MCUCFG_BASE + 0x78C) +#define MP2_AXI_CONFIG (MCUCFG_BASE + 0x220C) +#define MP2_AXI_CONFIG_ACINACTM BIT(0) +#define MP2_AXI_CONFIG_AINACTS BIT(4) + +#define MPx_AXI_CONFIG_ACINACTM BIT(4) +#define MPx_AXI_CONFIG_AINACTS BIT(5) + +#define MPx_CA7_MISC_CONFIG_standbywfil2 BIT(28) + +#define MP0_CPU0_STANDBYWFE BIT(20) +#define MP0_CPU1_STANDBYWFE BIT(21) +#define MP0_CPU2_STANDBYWFE BIT(22) +#define MP0_CPU3_STANDBYWFE BIT(23) + +#define MP1_CPU0_STANDBYWFE BIT(20) +#define MP1_CPU1_STANDBYWFE BIT(21) +#define MP1_CPU2_STANDBYWFE BIT(22) +#define MP1_CPU3_STANDBYWFE BIT(23) + +#define CPUSYS0_SPARKVRETCNTRL (MCUCFG_BASE+0x1c00) +#define CPUSYS0_SPARKEN (MCUCFG_BASE+0x1c04) +#define CPUSYS0_AMUXSEL (MCUCFG_BASE+0x1c08) +#define CPUSYS1_SPARKVRETCNTRL (MCUCFG_BASE+0x3c00) +#define CPUSYS1_SPARKEN (MCUCFG_BASE+0x3c04) +#define CPUSYS1_AMUXSEL (MCUCFG_BASE+0x3c08) + +#define MP2_PWR_RST_CTL (MCUCFG_BASE + 0x2008) +#define MP2_PTP3_CPUTOP_SPMC0 (MCUCFG_BASE + 0x22A0) +#define MP2_PTP3_CPUTOP_SPMC1 (MCUCFG_BASE + 0x22A4) + +#define MP2_COQ (MCUCFG_BASE + 0x22BC) +#define MP2_COQ_SW_DIS BIT(0) + +#define MP2_CA15M_MON_SEL (MCUCFG_BASE + 0x2400) +#define MP2_CA15M_MON_L (MCUCFG_BASE + 0x2404) + +#define CPUSYS2_CPU0_SPMC_CTL (MCUCFG_BASE + 0x2430) +#define CPUSYS2_CPU1_SPMC_CTL (MCUCFG_BASE + 0x2438) +#define CPUSYS2_CPU0_SPMC_STA (MCUCFG_BASE + 0x2434) +#define CPUSYS2_CPU1_SPMC_STA (MCUCFG_BASE + 0x243C) + +#define MP0_CA7L_DBG_PWR_CTRL (MCUCFG_BASE + 0x068) +#define MP1_CA7L_DBG_PWR_CTRL (MCUCFG_BASE + 0x268) +#define BIG_DBG_PWR_CTRL (MCUCFG_BASE + 0x75C) + +#define MP2_SW_RST_B BIT(0) +#define MP2_TOPAON_APB_MASK BIT(1) +#define B_SW_HOT_PLUG_RESET BIT(30) +#define B_SW_PD_OFFSET (18) +#define B_SW_PD (0x3F << B_SW_PD_OFFSET) + +#define B_SW_SRAM_SLEEPB_OFFSET (12) +#define B_SW_SRAM_SLEEPB (0x3F << B_SW_SRAM_SLEEPB_OFFSET) + +#define B_SW_SRAM_ISOINTB BIT(9) +#define B_SW_ISO BIT(8) +#define B_SW_LOGIC_PDB BIT(7) +#define B_SW_LOGIC_PRE2_PDB BIT(6) +#define B_SW_LOGIC_PRE1_PDB BIT(5) +#define B_SW_FSM_OVERRIDE BIT(4) +#define B_SW_PWR_ON BIT(3) +#define B_SW_PWR_ON_OVERRIDE_EN BIT(2) + +#define B_FSM_STATE_OUT_OFFSET (6) +#define B_FSM_STATE_OUT_MASK (0x1F << B_FSM_STATE_OUT_OFFSET) +#define B_SW_LOGIC_PDBO_ALL_OFF_ACK BIT(5) +#define B_SW_LOGIC_PDBO_ALL_ON_ACK BIT(4) +#define B_SW_LOGIC_PRE2_PDBO_ALL_ON_ACK BIT(3) +#define B_SW_LOGIC_PRE1_PDBO_ALL_ON_ACK BIT(2) + + +#define B_FSM_OFF (0U << B_FSM_STATE_OUT_OFFSET) +#define B_FSM_ON (1U << B_FSM_STATE_OUT_OFFSET) +#define B_FSM_RET (2U << B_FSM_STATE_OUT_OFFSET) + +#ifndef __ASSEMBLER__ +/* cpu boot mode */ +enum mp0_coucfg_64bit_ctrl { + MP0_CPUCFG_64BIT_SHIFT = 12, + MP1_CPUCFG_64BIT_SHIFT = 28, + MP0_CPUCFG_64BIT = 0xfu << MP0_CPUCFG_64BIT_SHIFT, + MP1_CPUCFG_64BIT = 0xfu << MP1_CPUCFG_64BIT_SHIFT, +}; + +enum mp1_dis_rgu0_ctrl { + MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK_SHIFT = 0, + MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK_SHIFT = 4, + MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK_SHIFT = 8, + MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK_SHIFT = 12, + MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK_SHIFT = 16, + MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK = 0xF << MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK_SHIFT, + MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK = 0xF << MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK_SHIFT, + MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK = 0xF << MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK_SHIFT, + MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK = 0xF << MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK_SHIFT, + MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK = 0xF << MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK_SHIFT, +}; + +enum mp1_ainacts_ctrl { + MP1_AINACTS_SHIFT = 4, + MP1_AINACTS = 1U << MP1_AINACTS_SHIFT, +}; + +enum mp1_sw_cg_gen { + MP1_SW_CG_GEN_SHIFT = 12, + MP1_SW_CG_GEN = 1U << MP1_SW_CG_GEN_SHIFT, +}; + +enum mp1_l2rstdisable { + MP1_L2RSTDISABLE_SHIFT = 14, + MP1_L2RSTDISABLE = 1U << MP1_L2RSTDISABLE_SHIFT, +}; +#endif /*__ASSEMBLER__*/ + +#endif /* MCUCFG_V1_H */ diff --git a/plat/mediatek/drivers/msdc/mt8186/mt_msdc_priv.h b/plat/mediatek/drivers/msdc/mt8186/mt_msdc_priv.h new file mode 100644 index 0000000..b3337ca --- /dev/null +++ b/plat/mediatek/drivers/msdc/mt8186/mt_msdc_priv.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_MSDC_PRIV_H +#define MT_MSDC_PRIV_H + +#define MSDC_CQHCI_CFG 0x808 +#define MSDC_CQHCI_CRYPTO_ENABLE BIT(1) + +#endif diff --git a/plat/mediatek/drivers/msdc/mt_msdc.c b/plat/mediatek/drivers/msdc/mt_msdc.c new file mode 100644 index 0000000..ccf440f --- /dev/null +++ b/plat/mediatek/drivers/msdc/mt_msdc.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#include <lib/mmio.h> +#include <mt_msdc.h> +#include <platform_def.h> + +uint64_t msdc_smc_dispatcher(uint64_t arg0, uint64_t arg1, + uint64_t arg2, uint64_t arg3) +{ + INFO("[%s] msdc setup call from kernel\n", __func__); + mmio_setbits_32(MSDC0_BASE + MSDC_CQHCI_CFG, MSDC_CQHCI_CRYPTO_ENABLE); + + return 0L; +} diff --git a/plat/mediatek/drivers/msdc/mt_msdc.h b/plat/mediatek/drivers/msdc/mt_msdc.h new file mode 100644 index 0000000..1c500c2 --- /dev/null +++ b/plat/mediatek/drivers/msdc/mt_msdc.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_MSDC_H +#define MT_MSDC_H + +#include <mt_msdc_priv.h> + +uint64_t msdc_smc_dispatcher(uint64_t arg0, uint64_t arg1, + uint64_t arg2, uint64_t arg3); + +#endif diff --git a/plat/mediatek/drivers/pmic/pmic.c b/plat/mediatek/drivers/pmic/pmic.c new file mode 100644 index 0000000..a11ad9a --- /dev/null +++ b/plat/mediatek/drivers/pmic/pmic.c @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <pmic.h> +#include <pmic_wrap_init.h> + +void pmic_power_off(void) +{ + pwrap_write(PMIC_PWRHOLD, 0x0); +} diff --git a/plat/mediatek/drivers/pmic/pmic.h b/plat/mediatek/drivers/pmic/pmic.h new file mode 100644 index 0000000..6c10f65 --- /dev/null +++ b/plat/mediatek/drivers/pmic/pmic.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PMIC_H +#define PMIC_H + +#define PMIC_PWRHOLD (0xa08) + +/* external API */ +void pmic_power_off(void); + +#endif /* PMIC_H */ diff --git a/plat/mediatek/drivers/pmic/rules.mk b/plat/mediatek/drivers/pmic/rules.mk new file mode 100644 index 0000000..e408b03 --- /dev/null +++ b/plat/mediatek/drivers/pmic/rules.mk @@ -0,0 +1,15 @@ +# +# Copyright (c) 2022, MediaTek Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +LOCAL_DIR := $(call GET_LOCAL_DIR) + +MODULE := pmic + +LOCAL_SRCS-y += ${LOCAL_DIR}/pmic.c + +PLAT_INCLUDES += -I${LOCAL_DIR}/ + +$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL))) diff --git a/plat/mediatek/drivers/pmic_wrap/mt8188/pmic_wrap_init.h b/plat/mediatek/drivers/pmic_wrap/mt8188/pmic_wrap_init.h new file mode 100644 index 0000000..9027daf --- /dev/null +++ b/plat/mediatek/drivers/pmic_wrap/mt8188/pmic_wrap_init.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PMIC_WRAP_INIT_H +#define PMIC_WRAP_INIT_H + +#include <stdint.h> + +#include "platform_def.h" +#include <pmic_wrap_init_common.h> + +static struct mt8188_pmic_wrap_regs *const mtk_pwrap = (void *)PMIC_WRAP_BASE; + +/* PMIC_WRAP registers */ +struct mt8188_pmic_wrap_regs { + uint32_t init_done; + uint32_t reserved[543]; + uint32_t wacs2_cmd; + uint32_t wacs2_wdata; + uint32_t reserved1[3]; + uint32_t wacs2_rdata; + uint32_t reserved2[3]; + uint32_t wacs2_vldclr; + uint32_t wacs2_sta; +}; + +#endif /* PMIC_WRAP_INIT_H */ diff --git a/plat/mediatek/drivers/pmic_wrap/pmic_wrap_init.c b/plat/mediatek/drivers/pmic_wrap/pmic_wrap_init.c new file mode 100644 index 0000000..0ee1c64 --- /dev/null +++ b/plat/mediatek/drivers/pmic_wrap/pmic_wrap_init.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2019-2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#include <drivers/delay_timer.h> +#include <lib/mmio.h> +#include <platform_def.h> +#include <pmic_wrap_init.h> + +/* pmic wrap module wait_idle and read polling interval (in microseconds) */ +enum { + WAIT_IDLE_POLLING_DELAY_US = 1, + READ_POLLING_DELAY_US = 2 +}; + +static inline uint32_t wait_for_state_idle(uint32_t timeout_us, + void *wacs_register, + void *wacs_vldclr_register, + uint32_t *read_reg) +{ + uint32_t reg_rdata; + uint32_t retry; + + retry = (timeout_us + WAIT_IDLE_POLLING_DELAY_US) / + WAIT_IDLE_POLLING_DELAY_US; + + do { + udelay(WAIT_IDLE_POLLING_DELAY_US); + reg_rdata = mmio_read_32((uintptr_t)wacs_register); + /* if last read command timeout,clear vldclr bit + * read command state machine:FSM_REQ-->wfdle-->WFVLDCLR; + * write:FSM_REQ-->idle + */ + switch (((reg_rdata >> RDATA_WACS_FSM_SHIFT) & + RDATA_WACS_FSM_MASK)) { + case WACS_FSM_WFVLDCLR: + mmio_write_32((uintptr_t)wacs_vldclr_register, 1); + ERROR("WACS_FSM = PMIC_WRAP_WACS_VLDCLR\n"); + break; + case WACS_FSM_WFDLE: + ERROR("WACS_FSM = WACS_FSM_WFDLE\n"); + break; + case WACS_FSM_REQ: + ERROR("WACS_FSM = WACS_FSM_REQ\n"); + break; + case WACS_FSM_IDLE: + goto done; + default: + break; + } + + retry--; + } while (retry); + +done: + if (!retry) /* timeout */ + return E_PWR_WAIT_IDLE_TIMEOUT; + + if (read_reg) + *read_reg = reg_rdata; + return 0; +} + +static inline uint32_t wait_for_state_ready(uint32_t timeout_us, + void *wacs_register, + uint32_t *read_reg) +{ + uint32_t reg_rdata; + uint32_t retry; + + retry = (timeout_us + READ_POLLING_DELAY_US) / READ_POLLING_DELAY_US; + + do { + udelay(READ_POLLING_DELAY_US); + reg_rdata = mmio_read_32((uintptr_t)wacs_register); + + if (((reg_rdata >> RDATA_WACS_FSM_SHIFT) & RDATA_WACS_FSM_MASK) + == WACS_FSM_WFVLDCLR) + break; + + retry--; + } while (retry); + + if (!retry) { /* timeout */ + ERROR("timeout when waiting for idle\n"); + return E_PWR_WAIT_IDLE_TIMEOUT_READ; + } + + if (read_reg) + *read_reg = reg_rdata; + return 0; +} + +static int32_t pwrap_wacs2(uint32_t write, + uint32_t adr, + uint32_t wdata, + uint32_t *rdata, + uint32_t init_check) +{ + uint32_t reg_rdata = 0; + uint32_t wacs_write = 0; + uint32_t wacs_adr = 0; + uint32_t wacs_cmd = 0; + uint32_t return_value = 0; + + if (init_check) { + reg_rdata = mmio_read_32((uintptr_t)&mtk_pwrap->wacs2_rdata); + /* Prevent someone to used pwrap before pwrap init */ + if (((reg_rdata >> RDATA_INIT_DONE_SHIFT) & + RDATA_INIT_DONE_MASK) != WACS_INIT_DONE) { + ERROR("initialization isn't finished\n"); + return E_PWR_NOT_INIT_DONE; + } + } + reg_rdata = 0; + /* Check IDLE in advance */ + return_value = wait_for_state_idle(TIMEOUT_WAIT_IDLE, + &mtk_pwrap->wacs2_rdata, + &mtk_pwrap->wacs2_vldclr, + 0); + if (return_value != 0) { + ERROR("wait_for_fsm_idle fail,return_value=%d\n", return_value); + goto FAIL; + } + wacs_write = write << 31; + wacs_adr = (adr >> 1) << 16; + wacs_cmd = wacs_write | wacs_adr | wdata; + + mmio_write_32((uintptr_t)&mtk_pwrap->wacs2_cmd, wacs_cmd); + if (write == 0) { + if (rdata == NULL) { + ERROR("rdata is a NULL pointer\n"); + return_value = E_PWR_INVALID_ARG; + goto FAIL; + } + return_value = wait_for_state_ready(TIMEOUT_READ, + &mtk_pwrap->wacs2_rdata, + ®_rdata); + if (return_value != 0) { + ERROR("wait_for_fsm_vldclr fail,return_value=%d\n", + return_value); + goto FAIL; + } + *rdata = ((reg_rdata >> RDATA_WACS_RDATA_SHIFT) + & RDATA_WACS_RDATA_MASK); + mmio_write_32((uintptr_t)&mtk_pwrap->wacs2_vldclr, 1); + } +FAIL: + return return_value; +} + +/* external API for pmic_wrap user */ + +int32_t pwrap_read(uint32_t adr, uint32_t *rdata) +{ + return pwrap_wacs2(0, adr, 0, rdata, 1); +} + +int32_t pwrap_write(uint32_t adr, uint32_t wdata) +{ + return pwrap_wacs2(1, adr, wdata, 0, 1); +} diff --git a/plat/mediatek/drivers/pmic_wrap/pmic_wrap_init_common.h b/plat/mediatek/drivers/pmic_wrap/pmic_wrap_init_common.h new file mode 100644 index 0000000..4ba1f5c --- /dev/null +++ b/plat/mediatek/drivers/pmic_wrap/pmic_wrap_init_common.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PMIC_WRAP_INIT_COMMON_H +#define PMIC_WRAP_INIT_COMMON_H + +#include <stdint.h> + +#include "platform_def.h" + +/* external API */ +int32_t pwrap_read(uint32_t adr, uint32_t *rdata); +int32_t pwrap_write(uint32_t adr, uint32_t wdata); + +#define GET_WACS_FSM(x) ((x >> 1) & 0x7) + +/* macro for SWINF_FSM */ +#define SWINF_FSM_IDLE (0x00) +#define SWINF_FSM_REQ (0x02) +#define SWINF_FSM_WFDLE (0x04) +#define SWINF_FSM_WFVLDCLR (0x06) +#define SWINF_INIT_DONE (0x01) + +/* timeout setting */ +#define PWRAP_READ_US (1000) +#define PWRAP_WAIT_IDLE_US (1000) + +/* error information flag */ +enum pwrap_errno { + E_PWR_INVALID_ARG = 1, + E_PWR_INVALID_RW = 2, + E_PWR_INVALID_ADDR = 3, + E_PWR_INVALID_WDAT = 4, + E_PWR_INVALID_OP_MANUAL = 5, + E_PWR_NOT_IDLE_STATE = 6, + E_PWR_NOT_INIT_DONE = 7, + E_PWR_NOT_INIT_DONE_READ = 8, + E_PWR_WAIT_IDLE_TIMEOUT = 9, + E_PWR_WAIT_IDLE_TIMEOUT_READ = 10, + E_PWR_INIT_SIDLY_FAIL = 11, + E_PWR_RESET_TIMEOUT = 12, + E_PWR_TIMEOUT = 13, + E_PWR_INIT_RESET_SPI = 20, + E_PWR_INIT_SIDLY = 21, + E_PWR_INIT_REG_CLOCK = 22, + E_PWR_INIT_ENABLE_PMIC = 23, + E_PWR_INIT_DIO = 24, + E_PWR_INIT_CIPHER = 25, + E_PWR_INIT_WRITE_TEST = 26, + E_PWR_INIT_ENABLE_CRC = 27, + E_PWR_INIT_ENABLE_DEWRAP = 28, + E_PWR_INIT_ENABLE_EVENT = 29, + E_PWR_READ_TEST_FAIL = 30, + E_PWR_WRITE_TEST_FAIL = 31, + E_PWR_SWITCH_DIO = 32, +}; + +#endif /* PMIC_WRAP_INIT_COMMON_H */ diff --git a/plat/mediatek/drivers/pmic_wrap/pmic_wrap_init_v2.c b/plat/mediatek/drivers/pmic_wrap/pmic_wrap_init_v2.c new file mode 100644 index 0000000..80f55de --- /dev/null +++ b/plat/mediatek/drivers/pmic_wrap/pmic_wrap_init_v2.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#include <drivers/delay_timer.h> +#include <lib/mmio.h> + +#include "platform_def.h" +#include "pmic_wrap_init.h" + +/* pmic wrap module wait_idle and read polling interval (in microseconds) */ +enum pwrap_polling_interval { + WAIT_IDLE_POLLING_DELAY_US = 1, + READ_POLLING_DELAY_US = 2 +}; + +static uint32_t pwrap_check_idle(void *wacs_register, uint32_t timeout_us) +{ + uint32_t reg_rdata = 0U, retry; + + retry = (timeout_us + WAIT_IDLE_POLLING_DELAY_US) / + WAIT_IDLE_POLLING_DELAY_US; + while (retry != 0) { + udelay(WAIT_IDLE_POLLING_DELAY_US); + reg_rdata = mmio_read_32((uintptr_t)wacs_register); + /* if last read command timeout,clear vldclr bit + * read command state machine:FSM_REQ-->wfdle-->WFVLDCLR; + * write:FSM_REQ-->idle + */ + switch (GET_WACS_FSM(reg_rdata)) { + case SWINF_FSM_WFVLDCLR: + mmio_write_32((uintptr_t)&mtk_pwrap->wacs2_vldclr, 0x1); + INFO("WACS_FSM = SWINF_FSM_WFVLDCLR\n"); + break; + case SWINF_FSM_WFDLE: + INFO("WACS_FSM = SWINF_FSM_WFDLE\n"); + break; + case SWINF_FSM_REQ: + INFO("WACS_FSM = SWINF_FSM_REQ\n"); + break; + case SWINF_FSM_IDLE: + goto done; + default: + break; + } + retry--; + }; + +done: + if (retry == 0) { + /* timeout */ + return E_PWR_WAIT_IDLE_TIMEOUT; + } + + return 0U; +} + +static uint32_t pwrap_check_vldclr(void *wacs_register, uint32_t timeout_us) +{ + uint32_t reg_rdata = 0U, retry; + + retry = (timeout_us + READ_POLLING_DELAY_US) / READ_POLLING_DELAY_US; + while (retry != 0) { + udelay(READ_POLLING_DELAY_US); + reg_rdata = mmio_read_32((uintptr_t)wacs_register); + if (GET_WACS_FSM(reg_rdata) == SWINF_FSM_WFVLDCLR) { + break; + } + retry--; + }; + + if (retry == 0) { + /* timeout */ + return E_PWR_WAIT_IDLE_TIMEOUT; + } + + return 0U; +} + +static int32_t pwrap_wacs2(uint32_t write, uint32_t adr, uint32_t wdata, + uint32_t *rdata, uint32_t init_check) +{ + uint32_t reg_rdata, return_value; + + if (init_check != 0) { + if ((mmio_read_32((uintptr_t)&mtk_pwrap->init_done) & 0x1) == 0) { + ERROR("initialization isn't finished\n"); + return E_PWR_NOT_INIT_DONE; + } + } + + /* Wait for Software Interface FSM state to be IDLE. */ + return_value = pwrap_check_idle(&mtk_pwrap->wacs2_sta, + PWRAP_WAIT_IDLE_US); + if (return_value != 0) { + return return_value; + } + + /* Set the write data */ + if (write == 1) { + /* Set the write data. */ + mmio_write_32((uintptr_t)&mtk_pwrap->wacs2_wdata, wdata); + } + + /* Send the command. */ + mmio_write_32((uintptr_t)&mtk_pwrap->wacs2_cmd, (write << 29) | adr); + + if (write == 0) { + /* + * Wait for Software Interface FSM state to be WFVLDCLR, + * read the data and clear the valid flag. + */ + return_value = pwrap_check_vldclr(&mtk_pwrap->wacs2_sta, + PWRAP_READ_US); + if (return_value != 0) { + return return_value; + } + + if (rdata == NULL) { + return E_PWR_INVALID_ARG; + } + + reg_rdata = mmio_read_32((uintptr_t)&mtk_pwrap->wacs2_rdata); + *rdata = reg_rdata; + mmio_write_32((uintptr_t)&mtk_pwrap->wacs2_vldclr, 0x1); + } + + return return_value; +} + +/* external API for pmic_wrap user */ +int32_t pwrap_read(uint32_t adr, uint32_t *rdata) +{ + return pwrap_wacs2(0, adr, 0, rdata, 1); +} + +int32_t pwrap_write(uint32_t adr, uint32_t wdata) +{ + return pwrap_wacs2(1, adr, wdata, 0, 1); +} diff --git a/plat/mediatek/drivers/pmic_wrap/rules.mk b/plat/mediatek/drivers/pmic_wrap/rules.mk new file mode 100644 index 0000000..9ba44a6 --- /dev/null +++ b/plat/mediatek/drivers/pmic_wrap/rules.mk @@ -0,0 +1,20 @@ +# +# Copyright (c) 2022, MediaTek Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +LOCAL_DIR := $(call GET_LOCAL_DIR) + +MODULE := pmic_wrap + +ifeq (${USE_PMIC_WRAP_INIT_V2}, 1) +LOCAL_SRCS-y += ${LOCAL_DIR}/pmic_wrap_init_v2.c +else +LOCAL_SRCS-y += ${LOCAL_DIR}/pmic_wrap_init.c +endif + +PLAT_INCLUDES += -I${LOCAL_DIR}/ +PLAT_INCLUDES += -I${LOCAL_DIR}/${MTK_SOC} + +$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL))) diff --git a/plat/mediatek/drivers/ptp3/mt8188/ptp3_plat.h b/plat/mediatek/drivers/ptp3/mt8188/ptp3_plat.h new file mode 100644 index 0000000..aa7d7ca --- /dev/null +++ b/plat/mediatek/drivers/ptp3/mt8188/ptp3_plat.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PTP3_PLAT_H +#define PTP3_PLAT_H + +#include <lib/mmio.h> +#include <lib/utils_def.h> +#include <ptp3_common.h> + +/* CPU Info */ +#define NR_PTP3_CFG_CPU U(8) +#define PTP3_CFG_CPU_START_ID_L U(0) +#define PTP3_CFG_CPU_START_ID_B U(6) +#define PTP3_CFG_CPU_END_ID U(7) + +#define NR_PTP3_CFG1_DATA U(2) +#define PTP3_CFG1_MASK (0x3000) + +#define NR_PTP3_CFG2_DATA U(5) + +#define PTP3_CFG3_MASK1 (0x1180) +#define PTP3_CFG3_MASK2 (0x35C0) +#define PTP3_CFG3_MASK3 (0x3DC0) + + +/* Central control */ +static unsigned int ptp3_cfg1[NR_PTP3_CFG1_DATA][NR_PTP3_CFG] = { + {0x0C53A2A0, 0x1000}, + {0x0C53A2A4, 0x1000} +}; + +static unsigned int ptp3_cfg2[NR_PTP3_CFG2_DATA][NR_PTP3_CFG] = { + {0x0C530404, 0x3A1000}, + {0x0C530428, 0x13E0408}, + {0x0C530434, 0xB22800}, + {0x0C53043C, 0x750}, + {0x0C530440, 0x0222c4cc} +}; + +static unsigned int ptp3_cfg3[NR_PTP3_CFG] = {0x0C530400, 0xC00}; +static unsigned int ptp3_cfg3_ext[NR_PTP3_CFG] = {0x0C530400, 0xC00}; + +#endif /* PTP3_PLAT_H */ diff --git a/plat/mediatek/drivers/ptp3/ptp3_common.c b/plat/mediatek/drivers/ptp3/ptp3_common.c new file mode 100644 index 0000000..6846852 --- /dev/null +++ b/plat/mediatek/drivers/ptp3/ptp3_common.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch_helpers.h> +#if MTK_PUBEVENT_ENABLE +#include <lib/pm/mtk_pm.h> +#endif +#include <ptp3_plat.h> + +#define PTP3_CORE_OFT(core) (0x800 * (core)) + +static void ptp3_init(unsigned int core) +{ + unsigned int i, addr, value; + + if (core < PTP3_CFG_CPU_START_ID_B) { + mmio_clrsetbits_32(ptp3_cfg1[0][PTP3_CFG_ADDR], PTP3_CFG1_MASK, + ptp3_cfg1[0][PTP3_CFG_VALUE]); + } else { + mmio_clrsetbits_32(ptp3_cfg1[1][PTP3_CFG_ADDR], PTP3_CFG1_MASK, + ptp3_cfg1[1][PTP3_CFG_VALUE]); + } + + if (core < PTP3_CFG_CPU_START_ID_B) { + for (i = 0; i < NR_PTP3_CFG2_DATA; i++) { + addr = ptp3_cfg2[i][PTP3_CFG_ADDR] + PTP3_CORE_OFT(core); + value = ptp3_cfg2[i][PTP3_CFG_VALUE]; + + mmio_write_32(addr, value); + } + } else { + for (i = 0; i < NR_PTP3_CFG2_DATA; i++) { + addr = ptp3_cfg2[i][PTP3_CFG_ADDR] + PTP3_CORE_OFT(core); + + if (i == 2) { + value = ptp3_cfg2[i][PTP3_CFG_VALUE] + 0x5E0; + } else { + value = ptp3_cfg2[i][PTP3_CFG_VALUE]; + } + mmio_write_32(addr, value); + } + } + + if (core < PTP3_CFG_CPU_START_ID_B) { + addr = ptp3_cfg3[PTP3_CFG_ADDR] + PTP3_CORE_OFT(core); + value = ptp3_cfg3[PTP3_CFG_VALUE]; + } else { + addr = ptp3_cfg3_ext[PTP3_CFG_ADDR] + PTP3_CORE_OFT(core); + value = ptp3_cfg3_ext[PTP3_CFG_VALUE]; + } + mmio_write_32(addr, value & PTP3_CFG3_MASK1); + mmio_write_32(addr, value & PTP3_CFG3_MASK2); + mmio_write_32(addr, value & PTP3_CFG3_MASK3); +} + +static void pdp_proc_arm_write(unsigned int pdp_n) +{ + unsigned long v = 0; + + dsb(); + __asm__ volatile ("mrs %0, S3_6_C15_C2_0" : "=r" (v)); + v |= (UL(0x0) << 52); + v |= (UL(0x1) << 53); + v |= (UL(0x0) << 54); + v |= (UL(0x0) << 48); + v |= (UL(0x1) << 49); + __asm__ volatile ("msr S3_6_C15_C2_0, %0" : : "r" (v)); + dsb(); +} + +static void pdp_init(unsigned int pdp_cpu) +{ + if ((pdp_cpu >= PTP3_CFG_CPU_START_ID_B) && (pdp_cpu < NR_PTP3_CFG_CPU)) { + pdp_proc_arm_write(pdp_cpu); + } +} + +void ptp3_core_init(unsigned int core) +{ + ptp3_init(core); + pdp_init(core); +} + +void ptp3_core_deinit(unsigned int core) +{ + /* TBD */ +} + +#if MTK_PUBEVENT_ENABLE +/* Handle for power on domain */ +void *ptp3_handle_pwr_on_event(const void *arg) +{ + if (arg != NULL) { + struct mt_cpupm_event_data *data = (struct mt_cpupm_event_data *)arg; + + if ((data->pwr_domain & MT_CPUPM_PWR_DOMAIN_CORE) > 0) { + ptp3_core_init(data->cpuid); + } + } + return (void *)arg; +} +MT_CPUPM_SUBCRIBE_EVENT_PWR_ON(ptp3_handle_pwr_on_event); + +/* Handle for power off domain */ +void *ptp3_handle_pwr_off_event(const void *arg) +{ + if (arg != NULL) { + struct mt_cpupm_event_data *data = (struct mt_cpupm_event_data *)arg; + + if ((data->pwr_domain & MT_CPUPM_PWR_DOMAIN_CORE) > 0) { + ptp3_core_deinit(data->cpuid); + } + } + return (void *)arg; +} +MT_CPUPM_SUBCRIBE_EVENT_PWR_OFF(ptp3_handle_pwr_off_event); +#else +#pragma message "PSCI hint not enable" +#endif diff --git a/plat/mediatek/drivers/ptp3/ptp3_common.h b/plat/mediatek/drivers/ptp3/ptp3_common.h new file mode 100644 index 0000000..83ce62b --- /dev/null +++ b/plat/mediatek/drivers/ptp3/ptp3_common.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PTP3_COMMON_H +#define PTP3_COMMON_H + +/* config enum */ +enum PTP3_CFG { + PTP3_CFG_ADDR, + PTP3_CFG_VALUE, + NR_PTP3_CFG, +}; + +/* prototype */ +void ptp3_core_init(unsigned int core); +void ptp3_core_deinit(unsigned int core); + +#endif /* PTP3_COMMON_H */ diff --git a/plat/mediatek/drivers/ptp3/rules.mk b/plat/mediatek/drivers/ptp3/rules.mk new file mode 100644 index 0000000..81d79d2 --- /dev/null +++ b/plat/mediatek/drivers/ptp3/rules.mk @@ -0,0 +1,16 @@ +# +# Copyright (c) 2022, MediaTek Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +LOCAL_DIR := $(call GET_LOCAL_DIR) + +MODULE := mtk_ptp3 + +LOCAL_SRCS-y := ${LOCAL_DIR}/ptp3_common.c + +PLAT_INCLUDES += -I${LOCAL_DIR} +PLAT_INCLUDES += -I${LOCAL_DIR}/$(MTK_SOC) + +$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL))) diff --git a/plat/mediatek/drivers/rtc/mt8188/rtc.h b/plat/mediatek/drivers/rtc/mt8188/rtc.h new file mode 100644 index 0000000..734e89f --- /dev/null +++ b/plat/mediatek/drivers/rtc/mt8188/rtc.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RTC_H +#define RTC_H + +#include <rtc_mt6359p.h> + +#endif /* RTC_H */ diff --git a/plat/mediatek/drivers/rtc/rtc_common.c b/plat/mediatek/drivers/rtc/rtc_common.c new file mode 100644 index 0000000..4efddff --- /dev/null +++ b/plat/mediatek/drivers/rtc/rtc_common.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2019-2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#include <drivers/delay_timer.h> + +#include <pmic_wrap_init.h> +#include <rtc.h> + +/* RTC busy status polling interval and retry count */ +enum { + RTC_WRTGR_POLLING_DELAY_MS = 10, + RTC_WRTGR_POLLING_CNT = 100 +}; + +uint16_t RTC_Read(uint32_t addr) +{ + uint32_t rdata = 0; + + pwrap_read((uint32_t)addr, &rdata); + return (uint16_t)rdata; +} + +void RTC_Write(uint32_t addr, uint16_t data) +{ + pwrap_write((uint32_t)addr, (uint32_t)data); +} + +int32_t rtc_busy_wait(void) +{ + uint64_t retry = RTC_WRTGR_POLLING_CNT; + + do { + mdelay(RTC_WRTGR_POLLING_DELAY_MS); + if (!(RTC_Read(RTC_BBPU) & RTC_BBPU_CBUSY)) + return 1; + retry--; + } while (retry); + + ERROR("[RTC] rtc cbusy time out!\n"); + return 0; +} + +int32_t RTC_Write_Trigger(void) +{ + RTC_Write(RTC_WRTGR, 1); + return rtc_busy_wait(); +} + +int32_t Writeif_unlock(void) +{ + RTC_Write(RTC_PROT, RTC_PROT_UNLOCK1); + if (!RTC_Write_Trigger()) + return 0; + RTC_Write(RTC_PROT, RTC_PROT_UNLOCK2); + if (!RTC_Write_Trigger()) + return 0; + + return 1; +} + diff --git a/plat/mediatek/drivers/rtc/rtc_mt6359p.c b/plat/mediatek/drivers/rtc/rtc_mt6359p.c new file mode 100644 index 0000000..3bf4337 --- /dev/null +++ b/plat/mediatek/drivers/rtc/rtc_mt6359p.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#include <drivers/delay_timer.h> +#include <rtc.h> + + +static void RTC_Config_Interface(uint32_t addr, uint16_t data, + uint16_t mask, uint16_t shift) +{ + uint16_t pmic_reg; + + pmic_reg = RTC_Read(addr); + + pmic_reg &= ~(mask << shift); + pmic_reg |= (data << shift); + + RTC_Write(addr, pmic_reg); +} + +static int32_t rtc_disable_2sec_reboot(void) +{ + uint16_t reboot; + + reboot = (RTC_Read(RTC_AL_SEC) & ~RTC_BBPU_2SEC_EN) & + ~RTC_BBPU_AUTO_PDN_SEL; + RTC_Write(RTC_AL_SEC, reboot); + + return RTC_Write_Trigger(); +} + +static int32_t rtc_enable_k_eosc(void) +{ + uint16_t alm_dow, alm_sec; + int16_t ret; + + /* Turning on eosc cali mode clock */ + RTC_Config_Interface(PMIC_RG_SCK_TOP_CKPDN_CON0_CLR, 1, + PMIC_RG_RTC_EOSC32_CK_PDN_MASK, + PMIC_RG_RTC_EOSC32_CK_PDN_SHIFT); + + alm_sec = RTC_Read(RTC_AL_SEC) & (~RTC_LPD_OPT_MASK); + RTC_Write(RTC_AL_SEC, alm_sec); + ret = RTC_Write_Trigger(); + if (ret == 0) { + return 0; + } + + RTC_Write(RTC_CON, RTC_LPD_EN); + ret = RTC_Write_Trigger(); + if (ret == 0) { + return 0; + } + + RTC_Write(RTC_CON, RTC_LPD_RST); + ret = RTC_Write_Trigger(); + if (ret == 0) { + return 0; + } + + RTC_Write(RTC_CON, RTC_LPD_EN); + ret = RTC_Write_Trigger(); + if (ret == 0) { + return 0; + } + + RTC_Write(RTC_POWERKEY1, RTC_POWERKEY1_KEY); + RTC_Write(RTC_POWERKEY2, RTC_POWERKEY2_KEY); + ret = RTC_Write_Trigger(); + if (ret == 0) { + return 0; + } + + /* set RTC EOSC calibration period = 8sec */ + alm_dow = (RTC_Read(RTC_AL_DOW) & (~RTC_RG_EOSC_CALI_TD_MASK)) | + RTC_RG_EOSC_CALI_TD_8SEC; + RTC_Write(RTC_AL_DOW, alm_dow); + ret = RTC_Write_Trigger(); + if (ret == 0) { + return 0; + } + + RTC_Write(RTC_BBPU, + RTC_Read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_RELOAD); + ret = RTC_Write_Trigger(); + if (ret == 0) { + return 0; + } + + /* Enable K EOSC mode :use solution1 of eosc cali to fix mt6359p 32K*/ + RTC_Write(RTC_AL_YEA, (((RTC_Read(RTC_AL_YEA) | RTC_K_EOSC_RSV_0) + & (~RTC_K_EOSC_RSV_1)) | (RTC_K_EOSC_RSV_2))); + ret = RTC_Write_Trigger(); + if (ret == 0) { + return 0; + } + + INFO("[RTC] RTC_enable_k_eosc\n"); + + return 1; +} + +void rtc_power_off_sequence(void) +{ + uint16_t bbpu; + int16_t ret; + + ret = rtc_disable_2sec_reboot(); + if (ret == 0) { + return; + } + + ret = rtc_enable_k_eosc(); + if (ret == 0) { + return; + } + + bbpu = RTC_BBPU_KEY | RTC_BBPU_PWREN; + + if (Writeif_unlock() != 0) { + RTC_Write(RTC_BBPU, + bbpu | RTC_BBPU_RESET_ALARM | RTC_BBPU_RESET_SPAR); + RTC_Write(RTC_AL_MASK, RTC_AL_MASK_DOW); + ret = RTC_Write_Trigger(); + if (ret == 0) { + return; + } + mdelay(1); + + bbpu = RTC_Read(RTC_BBPU); + + if (((bbpu & RTC_BBPU_RESET_ALARM) > 0) || + ((bbpu & RTC_BBPU_RESET_SPAR) > 0)) { + INFO("[RTC] timeout\n"); + } + + bbpu = RTC_Read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_RELOAD; + RTC_Write(RTC_BBPU, bbpu); + ret = RTC_Write_Trigger(); + if (ret == 0) { + return; + } + } +} diff --git a/plat/mediatek/drivers/rtc/rtc_mt6359p.h b/plat/mediatek/drivers/rtc/rtc_mt6359p.h new file mode 100644 index 0000000..199f152 --- /dev/null +++ b/plat/mediatek/drivers/rtc/rtc_mt6359p.h @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RTC_MT6359P_H +#define RTC_MT6359P_H + +/* RTC registers */ +enum { + RTC_BBPU = 0x0588, + RTC_IRQ_STA = 0x058A, + RTC_IRQ_EN = 0x058C, + RTC_CII_EN = 0x058E +}; + +enum { + RTC_AL_SEC = 0x05A0, + RTC_AL_MIN = 0x05A2, + RTC_AL_HOU = 0x05A4, + RTC_AL_DOM = 0x05A6, + RTC_AL_DOW = 0x05A8, + RTC_AL_MTH = 0x05AA, + RTC_AL_YEA = 0x05AC, + RTC_AL_MASK = 0x0590 +}; + +enum { + RTC_OSC32CON = 0x05AE, + RTC_CON = 0x05C4, + RTC_WRTGR = 0x05C2 +}; + +enum { + RTC_POWERKEY1 = 0x05B0, + RTC_POWERKEY2 = 0x05B2 +}; + +enum { + RTC_POWERKEY1_KEY = 0xA357, + RTC_POWERKEY2_KEY = 0x67D2 +}; + +enum { + RTC_PDN1 = 0x05B4, + RTC_PDN2 = 0x05B6, + RTC_SPAR0 = 0x05B8, + RTC_SPAR1 = 0x05BA, + RTC_PROT = 0x05BC, + RTC_DIFF = 0x05BE, + RTC_CALI = 0x05C0 +}; + +enum { + RTC_OSC32CON_UNLOCK1 = 0x1A57, + RTC_OSC32CON_UNLOCK2 = 0x2B68 +}; + +enum { + RTC_LPD_EN = 0x0406, + RTC_LPD_RST = 0x040E +}; + +enum { + RTC_LPD_OPT_XOSC_AND_EOSC_LPD = 0U << 13, + RTC_LPD_OPT_EOSC_LPD = 1U << 13, + RTC_LPD_OPT_XOSC_LPD = 2U << 13, + RTC_LPD_OPT_F32K_CK_ALIVE = 3U << 13, +}; + +#define RTC_LPD_OPT_MASK (3U << 13) + +enum { + RTC_PROT_UNLOCK1 = 0x586A, + RTC_PROT_UNLOCK2 = 0x9136 +}; + +enum { + RTC_BBPU_PWREN = 1U << 0, + RTC_BBPU_SPAR_SW = 1U << 1, + RTC_BBPU_RESET_SPAR = 1U << 2, + RTC_BBPU_RESET_ALARM = 1U << 3, + RTC_BBPU_CLRPKY = 1U << 4, + RTC_BBPU_RELOAD = 1U << 5, + RTC_BBPU_CBUSY = 1U << 6 +}; + +enum { + RTC_AL_MASK_SEC = 1U << 0, + RTC_AL_MASK_MIN = 1U << 1, + RTC_AL_MASK_HOU = 1U << 2, + RTC_AL_MASK_DOM = 1U << 3, + RTC_AL_MASK_DOW = 1U << 4, + RTC_AL_MASK_MTH = 1U << 5, + RTC_AL_MASK_YEA = 1U << 6 +}; + +enum { + RTC_BBPU_AUTO_PDN_SEL = 1U << 6, + RTC_BBPU_2SEC_CK_SEL = 1U << 7, + RTC_BBPU_2SEC_EN = 1U << 8, + RTC_BBPU_2SEC_MODE = 0x3 << 9, + RTC_BBPU_2SEC_STAT_CLEAR = 1U << 11, + RTC_BBPU_2SEC_STAT_STA = 1U << 12 +}; + +enum { + RTC_BBPU_KEY = 0x43 << 8 +}; + +enum { + RTC_EMBCK_SRC_SEL = 1 << 8, + RTC_EMBCK_SEL_MODE = 3 << 6, + RTC_XOSC32_ENB = 1 << 5, + RTC_REG_XOSC32_ENB = 1 << 15 +}; + +enum { + RTC_K_EOSC_RSV_0 = 1 << 8, + RTC_K_EOSC_RSV_1 = 1 << 9, + RTC_K_EOSC_RSV_2 = 1 << 10 +}; + +enum { + RTC_RG_EOSC_CALI_TD_1SEC = 3 << 5, + RTC_RG_EOSC_CALI_TD_2SEC = 4 << 5, + RTC_RG_EOSC_CALI_TD_4SEC = 5 << 5, + RTC_RG_EOSC_CALI_TD_8SEC = 6 << 5, + RTC_RG_EOSC_CALI_TD_16SEC = 7 << 5, + RTC_RG_EOSC_CALI_TD_MASK = 7 << 5 +}; + +/* PMIC TOP Register Definition */ +enum { + PMIC_RG_TOP_CON = 0x0020, + PMIC_RG_TOP_CKPDN_CON1 = 0x0112, + PMIC_RG_TOP_CKPDN_CON1_SET = 0x0114, + PMIC_RG_TOP_CKPDN_CON1_CLR = 0x0116, + PMIC_RG_TOP_CKSEL_CON0 = 0x0118, + PMIC_RG_TOP_CKSEL_CON0_SET = 0x011A, + PMIC_RG_TOP_CKSEL_CON0_CLR = 0x011C +}; + +/* PMIC SCK Register Definition */ +enum { + PMIC_RG_SCK_TOP_CKPDN_CON0 = 0x0514, + PMIC_RG_SCK_TOP_CKPDN_CON0_SET = 0x0516, + PMIC_RG_SCK_TOP_CKPDN_CON0_CLR = 0x0518, + PMIC_RG_EOSC_CALI_CON0 = 0x53A +}; + +enum { + PMIC_EOSC_CALI_START_ADDR = 0x53A +}; + +enum { + PMIC_EOSC_CALI_START_MASK = 0x1, + PMIC_EOSC_CALI_START_SHIFT = 0 +}; + +/* PMIC DCXO Register Definition */ +enum { + PMIC_RG_DCXO_CW00 = 0x0788, + PMIC_RG_DCXO_CW02 = 0x0790, + PMIC_RG_DCXO_CW08 = 0x079C, + PMIC_RG_DCXO_CW09 = 0x079E, + PMIC_RG_DCXO_CW09_CLR = 0x07A2, + PMIC_RG_DCXO_CW10 = 0x07A4, + PMIC_RG_DCXO_CW12 = 0x07A8, + PMIC_RG_DCXO_CW13 = 0x07AA, + PMIC_RG_DCXO_CW15 = 0x07AE, + PMIC_RG_DCXO_CW19 = 0x07B6, +}; + +enum { + PMIC_RG_SRCLKEN_IN0_HW_MODE_MASK = 0x1, + PMIC_RG_SRCLKEN_IN0_HW_MODE_SHIFT = 1, + PMIC_RG_SRCLKEN_IN1_HW_MODE_MASK = 0x1, + PMIC_RG_SRCLKEN_IN1_HW_MODE_SHIFT = 3, + PMIC_RG_RTC_EOSC32_CK_PDN_MASK = 0x1, + PMIC_RG_RTC_EOSC32_CK_PDN_SHIFT = 2, + PMIC_RG_EOSC_CALI_TD_MASK = 0x7, + PMIC_RG_EOSC_CALI_TD_SHIFT = 5, + PMIC_RG_XO_EN32K_MAN_MASK = 0x1, + PMIC_RG_XO_EN32K_MAN_SHIFT = 0 +}; + +/* external API */ +uint16_t RTC_Read(uint32_t addr); +void RTC_Write(uint32_t addr, uint16_t data); +int32_t rtc_busy_wait(void); +int32_t RTC_Write_Trigger(void); +int32_t Writeif_unlock(void); +void rtc_power_off_sequence(void); + +#endif /* RTC_MT6359P_H */ diff --git a/plat/mediatek/drivers/rtc/rules.mk b/plat/mediatek/drivers/rtc/rules.mk new file mode 100644 index 0000000..2398f8a --- /dev/null +++ b/plat/mediatek/drivers/rtc/rules.mk @@ -0,0 +1,20 @@ +# +# Copyright (c) 2022, MediaTek Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +LOCAL_DIR := $(call GET_LOCAL_DIR) + +MODULE := rtc + +LOCAL_SRCS-y := ${LOCAL_DIR}/rtc_common.c + +ifeq (${USE_RTC_MT6359P}, 1) +LOCAL_SRCS-y += ${LOCAL_DIR}/rtc_mt6359p.c +PLAT_INCLUDES += -I${LOCAL_DIR} +endif + +PLAT_INCLUDES += -I${LOCAL_DIR}/${MTK_SOC} + +$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL))) diff --git a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_api.c b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_api.c new file mode 100644 index 0000000..257caa3 --- /dev/null +++ b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_api.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <lpm/mt_lpm_smc.h> +#include <mt_spm.h> +#include "mt_spm_rc_api.h" +#include "mt_spm_rc_internal.h" + +int spm_rc_condition_modifier(unsigned int id, unsigned int act, + const void *val, + enum mt_spm_rm_rc_type dest_rc_id, + struct mt_spm_cond_tables * const tlb) +{ + unsigned int rc_id, cond_id, cond; + int res = 0; + + spin_lock(&spm_lock); + rc_id = SPM_RC_UPDATE_COND_RC_ID_GET(id); + cond_id = SPM_RC_UPDATE_COND_ID_GET(id); + + do { + if ((dest_rc_id != rc_id) || (val == NULL) || (tlb == NULL)) { + res = -1; + break; + } + + cond = *((unsigned int *)val); + + if (cond_id < PLAT_SPM_COND_MAX) { + if ((act & MT_LPM_SMC_ACT_SET) > 0U) { + SPM_RC_BITS_SET(tlb->table_cg[cond_id], cond); + } else if ((act & MT_LPM_SMC_ACT_CLR) > 0U) { + SPM_RC_BITS_CLR(tlb->table_cg[cond_id], cond); + } else { + res = -1; + } + } else if ((cond_id - PLAT_SPM_COND_MAX) < PLAT_SPM_COND_PLL_MAX) { + unsigned int pll_idx = cond_id - PLAT_SPM_COND_MAX; + + cond = !!cond; + if ((act & MT_LPM_SMC_ACT_SET) > 0U) { + SPM_RC_BITS_SET(tlb->table_pll, (cond << pll_idx)); + } else if ((act & MT_LPM_SMC_ACT_CLR) > 0U) { + SPM_RC_BITS_CLR(tlb->table_pll, (cond << pll_idx)); + } else { + res = -1; + } + } else { + res = -1; + } + } while (0); + + spin_unlock(&spm_lock); + + return res; +} + +int spm_rc_constraint_status_get(unsigned int id, unsigned int type, + unsigned int act, + enum mt_spm_rm_rc_type dest_rc_id, + struct constraint_status * const src, + struct constraint_status * const dest) +{ + if (((id != MT_RM_CONSTRAINT_ID_ALL) && (id != dest_rc_id)) || (dest == NULL) || + (src == NULL)) { + return -1; + } + spin_lock(&spm_lock); + + switch (type) { + case CONSTRAINT_GET_ENTER_CNT: + if (id == MT_RM_CONSTRAINT_ID_ALL) { + dest->enter_cnt += src->enter_cnt; + } else { + dest->enter_cnt = src->enter_cnt; + } + break; + case CONSTRAINT_GET_VALID: + dest->is_valid = src->is_valid; + break; + case CONSTRAINT_COND_BLOCK: + dest->is_cond_block = src->is_cond_block; + dest->all_pll_dump = src->all_pll_dump; + break; + case CONSTRAINT_GET_COND_BLOCK_DETAIL: + dest->cond_res = src->cond_res; + break; + case CONSTRAINT_GET_RESIDNECY: + dest->residency = src->residency; + if (act & MT_LPM_SMC_ACT_CLR) { + src->residency = 0; + } + break; + default: + break; + } + + spin_unlock(&spm_lock); + return 0; +} + +int spm_rc_constraint_status_set(unsigned int id, unsigned int type, + unsigned int act, + enum mt_spm_rm_rc_type dest_rc_id, + struct constraint_status * const src, + struct constraint_status * const dest) +{ + if (((id != MT_RM_CONSTRAINT_ID_ALL) && (id != dest_rc_id)) || (dest == NULL)) { + return -1; + } + + spin_lock(&spm_lock); + + switch (type) { + case CONSTRAINT_UPDATE_VALID: + if (src != NULL) { + if ((act & MT_LPM_SMC_ACT_SET) > 0U) { + SPM_RC_BITS_SET(dest->is_valid, src->is_valid); + } else if ((act & MT_LPM_SMC_ACT_CLR) > 0U) { + SPM_RC_BITS_CLR(dest->is_valid, src->is_valid); + } + } + break; + case CONSTRAINT_RESIDNECY: + if (act & MT_LPM_SMC_ACT_CLR) { + dest->residency = 0; + } + break; + default: + break; + } + + spin_unlock(&spm_lock); + + return 0; +} + +int spm_rc_constraint_valid_set(enum mt_spm_rm_rc_type id, + enum mt_spm_rm_rc_type dest_rc_id, + unsigned int valid, + struct constraint_status * const dest) +{ + if (((id != MT_RM_CONSTRAINT_ID_ALL) && (id != dest_rc_id)) || (dest == NULL)) { + return -1; + } + + spin_lock(&spm_lock); + SPM_RC_BITS_SET(dest->is_valid, valid); + spin_unlock(&spm_lock); + + return 0; +} + +int spm_rc_constraint_valid_clr(enum mt_spm_rm_rc_type id, + enum mt_spm_rm_rc_type dest_rc_id, + unsigned int valid, + struct constraint_status * const dest) +{ + if (((id != MT_RM_CONSTRAINT_ID_ALL) && (id != dest_rc_id)) || (dest == NULL)) { + return -1; + } + + spin_lock(&spm_lock); + SPM_RC_BITS_CLR(dest->is_valid, valid); + spin_unlock(&spm_lock); + + return 0; +} diff --git a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_api.h b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_api.h new file mode 100644 index 0000000..0736ca3 --- /dev/null +++ b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_api.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_SPM_RC_API_H +#define MT_SPM_RC_API_H + +#include <mt_spm.h> +#include <mt_spm_cond.h> +#include <mt_spm_constraint.h> +#include <mt_spm_internal.h> + +#define SPM_RC_BITS_SET(dest, src) ({ (dest) |= (src); }) +#define SPM_RC_BITS_CLR(dest, src) ({ (dest) &= (~src); }) + +int spm_rc_condition_modifier(unsigned int id, unsigned int act, + const void *val, + enum mt_spm_rm_rc_type dest_rc_id, + struct mt_spm_cond_tables * const tlb); + +int spm_rc_constraint_status_get(unsigned int id, unsigned int type, + unsigned int act, + enum mt_spm_rm_rc_type dest_rc_id, + struct constraint_status * const src, + struct constraint_status * const dest); + +int spm_rc_constraint_status_set(unsigned int id, unsigned int type, + unsigned int act, + enum mt_spm_rm_rc_type dest_rc_id, + struct constraint_status * const src, + struct constraint_status * const dest); + +int spm_rc_constraint_valid_set(enum mt_spm_rm_rc_type id, + enum mt_spm_rm_rc_type dest_rc_id, + unsigned int valid, + struct constraint_status * const dest); + +int spm_rc_constraint_valid_clr(enum mt_spm_rm_rc_type id, + enum mt_spm_rm_rc_type dest_rc_id, + unsigned int valid, + struct constraint_status * const dest); + +#endif diff --git a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_bus26m.c b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_bus26m.c new file mode 100644 index 0000000..c8a2d4c --- /dev/null +++ b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_bus26m.c @@ -0,0 +1,398 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#ifndef MTK_PLAT_CIRQ_UNSUPPORT +#include <mtk_cirq.h> +#endif +#include <drivers/spm/mt_spm_resource_req.h> +#include <lib/pm/mtk_pm.h> +#include <lpm/mt_lp_rm.h> +#include <mt_spm.h> +#include <mt_spm_cond.h> +#include <mt_spm_conservation.h> +#include <mt_spm_constraint.h> +#include <mt_spm_idle.h> +#include <mt_spm_internal.h> +#include <mt_spm_notifier.h> +#include "mt_spm_rc_api.h" +#include "mt_spm_rc_internal.h" +#include <mt_spm_reg.h> +#include <mt_spm_suspend.h> + +#define CONSTRAINT_BUS26M_ALLOW (MT_RM_CONSTRAINT_ALLOW_CPU_BUCK_OFF | \ + MT_RM_CONSTRAINT_ALLOW_DRAM_S0 | \ + MT_RM_CONSTRAINT_ALLOW_DRAM_S1 | \ + MT_RM_CONSTRAINT_ALLOW_VCORE_LP | \ + MT_RM_CONSTRAINT_ALLOW_LVTS_STATE | \ + MT_RM_CONSTRAINT_ALLOW_BUS26M_OFF) + +#define CONSTRAINT_BUS26M_PCM_FLAG (SPM_FLAG_DISABLE_INFRA_PDN | \ + SPM_FLAG_DISABLE_VCORE_DVS | \ + SPM_FLAG_DISABLE_VCORE_DFS | \ + SPM_FLAG_SRAM_SLEEP_CTRL | \ + SPM_FLAG_ENABLE_LVTS_WORKAROUND | \ + SPM_FLAG_KEEP_CSYSPWRACK_HIGH | \ + SPM_FLAG_DISABLE_DRAMC_MCU_SRAM_SLEEP) + +#define CONSTRAINT_BUS26M_PCM_FLAG1 (SPM_FLAG1_DISABLE_PWRAP_CLK_SWITCH) + +/* If sspm sram won't enter sleep voltage then vcore couldn't enter low power mode */ +#if defined(MTK_PLAT_SPM_SRAM_SLP_UNSUPPORT) && SPM_SRAM_SLEEP_RC_RES_RESTRICT +#define CONSTRAINT_BUS26M_RESOURCE_REQ (MT_SPM_26M) +#else +#define CONSTRAINT_BUS26M_RESOURCE_REQ (0) +#endif + +static unsigned int bus26m_ext_opand; +static unsigned int bus26m_ext_opand2; + +static struct mt_irqremain *refer2remain_irq; + +static struct mt_spm_cond_tables cond_bus26m = { + .name = "bus26m", + .table_cg = { + 0xFF5DD002, /* MTCMOS1 */ + 0x0000003C, /* MTCMOS2 */ + 0x27AF8000, /* INFRA0 */ + 0x22010876, /* INFRA1 */ + 0x86000650, /* INFRA2 */ + 0x30008020, /* INFRA3 */ + 0x80000000, /* INFRA4 */ + 0x01002A3B, /* PERI0 */ + 0x00090000, /* VPPSYS0_0 */ + 0x38FF3E69, /* VPPSYS0_1 */ + 0xF0081450, /* VPPSYS1_0 */ + 0x00003000, /* VPPSYS1_1 */ + 0x00000000, /* VDOSYS0_0 */ + 0x00000000, /* VDOSYS0_1 */ + 0x000001FF, /* VDOSYS1_0 */ + 0x000001E0, /* VDOSYS1_1 */ + 0x00FB0007, /* VDOSYS1_2 */ + }, + .table_pll = (PLL_BIT_UNIVPLL | + PLL_BIT_MFGPLL | + PLL_BIT_MSDCPLL | + PLL_BIT_TVDPLL1 | + PLL_BIT_TVDPLL2 | + PLL_BIT_MMPLL | + PLL_BIT_ETHPLL | + PLL_BIT_IMGPLL | + PLL_BIT_APLL1 | + PLL_BIT_APLL2 | + PLL_BIT_APLL3 | + PLL_BIT_APLL4 | + PLL_BIT_APLL5), +}; + +static struct mt_spm_cond_tables cond_bus26m_res = { + .table_cg = { 0U }, + .table_pll = 0U, +}; + +static struct constraint_status status = { + .id = MT_RM_CONSTRAINT_ID_BUS26M, + .is_valid = (MT_SPM_RC_VALID_SW | + MT_SPM_RC_VALID_COND_CHECK | + MT_SPM_RC_VALID_COND_LATCH | + MT_SPM_RC_VALID_TRACE_TIME), + .is_cond_block = 0U, + .enter_cnt = 0U, + .all_pll_dump = 0U, + .cond_res = &cond_bus26m_res, + .residency = 0ULL, +}; + +#ifdef MTK_PLAT_CIRQ_UNSUPPORT +#define do_irqs_delivery() +#else +static void mt_spm_irq_remain_dump(struct mt_irqremain *irqs, + unsigned int irq_index, + struct wake_status *wakeup) +{ + if ((irqs == NULL) || (wakeup == NULL)) { + return; + } + + INFO("[SPM] r12=0x%08x(0x%08x), flag=0x%08x 0x%08x 0x%08x, irq:%u(0x%08x) set pending\n", + wakeup->tr.comm.r12, + wakeup->md32pcm_wakeup_sta, + wakeup->tr.comm.debug_flag, + wakeup->tr.comm.b_sw_flag0, + wakeup->tr.comm.b_sw_flag1, + irqs->wakeupsrc[irq_index], + irqs->irqs[irq_index]); +} + +static void do_irqs_delivery(void) +{ + unsigned int idx; + struct wake_status *wakeup = NULL; + struct mt_irqremain *irqs = refer2remain_irq; + + if (irqs == NULL) { + return; + } + + if (spm_conservation_get_result(&wakeup) == 0) { + if (wakeup != NULL) { + for (idx = 0; idx < irqs->count; idx++) { + if (((wakeup->tr.comm.r12 & irqs->wakeupsrc[idx]) != 0U) || + ((wakeup->tr.comm.raw_sta & irqs->wakeupsrc[idx]) != 0U)) { + if ((irqs->wakeupsrc_cat[idx] & + MT_IRQ_REMAIN_CAT_LOG) != 0U) { + mt_spm_irq_remain_dump(irqs, idx, wakeup); + } + mt_irq_set_pending(irqs->irqs[idx]); + } + } + } + } +} +#endif + +int spm_bus26m_conduct(int state_id, struct spm_lp_scen *spm_lp, unsigned int *resource_req) +{ + unsigned int res_req = CONSTRAINT_BUS26M_RESOURCE_REQ; + + if ((spm_lp == NULL) || (resource_req == NULL)) { + return -1; + } + + spm_lp->pwrctrl->pcm_flags = (uint32_t)CONSTRAINT_BUS26M_PCM_FLAG; + spm_lp->pwrctrl->pcm_flags1 = (uint32_t)CONSTRAINT_BUS26M_PCM_FLAG1; + + *resource_req |= res_req; + return 0; +} + +bool spm_is_valid_rc_bus26m(unsigned int cpu, int state_id) +{ + return (!(status.is_cond_block && (status.is_valid & MT_SPM_RC_VALID_COND_CHECK) > 0) && + IS_MT_RM_RC_READY(status.is_valid) && + (IS_PLAT_SUSPEND_ID(state_id) || (state_id == MT_PLAT_PWR_STATE_SYSTEM_BUS))); +} + +static int update_rc_condition(int state_id, const void *val) +{ + const struct mt_spm_cond_tables *tlb = (const struct mt_spm_cond_tables *)val; + const struct mt_spm_cond_tables *tlb_check = + (const struct mt_spm_cond_tables *)&cond_bus26m; + + if (tlb == NULL) { + return MT_RM_STATUS_BAD; + } + + status.is_cond_block = mt_spm_cond_check(state_id, tlb, tlb_check, + (status.is_valid & MT_SPM_RC_VALID_COND_LATCH) ? + &cond_bus26m_res : NULL); + status.all_pll_dump = mt_spm_dump_all_pll(tlb, tlb_check, + (status.is_valid & MT_SPM_RC_VALID_COND_LATCH) ? + &cond_bus26m_res : NULL); + return MT_RM_STATUS_OK; +} + +static void update_rc_remain_irqs(const void *val) +{ + refer2remain_irq = (struct mt_irqremain *)val; +} + +static void update_rc_fmaudio_adsp(int type, const void *val) +{ + int *flag = (int *)val; + unsigned int ext_op = (type == PLAT_RC_IS_ADSP) ? + (MT_SPM_EX_OP_SET_IS_ADSP | MT_SPM_EX_OP_SET_SUSPEND_MODE) : + MT_SPM_EX_OP_SET_SUSPEND_MODE; + + if (flag == NULL) { + return; + } + + if (*flag != 0) { + SPM_RC_BITS_SET(bus26m_ext_opand, ext_op); + } else { + SPM_RC_BITS_CLR(bus26m_ext_opand, ext_op); + } +} + +static void update_rc_usb_peri(const void *val) +{ + int *flag = (int *)val; + + if (flag == NULL) { + return; + } + + if (*flag != 0) { + SPM_RC_BITS_SET(bus26m_ext_opand2, MT_SPM_EX_OP_PERI_ON); + } else { + SPM_RC_BITS_CLR(bus26m_ext_opand2, MT_SPM_EX_OP_PERI_ON); + } +} + +static void update_rc_usb_infra(const void *val) +{ + int *flag = (int *)val; + + if (flag == NULL) { + return; + } + + if (*flag != 0) { + SPM_RC_BITS_SET(bus26m_ext_opand2, MT_SPM_EX_OP_INFRA_ON); + } else { + SPM_RC_BITS_CLR(bus26m_ext_opand2, MT_SPM_EX_OP_INFRA_ON); + } +} + +static void update_rc_status(const void *val) +{ + const struct rc_common_state *st; + + st = (const struct rc_common_state *)val; + + if (st == NULL) { + return; + } + + if (st->type == CONSTRAINT_UPDATE_COND_CHECK) { + struct mt_spm_cond_tables * const tlb = &cond_bus26m; + + spm_rc_condition_modifier(st->id, st->act, st->value, + MT_RM_CONSTRAINT_ID_BUS26M, tlb); + } else if ((st->type == CONSTRAINT_UPDATE_VALID) || + (st->type == CONSTRAINT_RESIDNECY)) { + spm_rc_constraint_status_set(st->id, st->type, st->act, + MT_RM_CONSTRAINT_ID_BUS26M, + (struct constraint_status * const)st->value, + (struct constraint_status * const)&status); + } else { + INFO("[%s:%d] - Unknown type: 0x%x\n", __func__, __LINE__, st->type); + } +} + +int spm_update_rc_bus26m(int state_id, int type, const void *val) +{ + int res = MT_RM_STATUS_OK; + + switch (type) { + case PLAT_RC_UPDATE_CONDITION: + res = update_rc_condition(state_id, val); + break; + case PLAT_RC_UPDATE_REMAIN_IRQS: + update_rc_remain_irqs(val); + break; + case PLAT_RC_IS_FMAUDIO: + case PLAT_RC_IS_ADSP: + update_rc_fmaudio_adsp(type, val); + break; + case PLAT_RC_IS_USB_PERI: + update_rc_usb_peri(val); + break; + case PLAT_RC_IS_USB_INFRA: + update_rc_usb_infra(val); + break; + case PLAT_RC_STATUS: + update_rc_status(val); + break; + default: + INFO("[%s:%d] - Do nothing for type: %d\n", __func__, __LINE__, type); + break; + } + return res; +} + +unsigned int spm_allow_rc_bus26m(int state_id) +{ + return CONSTRAINT_BUS26M_ALLOW; +} + +int spm_run_rc_bus26m(unsigned int cpu, int state_id) +{ + unsigned int ext_op = MT_SPM_EX_OP_HW_S1_DETECT; + +#ifndef MTK_PLAT_SPM_SSPM_NOTIFIER_UNSUPPORT + mt_spm_sspm_notify_u32(MT_SPM_NOTIFY_LP_ENTER, CONSTRAINT_BUS26M_ALLOW | + (IS_PLAT_SUSPEND_ID(state_id) ? + MT_RM_CONSTRAINT_ALLOW_AP_SUSPEND : 0)); +#endif + if (status.is_valid & MT_SPM_RC_VALID_TRACE_TIME) { + ext_op |= MT_SPM_EX_OP_TRACE_TIMESTAMP_EN; + } + + if (IS_PLAT_SUSPEND_ID(state_id)) { + mt_spm_suspend_enter(state_id, + (MT_SPM_EX_OP_CLR_26M_RECORD | + MT_SPM_EX_OP_SET_WDT | + MT_SPM_EX_OP_HW_S1_DETECT | + bus26m_ext_opand | + bus26m_ext_opand2), + CONSTRAINT_BUS26M_RESOURCE_REQ); + } else { + mt_spm_idle_generic_enter(state_id, ext_op, spm_bus26m_conduct); + } + return MT_RM_STATUS_OK; +} + +int spm_reset_rc_bus26m(unsigned int cpu, int state_id) +{ + unsigned int ext_op = MT_SPM_EX_OP_HW_S1_DETECT; + +#ifndef MTK_PLAT_SPM_SSPM_NOTIFIER_UNSUPPORT + mt_spm_sspm_notify_u32(MT_SPM_NOTIFY_LP_LEAVE, 0); +#endif + if (status.is_valid & MT_SPM_RC_VALID_TRACE_TIME) { + ext_op |= MT_SPM_EX_OP_TRACE_TIMESTAMP_EN; + } + + if (IS_PLAT_SUSPEND_ID(state_id)) { + mt_spm_suspend_resume(state_id, + (bus26m_ext_opand | bus26m_ext_opand2 | + MT_SPM_EX_OP_SET_WDT | ext_op), + NULL); + bus26m_ext_opand = 0; + } else { + struct wake_status *waken = NULL; + + if (spm_unlikely(status.is_valid & MT_SPM_RC_VALID_TRACE_EVENT)) { + ext_op |= MT_SPM_EX_OP_TRACE_LP; + } + + mt_spm_idle_generic_resume(state_id, ext_op, &waken, NULL); + status.enter_cnt++; + + if (spm_unlikely(status.is_valid & MT_SPM_RC_VALID_RESIDNECY)) { + status.residency += (waken != NULL) ? waken->tr.comm.timer_out : 0; + } + } + + do_irqs_delivery(); + + return MT_RM_STATUS_OK; +} + +int spm_get_status_rc_bus26m(unsigned int type, void *priv) +{ + int ret = MT_RM_STATUS_OK; + + if (type == PLAT_RC_STATUS) { + int res = 0; + struct rc_common_state *st = (struct rc_common_state *)priv; + + if (st == NULL) { + return MT_RM_STATUS_BAD; + } + + res = spm_rc_constraint_status_get(st->id, st->type, + st->act, MT_RM_CONSTRAINT_ID_BUS26M, + (struct constraint_status * const)&status, + (struct constraint_status * const)st->value); + if ((res == 0) && (st->id != MT_RM_CONSTRAINT_ID_ALL)) { + ret = MT_RM_STATUS_STOP; + } + } + return ret; +} diff --git a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_cpu_buck_ldo.c b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_cpu_buck_ldo.c new file mode 100644 index 0000000..1bcd509 --- /dev/null +++ b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_cpu_buck_ldo.c @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#include <drivers/spm/mt_spm_resource_req.h> +#include <lib/pm/mtk_pm.h> +#include <lpm/mt_lpm_smc.h> +#include <mt_spm.h> +#include <mt_spm_cond.h> +#include <mt_spm_conservation.h> +#include <mt_spm_constraint.h> +#include <mt_spm_idle.h> +#include <mt_spm_internal.h> +#include <mt_spm_notifier.h> +#include "mt_spm_rc_api.h" +#include "mt_spm_rc_internal.h" +#include <mt_spm_reg.h> +#include <mt_spm_suspend.h> + +#define CONSTRAINT_CPU_BUCK_PCM_FLAG (SPM_FLAG_DISABLE_INFRA_PDN | \ + SPM_FLAG_DISABLE_VCORE_DVS | \ + SPM_FLAG_DISABLE_VCORE_DFS | \ + SPM_FLAG_SRAM_SLEEP_CTRL | \ + SPM_FLAG_DISABLE_DRAMC_MCU_SRAM_SLEEP | \ + SPM_FLAG_KEEP_CSYSPWRACK_HIGH) + +#define CONSTRAINT_CPU_BUCK_PCM_FLAG1 (0) + +#define CONSTRAINT_CPU_BUCK_RESOURCE_REQ (MT_SPM_DRAM_S1 | \ + MT_SPM_DRAM_S0 | \ + MT_SPM_SYSPLL | \ + MT_SPM_INFRA | \ + MT_SPM_26M | \ + MT_SPM_XO_FPM) + +static unsigned int cpubuckldo_status = (MT_SPM_RC_VALID_SW | MT_SPM_RC_VALID_TRACE_TIME); +static unsigned int cpubuckldo_enter_cnt; + +int spm_cpu_bcuk_ldo_conduct(int state_id, + struct spm_lp_scen *spm_lp, + unsigned int *resource_req) +{ + unsigned int res_req = CONSTRAINT_CPU_BUCK_RESOURCE_REQ; + + if ((spm_lp == NULL) || (resource_req == NULL)) { + return -1; + } + + spm_lp->pwrctrl->pcm_flags = (uint32_t)CONSTRAINT_CPU_BUCK_PCM_FLAG; + spm_lp->pwrctrl->pcm_flags1 = (uint32_t)CONSTRAINT_CPU_BUCK_PCM_FLAG1; + + *resource_req |= res_req; + return 0; +} + +bool spm_is_valid_rc_cpu_buck_ldo(unsigned int cpu, int state_id) +{ + return IS_MT_RM_RC_READY(cpubuckldo_status); +} + +static void update_rc_status(const void *val) +{ + const struct rc_common_state *st = (const struct rc_common_state *)val; + + if (st == NULL) { + return; + } + + if ((st->type == CONSTRAINT_UPDATE_VALID) && st->value) { + if ((st->id == MT_RM_CONSTRAINT_ID_ALL) || + (st->id == MT_RM_CONSTRAINT_ID_CPU_BUCK_LDO)) { + struct constraint_status *con = (struct constraint_status *)st->value; + + if ((st->act & MT_LPM_SMC_ACT_CLR) > 0U) { + SPM_RC_BITS_CLR(cpubuckldo_status, con->is_valid); + } else { + SPM_RC_BITS_SET(cpubuckldo_status, con->is_valid); + } + } + } +} + +int spm_update_rc_cpu_buck_ldo(int state_id, int type, const void *val) +{ + if (type == PLAT_RC_STATUS) { + update_rc_status(val); + } + return MT_RM_STATUS_OK; +} + +unsigned int spm_allow_rc_cpu_buck_ldo(int state_id) +{ + return MT_RM_CONSTRAINT_ALLOW_CPU_BUCK_OFF; +} + +int spm_run_rc_cpu_buck_ldo(unsigned int cpu, int state_id) +{ + (void)cpu; + unsigned int ext_op = 0U; + +#ifndef MTK_PLAT_SPM_SSPM_NOTIFIER_UNSUPPORT + mt_spm_sspm_notify_u32(MT_SPM_NOTIFY_LP_ENTER, + (IS_PLAT_SUSPEND_ID(state_id) ? + MT_RM_CONSTRAINT_ALLOW_AP_SUSPEND : (0U))); +#endif + if (cpubuckldo_status & MT_SPM_RC_VALID_TRACE_TIME) { + ext_op |= MT_SPM_EX_OP_TRACE_TIMESTAMP_EN; + } + + if (IS_PLAT_SUSPEND_ID(state_id)) { + mt_spm_suspend_enter(state_id, + (MT_SPM_EX_OP_CLR_26M_RECORD | + MT_SPM_EX_OP_SET_SUSPEND_MODE | + MT_SPM_EX_OP_SET_WDT), + CONSTRAINT_CPU_BUCK_RESOURCE_REQ); + } else { + mt_spm_idle_generic_enter(state_id, ext_op, spm_cpu_bcuk_ldo_conduct); + } + + cpubuckldo_enter_cnt++; + + return 0; +} + +int spm_reset_rc_cpu_buck_ldo(unsigned int cpu, int state_id) +{ + (void)cpu; + unsigned int ext_op = 0U; + +#ifndef MTK_PLAT_SPM_SSPM_NOTIFIER_UNSUPPORT + mt_spm_sspm_notify_u32(MT_SPM_NOTIFY_LP_LEAVE, 0U); +#endif + if (cpubuckldo_status & MT_SPM_RC_VALID_TRACE_TIME) { + ext_op |= MT_SPM_EX_OP_TRACE_TIMESTAMP_EN; + } + + if (IS_PLAT_SUSPEND_ID(state_id)) { + mt_spm_suspend_resume(state_id, MT_SPM_EX_OP_SET_WDT, NULL); + } else { + mt_spm_idle_generic_resume(state_id, ext_op, NULL, NULL); + } + + return 0; +} + +int spm_get_status_rc_cpu_buck_ldo(unsigned int type, void *priv) +{ + int ret = MT_RM_STATUS_OK; + + if (type != PLAT_RC_STATUS) { + return ret; + } + + struct rc_common_state *st = (struct rc_common_state *)priv; + + if (st == NULL) { + return MT_RM_STATUS_BAD; + } + + if ((st->id == MT_RM_CONSTRAINT_ID_ALL) || + (st->id == MT_RM_CONSTRAINT_ID_CPU_BUCK_LDO)) { + struct constraint_status *dest; + + dest = (struct constraint_status *)st->value; + do { + if (dest == NULL) { + break; + } + if (st->type == CONSTRAINT_GET_VALID) { + dest->is_valid = cpubuckldo_status; + } else if (st->type == CONSTRAINT_COND_BLOCK) { + dest->is_cond_block = 0; + } else if (st->type == CONSTRAINT_GET_ENTER_CNT) { + if (st->id == MT_RM_CONSTRAINT_ID_ALL) { + dest->enter_cnt += cpubuckldo_enter_cnt; + } else { + dest->enter_cnt = cpubuckldo_enter_cnt; + } + } else { + break; + } + if (st->id != MT_RM_CONSTRAINT_ID_ALL) { + ret = MT_RM_STATUS_STOP; + } + } while (0); + } + return ret; +} diff --git a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_dram.c b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_dram.c new file mode 100644 index 0000000..82b38ad --- /dev/null +++ b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_dram.c @@ -0,0 +1,318 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#include <drivers/spm/mt_spm_resource_req.h> +#include <lib/pm/mtk_pm.h> +#include <lpm/mt_lp_api.h> +#include <lpm/mt_lp_rm.h> +#include <mt_spm.h> +#include <mt_spm_cond.h> +#include <mt_spm_conservation.h> +#include <mt_spm_constraint.h> +#include <mt_spm_idle.h> +#include <mt_spm_internal.h> +#include <mt_spm_notifier.h> +#include "mt_spm_rc_api.h" +#include "mt_spm_rc_internal.h" +#include <mt_spm_reg.h> +#include <mt_spm_suspend.h> + +#define CONSTRAINT_DRAM_ALLOW (MT_RM_CONSTRAINT_ALLOW_DRAM_S0 | \ + MT_RM_CONSTRAINT_ALLOW_DRAM_S1 | \ + MT_RM_CONSTRAINT_ALLOW_CPU_BUCK_OFF) + +#define CONSTRAINT_DRAM_PCM_FLAG (SPM_FLAG_DISABLE_INFRA_PDN | \ + SPM_FLAG_DISABLE_VCORE_DVS | \ + SPM_FLAG_DISABLE_VCORE_DFS | \ + SPM_FLAG_SRAM_SLEEP_CTRL | \ + SPM_FLAG_KEEP_CSYSPWRACK_HIGH | \ + SPM_FLAG_DISABLE_DRAMC_MCU_SRAM_SLEEP) + +#define CONSTRAINT_DRAM_PCM_FLAG1 (0) + +#define CONSTRAINT_DRAM_RESOURCE_REQ (MT_SPM_SYSPLL | MT_SPM_INFRA | MT_SPM_26M) + +static struct mt_spm_cond_tables cond_dram = { + .name = "dram", + .table_cg = { + 0xFF5DD002, /* MTCMOS1 */ + 0x0000003C, /* MTCMOS2 */ + 0x27AF8000, /* INFRA0 */ + 0x20010876, /* INFRA1 */ + 0x86000640, /* INFRA2 */ + 0x00000000, /* INFRA3 */ + 0x80000000, /* INFRA4 */ + 0x01002A00, /* PERI0 */ + 0x00080000, /* VPPSYS0_0 */ + 0x38803000, /* VPPSYS0_1 */ + 0x00081450, /* VPPSYS1_0 */ + 0x00003000, /* VPPSYS1_1 */ + 0x00000000, /* VDOSYS0_0 */ + 0x00000000, /* VDOSYS0_1 */ + 0x000001F8, /* VDOSYS1_0 */ + 0x000001E0, /* VDOSYS1_1 */ + 0x00FB0007, /* VDOSYS1_2 */ + }, + .table_pll = 0U, +}; + +static struct mt_spm_cond_tables cond_dram_res = { + .table_cg = { 0U }, + .table_pll = 0U, +}; + +static struct constraint_status status = { + .id = MT_RM_CONSTRAINT_ID_DRAM, + .is_valid = (MT_SPM_RC_VALID_SW | + MT_SPM_RC_VALID_COND_CHECK | + MT_SPM_RC_VALID_COND_LATCH | + MT_SPM_RC_VALID_XSOC_BBLPM | + MT_SPM_RC_VALID_TRACE_TIME), + .is_cond_block = 0U, + .enter_cnt = 0U, + .cond_res = &cond_dram_res, + .residency = 0ULL, +}; + +static unsigned short ext_status_dram; + +int spm_dram_conduct(int state_id, struct spm_lp_scen *spm_lp, unsigned int *resource_req) +{ + unsigned int res_req = CONSTRAINT_DRAM_RESOURCE_REQ; + + if ((spm_lp == NULL) || (resource_req == NULL)) { + return -1; + } + + spm_lp->pwrctrl->pcm_flags = (uint32_t)CONSTRAINT_DRAM_PCM_FLAG; + spm_lp->pwrctrl->pcm_flags1 = (uint32_t)CONSTRAINT_DRAM_PCM_FLAG1; + + *resource_req |= res_req; + return 0; +} + +bool spm_is_valid_rc_dram(unsigned int cpu, int state_id) +{ + return (!(status.is_cond_block && (status.is_valid & MT_SPM_RC_VALID_COND_CHECK)) && + IS_MT_RM_RC_READY(status.is_valid) && + (IS_PLAT_SUSPEND_ID(state_id) || + (state_id == MT_PLAT_PWR_STATE_SYSTEM_MEM) || + (state_id == MT_PLAT_PWR_STATE_SYSTEM_PLL) || + (state_id == MT_PLAT_PWR_STATE_SYSTEM_BUS))); +} + +static int update_rc_condition(int state_id, const void *val) +{ + const struct mt_spm_cond_tables *tlb = (const struct mt_spm_cond_tables *)val; + const struct mt_spm_cond_tables *tlb_check = (const struct mt_spm_cond_tables *)&cond_dram; + + if (tlb == NULL) { + return MT_RM_STATUS_BAD; + } + + status.is_cond_block = mt_spm_cond_check(state_id, tlb, tlb_check, + (status.is_valid & MT_SPM_RC_VALID_COND_LATCH) ? + &cond_dram_res : NULL); + return MT_RM_STATUS_OK; +} + +static void update_rc_clkbuf_status(const void *val) +{ + unsigned int is_flight = (val) ? !!(*((unsigned int *)val) == FLIGHT_MODE_ON) : 0; + + if (is_flight != 0U) { + spm_rc_constraint_valid_set(MT_RM_CONSTRAINT_ID_DRAM, + MT_RM_CONSTRAINT_ID_DRAM, + MT_SPM_RC_VALID_FLIGHTMODE, + (struct constraint_status * const)&status); + } else { + spm_rc_constraint_valid_clr(MT_RM_CONSTRAINT_ID_DRAM, + MT_RM_CONSTRAINT_ID_DRAM, + MT_SPM_RC_VALID_FLIGHTMODE, + (struct constraint_status * const)&status); + } +} + +static void update_rc_ufs_status(const void *val) +{ + unsigned int is_ufs_h8 = (val) ? !!(*((unsigned int *)val) == UFS_REF_CLK_OFF) : 0; + + if (is_ufs_h8 != 0U) { + spm_rc_constraint_valid_set(MT_RM_CONSTRAINT_ID_DRAM, + MT_RM_CONSTRAINT_ID_DRAM, + MT_SPM_RC_VALID_UFS_H8, + (struct constraint_status * const)&status); + } else { + spm_rc_constraint_valid_clr(MT_RM_CONSTRAINT_ID_DRAM, + MT_RM_CONSTRAINT_ID_DRAM, + MT_SPM_RC_VALID_UFS_H8, + (struct constraint_status * const)&status); + } +} + +static void update_rc_status(const void *val) +{ + const struct rc_common_state *st; + + st = (const struct rc_common_state *)val; + + if (st == NULL) { + return; + } + + if (st->type == CONSTRAINT_UPDATE_COND_CHECK) { + struct mt_spm_cond_tables * const tlb = &cond_dram; + + spm_rc_condition_modifier(st->id, st->act, st->value, + MT_RM_CONSTRAINT_ID_DRAM, tlb); + } else if ((st->type == CONSTRAINT_UPDATE_VALID) || + (st->type == CONSTRAINT_RESIDNECY)) { + spm_rc_constraint_status_set(st->id, st->type, st->act, + MT_RM_CONSTRAINT_ID_DRAM, + (struct constraint_status * const)st->value, + (struct constraint_status * const)&status); + } else { + INFO("[%s:%d] - Unknown type: 0x%x\n", __func__, __LINE__, st->type); + } +} + +int spm_update_rc_dram(int state_id, int type, const void *val) +{ + int res = MT_RM_STATUS_OK; + + switch (type) { + case PLAT_RC_UPDATE_CONDITION: + res = update_rc_condition(state_id, val); + break; + case PLAT_RC_CLKBUF_STATUS: + update_rc_clkbuf_status(val); + break; + case PLAT_RC_UFS_STATUS: + update_rc_ufs_status(val); + break; + case PLAT_RC_STATUS: + update_rc_status(val); + break; + default: + INFO("[%s:%d] - Do nothing for type: %d\n", __func__, __LINE__, type); + break; + } + + return res; +} + +unsigned int spm_allow_rc_dram(int state_id) +{ + return CONSTRAINT_DRAM_ALLOW; +} + +int spm_run_rc_dram(unsigned int cpu, int state_id) +{ + unsigned int ext_op = MT_SPM_EX_OP_HW_S1_DETECT; + unsigned int allows = CONSTRAINT_DRAM_ALLOW; + + ext_status_dram = status.is_valid; + + if (IS_MT_SPM_RC_BBLPM_MODE(ext_status_dram)) { +#ifdef MT_SPM_USING_SRCLKEN_RC + ext_op |= MT_SPM_EX_OP_SRCLKEN_RC_BBLPM; +#else + allows |= MT_RM_CONSTRAINT_ALLOW_BBLPM; +#endif + } + +#ifndef MTK_PLAT_SPM_SSPM_NOTIFIER_UNSUPPORT + mt_spm_sspm_notify_u32(MT_SPM_NOTIFY_LP_ENTER, allows | (IS_PLAT_SUSPEND_ID(state_id) ? + (MT_RM_CONSTRAINT_ALLOW_AP_SUSPEND) : (0U))); +#else + (void)allows; +#endif + + if (ext_status_dram & MT_SPM_RC_VALID_TRACE_TIME) { + ext_op |= MT_SPM_EX_OP_TRACE_TIMESTAMP_EN; + } + + if (IS_PLAT_SUSPEND_ID(state_id)) { + mt_spm_suspend_enter(state_id, + (MT_SPM_EX_OP_CLR_26M_RECORD | + MT_SPM_EX_OP_SET_WDT | + MT_SPM_EX_OP_SET_SUSPEND_MODE | + MT_SPM_EX_OP_HW_S1_DETECT), + CONSTRAINT_DRAM_RESOURCE_REQ); + } else { + mt_spm_idle_generic_enter(state_id, ext_op, spm_dram_conduct); + } + + return 0; +} + +int spm_reset_rc_dram(unsigned int cpu, int state_id) +{ + unsigned int ext_op = MT_SPM_EX_OP_HW_S1_DETECT; + unsigned int allows = CONSTRAINT_DRAM_ALLOW; + + if (IS_MT_SPM_RC_BBLPM_MODE(ext_status_dram)) { +#ifdef MT_SPM_USING_SRCLKEN_RC + ext_op |= MT_SPM_EX_OP_SRCLKEN_RC_BBLPM; +#else + allows |= MT_RM_CONSTRAINT_ALLOW_BBLPM; +#endif + } + +#ifndef MTK_PLAT_SPM_SSPM_NOTIFIER_UNSUPPORT + mt_spm_sspm_notify_u32(MT_SPM_NOTIFY_LP_LEAVE, allows); +#else + (void)allows; +#endif + + if (ext_status_dram & MT_SPM_RC_VALID_TRACE_TIME) { + ext_op |= MT_SPM_EX_OP_TRACE_TIMESTAMP_EN; + } + + if (IS_PLAT_SUSPEND_ID(state_id)) { + mt_spm_suspend_resume(state_id, + (MT_SPM_EX_OP_SET_WDT | MT_SPM_EX_OP_HW_S1_DETECT), + NULL); + } else { + struct wake_status *waken = NULL; + + if (spm_unlikely(status.is_valid & MT_SPM_RC_VALID_TRACE_EVENT)) { + ext_op |= MT_SPM_EX_OP_TRACE_LP; + } + mt_spm_idle_generic_resume(state_id, ext_op, &waken, NULL); + status.enter_cnt++; + + if (spm_unlikely(status.is_valid & MT_SPM_RC_VALID_RESIDNECY)) { + status.residency += (waken != NULL) ? waken->tr.comm.timer_out : 0; + } + } + + return 0; +} + +int spm_get_status_rc_dram(unsigned int type, void *priv) +{ + int ret = MT_RM_STATUS_OK; + + if (type == PLAT_RC_STATUS) { + int res = 0; + struct rc_common_state *st = (struct rc_common_state *)priv; + + if (st == NULL) { + return MT_RM_STATUS_BAD; + } + + res = spm_rc_constraint_status_get(st->id, st->type, + st->act, MT_RM_CONSTRAINT_ID_DRAM, + (struct constraint_status * const)&status, + (struct constraint_status * const)st->value); + if ((res == 0) && (st->id != MT_RM_CONSTRAINT_ID_ALL)) { + ret = MT_RM_STATUS_STOP; + } + } + return ret; +} diff --git a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_internal.h b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_internal.h new file mode 100644 index 0000000..7763152 --- /dev/null +++ b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_internal.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_SPM_RC_INTERNAL_H +#define MT_SPM_RC_INTERNAL_H + +#ifdef MTK_PLAT_SPM_SRAM_SLP_UNSUPPORT +#define SPM_FLAG_SRAM_SLEEP_CTRL (SPM_FLAG_DISABLE_DRAMC_MCU_SRAM_SLEEP) +#define SPM_SRAM_SLEEP_RC_RES_RESTRICT (0) +#else +#define SPM_FLAG_SRAM_SLEEP_CTRL (0) +#define SPM_SRAM_SLEEP_RC_RES_RESTRICT (0) +#endif + +#define SPM_RC_UPDATE_COND_ID_MASK (0xffff) +#define SPM_RC_UPDATE_COND_RC_ID_MASK (0xffff) +#define SPM_RC_UPDATE_COND_RC_ID_SHIFT (16) + +#define SPM_RC_UPDATE_COND_RC_ID_GET(val) \ + ((val >> SPM_RC_UPDATE_COND_RC_ID_SHIFT) & SPM_RC_UPDATE_COND_RC_ID_MASK) + +#define SPM_RC_UPDATE_COND_ID_GET(val) (val & SPM_RC_UPDATE_COND_ID_MASK) + +/* cpu buck/ldo constraint function */ +bool spm_is_valid_rc_cpu_buck_ldo(unsigned int cpu, int state_id); +int spm_update_rc_cpu_buck_ldo(int state_id, int type, const void *val); +unsigned int spm_allow_rc_cpu_buck_ldo(int state_id); +int spm_run_rc_cpu_buck_ldo(unsigned int cpu, int state_id); +int spm_reset_rc_cpu_buck_ldo(unsigned int cpu, int state_id); +int spm_get_status_rc_cpu_buck_ldo(unsigned int type, void *priv); + +/* spm resource dram constraint function */ +bool spm_is_valid_rc_dram(unsigned int cpu, int state_id); +int spm_update_rc_dram(int state_id, int type, const void *val); +unsigned int spm_allow_rc_dram(int state_id); +int spm_run_rc_dram(unsigned int cpu, int state_id); +int spm_reset_rc_dram(unsigned int cpu, int state_id); +int spm_get_status_rc_dram(unsigned int type, void *priv); + +/* spm resource syspll constraint function */ +bool spm_is_valid_rc_syspll(unsigned int cpu, int state_id); +int spm_update_rc_syspll(int state_id, int type, const void *val); +unsigned int spm_allow_rc_syspll(int state_id); +int spm_run_rc_syspll(unsigned int cpu, int state_id); +int spm_reset_rc_syspll(unsigned int cpu, int state_id); +int spm_get_status_rc_syspll(unsigned int type, void *priv); + +/* spm resource bus26m constraint function */ +bool spm_is_valid_rc_bus26m(unsigned int cpu, int state_id); +int spm_update_rc_bus26m(int state_id, int type, const void *val); +unsigned int spm_allow_rc_bus26m(int state_id); +int spm_run_rc_bus26m(unsigned int cpu, int state_id); +int spm_reset_rc_bus26m(unsigned int cpu, int state_id); +int spm_get_status_rc_bus26m(unsigned int type, void *priv); + +#endif diff --git a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_syspll.c b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_syspll.c new file mode 100644 index 0000000..5359c7c --- /dev/null +++ b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_syspll.c @@ -0,0 +1,365 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <common/debug.h> +#include <drivers/spm/mt_spm_resource_req.h> +#include <lib/pm/mtk_pm.h> +#include <lpm/mt_lp_api.h> +#include <lpm/mt_lp_rm.h> +#include <mt_spm.h> +#include <mt_spm_cond.h> +#include <mt_spm_conservation.h> +#include <mt_spm_constraint.h> +#include <mt_spm_idle.h> +#include <mt_spm_internal.h> +#include <mt_spm_notifier.h> +#include "mt_spm_rc_api.h" +#include "mt_spm_rc_internal.h" +#include <mt_spm_reg.h> +#include <mt_spm_suspend.h> + +#define CONSTRAINT_SYSPLL_ALLOW (MT_RM_CONSTRAINT_ALLOW_CPU_BUCK_OFF | \ + MT_RM_CONSTRAINT_ALLOW_DRAM_S0 | \ + MT_RM_CONSTRAINT_ALLOW_DRAM_S1 | \ + MT_RM_CONSTRAINT_ALLOW_VCORE_LP) + +#define CONSTRAINT_SYSPLL_PCM_FLAG (SPM_FLAG_DISABLE_INFRA_PDN | \ + SPM_FLAG_DISABLE_VCORE_DVS | \ + SPM_FLAG_DISABLE_VCORE_DFS | \ + SPM_FLAG_SRAM_SLEEP_CTRL | \ + SPM_FLAG_KEEP_CSYSPWRACK_HIGH | \ + SPM_FLAG_ENABLE_6315_CTRL | \ + SPM_FLAG_DISABLE_DRAMC_MCU_SRAM_SLEEP | \ + SPM_FLAG_USE_SRCCLKENO2) + +#define CONSTRAINT_SYSPLL_PCM_FLAG1 (0) + +/* If sspm sram won't enter sleep voltage then vcore couldn't enter low power mode */ +#if defined(MTK_PLAT_SPM_SRAM_SLP_UNSUPPORT) && SPM_SRAM_SLEEP_RC_RES_RESTRICT +#define CONSTRAINT_SYSPLL_RESOURCE_REQ (MT_SPM_26M) +#else +#define CONSTRAINT_SYSPLL_RESOURCE_REQ (MT_SPM_26M) +#endif + +static unsigned int syspll_ext_opand2; +static unsigned short ext_status_syspll; + +static struct mt_spm_cond_tables cond_syspll = { + .name = "syspll", + .table_cg = { + 0xFF5DD002, /* MTCMOS1 */ + 0x0000003C, /* MTCMOS2 */ + 0x27AF8000, /* INFRA0 */ + 0x20010876, /* INFRA1 */ + 0x86000640, /* INFRA2 */ + 0x30008020, /* INFRA3 */ + 0x80000000, /* INFRA4 */ + 0x01002A0B, /* PERI0 */ + 0x00090000, /* VPPSYS0_0 */ + 0x38FF3E69, /* VPPSYS0_1 */ + 0xF0081450, /* VPPSYS1_0 */ + 0x00003000, /* VPPSYS1_1 */ + 0x00000000, /* VDOSYS0_0 */ + 0x00000000, /* VDOSYS0_1 */ + 0x000001FF, /* VDOSYS1_0 */ + 0x008001E0, /* VDOSYS1_1 */ + 0x00FB0007, /* VDOSYS1_2 */ + }, + .table_pll = 0U, +}; + +static struct mt_spm_cond_tables cond_syspll_res = { + .table_cg = { 0U }, + .table_pll = 0U, +}; + +static struct constraint_status status = { + .id = MT_RM_CONSTRAINT_ID_SYSPLL, + .is_valid = (MT_SPM_RC_VALID_SW | + MT_SPM_RC_VALID_COND_CHECK | + MT_SPM_RC_VALID_COND_LATCH | + MT_SPM_RC_VALID_XSOC_BBLPM | + MT_SPM_RC_VALID_TRACE_TIME), + .is_cond_block = 0U, + .enter_cnt = 0U, + .cond_res = &cond_syspll_res, + .residency = 0ULL, +}; + +int spm_syspll_conduct(int state_id, struct spm_lp_scen *spm_lp, unsigned int *resource_req) +{ + unsigned int res_req = CONSTRAINT_SYSPLL_RESOURCE_REQ; + + if ((spm_lp == NULL) || (resource_req == NULL)) { + return -1; + } + + spm_lp->pwrctrl->pcm_flags = (uint32_t)CONSTRAINT_SYSPLL_PCM_FLAG; + spm_lp->pwrctrl->pcm_flags1 = (uint32_t)CONSTRAINT_SYSPLL_PCM_FLAG1; + + *resource_req |= res_req; + return 0; +} + +bool spm_is_valid_rc_syspll(unsigned int cpu, int state_id) +{ + return (!(status.is_cond_block && (status.is_valid & MT_SPM_RC_VALID_COND_CHECK) > 0) && + IS_MT_RM_RC_READY(status.is_valid) && + (IS_PLAT_SUSPEND_ID(state_id) || + (state_id == MT_PLAT_PWR_STATE_SYSTEM_PLL) || + (state_id == MT_PLAT_PWR_STATE_SYSTEM_BUS))); +} + +static int update_rc_condition(int state_id, const void *val) +{ + int res = MT_RM_STATUS_OK; + + const struct mt_spm_cond_tables * const tlb = + (const struct mt_spm_cond_tables * const)val; + const struct mt_spm_cond_tables *tlb_check = + (const struct mt_spm_cond_tables *)&cond_syspll; + + if (tlb == NULL) { + return MT_RM_STATUS_BAD; + } + + status.is_cond_block = mt_spm_cond_check(state_id, tlb, tlb_check, + (status.is_valid & MT_SPM_RC_VALID_COND_LATCH) ? + &cond_syspll_res : NULL); + return res; +} + +static void update_rc_clkbuf_status(const void *val) +{ + unsigned int is_flight = (val) ? !!(*((unsigned int *)val) == FLIGHT_MODE_ON) : 0; + + if (is_flight != 0U) { + spm_rc_constraint_valid_set(MT_RM_CONSTRAINT_ID_SYSPLL, + MT_RM_CONSTRAINT_ID_SYSPLL, + MT_SPM_RC_VALID_FLIGHTMODE, + (struct constraint_status * const)&status); + } else { + spm_rc_constraint_valid_clr(MT_RM_CONSTRAINT_ID_SYSPLL, + MT_RM_CONSTRAINT_ID_SYSPLL, + MT_SPM_RC_VALID_FLIGHTMODE, + (struct constraint_status * const)&status); + } +} + +static void update_rc_ufs_status(const void *val) +{ + unsigned int is_ufs_h8 = (val) ? !!(*((unsigned int *)val) == UFS_REF_CLK_OFF) : 0; + + if (is_ufs_h8 != 0U) { + spm_rc_constraint_valid_set(MT_RM_CONSTRAINT_ID_SYSPLL, + MT_RM_CONSTRAINT_ID_SYSPLL, + MT_SPM_RC_VALID_UFS_H8, + (struct constraint_status * const)&status); + } else { + spm_rc_constraint_valid_clr(MT_RM_CONSTRAINT_ID_SYSPLL, + MT_RM_CONSTRAINT_ID_SYSPLL, + MT_SPM_RC_VALID_UFS_H8, + (struct constraint_status * const)&status); + } +} + +static void update_rc_usb_peri(const void *val) +{ + int *flag = (int *)val; + + if (flag == NULL) { + return; + } + + if (*flag != 0) { + SPM_RC_BITS_SET(syspll_ext_opand2, MT_SPM_EX_OP_PERI_ON); + } else { + SPM_RC_BITS_CLR(syspll_ext_opand2, MT_SPM_EX_OP_PERI_ON); + } +} + +static void update_rc_usb_infra(const void *val) +{ + int *flag = (int *)val; + + if (flag == NULL) { + return; + } + + if (*flag != 0) { + SPM_RC_BITS_SET(syspll_ext_opand2, MT_SPM_EX_OP_INFRA_ON); + } else { + SPM_RC_BITS_CLR(syspll_ext_opand2, MT_SPM_EX_OP_INFRA_ON); + } +} + +static void update_rc_status(const void *val) +{ + const struct rc_common_state *st; + + st = (const struct rc_common_state *)val; + + if (st == NULL) { + return; + } + + if (st->type == CONSTRAINT_UPDATE_COND_CHECK) { + struct mt_spm_cond_tables * const tlb = &cond_syspll; + + spm_rc_condition_modifier(st->id, st->act, st->value, + MT_RM_CONSTRAINT_ID_SYSPLL, tlb); + } else if ((st->type == CONSTRAINT_UPDATE_VALID) || + (st->type == CONSTRAINT_RESIDNECY)) { + spm_rc_constraint_status_set(st->id, st->type, st->act, + MT_RM_CONSTRAINT_ID_SYSPLL, + (struct constraint_status * const)st->value, + (struct constraint_status * const)&status); + } else { + INFO("[%s:%d] - Unknown type: 0x%x\n", __func__, __LINE__, st->type); + } +} + +int spm_update_rc_syspll(int state_id, int type, const void *val) +{ + int res = MT_RM_STATUS_OK; + + switch (type) { + case PLAT_RC_UPDATE_CONDITION: + res = update_rc_condition(state_id, val); + break; + case PLAT_RC_CLKBUF_STATUS: + update_rc_clkbuf_status(val); + break; + case PLAT_RC_UFS_STATUS: + update_rc_ufs_status(val); + break; + case PLAT_RC_IS_USB_PERI: + update_rc_usb_peri(val); + break; + case PLAT_RC_IS_USB_INFRA: + update_rc_usb_infra(val); + break; + case PLAT_RC_STATUS: + update_rc_status(val); + break; + default: + INFO("[%s:%d] - Do nothing for type: %d\n", __func__, __LINE__, type); + break; + } + return res; +} + +unsigned int spm_allow_rc_syspll(int state_id) +{ + return CONSTRAINT_SYSPLL_ALLOW; +} + +int spm_run_rc_syspll(unsigned int cpu, int state_id) +{ + unsigned int ext_op = MT_SPM_EX_OP_HW_S1_DETECT; + unsigned int allows = CONSTRAINT_SYSPLL_ALLOW; + + ext_status_syspll = status.is_valid; + + if (IS_MT_SPM_RC_BBLPM_MODE(ext_status_syspll)) { +#ifdef MT_SPM_USING_SRCLKEN_RC + ext_op |= MT_SPM_EX_OP_SRCLKEN_RC_BBLPM; +#else + allows |= MT_RM_CONSTRAINT_ALLOW_BBLPM; +#endif + } + +#ifndef MTK_PLAT_SPM_SSPM_NOTIFIER_UNSUPPORT + mt_spm_sspm_notify_u32(MT_SPM_NOTIFY_LP_ENTER, allows | (IS_PLAT_SUSPEND_ID(state_id) ? + MT_RM_CONSTRAINT_ALLOW_AP_SUSPEND : 0)); +#else + (void)allows; +#endif + if (ext_status_syspll & MT_SPM_RC_VALID_TRACE_TIME) { + ext_op |= MT_SPM_EX_OP_TRACE_TIMESTAMP_EN; + } + + if (IS_PLAT_SUSPEND_ID(state_id)) { + mt_spm_suspend_enter(state_id, + (syspll_ext_opand2 | MT_SPM_EX_OP_CLR_26M_RECORD | + MT_SPM_EX_OP_SET_WDT | MT_SPM_EX_OP_HW_S1_DETECT | + MT_SPM_EX_OP_SET_SUSPEND_MODE), + CONSTRAINT_SYSPLL_RESOURCE_REQ); + } else { + mt_spm_idle_generic_enter(state_id, ext_op, spm_syspll_conduct); + } + + return 0; +} + +int spm_reset_rc_syspll(unsigned int cpu, int state_id) +{ + unsigned int ext_op = MT_SPM_EX_OP_HW_S1_DETECT; + unsigned int allows = CONSTRAINT_SYSPLL_ALLOW; + + if (IS_MT_SPM_RC_BBLPM_MODE(ext_status_syspll)) { +#ifdef MT_SPM_USING_SRCLKEN_RC + ext_op |= MT_SPM_EX_OP_SRCLKEN_RC_BBLPM; +#else + allows |= MT_RM_CONSTRAINT_ALLOW_BBLPM; +#endif + } + +#ifndef MTK_PLAT_SPM_SSPM_NOTIFIER_UNSUPPORT + mt_spm_sspm_notify_u32(MT_SPM_NOTIFY_LP_LEAVE, allows); +#else + (void)allows; +#endif + if (ext_status_syspll & MT_SPM_RC_VALID_TRACE_TIME) { + ext_op |= MT_SPM_EX_OP_TRACE_TIMESTAMP_EN; + } + + if (IS_PLAT_SUSPEND_ID(state_id)) { + mt_spm_suspend_resume(state_id, + (syspll_ext_opand2 | MT_SPM_EX_OP_SET_SUSPEND_MODE | + MT_SPM_EX_OP_SET_WDT | MT_SPM_EX_OP_HW_S1_DETECT), + NULL); + } else { + struct wake_status *waken = NULL; + + if (spm_unlikely(status.is_valid & MT_SPM_RC_VALID_TRACE_EVENT)) { + ext_op |= MT_SPM_EX_OP_TRACE_LP; + } + + mt_spm_idle_generic_resume(state_id, ext_op, &waken, NULL); + status.enter_cnt++; + + if (spm_unlikely(status.is_valid & MT_SPM_RC_VALID_RESIDNECY)) { + status.residency += (waken != NULL) ? waken->tr.comm.timer_out : 0; + } + } + + return 0; +} + +int spm_get_status_rc_syspll(unsigned int type, void *priv) +{ + int ret = MT_RM_STATUS_OK; + + if (type == PLAT_RC_STATUS) { + int res = 0; + struct rc_common_state *st = (struct rc_common_state *)priv; + + if (st == NULL) { + return MT_RM_STATUS_BAD; + } + + res = spm_rc_constraint_status_get(st->id, st->type, st->act, + MT_RM_CONSTRAINT_ID_SYSPLL, + (struct constraint_status * const)&status, + (struct constraint_status * const)st->value); + if ((res == 0) && (st->id != MT_RM_CONSTRAINT_ID_ALL)) { + ret = MT_RM_STATUS_STOP; + } + } + return ret; +} diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm.c b/plat/mediatek/drivers/spm/mt8188/mt_spm.c new file mode 100644 index 0000000..6c4e681 --- /dev/null +++ b/plat/mediatek/drivers/spm/mt8188/mt_spm.c @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <stddef.h> +#include <stdio.h> +#include <string.h> + +#include <arch.h> +#include <common/debug.h> +#include <drivers/console.h> +#include <lib/mmio.h> +#include <lib/utils_def.h> + +#include "constraints/mt_spm_rc_internal.h" +#include <drivers/spm/mt_spm_resource_req.h> +#include <lib/mtk_init/mtk_init.h> +#include <lib/pm/mtk_pm.h> +#include <lpm/mt_lp_rm.h> +#include <lpm/mt_lp_rqm.h> +#include <lpm/mt_lpm_smc.h> +#include "mt_spm.h" +#include "mt_spm_cond.h" +#include "mt_spm_conservation.h" +#include "mt_spm_constraint.h" +#include "mt_spm_idle.h" +#include "mt_spm_internal.h" +#include "mt_spm_pmic_wrap.h" +#include "mt_spm_reg.h" +#include "mt_spm_suspend.h" +#include <mtk_mmap_pool.h> +#include <platform_def.h> +#include "sleep_def.h" + +/* + * System Power Manager (SPM) is a hardware module which provides CPU idle + * and system suspend features. + */ + +spinlock_t spm_lock; + +#ifdef MTK_PLAT_SPM_UNSUPPORT +struct mt_resource_manager plat_mt8188_rm = { +}; +#else +struct mt_lp_res_req rq_xo_fpm = { + .res_id = MT_LP_RQ_XO_FPM, + .res_rq = MT_SPM_XO_FPM, + .res_usage = 0, +}; + +struct mt_lp_res_req rq_26m = { + .res_id = MT_LP_RQ_26M, + .res_rq = MT_SPM_26M, + .res_usage = 0, +}; + +struct mt_lp_res_req rq_infra = { + .res_id = MT_LP_RQ_INFRA, + .res_rq = MT_SPM_INFRA, + .res_usage = 0, +}; + +struct mt_lp_res_req rq_syspll = { + .res_id = MT_LP_RQ_SYSPLL, + .res_rq = MT_SPM_SYSPLL, + .res_usage = 0, +}; + +struct mt_lp_res_req rq_dram_s0 = { + .res_id = MT_LP_RQ_DRAM, + .res_rq = MT_SPM_DRAM_S0, + .res_usage = 0, +}; + +struct mt_lp_res_req rq_dram_s1 = { + .res_id = MT_LP_RQ_DRAM, + .res_rq = MT_SPM_DRAM_S1, + .res_usage = 0, +}; + +struct mt_lp_res_req *spm_resources[] = { + &rq_xo_fpm, + &rq_26m, + &rq_infra, + &rq_syspll, + &rq_dram_s0, + &rq_dram_s1, + NULL, +}; + +struct mt_resource_req_manager plat_mt8188_rq = { + .res = spm_resources, +}; + +struct mt_resource_constraint plat_constraint_bus26m = { + .is_valid = spm_is_valid_rc_bus26m, + .update = spm_update_rc_bus26m, + .allow = spm_allow_rc_bus26m, + .run = spm_run_rc_bus26m, + .reset = spm_reset_rc_bus26m, + .get_status = spm_get_status_rc_bus26m, +}; + +struct mt_resource_constraint plat_constraint_syspll = { + .is_valid = spm_is_valid_rc_syspll, + .update = spm_update_rc_syspll, + .allow = spm_allow_rc_syspll, + .run = spm_run_rc_syspll, + .reset = spm_reset_rc_syspll, + .get_status = spm_get_status_rc_syspll, +}; + +struct mt_resource_constraint plat_constraint_dram = { + .is_valid = spm_is_valid_rc_dram, + .update = spm_update_rc_dram, + .allow = spm_allow_rc_dram, + .run = spm_run_rc_dram, + .reset = spm_reset_rc_dram, + .get_status = spm_get_status_rc_dram, +}; + +struct mt_resource_constraint plat_constraint_cpu = { + .is_valid = spm_is_valid_rc_cpu_buck_ldo, + .update = spm_update_rc_cpu_buck_ldo, + .allow = spm_allow_rc_cpu_buck_ldo, + .run = spm_run_rc_cpu_buck_ldo, + .reset = spm_reset_rc_cpu_buck_ldo, + .get_status = spm_get_status_rc_cpu_buck_ldo, +}; + +struct mt_resource_constraint *plat_constraints[] = { + &plat_constraint_bus26m, + &plat_constraint_syspll, + &plat_constraint_dram, + &plat_constraint_cpu, + NULL, +}; + +struct mt_resource_manager plat_mt8188_rm = { + .update = mt_spm_cond_update, + .consts = plat_constraints, +}; +#endif + +/* Determine for SPM software resource user */ +static struct mt_lp_resource_user spm_res_user; + +struct mt_lp_resource_user *get_spm_res_user(void) +{ + return &spm_res_user; +} + +int spm_boot_init(void) +{ + mt_spm_pmic_wrap_set_phase(PMIC_WRAP_PHASE_ALLINONE); + mt_lp_rm_register(&plat_mt8188_rm); + + /* SPM service won't run when SPM not ready */ +#ifndef MTK_PLAT_SPM_UNSUPPORT + mt_lp_resource_request_manager_register(&plat_mt8188_rq); + mt_lp_resource_user_register("SPM", &spm_res_user); +#endif + + return 0; +} +MTK_ARCH_INIT(spm_boot_init); diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm.h b/plat/mediatek/drivers/spm/mt8188/mt_spm.h new file mode 100644 index 0000000..0688b71 --- /dev/null +++ b/plat/mediatek/drivers/spm/mt8188/mt_spm.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_SPM_H +#define MT_SPM_H + +#include <stdint.h> +#include <stdio.h> +#include <lib/spinlock.h> +#include <lib/pm/mtk_pm.h> +#include <lpm/mt_lp_rq.h> + +/* + * ARM v8.2, the cache will turn off automatically when cpu + * power down. Therefore, there is no doubt to use the spin_lock here. + */ +extern spinlock_t spm_lock; + +#ifdef __GNUC__ +#define spm_likely(x) __builtin_expect(!!(x), 1) +#define spm_unlikely(x) __builtin_expect(!!(x), 0) +#else +#define spm_likely(x) (x) +#define spm_unlikely(x) (x) +#endif + +#define MT_SPM_USING_SRCLKEN_RC +/* spm extern operand definition */ +#define MT_SPM_EX_OP_CLR_26M_RECORD BIT(0) +#define MT_SPM_EX_OP_SET_WDT BIT(1) +#define MT_SPM_EX_OP_NON_GENERIC_RESOURCE_REQ BIT(2) +#define MT_SPM_EX_OP_SET_SUSPEND_MODE BIT(3) +#define MT_SPM_EX_OP_SET_IS_ADSP BIT(4) +#define MT_SPM_EX_OP_SRCLKEN_RC_BBLPM BIT(5) +#define MT_SPM_EX_OP_HW_S1_DETECT BIT(6) +#define MT_SPM_EX_OP_TRACE_LP BIT(7) +#define MT_SPM_EX_OP_TRACE_SUSPEND BIT(8) +#define MT_SPM_EX_OP_TRACE_TIMESTAMP_EN BIT(9) +#define MT_SPM_EX_OP_TIME_CHECK BIT(10) +#define MT_SPM_EX_OP_TIME_OBS BIT(11) +#define MT_SPM_EX_OP_PERI_ON BIT(12) +#define MT_SPM_EX_OP_INFRA_ON BIT(13) + +typedef enum { + WR_NONE = 0, + WR_UART_BUSY = 1, + WR_ABORT = 2, + WR_PCM_TIMER = 3, + WR_WAKE_SRC = 4, + WR_DVFSRC = 5, + WR_TWAM = 6, + WR_PMSR = 7, + WR_SPM_ACK_CHK = 8, + WR_UNKNOWN = 9, +} wake_reason_t; + +struct mt_lp_resource_user *get_spm_res_user(void); +int spm_boot_init(void); + +#endif /* MT_SPM_H */ diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.c b/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.c new file mode 100644 index 0000000..bed55c9 --- /dev/null +++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.c @@ -0,0 +1,264 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdbool.h> +#include <lib/mmio.h> +#include <lib/pm/mtk_pm.h> +#include <mt_spm_cond.h> +#include <mt_spm_conservation.h> +#include <mt_spm_constraint.h> +#include <platform_def.h> + +#define TOPCKGEB_BASE (IO_PHYS) + +#define MT_LP_TZ_INFRA_REG(ofs) (INFRACFG_AO_BASE + ofs) + +#define MT_LP_TZ_SPM_REG(ofs) (SPM_BASE + ofs) +#define MT_LP_TZ_TOPCK_REG(ofs) (TOPCKGEB_BASE + ofs) +#define MT_LP_TZ_APMIXEDSYS(ofs) (APMIXEDSYS + ofs) + +#define MT_LP_TZ_VPPSYS0_REG(ofs) (VPPSYS0_BASE + ofs) +#define MT_LP_TZ_VPPSYS1_REG(ofs) (VPPSYS1_BASE + ofs) +#define MT_LP_TZ_VDOSYS0_REG(ofs) (VDOSYS0_BASE + ofs) +#define MT_LP_TZ_VDOSYS1_REG(ofs) (VDOSYS1_BASE + ofs) + +#define MT_LP_TZ_PERI_AO_REG(ofs) (PERICFG_AO_BASE + ofs) + +#undef SPM_PWR_STATUS +#define SPM_PWR_STATUS MT_LP_TZ_SPM_REG(0x016C) +#define SPM_PWR_STATUS_2ND MT_LP_TZ_SPM_REG(0x0170) +#define SPM_CPU_PWR_STATUS MT_LP_TZ_SPM_REG(0x0174) +#define INFRA_SW_CG0 MT_LP_TZ_INFRA_REG(0x0090) +#define INFRA_SW_CG1 MT_LP_TZ_INFRA_REG(0x0094) +#define INFRA_SW_CG2 MT_LP_TZ_INFRA_REG(0x00AC) +#define INFRA_SW_CG3 MT_LP_TZ_INFRA_REG(0x00C8) +#define INFRA_SW_CG4 MT_LP_TZ_INFRA_REG(0x00E8) +#define TOP_SW_I2C_CG MT_LP_TZ_TOPCK_REG(0x00A4) +#define PERI_SW_CG0 MT_LP_TZ_PERI_AO_REG(0x0018) +#define VPPSYS0_SW_CG0 MT_LP_TZ_VPPSYS0_REG(0x0020) +#define VPPSYS0_SW_CG1 MT_LP_TZ_VPPSYS0_REG(0x002C) +#define VPPSYS0_SW_CG2 MT_LP_TZ_VPPSYS0_REG(0x0038) +#define VPPSYS1_SW_CG0 MT_LP_TZ_VPPSYS1_REG(0x0100) +#define VPPSYS1_SW_CG1 MT_LP_TZ_VPPSYS1_REG(0x0110) +#define VDOSYS0_SW_CG0 MT_LP_TZ_VDOSYS0_REG(0x0100) +#define VDOSYS0_SW_CG1 MT_LP_TZ_VDOSYS0_REG(0x0110) +#define VDOSYS1_SW_CG0 MT_LP_TZ_VDOSYS1_REG(0x0100) +#define VDOSYS1_SW_CG1 MT_LP_TZ_VDOSYS1_REG(0x0120) +#define VDOSYS1_SW_CG2 MT_LP_TZ_VDOSYS1_REG(0x0130) + +#define CLK_CFG(id) MT_LP_TZ_TOPCK_REG(0x2c + id * 0xc) + +enum { + /* CLK_CFG_0 1000_002c */ + CLKMUX_VPP = 0, + NF_CLKMUX, +}; + +#define CLK_CHECK BIT(31) + +static bool check_clkmux_pdn(unsigned int clkmux_id) +{ + unsigned int reg, val, idx; + bool ret = false; + + if ((clkmux_id & CLK_CHECK) != 0U) { + clkmux_id = (clkmux_id & ~CLK_CHECK); + reg = clkmux_id / 4U; + val = mmio_read_32(CLK_CFG(reg)); + idx = clkmux_id % 4U; + ret = (((val >> (idx * 8U)) & 0x80) != 0U); + } + + return ret; +} + +static struct mt_spm_cond_tables spm_cond_t; + +/* local definitions */ +struct idle_cond_info { + /* check SPM_PWR_STATUS for bit definition */ + unsigned int subsys_mask; + /* cg address */ + uintptr_t addr; + /* bitflip value from *addr ? */ + bool bBitflip; + /* check clkmux if bit 31 = 1, id is bit[30:0] */ + unsigned int clkmux_id; +}; + +#define IDLE_CG(mask, addr, bitflip, clkmux) {mask, (uintptr_t)addr, bitflip, clkmux} + +static struct idle_cond_info idle_cg_info[PLAT_SPM_COND_MAX] = { + IDLE_CG(0xffffffff, SPM_PWR_STATUS, false, 0), + IDLE_CG(0xffffffff, SPM_CPU_PWR_STATUS, false, 0), + IDLE_CG(0xffffffff, INFRA_SW_CG0, true, 0), + IDLE_CG(0xffffffff, INFRA_SW_CG1, true, 0), + IDLE_CG(0xffffffff, INFRA_SW_CG2, true, 0), + IDLE_CG(0xffffffff, INFRA_SW_CG3, true, 0), + IDLE_CG(0xffffffff, INFRA_SW_CG4, true, 0), + IDLE_CG(0xffffffff, PERI_SW_CG0, true, 0), + IDLE_CG(0x00000800, VPPSYS0_SW_CG0, true, (CLK_CHECK | CLKMUX_VPP)), + IDLE_CG(0x00000800, VPPSYS0_SW_CG1, true, (CLK_CHECK | CLKMUX_VPP)), + IDLE_CG(0x00001000, VPPSYS1_SW_CG0, true, (CLK_CHECK | CLKMUX_VPP)), + IDLE_CG(0x00001000, VPPSYS1_SW_CG1, true, (CLK_CHECK | CLKMUX_VPP)), + IDLE_CG(0x00002000, VDOSYS0_SW_CG0, true, (CLK_CHECK | CLKMUX_VPP)), + IDLE_CG(0x00002000, VDOSYS0_SW_CG1, true, (CLK_CHECK | CLKMUX_VPP)), + IDLE_CG(0x00004000, VDOSYS1_SW_CG0, true, (CLK_CHECK | CLKMUX_VPP)), + IDLE_CG(0x00004000, VDOSYS1_SW_CG1, true, (CLK_CHECK | CLKMUX_VPP)), + IDLE_CG(0x00004000, VDOSYS1_SW_CG2, true, (CLK_CHECK | CLKMUX_VPP)), +}; + +/* check pll idle condition */ +#define PLL_MFGPLL MT_LP_TZ_APMIXEDSYS(0x340) +#define PLL_MMPLL MT_LP_TZ_APMIXEDSYS(0x544) +#define PLL_UNIVPLL MT_LP_TZ_APMIXEDSYS(0x504) +#define PLL_MSDCPLL MT_LP_TZ_APMIXEDSYS(0x514) +#define PLL_TVDPLL1 MT_LP_TZ_APMIXEDSYS(0x524) +#define PLL_TVDPLL2 MT_LP_TZ_APMIXEDSYS(0x534) +#define PLL_ETHPLL MT_LP_TZ_APMIXEDSYS(0x44c) +#define PLL_IMGPLL MT_LP_TZ_APMIXEDSYS(0x554) +#define PLL_APLL1 MT_LP_TZ_APMIXEDSYS(0x304) +#define PLL_APLL2 MT_LP_TZ_APMIXEDSYS(0x318) +#define PLL_APLL3 MT_LP_TZ_APMIXEDSYS(0x32c) +#define PLL_APLL4 MT_LP_TZ_APMIXEDSYS(0x404) +#define PLL_APLL5 MT_LP_TZ_APMIXEDSYS(0x418) + +unsigned int mt_spm_cond_check(int state_id, + const struct mt_spm_cond_tables *src, + const struct mt_spm_cond_tables *dest, + struct mt_spm_cond_tables *res) +{ + unsigned int b_res = 0U; + unsigned int i; + bool is_system_suspend = IS_PLAT_SUSPEND_ID(state_id); + + if ((src == NULL) || (dest == NULL)) { + return SPM_COND_CHECK_FAIL; + } + + for (i = 0; i < PLAT_SPM_COND_MAX; i++) { + if (res != NULL) { + res->table_cg[i] = (src->table_cg[i] & dest->table_cg[i]); + if (is_system_suspend && ((res->table_cg[i]) != 0U)) { + INFO("suspend: %s block[%u](0x%lx) = 0x%08x\n", + dest->name, i, idle_cg_info[i].addr, + res->table_cg[i]); + } + + if ((res->table_cg[i]) != 0U) { + b_res |= BIT(i); + } + } else if ((src->table_cg[i] & dest->table_cg[i]) != 0U) { + b_res |= BIT(i); + break; + } + } + + if (res != NULL) { + res->table_pll = (src->table_pll & dest->table_pll); + + if ((res->table_pll) != 0U) { + b_res |= (res->table_pll << SPM_COND_BLOCKED_PLL_IDX) | + SPM_COND_CHECK_BLOCKED_PLL; + } + } else if ((src->table_pll & dest->table_pll) != 0U) { + b_res |= SPM_COND_CHECK_BLOCKED_PLL; + } + + if (is_system_suspend && ((b_res) != 0U)) { + INFO("suspend: %s total blocked = 0x%08x\n", dest->name, b_res); + } + + return b_res; +} + +unsigned int mt_spm_dump_all_pll(const struct mt_spm_cond_tables *src, + const struct mt_spm_cond_tables *dest, + struct mt_spm_cond_tables *res) +{ + unsigned int b_res = 0U; + + if (res != NULL) { + res->table_all_pll = src->table_all_pll; + if ((res->table_all_pll) != 0U) { + b_res |= (res->table_all_pll << SPM_COND_BLOCKED_PLL_IDX) | + SPM_COND_CHECK_BLOCKED_PLL; + } + } else if ((src->table_pll & dest->table_pll) != 0U) { + b_res |= SPM_COND_CHECK_BLOCKED_PLL; + } + + return b_res; +} + +#define IS_MT_SPM_PWR_OFF(mask) \ + (!(mmio_read_32(SPM_PWR_STATUS) & mask) && \ + !(mmio_read_32(SPM_PWR_STATUS_2ND) & mask)) + +int mt_spm_cond_update(struct mt_resource_constraint **con, unsigned int num, + int stateid, void *priv) +{ + static const struct { + uintptr_t en_reg; + uint32_t pll_b; + } plls[] = { + { PLL_MFGPLL, PLL_BIT_MFGPLL }, + { PLL_MMPLL, PLL_BIT_MMPLL }, + { PLL_UNIVPLL, PLL_BIT_UNIVPLL }, + { PLL_MSDCPLL, PLL_BIT_MSDCPLL }, + { PLL_TVDPLL1, PLL_BIT_TVDPLL1 }, + { PLL_TVDPLL2, PLL_BIT_TVDPLL2 }, + { PLL_ETHPLL, PLL_BIT_ETHPLL }, + { PLL_IMGPLL, PLL_BIT_IMGPLL }, + { PLL_APLL1, PLL_BIT_APLL1 }, + { PLL_APLL2, PLL_BIT_APLL2 }, + { PLL_APLL3, PLL_BIT_APLL3 }, + { PLL_APLL4, PLL_BIT_APLL4 }, + { PLL_APLL5, PLL_BIT_APLL5 }, + }; + + int res; + unsigned int i; + struct mt_resource_constraint *const *_con; + + /* read all cg state */ + for (i = 0U; i < PLAT_SPM_COND_MAX; i++) { + spm_cond_t.table_cg[i] = 0U; + + /* check mtcmos, if off set idle_value and clk to 0 disable */ + if (IS_MT_SPM_PWR_OFF(idle_cg_info[i].subsys_mask)) { + continue; + } + /* check clkmux */ + if (check_clkmux_pdn(idle_cg_info[i].clkmux_id)) { + continue; + } + spm_cond_t.table_cg[i] = idle_cg_info[i].bBitflip ? + ~mmio_read_32(idle_cg_info[i].addr) : + mmio_read_32(idle_cg_info[i].addr); + } + + spm_cond_t.table_pll = 0U; + for (i = 0U; i < ARRAY_SIZE(plls); i++) { + if ((mmio_read_32(plls[i].en_reg) & BIT(9)) != 0U) { + spm_cond_t.table_pll |= plls[i].pll_b; + } + } + + spm_cond_t.priv = priv; + for (i = 0U, _con = con; (*_con != NULL) && (i < num); _con++, i++) { + if ((*_con)->update == NULL) { + continue; + } + res = (*_con)->update(stateid, PLAT_RC_UPDATE_CONDITION, + (void const *)&spm_cond_t); + if (res != MT_RM_STATUS_OK) { + break; + } + } + + return 0; +} diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.h b/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.h new file mode 100644 index 0000000..d93df57 --- /dev/null +++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_SPM_COND_H +#define MT_SPM_COND_H + +#include <lpm/mt_lp_rm.h> + +enum plat_spm_cond { + PLAT_SPM_COND_MTCMOS1 = 0, + PLAT_SPM_COND_MTCMOS2, + PLAT_SPM_COND_CG_INFRA_0, + PLAT_SPM_COND_CG_INFRA_1, + PLAT_SPM_COND_CG_INFRA_2, + PLAT_SPM_COND_CG_INFRA_3, + PLAT_SPM_COND_CG_INFRA_4, + PLAT_SPM_COND_CG_PERI_0, + PLAT_SPM_COND_CG_VPPSYS0_0, + PLAT_SPM_COND_CG_VPPSYS0_1, + PLAT_SPM_COND_CG_VPPSYS1_0, + PLAT_SPM_COND_CG_VPPSYS1_1, + PLAT_SPM_COND_CG_VDOSYS0_0, + PLAT_SPM_COND_CG_VDOSYS0_1, + PLAT_SPM_COND_CG_VDOSYS1_0, + PLAT_SPM_COND_CG_VDOSYS1_1, + PLAT_SPM_COND_CG_VDOSYS1_2, + PLAT_SPM_COND_MAX, +}; + +/* For PLL id >= PLAT_SPM_COND_PLL_MAX is not checked in idle condition */ +enum plat_spm_cond_pll { + PLAT_SPM_COND_PLL_UNIVPLL = 0, + PLAT_SPM_COND_PLL_MFGPLL, + PLAT_SPM_COND_PLL_MSDCPLL, + PLAT_SPM_COND_PLL_TVDPLL1, + PLAT_SPM_COND_PLL_TVDPLL2, + PLAT_SPM_COND_PLL_MMPLL, + PLAT_SPM_COND_PLL_ETHPLL, + PLAT_SPM_COND_PLL_IMGPLL, + PLAT_SPM_COND_PLL_APLL1, + PLAT_SPM_COND_PLL_APLL2, + PLAT_SPM_COND_PLL_APLL3, + PLAT_SPM_COND_PLL_APLL4, + PLAT_SPM_COND_PLL_APLL5, + PLAT_SPM_COND_PLL_MAX, +}; + +#define PLL_BIT_MFGPLL BIT(PLAT_SPM_COND_PLL_MFGPLL) +#define PLL_BIT_MMPLL BIT(PLAT_SPM_COND_PLL_MMPLL) +#define PLL_BIT_UNIVPLL BIT(PLAT_SPM_COND_PLL_UNIVPLL) +#define PLL_BIT_MSDCPLL BIT(PLAT_SPM_COND_PLL_MSDCPLL) +#define PLL_BIT_TVDPLL1 BIT(PLAT_SPM_COND_PLL_TVDPLL1) +#define PLL_BIT_TVDPLL2 BIT(PLAT_SPM_COND_PLL_TVDPLL2) +#define PLL_BIT_ETHPLL BIT(PLAT_SPM_COND_PLL_ETHPLL) +#define PLL_BIT_IMGPLL BIT(PLAT_SPM_COND_PLL_IMGPLL) +#define PLL_BIT_APLL1 BIT(PLAT_SPM_COND_PLL_APLL1) +#define PLL_BIT_APLL2 BIT(PLAT_SPM_COND_PLL_APLL2) +#define PLL_BIT_APLL3 BIT(PLAT_SPM_COND_PLL_APLL3) +#define PLL_BIT_APLL4 BIT(PLAT_SPM_COND_PLL_APLL4) +#define PLL_BIT_APLL5 BIT(PLAT_SPM_COND_PLL_APLL5) + +/* + * Definition about SPM_COND_CHECK_BLOCKED + * bit[00:16]: cg blocking index + * bit[17:29]: pll blocking index + * bit[30]: pll blocking information + * bit[31]: idle condition check fail + */ +#define SPM_COND_BLOCKED_CG_IDX (0) +#define SPM_COND_BLOCKED_PLL_IDX (17) +#define SPM_COND_CHECK_BLOCKED_PLL BIT(30) +#define SPM_COND_CHECK_FAIL BIT(31) + +struct mt_spm_cond_tables { + char *name; + unsigned int table_cg[PLAT_SPM_COND_MAX]; + unsigned int table_pll; + unsigned int table_all_pll; + void *priv; +}; + +unsigned int mt_spm_cond_check(int state_id, + const struct mt_spm_cond_tables *src, + const struct mt_spm_cond_tables *dest, + struct mt_spm_cond_tables *res); +unsigned int mt_spm_dump_all_pll(const struct mt_spm_cond_tables *src, + const struct mt_spm_cond_tables *dest, + struct mt_spm_cond_tables *res); +int mt_spm_cond_update(struct mt_resource_constraint **con, unsigned int num, + int stateid, void *priv); + +#endif diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_conservation.c b/plat/mediatek/drivers/spm/mt8188/mt_spm_conservation.c new file mode 100644 index 0000000..395448a --- /dev/null +++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_conservation.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <stddef.h> +#include <stdio.h> +#include <string.h> + +#include <common/debug.h> +#include <lib/mmio.h> +#include <plat/common/platform.h> +#include <lib/pm/mtk_pm.h> +#include <lpm/mt_lp_rqm.h> +#include "mt_spm.h" +#include "mt_spm_conservation.h" +#include "mt_spm_reg.h" +#include <platform_def.h> + +#define INFRA_EMI_DCM_CFG0 U(0x10002028) + +static struct wake_status spm_wakesta; /* record last wakesta */ +static wake_reason_t spm_wake_reason = WR_NONE; +static unsigned int emi_bak; + +static int go_to_spm_before_wfi(int state_id, unsigned int ext_opand, + struct spm_lp_scen *spm_lp, + unsigned int resource_req) +{ + int ret = 0; + struct pwr_ctrl *pwrctrl; + unsigned int cpu = plat_my_core_pos(); + + pwrctrl = spm_lp->pwrctrl; + + /* EMI workaround */ + emi_bak = mmio_read_32(INFRA_EMI_DCM_CFG0) & BIT(22); + mmio_setbits_32(INFRA_EMI_DCM_CFG0, BIT(22)); + + __spm_set_cpu_status(cpu); + __spm_set_power_control(pwrctrl); + __spm_set_wakeup_event(pwrctrl); + + __spm_set_pcm_flags(pwrctrl); + + __spm_src_req_update(pwrctrl, resource_req); + + if ((ext_opand & MT_SPM_EX_OP_CLR_26M_RECORD) != 0U) { + __spm_clean_before_wfi(); + } + + if ((ext_opand & MT_SPM_EX_OP_SET_WDT) != 0U) { + __spm_set_pcm_wdt(1); + } + + if ((ext_opand & MT_SPM_EX_OP_HW_S1_DETECT) != 0U) { + spm_hw_s1_state_monitor_resume(); + } + + __spm_send_cpu_wakeup_event(); + + INFO("cpu%d: wakesrc = 0x%x, settle = 0x%x, sec = %u\n", + cpu, pwrctrl->wake_src, mmio_read_32(SPM_CLK_SETTLE), + (mmio_read_32(PCM_TIMER_VAL) / 32768)); + INFO("sw_flag = 0x%x 0x%x, req = 0x%x, pwr = 0x%x 0x%x\n", + pwrctrl->pcm_flags, pwrctrl->pcm_flags1, + mmio_read_32(SPM_SRC_REQ), mmio_read_32(PWR_STATUS), + mmio_read_32(PWR_STATUS_2ND)); + + return ret; +} + +static void go_to_spm_after_wfi(int state_id, unsigned int ext_opand, + struct spm_lp_scen *spm_lp, + struct wake_status **status) +{ + unsigned int ext_status = 0U; + + if ((ext_opand & MT_SPM_EX_OP_SET_WDT) != 0U) { + __spm_set_pcm_wdt(0); + } + + if ((ext_opand & MT_SPM_EX_OP_HW_S1_DETECT) != 0U) { + spm_hw_s1_state_monitor_pause(&ext_status); + } + + __spm_ext_int_wakeup_req_clr(); + + __spm_get_wakeup_status(&spm_wakesta, ext_status); + + if (status != NULL) { + *status = &spm_wakesta; + } + + __spm_clean_after_wakeup(); + spm_wake_reason = __spm_output_wake_reason(&spm_wakesta); + + /* EMI workaround */ + if (emi_bak == 0U) { + mmio_clrbits_32(INFRA_EMI_DCM_CFG0, BIT(22)); + } +} + +int spm_conservation(int state_id, unsigned int ext_opand, + struct spm_lp_scen *spm_lp, + unsigned int resource_req) +{ + unsigned int rc_state = resource_req; + + if (spm_lp == NULL) { + return -1; + } + + spin_lock(&spm_lock); + go_to_spm_before_wfi(state_id, ext_opand, spm_lp, rc_state); + spin_unlock(&spm_lock); + + return 0; +} + +void spm_conservation_finish(int state_id, unsigned int ext_opand, struct spm_lp_scen *spm_lp, + struct wake_status **status) +{ + spin_lock(&spm_lock); + go_to_spm_after_wfi(state_id, ext_opand, spm_lp, status); + spin_unlock(&spm_lock); +} + +int spm_conservation_get_result(struct wake_status **res) +{ + if (res == NULL) { + return -1; + } + *res = &spm_wakesta; + return 0; +} diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_conservation.h b/plat/mediatek/drivers/spm/mt8188/mt_spm_conservation.h new file mode 100644 index 0000000..4be8567 --- /dev/null +++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_conservation.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_SPM_CONSERVATION_H +#define MT_SPM_CONSERVATION_H + +#include "mt_spm_internal.h" + +int spm_conservation(int state_id, unsigned int ext_opand, + struct spm_lp_scen *spm_lp, + unsigned int resource_req); +void spm_conservation_finish(int state_id, unsigned int ext_opand, + struct spm_lp_scen *spm_lp, + struct wake_status **status); +int spm_conservation_get_result(struct wake_status **res); + +#endif /* MT_SPM_CONSERVATION_H */ diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_constraint.h b/plat/mediatek/drivers/spm/mt8188/mt_spm_constraint.h new file mode 100644 index 0000000..43bb76b --- /dev/null +++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_constraint.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_SPM_CONSTRAINT_H +#define MT_SPM_CONSTRAINT_H + +#include <lpm/mt_lp_rm.h> + +#define MT_RM_CONSTRAINT_ALLOW_CPU_BUCK_OFF BIT(0) +#define MT_RM_CONSTRAINT_ALLOW_DRAM_S0 BIT(1) +#define MT_RM_CONSTRAINT_ALLOW_DRAM_S1 BIT(2) +#define MT_RM_CONSTRAINT_ALLOW_VCORE_LP BIT(3) +#define MT_RM_CONSTRAINT_ALLOW_INFRA_PDN BIT(4) +#define MT_RM_CONSTRAINT_ALLOW_BUS26M_OFF BIT(5) +#define MT_RM_CONSTRAINT_ALLOW_AP_SUSPEND BIT(6) +#define MT_RM_CONSTRAINT_ALLOW_BBLPM BIT(7) +#define MT_RM_CONSTRAINT_ALLOW_XO_UFS BIT(8) +#define MT_RM_CONSTRAINT_ALLOW_GPS_STATE BIT(9) +#define MT_RM_CONSTRAINT_ALLOW_LVTS_STATE BIT(10) + +enum mt_spm_rm_rc_type { + MT_RM_CONSTRAINT_ID_BUS26M, + MT_RM_CONSTRAINT_ID_SYSPLL, + MT_RM_CONSTRAINT_ID_DRAM, + MT_RM_CONSTRAINT_ID_CPU_BUCK_LDO, + MT_RM_CONSTRAINT_ID_ALL, +}; + +#define MT_SPM_RC_INVALID (0x0) +#define MT_SPM_RC_VALID_SW BIT(0) +#define MT_SPM_RC_VALID_FW BIT(1) +#define MT_SPM_RC_VALID_RESIDNECY BIT(2) +#define MT_SPM_RC_VALID_COND_CHECK BIT(3) +#define MT_SPM_RC_VALID_COND_LATCH BIT(4) +#define MT_SPM_RC_VALID_UFS_H8 BIT(5) +#define MT_SPM_RC_VALID_FLIGHTMODE BIT(6) +#define MT_SPM_RC_VALID_XSOC_BBLPM BIT(7) +#define MT_SPM_RC_VALID_TRACE_EVENT BIT(8) +#define MT_SPM_RC_VALID_TRACE_TIME BIT(9) + +/* MT_RM_CONSTRAINT_SW_VALID | MT_RM_CONSTRAINT_FW_VALID */ +#define MT_SPM_RC_VALID (MT_SPM_RC_VALID_SW) + +#define IS_MT_RM_RC_READY(status) ((status & MT_SPM_RC_VALID) == MT_SPM_RC_VALID) + +struct constraint_status { + uint16_t id; + uint16_t is_valid; + uint32_t is_cond_block; + uint32_t enter_cnt; + uint32_t all_pll_dump; + uint64_t residency; + struct mt_spm_cond_tables *cond_res; +}; + +enum constraint_status_update_type { + CONSTRAINT_UPDATE_VALID, + CONSTRAINT_UPDATE_COND_CHECK, + CONSTRAINT_RESIDNECY, +}; + +enum constraint_status_get_type { + CONSTRAINT_GET_VALID = 0xD0000000, + CONSTRAINT_GET_ENTER_CNT, + CONSTRAINT_GET_RESIDENCY, + CONSTRAINT_GET_COND_EN, + CONSTRAINT_COND_BLOCK, + CONSTRAINT_GET_COND_BLOCK_LATCH, + CONSTRAINT_GET_COND_BLOCK_DETAIL, + CONSTRAINT_GET_RESIDNECY, +}; + +struct rc_common_state { + unsigned int id; + unsigned int act; + unsigned int type; + void *value; +}; + +#define MT_SPM_RC_BBLPM_MODE (MT_SPM_RC_VALID_UFS_H8 | \ + MT_SPM_RC_VALID_FLIGHTMODE | \ + MT_SPM_RC_VALID_XSOC_BBLPM) + +#define IS_MT_SPM_RC_BBLPM_MODE(st) ((st & (MT_SPM_RC_BBLPM_MODE)) == MT_SPM_RC_BBLPM_MODE) + +#endif /* MT_SPM_CONSTRAINT_H */ diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_idle.c b/plat/mediatek/drivers/spm/mt8188/mt_spm_idle.c new file mode 100644 index 0000000..b4dc3f9 --- /dev/null +++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_idle.c @@ -0,0 +1,369 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stddef.h> +#include <stdio.h> +#include <string.h> +#include <common/debug.h> +#include <lib/mmio.h> +#include <drivers/spm/mt_spm_resource_req.h> +#include <lib/pm/mtk_pm.h> +#include <lpm/mt_lp_api.h> + +#include <mt_spm.h> +#include <mt_spm_conservation.h> +#include <mt_spm_idle.h> +#include <mt_spm_internal.h> +#include <mt_spm_reg.h> + +#define SPM_BYPASS_SYSPWREQ_GENERIC (1) + +#define __WAKE_SRC_FOR_IDLE_COMMON__ ( \ + (R12_PCM_TIMER) | \ + (R12_KP_IRQ_B) | \ + (R12_APWDT_EVENT_B) | \ + (R12_APXGPT1_EVENT_B) | \ + (R12_MSDC_WAKEUP_B) | \ + (R12_EINT_EVENT_B) | \ + (R12_SBD_INTR_WAKEUP_B) | \ + (R12_SSPM2SPM_WAKEUP_B) | \ + (R12_SCP2SPM_WAKEUP_B) | \ + (R12_ADSP2SPM_WAKEUP_B) | \ + (R12_USBX_CDSC_B) | \ + (R12_USBX_POWERDWN_B) | \ + (R12_SYS_TIMER_EVENT_B) | \ + (R12_EINT_EVENT_SECURE_B) | \ + (R12_ECE_INT_HDMI_B) | \ + (R12_AFE_IRQ_MCU_B) | \ + (R12_SYS_CIRQ_IRQ_B) | \ + (R12_PCIE_WAKEUPEVENT_B) | \ + (R12_SPM_CPU_WAKEUPEVENT_B) | \ + (R12_APUSYS_WAKE_HOST_B)) + +#if defined(CFG_MICROTRUST_TEE_SUPPORT) +#define WAKE_SRC_FOR_IDLE (__WAKE_SRC_FOR_IDLE_COMMON__) +#else +#define WAKE_SRC_FOR_IDLE (__WAKE_SRC_FOR_IDLE_COMMON__ | R12_SEJ_EVENT_B) +#endif + +static struct pwr_ctrl idle_spm_pwr = { + .wake_src = WAKE_SRC_FOR_IDLE, + + /* SPM_AP_STANDBY_CON */ + /* [0] */ + .reg_wfi_op = 0, + /* [1] */ + .reg_wfi_type = 0, + /* [2] */ + .reg_mp0_cputop_idle_mask = 0, + /* [3] */ + .reg_mp1_cputop_idle_mask = 0, + /* [4] */ + .reg_mcusys_idle_mask = 0, + /* [25] */ + .reg_md_apsrc_1_sel = 0, + /* [26] */ + .reg_md_apsrc_0_sel = 0, + /* [29] */ + .reg_conn_apsrc_sel = 0, + + /* SPM_SRC_REQ */ + /* [0] */ + .reg_spm_apsrc_req = 0, + /* [1] */ + .reg_spm_f26m_req = 0, + /* [3] */ + .reg_spm_infra_req = 0, + /* [4] */ + .reg_spm_vrf18_req = 0, + /* [7] */ + .reg_spm_ddr_en_req = 0, + /* [8] */ + .reg_spm_dvfs_req = 0, + /* [9] */ + .reg_spm_sw_mailbox_req = 0, + /* [10] */ + .reg_spm_sspm_mailbox_req = 0, + /* [11] */ + .reg_spm_adsp_mailbox_req = 0, + /* [12] */ + .reg_spm_scp_mailbox_req = 0, + + /* SPM_SRC_MASK */ + /* [0] */ + .reg_sspm_srcclkena_0_mask_b = 1, + /* [1] */ + .reg_sspm_infra_req_0_mask_b = 1, + /* [2] */ + .reg_sspm_apsrc_req_0_mask_b = 1, + /* [3] */ + .reg_sspm_vrf18_req_0_mask_b = 1, + /* [4] */ + .reg_sspm_ddr_en_0_mask_b = 1, + /* [5] */ + .reg_scp_srcclkena_mask_b = 1, + /* [6] */ + .reg_scp_infra_req_mask_b = 1, + /* [7] */ + .reg_scp_apsrc_req_mask_b = 1, + /* [8] */ + .reg_scp_vrf18_req_mask_b = 1, + /* [9] */ + .reg_scp_ddr_en_mask_b = 1, + /* [10] */ + .reg_audio_dsp_srcclkena_mask_b = 1, + /* [11] */ + .reg_audio_dsp_infra_req_mask_b = 1, + /* [12] */ + .reg_audio_dsp_apsrc_req_mask_b = 1, + /* [13] */ + .reg_audio_dsp_vrf18_req_mask_b = 1, + /* [14] */ + .reg_audio_dsp_ddr_en_mask_b = 1, + /* [15] */ + .reg_apu_srcclkena_mask_b = 1, + /* [16] */ + .reg_apu_infra_req_mask_b = 1, + /* [17] */ + .reg_apu_apsrc_req_mask_b = 1, + /* [18] */ + .reg_apu_vrf18_req_mask_b = 1, + /* [19] */ + .reg_apu_ddr_en_mask_b = 1, + /* [20] */ + .reg_cpueb_srcclkena_mask_b = 1, + /* [21] */ + .reg_cpueb_infra_req_mask_b = 1, + /* [22] */ + .reg_cpueb_apsrc_req_mask_b = 1, + /* [23] */ + .reg_cpueb_vrf18_req_mask_b = 1, + /* [24] */ + .reg_cpueb_ddr_en_mask_b = 1, + /* [25] */ + .reg_bak_psri_srcclkena_mask_b = 0, + /* [26] */ + .reg_bak_psri_infra_req_mask_b = 0, + /* [27] */ + .reg_bak_psri_apsrc_req_mask_b = 0, + /* [28] */ + .reg_bak_psri_vrf18_req_mask_b = 0, + /* [29] */ + .reg_bak_psri_ddr_en_mask_b = 0, + /* [30] */ + .reg_cam_ddren_req_mask_b = 1, + /* [31] */ + .reg_img_ddren_req_mask_b = 1, + + /* SPM_SRC2_MASK */ + /* [0] */ + .reg_msdc0_srcclkena_mask_b = 1, + /* [1] */ + .reg_msdc0_infra_req_mask_b = 1, + /* [2] */ + .reg_msdc0_apsrc_req_mask_b = 1, + /* [3] */ + .reg_msdc0_vrf18_req_mask_b = 1, + /* [4] */ + .reg_msdc0_ddr_en_mask_b = 1, + /* [5] */ + .reg_msdc1_srcclkena_mask_b = 1, + /* [6] */ + .reg_msdc1_infra_req_mask_b = 1, + /* [7] */ + .reg_msdc1_apsrc_req_mask_b = 1, + /* [8] */ + .reg_msdc1_vrf18_req_mask_b = 1, + /* [9] */ + .reg_msdc1_ddr_en_mask_b = 1, + /* [10] */ + .reg_msdc2_srcclkena_mask_b = 1, + /* [11] */ + .reg_msdc2_infra_req_mask_b = 1, + /* [12] */ + .reg_msdc2_apsrc_req_mask_b = 1, + /* [13] */ + .reg_msdc2_vrf18_req_mask_b = 1, + /* [14] */ + .reg_msdc2_ddr_en_mask_b = 1, + /* [15] */ + .reg_ufs_srcclkena_mask_b = 1, + /* [16] */ + .reg_ufs_infra_req_mask_b = 1, + /* [17] */ + .reg_ufs_apsrc_req_mask_b = 1, + /* [18] */ + .reg_ufs_vrf18_req_mask_b = 1, + /* [19] */ + .reg_ufs_ddr_en_mask_b = 1, + /* [20] */ + .reg_usb_srcclkena_mask_b = 1, + /* [21] */ + .reg_usb_infra_req_mask_b = 1, + /* [22] */ + .reg_usb_apsrc_req_mask_b = 1, + /* [23] */ + .reg_usb_vrf18_req_mask_b = 1, + /* [24] */ + .reg_usb_ddr_en_mask_b = 1, + /* [25] */ + .reg_pextp_p0_srcclkena_mask_b = 1, + /* [26] */ + .reg_pextp_p0_infra_req_mask_b = 1, + /* [27] */ + .reg_pextp_p0_apsrc_req_mask_b = 1, + /* [28] */ + .reg_pextp_p0_vrf18_req_mask_b = 1, + /* [29] */ + .reg_pextp_p0_ddr_en_mask_b = 1, + + /* SPM_SRC3_MASK */ + /* [0] */ + .reg_pextp_p1_srcclkena_mask_b = 1, + /* [1] */ + .reg_pextp_p1_infra_req_mask_b = 1, + /* [2] */ + .reg_pextp_p1_apsrc_req_mask_b = 1, + /* [3] */ + .reg_pextp_p1_vrf18_req_mask_b = 1, + /* [4] */ + .reg_pextp_p1_ddr_en_mask_b = 1, + /* [5] */ + .reg_gce0_infra_req_mask_b = 1, + /* [6] */ + .reg_gce0_apsrc_req_mask_b = 1, + /* [7] */ + .reg_gce0_vrf18_req_mask_b = 1, + /* [8] */ + .reg_gce0_ddr_en_mask_b = 1, + /* [9] */ + .reg_gce1_infra_req_mask_b = 1, + /* [10] */ + .reg_gce1_apsrc_req_mask_b = 1, + /* [11] */ + .reg_gce1_vrf18_req_mask_b = 1, + /* [12] */ + .reg_gce1_ddr_en_mask_b = 1, + /* [13] */ + .reg_spm_srcclkena_reserved_mask_b = 1, + /* [14] */ + .reg_spm_infra_req_reserved_mask_b = 1, + /* [15] */ + .reg_spm_apsrc_req_reserved_mask_b = 1, + /* [16] */ + .reg_spm_vrf18_req_reserved_mask_b = 1, + /* [17] */ + .reg_spm_ddr_en_reserved_mask_b = 1, + /* [18] */ + .reg_disp0_apsrc_req_mask_b = 1, + /* [19] */ + .reg_disp0_ddr_en_mask_b = 1, + /* [20] */ + .reg_disp1_apsrc_req_mask_b = 1, + /* [21] */ + .reg_disp1_ddr_en_mask_b = 1, + /* [22] */ + .reg_disp2_apsrc_req_mask_b = 1, + /* [23] */ + .reg_disp2_ddr_en_mask_b = 1, + /* [24] */ + .reg_disp3_apsrc_req_mask_b = 1, + /* [25] */ + .reg_disp3_ddr_en_mask_b = 1, + /* [26] */ + .reg_infrasys_apsrc_req_mask_b = 0, + /* [27] */ + .reg_infrasys_ddr_en_mask_b = 1, + + /* [28] */ + .reg_cg_check_srcclkena_mask_b = 1, + /* [29] */ + .reg_cg_check_apsrc_req_mask_b = 1, + /* [30] */ + .reg_cg_check_vrf18_req_mask_b = 1, + /* [31] */ + .reg_cg_check_ddr_en_mask_b = 1, + + /* SPM_SRC4_MASK */ + /* [8:0] */ + .reg_mcusys_merge_apsrc_req_mask_b = 0, + /* [17:9] */ + .reg_mcusys_merge_ddr_en_mask_b = 0, + /* [19:18] */ + .reg_dramc_md32_infra_req_mask_b = 3, + /* [21:20] */ + .reg_dramc_md32_vrf18_req_mask_b = 3, + /* [23:22] */ + .reg_dramc_md32_ddr_en_mask_b = 0, + /* [24] */ + .reg_dvfsrc_event_trigger_mask_b = 1, + + /* SPM_WAKEUP_EVENT_MASK2 */ + /* [3:0] */ + .reg_sc_sw2spm_wakeup_mask_b = 0, + /* [4] */ + .reg_sc_adsp2spm_wakeup_mask_b = 0, + /* [8:5] */ + .reg_sc_sspm2spm_wakeup_mask_b = 0, + /* [9] */ + .reg_sc_scp2spm_wakeup_mask_b = 0, + /* [10] */ + .reg_csyspwrup_ack_mask = 0, + /* [11] */ + .reg_csyspwrup_req_mask = 1, + + /* SPM_WAKEUP_EVENT_MASK */ + /* [31:0] */ + .reg_wakeup_event_mask = 0xC1282203, + + /* SPM_WAKEUP_EVENT_EXT_MASK */ + /* [31:0] */ + .reg_ext_wakeup_event_mask = 0xFFFFFFFF, +}; + +struct spm_lp_scen idle_spm_lp = { + .pwrctrl = &idle_spm_pwr, +}; + +int mt_spm_idle_generic_enter(int state_id, unsigned int ext_opand, spm_idle_conduct fn) +{ + int ret = 0; + unsigned int src_req = 0U; + + if (fn != NULL) { + fn(state_id, &idle_spm_lp, &src_req); + } + + ret = spm_conservation(state_id, ext_opand, &idle_spm_lp, src_req); + + if (ret == 0) { + struct mt_lp_publish_event event = { + .id = MT_LPM_PUBEVENTS_SYS_POWER_OFF, + .val.u32 = 0U, + }; + + MT_LP_PUBLISH_EVENT(&event); + } + return ret; +} + +void mt_spm_idle_generic_resume(int state_id, unsigned int ext_opand, + struct wake_status **status, + spm_idle_conduct_restore fn) +{ + struct mt_lp_publish_event event = { + .id = MT_LPM_PUBEVENTS_SYS_POWER_ON, + .val.u32 = 0U, + }; + + ext_opand |= (MT_SPM_EX_OP_TIME_CHECK | MT_SPM_EX_OP_TIME_OBS); + spm_conservation_finish(state_id, ext_opand, &idle_spm_lp, status); + + if (spm_unlikely(fn)) { + fn(state_id, &idle_spm_lp, *status); + } + MT_LP_PUBLISH_EVENT(&event); +} diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_idle.h b/plat/mediatek/drivers/spm/mt8188/mt_spm_idle.h new file mode 100644 index 0000000..4d78a28 --- /dev/null +++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_idle.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_SPM_IDLE_H +#define MT_SPM_IDLE_H + +#include "mt_spm_internal.h" + +typedef int (*spm_idle_conduct)(int state_id, + struct spm_lp_scen *spm_lp, + unsigned int *resource_req); +typedef int (*spm_idle_conduct_restore)(int state_id, + struct spm_lp_scen *spm_lp, + struct wake_status *status); + +int mt_spm_idle_generic_enter(int state_id, unsigned int ext_opand, spm_idle_conduct fn); +void mt_spm_idle_generic_resume(int state_id, unsigned int ext_opand, + struct wake_status **status, + spm_idle_conduct_restore fn); + +#endif diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.c b/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.c new file mode 100644 index 0000000..5eb16b3 --- /dev/null +++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.c @@ -0,0 +1,465 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <stddef.h> +#include <stdio.h> +#include <string.h> + +#include <common/debug.h> +#include <drivers/delay_timer.h> +#include <lib/mmio.h> + +#include <drivers/spm/mt_spm_resource_req.h> +#include "mt_spm.h" +#include "mt_spm_internal.h" +#include "mt_spm_pmic_wrap.h" +#include "mt_spm_reg.h" +#include <platform_def.h> + +#define SPM_INIT_DONE_US (20) /* Simulation result */ + +wake_reason_t __spm_output_wake_reason(const struct wake_status *wakesta) +{ + uint32_t bk_vtcxo_dur, spm_26m_off_pct; + wake_reason_t wr = WR_UNKNOWN; + + if (wakesta == NULL) { + return wr; + } + + if (wakesta->is_abort != 0U) { + VERBOSE("SPM EARLY WAKE r12 = 0x%x, debug_flag = 0x%x 0x%x\n", + wakesta->tr.comm.r12, + wakesta->tr.comm.debug_flag, wakesta->tr.comm.debug_flag1); + VERBOSE("SPM EARLY WAKE sw_flag = 0x%x 0x%x b_sw_flag = 0x%x 0x%x\n", + wakesta->sw_flag0, wakesta->sw_flag1, + wakesta->tr.comm.b_sw_flag0, wakesta->tr.comm.b_sw_flag1); + } + + if ((wakesta->tr.comm.r12 & R12_PCM_TIMER) != 0U) { + + if ((wakesta->wake_misc & WAKE_MISC_PCM_TIMER_EVENT) != 0U) { + wr = WR_PCM_TIMER; + } + } + + INFO("r12 = 0x%x, r12_ext = 0x%x, r13 = 0x%x, debug_flag = 0x%x 0x%x\n", + wakesta->tr.comm.r12, wakesta->r12_ext, wakesta->tr.comm.r13, wakesta->tr.comm.debug_flag, + wakesta->tr.comm.debug_flag1); + INFO("raw_sta = 0x%x 0x%x 0x%x, idle_sta = 0x%x, cg_check_sta = 0x%x\n", + wakesta->tr.comm.raw_sta, wakesta->md32pcm_wakeup_sta, + wakesta->md32pcm_event_sta, wakesta->idle_sta, + wakesta->cg_check_sta); + INFO("req_sta = 0x%x 0x%x 0x%x 0x%x 0x%x, isr = 0x%x\n", + wakesta->tr.comm.req_sta0, wakesta->tr.comm.req_sta1, wakesta->tr.comm.req_sta2, + wakesta->tr.comm.req_sta3, wakesta->tr.comm.req_sta4, wakesta->isr); + INFO("rt_req_sta0 = 0x%x, rt_req_sta1 = 0x%x, rt_req_sta2 = 0x%x\n", + wakesta->rt_req_sta0, wakesta->rt_req_sta1, wakesta->rt_req_sta2); + INFO("rt_req_sta3 = 0x%x, dram_sw_con_3 = 0x%x, raw_ext_sta = 0x%x\n", + wakesta->rt_req_sta3, wakesta->rt_req_sta4, wakesta->raw_ext_sta); + INFO("wake_misc = 0x%x, pcm_flag = 0x%x 0x%x 0x%x 0x%x, req = 0x%x\n", + wakesta->wake_misc, wakesta->sw_flag0, wakesta->sw_flag1, + wakesta->tr.comm.b_sw_flag0, wakesta->tr.comm.b_sw_flag1, wakesta->src_req); + INFO("clk_settle = 0x%x, wlk_cntcv_l = 0x%x, wlk_cntcv_h = 0x%x\n", + wakesta->clk_settle, mmio_read_32(SYS_TIMER_VALUE_L), + mmio_read_32(SYS_TIMER_VALUE_H)); + + if (wakesta->tr.comm.timer_out != 0U) { + bk_vtcxo_dur = mmio_read_32(SPM_BK_VTCXO_DUR); + spm_26m_off_pct = (100 * bk_vtcxo_dur) / wakesta->tr.comm.timer_out; + INFO("spm_26m_off_pct = %u\n", spm_26m_off_pct); + } + + return wr; +} + +void __spm_set_cpu_status(unsigned int cpu) +{ + if (cpu >= 8) { + ERROR("%s: error cpu number %d\n", __func__, cpu); + return; + } + mmio_write_32(ROOT_CPUTOP_ADDR, BIT(cpu)); + mmio_write_32(ROOT_CORE_ADDR, SPM_CPU0_PWR_CON + (cpu * 0x4) + 0x20000000); + /* Notify MCUPM to wake the target CPU up */ + mmio_write_32(MCUPM_MBOX_WAKEUP_CPU, cpu); +} + +void __spm_src_req_update(const struct pwr_ctrl *pwrctrl, unsigned int resource_usage) +{ + + uint8_t reg_spm_apsrc_req = (resource_usage & MT_SPM_DRAM_S0) ? + 1 : pwrctrl->reg_spm_apsrc_req; + uint8_t reg_spm_ddr_en_req = (resource_usage & MT_SPM_DRAM_S1) ? + 1 : pwrctrl->reg_spm_ddr_en_req; + uint8_t reg_spm_vrf18_req = (resource_usage & MT_SPM_SYSPLL) ? + 1 : pwrctrl->reg_spm_vrf18_req; + uint8_t reg_spm_infra_req = (resource_usage & MT_SPM_INFRA) ? + 1 : pwrctrl->reg_spm_infra_req; + uint8_t reg_spm_f26m_req = (resource_usage & (MT_SPM_26M | MT_SPM_XO_FPM)) ? + 1 : pwrctrl->reg_spm_f26m_req; + + /* SPM_SRC_REQ */ + mmio_write_32(SPM_SRC_REQ, + ((reg_spm_apsrc_req & 0x1) << 0) | + ((reg_spm_f26m_req & 0x1) << 1) | + ((reg_spm_infra_req & 0x1) << 3) | + ((reg_spm_vrf18_req & 0x1) << 4) | + ((reg_spm_ddr_en_req & 0x1) << 7) | + ((pwrctrl->reg_spm_dvfs_req & 0x1) << 8) | + ((pwrctrl->reg_spm_sw_mailbox_req & 0x1) << 9) | + ((pwrctrl->reg_spm_sspm_mailbox_req & 0x1) << 10) | + ((pwrctrl->reg_spm_adsp_mailbox_req & 0x1) << 11) | + ((pwrctrl->reg_spm_scp_mailbox_req & 0x1) << 12)); +} + +void __spm_set_power_control(const struct pwr_ctrl *pwrctrl) +{ + /* SPM_AP_STANDBY_CON */ + mmio_write_32(SPM_AP_STANDBY_CON, + ((pwrctrl->reg_wfi_op & 0x1) << 0) | + ((pwrctrl->reg_wfi_type & 0x1) << 1) | + ((pwrctrl->reg_mp0_cputop_idle_mask & 0x1) << 2) | + ((pwrctrl->reg_mp1_cputop_idle_mask & 0x1) << 3) | + ((pwrctrl->reg_mcusys_idle_mask & 0x1) << 4) | + ((pwrctrl->reg_md_apsrc_1_sel & 0x1) << 25) | + ((pwrctrl->reg_md_apsrc_0_sel & 0x1) << 26) | + ((pwrctrl->reg_conn_apsrc_sel & 0x1) << 29)); + + /* SPM_SRC_REQ */ + mmio_write_32(SPM_SRC_REQ, + ((pwrctrl->reg_spm_apsrc_req & 0x1) << 0) | + ((pwrctrl->reg_spm_f26m_req & 0x1) << 1) | + ((pwrctrl->reg_spm_infra_req & 0x1) << 3) | + ((pwrctrl->reg_spm_vrf18_req & 0x1) << 4) | + ((pwrctrl->reg_spm_ddr_en_req & 0x1) << 7) | + ((pwrctrl->reg_spm_dvfs_req & 0x1) << 8) | + ((pwrctrl->reg_spm_sw_mailbox_req & 0x1) << 9) | + ((pwrctrl->reg_spm_sspm_mailbox_req & 0x1) << 10) | + ((pwrctrl->reg_spm_adsp_mailbox_req & 0x1) << 11) | + ((pwrctrl->reg_spm_scp_mailbox_req & 0x1) << 12)); + + /* SPM_SRC_MASK */ + mmio_write_32(SPM_SRC_MASK, + ((pwrctrl->reg_sspm_srcclkena_0_mask_b & 0x1) << 0) | + ((pwrctrl->reg_sspm_infra_req_0_mask_b & 0x1) << 1) | + ((pwrctrl->reg_sspm_apsrc_req_0_mask_b & 0x1) << 2) | + ((pwrctrl->reg_sspm_vrf18_req_0_mask_b & 0x1) << 3) | + ((pwrctrl->reg_sspm_ddr_en_0_mask_b & 0x1) << 4) | + ((pwrctrl->reg_scp_srcclkena_mask_b & 0x1) << 5) | + ((pwrctrl->reg_scp_infra_req_mask_b & 0x1) << 6) | + ((pwrctrl->reg_scp_apsrc_req_mask_b & 0x1) << 7) | + ((pwrctrl->reg_scp_vrf18_req_mask_b & 0x1) << 8) | + ((pwrctrl->reg_scp_ddr_en_mask_b & 0x1) << 9) | + ((pwrctrl->reg_audio_dsp_srcclkena_mask_b & 0x1) << 10) | + ((pwrctrl->reg_audio_dsp_infra_req_mask_b & 0x1) << 11) | + ((pwrctrl->reg_audio_dsp_apsrc_req_mask_b & 0x1) << 12) | + ((pwrctrl->reg_audio_dsp_vrf18_req_mask_b & 0x1) << 13) | + ((pwrctrl->reg_audio_dsp_ddr_en_mask_b & 0x1) << 14) | + ((pwrctrl->reg_apu_srcclkena_mask_b & 0x1) << 15) | + ((pwrctrl->reg_apu_infra_req_mask_b & 0x1) << 16) | + ((pwrctrl->reg_apu_apsrc_req_mask_b & 0x1) << 17) | + ((pwrctrl->reg_apu_vrf18_req_mask_b & 0x1) << 18) | + ((pwrctrl->reg_apu_ddr_en_mask_b & 0x1) << 19) | + ((pwrctrl->reg_cpueb_srcclkena_mask_b & 0x1) << 20) | + ((pwrctrl->reg_cpueb_infra_req_mask_b & 0x1) << 21) | + ((pwrctrl->reg_cpueb_apsrc_req_mask_b & 0x1) << 22) | + ((pwrctrl->reg_cpueb_vrf18_req_mask_b & 0x1) << 23) | + ((pwrctrl->reg_cpueb_ddr_en_mask_b & 0x1) << 24) | + ((pwrctrl->reg_bak_psri_srcclkena_mask_b & 0x1) << 25) | + ((pwrctrl->reg_bak_psri_infra_req_mask_b & 0x1) << 26) | + ((pwrctrl->reg_bak_psri_apsrc_req_mask_b & 0x1) << 27) | + ((pwrctrl->reg_bak_psri_vrf18_req_mask_b & 0x1) << 28) | + ((pwrctrl->reg_bak_psri_ddr_en_mask_b & 0x1) << 29) | + ((pwrctrl->reg_cam_ddren_req_mask_b & 0x1) << 30) | + ((pwrctrl->reg_img_ddren_req_mask_b & 0x1) << 31)); + + /* SPM_SRC2_MASK */ + mmio_write_32(SPM_SRC2_MASK, + ((pwrctrl->reg_msdc0_srcclkena_mask_b & 0x1) << 0) | + ((pwrctrl->reg_msdc0_infra_req_mask_b & 0x1) << 1) | + ((pwrctrl->reg_msdc0_apsrc_req_mask_b & 0x1) << 2) | + ((pwrctrl->reg_msdc0_vrf18_req_mask_b & 0x1) << 3) | + ((pwrctrl->reg_msdc0_ddr_en_mask_b & 0x1) << 4) | + ((pwrctrl->reg_msdc1_srcclkena_mask_b & 0x1) << 5) | + ((pwrctrl->reg_msdc1_infra_req_mask_b & 0x1) << 6) | + ((pwrctrl->reg_msdc1_apsrc_req_mask_b & 0x1) << 7) | + ((pwrctrl->reg_msdc1_vrf18_req_mask_b & 0x1) << 8) | + ((pwrctrl->reg_msdc1_ddr_en_mask_b & 0x1) << 9) | + ((pwrctrl->reg_msdc2_srcclkena_mask_b & 0x1) << 10) | + ((pwrctrl->reg_msdc2_infra_req_mask_b & 0x1) << 11) | + ((pwrctrl->reg_msdc2_apsrc_req_mask_b & 0x1) << 12) | + ((pwrctrl->reg_msdc2_vrf18_req_mask_b & 0x1) << 13) | + ((pwrctrl->reg_msdc2_ddr_en_mask_b & 0x1) << 14) | + ((pwrctrl->reg_ufs_srcclkena_mask_b & 0x1) << 15) | + ((pwrctrl->reg_ufs_infra_req_mask_b & 0x1) << 16) | + ((pwrctrl->reg_ufs_apsrc_req_mask_b & 0x1) << 17) | + ((pwrctrl->reg_ufs_vrf18_req_mask_b & 0x1) << 18) | + ((pwrctrl->reg_ufs_ddr_en_mask_b & 0x1) << 19) | + ((pwrctrl->reg_usb_srcclkena_mask_b & 0x1) << 20) | + ((pwrctrl->reg_usb_infra_req_mask_b & 0x1) << 21) | + ((pwrctrl->reg_usb_apsrc_req_mask_b & 0x1) << 22) | + ((pwrctrl->reg_usb_vrf18_req_mask_b & 0x1) << 23) | + ((pwrctrl->reg_usb_ddr_en_mask_b & 0x1) << 24) | + ((pwrctrl->reg_pextp_p0_srcclkena_mask_b & 0x1) << 25) | + ((pwrctrl->reg_pextp_p0_infra_req_mask_b & 0x1) << 26) | + ((pwrctrl->reg_pextp_p0_apsrc_req_mask_b & 0x1) << 27) | + ((pwrctrl->reg_pextp_p0_vrf18_req_mask_b & 0x1) << 28) | + ((pwrctrl->reg_pextp_p0_ddr_en_mask_b & 0x1) << 29)); + + /* SPM_SRC3_MASK */ + mmio_write_32(SPM_SRC3_MASK, + ((pwrctrl->reg_pextp_p1_srcclkena_mask_b & 0x1) << 0) | + ((pwrctrl->reg_pextp_p1_infra_req_mask_b & 0x1) << 1) | + ((pwrctrl->reg_pextp_p1_apsrc_req_mask_b & 0x1) << 2) | + ((pwrctrl->reg_pextp_p1_vrf18_req_mask_b & 0x1) << 3) | + ((pwrctrl->reg_pextp_p1_ddr_en_mask_b & 0x1) << 4) | + ((pwrctrl->reg_gce0_infra_req_mask_b & 0x1) << 5) | + ((pwrctrl->reg_gce0_apsrc_req_mask_b & 0x1) << 6) | + ((pwrctrl->reg_gce0_vrf18_req_mask_b & 0x1) << 7) | + ((pwrctrl->reg_gce0_ddr_en_mask_b & 0x1) << 8) | + ((pwrctrl->reg_gce1_infra_req_mask_b & 0x1) << 9) | + ((pwrctrl->reg_gce1_apsrc_req_mask_b & 0x1) << 10) | + ((pwrctrl->reg_gce1_vrf18_req_mask_b & 0x1) << 11) | + ((pwrctrl->reg_gce1_ddr_en_mask_b & 0x1) << 12) | + ((pwrctrl->reg_spm_srcclkena_reserved_mask_b & 0x1) << 13) | + ((pwrctrl->reg_spm_infra_req_reserved_mask_b & 0x1) << 14) | + ((pwrctrl->reg_spm_apsrc_req_reserved_mask_b & 0x1) << 15) | + ((pwrctrl->reg_spm_vrf18_req_reserved_mask_b & 0x1) << 16) | + ((pwrctrl->reg_spm_ddr_en_reserved_mask_b & 0x1) << 17) | + ((pwrctrl->reg_disp0_ddr_en_mask_b & 0x1) << 18) | + ((pwrctrl->reg_disp0_ddr_en_mask_b & 0x1) << 19) | + ((pwrctrl->reg_disp1_apsrc_req_mask_b & 0x1) << 20) | + ((pwrctrl->reg_disp1_ddr_en_mask_b & 0x1) << 21) | + ((pwrctrl->reg_disp2_apsrc_req_mask_b & 0x1) << 22) | + ((pwrctrl->reg_disp2_ddr_en_mask_b & 0x1) << 23) | + ((pwrctrl->reg_disp3_apsrc_req_mask_b & 0x1) << 24) | + ((pwrctrl->reg_disp3_ddr_en_mask_b & 0x1) << 25) | + ((pwrctrl->reg_infrasys_apsrc_req_mask_b & 0x1) << 26) | + ((pwrctrl->reg_infrasys_ddr_en_mask_b & 0x1) << 27)); + + /* SPM_SRC4_MASK */ + mmio_write_32(SPM_SRC4_MASK, + ((pwrctrl->reg_mcusys_merge_apsrc_req_mask_b & 0x1ff) << 0) | + ((pwrctrl->reg_mcusys_merge_ddr_en_mask_b & 0x1ff) << 9) | + ((pwrctrl->reg_dramc_md32_infra_req_mask_b & 0x3) << 18) | + ((pwrctrl->reg_dramc_md32_vrf18_req_mask_b & 0x3) << 20) | + ((pwrctrl->reg_dramc_md32_ddr_en_mask_b & 0x3) << 22) | + ((pwrctrl->reg_dvfsrc_event_trigger_mask_b & 0x1) << 24)); + + /* SPM_WAKEUP_EVENT_MASK */ + mmio_write_32(SPM_WAKEUP_EVENT_MASK, + ((pwrctrl->reg_wakeup_event_mask & 0xffffffff) << 0)); + + /* SPM_WAKEUP_EVENT_EXT_MASK */ + mmio_write_32(SPM_WAKEUP_EVENT_EXT_MASK, + ((pwrctrl->reg_ext_wakeup_event_mask & 0xffffffff) << 0)); +} + +void __spm_set_wakeup_event(const struct pwr_ctrl *pwrctrl) +{ + unsigned int val, mask; + + /* toggle event counter clear */ + mmio_setbits_32(PCM_CON1, SPM_REGWR_CFG_KEY | SPM_EVENT_COUNTER_CLR_LSB); + /* toggle for reset SYS TIMER start point */ + mmio_setbits_32(SYS_TIMER_CON, SYS_TIMER_START_EN_LSB); + + if (pwrctrl->timer_val_cust == 0U) { + val = (pwrctrl->timer_val != 0U) ? pwrctrl->timer_val : PCM_TIMER_MAX; + } else { + val = pwrctrl->timer_val_cust; + } + + mmio_write_32(PCM_TIMER_VAL, val); + mmio_setbits_32(PCM_CON1, SPM_REGWR_CFG_KEY | RG_PCM_TIMER_EN_LSB); + + /* unmask AP wakeup source */ + if (pwrctrl->wake_src_cust == 0U) { + mask = pwrctrl->wake_src; + } else { + mask = pwrctrl->wake_src_cust; + } + + mmio_write_32(SPM_WAKEUP_EVENT_MASK, ~mask); + + /* unmask SPM ISR (keep TWAM setting) */ + mmio_setbits_32(SPM_IRQ_MASK, ISRM_RET_IRQ_AUX); + + /* toggle event counter clear */ + mmio_clrsetbits_32(PCM_CON1, SPM_EVENT_COUNTER_CLR_LSB, SPM_REGWR_CFG_KEY); + /* toggle for reset SYS TIMER start point */ + mmio_clrbits_32(SYS_TIMER_CON, SYS_TIMER_START_EN_LSB); +} + +void __spm_set_pcm_flags(struct pwr_ctrl *pwrctrl) +{ + /* set PCM flags and data */ + if (pwrctrl->pcm_flags_cust_clr != 0U) { + pwrctrl->pcm_flags &= ~pwrctrl->pcm_flags_cust_clr; + } + if (pwrctrl->pcm_flags_cust_set != 0U) { + pwrctrl->pcm_flags |= pwrctrl->pcm_flags_cust_set; + } + if (pwrctrl->pcm_flags1_cust_clr != 0U) { + pwrctrl->pcm_flags1 &= ~pwrctrl->pcm_flags1_cust_clr; + } + if (pwrctrl->pcm_flags1_cust_set != 0U) { + pwrctrl->pcm_flags1 |= pwrctrl->pcm_flags1_cust_set; + } + + mmio_write_32(SPM_SW_FLAG_0, pwrctrl->pcm_flags); + + mmio_write_32(SPM_SW_FLAG_1, pwrctrl->pcm_flags1); + + mmio_write_32(SPM_SW_RSV_7, pwrctrl->pcm_flags); + + mmio_write_32(SPM_SW_RSV_8, pwrctrl->pcm_flags1); +} + +void __spm_get_wakeup_status(struct wake_status *wakesta, unsigned int ext_status) +{ + /* get wakeup event */ + wakesta->tr.comm.r12 = mmio_read_32(SPM_BK_WAKE_EVENT); /* backup of PCM_REG12_DATA */ + wakesta->r12_ext = mmio_read_32(SPM_WAKEUP_EXT_STA); + wakesta->tr.comm.raw_sta = mmio_read_32(SPM_WAKEUP_STA); + wakesta->raw_ext_sta = mmio_read_32(SPM_WAKEUP_EXT_STA); + wakesta->md32pcm_wakeup_sta = mmio_read_32(MD32PCM_WAKEUP_STA); + wakesta->md32pcm_event_sta = mmio_read_32(MD32PCM_EVENT_STA); + wakesta->wake_misc = mmio_read_32(SPM_BK_WAKE_MISC); /* backup of SPM_WAKEUP_MISC */ + + /* get sleep time */ + wakesta->tr.comm.timer_out = + mmio_read_32(SPM_BK_PCM_TIMER); /* backup of PCM_TIMER_OUT */ + + /* get other SYS and co-clock status */ + wakesta->tr.comm.r13 = mmio_read_32(PCM_REG13_DATA); + wakesta->idle_sta = mmio_read_32(SUBSYS_IDLE_STA); + wakesta->tr.comm.req_sta0 = mmio_read_32(SRC_REQ_STA_0); + wakesta->tr.comm.req_sta1 = mmio_read_32(SRC_REQ_STA_1); + wakesta->tr.comm.req_sta2 = mmio_read_32(SRC_REQ_STA_2); + wakesta->tr.comm.req_sta3 = mmio_read_32(SRC_REQ_STA_3); + wakesta->tr.comm.req_sta4 = mmio_read_32(SRC_REQ_STA_4); + + /* get debug flag for PCM execution check */ + wakesta->tr.comm.debug_flag = mmio_read_32(PCM_WDT_LATCH_SPARE_0); + wakesta->tr.comm.debug_flag1 = mmio_read_32(PCM_WDT_LATCH_SPARE_1); + + if ((ext_status & SPM_INTERNAL_STATUS_HW_S1) != 0U) { + wakesta->tr.comm.debug_flag |= (SPM_DBG_DEBUG_IDX_DDREN_WAKE | + SPM_DBG_DEBUG_IDX_DDREN_SLEEP); + mmio_write_32(PCM_WDT_LATCH_SPARE_0, wakesta->tr.comm.debug_flag); + } + + /* get backup SW flag status */ + wakesta->tr.comm.b_sw_flag0 = mmio_read_32(SPM_SW_RSV_7); /* SPM_SW_RSV_7 */ + wakesta->tr.comm.b_sw_flag1 = mmio_read_32(SPM_SW_RSV_8); /* SPM_SW_RSV_8 */ + + /* record below spm info for debug */ + wakesta->src_req = mmio_read_32(SPM_SRC_REQ); + + /* get HW CG check status */ + wakesta->cg_check_sta = mmio_read_32(SPM_CG_CHECK_STA); + + wakesta->rt_req_sta0 = mmio_read_32(SPM_SW_RSV_2); + wakesta->rt_req_sta1 = mmio_read_32(SPM_SW_RSV_3); + wakesta->rt_req_sta2 = mmio_read_32(SPM_SW_RSV_4); + wakesta->rt_req_sta3 = mmio_read_32(SPM_SW_RSV_5); + wakesta->rt_req_sta4 = mmio_read_32(SPM_SW_RSV_6); + + /* get ISR status */ + wakesta->isr = mmio_read_32(SPM_IRQ_STA); + + /* get SW flag status */ + wakesta->sw_flag0 = mmio_read_32(SPM_SW_FLAG_0); + wakesta->sw_flag1 = mmio_read_32(SPM_SW_FLAG_1); + + /* get CLK SETTLE */ + wakesta->clk_settle = mmio_read_32(SPM_CLK_SETTLE); + + /* check abort */ + wakesta->is_abort = wakesta->tr.comm.debug_flag & DEBUG_ABORT_MASK; + wakesta->is_abort |= wakesta->tr.comm.debug_flag1 & DEBUG_ABORT_MASK_1; +} + +void __spm_clean_after_wakeup(void) +{ + /* + * Copy SPM_WAKEUP_STA to SPM_BK_WAKE_EVENT before clear SPM_WAKEUP_STA + * + * CPU dormant driver @kernel will copy edge-trig IRQ pending + * (recorded @SPM_BK_WAKE_EVENT) to GIC + */ + mmio_write_32(SPM_BK_WAKE_EVENT, mmio_read_32(SPM_WAKEUP_STA) | + mmio_read_32(SPM_BK_WAKE_EVENT)); + + /* clean CPU wakeup event */ + mmio_write_32(SPM_CPU_WAKEUP_EVENT, 0U); + + /* clean wakeup event raw status (for edge trigger event) */ + mmio_write_32(SPM_WAKEUP_EVENT_MASK, 0xefffffff); /* bit[28] for cpu wake up event */ + + /* clean ISR status (except TWAM) */ + mmio_setbits_32(SPM_IRQ_MASK, ISRM_ALL_EXC_TWAM); + mmio_write_32(SPM_IRQ_STA, ISRC_ALL_EXC_TWAM); + mmio_write_32(SPM_SWINT_CLR, PCM_SW_INT_ALL); +} + +void __spm_set_pcm_wdt(int en) +{ + /* enable PCM WDT (normal mode) to start count if needed */ + if (en != 0) { + mmio_clrsetbits_32(PCM_CON1, RG_PCM_WDT_WAKE_LSB, SPM_REGWR_CFG_KEY); + + if (mmio_read_32(PCM_TIMER_VAL) > PCM_TIMER_MAX) { + mmio_write_32(PCM_TIMER_VAL, PCM_TIMER_MAX); + } + mmio_write_32(PCM_WDT_VAL, mmio_read_32(PCM_TIMER_VAL) + PCM_WDT_TIMEOUT); + mmio_setbits_32(PCM_CON1, SPM_REGWR_CFG_KEY | RG_PCM_WDT_EN_LSB); + } else { + mmio_clrsetbits_32(PCM_CON1, RG_PCM_WDT_EN_LSB, SPM_REGWR_CFG_KEY); + } +} + +void __spm_send_cpu_wakeup_event(void) +{ + mmio_write_32(SPM_CPU_WAKEUP_EVENT, 1); + /* SPM will clear SPM_CPU_WAKEUP_EVENT */ +} + +void __spm_ext_int_wakeup_req_clr(void) +{ + mmio_write_32(EXT_INT_WAKEUP_REQ_CLR, mmio_read_32(ROOT_CPUTOP_ADDR)); + + /* clear spm2mcupm wakeup interrupt status */ + mmio_write_32(SPM2CPUEB_CON, 0); +} + +void __spm_clean_before_wfi(void) +{ +} + +void __spm_hw_s1_state_monitor(int en, unsigned int *status) +{ + unsigned int reg; + + if (en != 0) { + mmio_clrsetbits_32(SPM_ACK_CHK_CON_3, SPM_ACK_CHK_3_CON_CLR_ALL, + SPM_ACK_CHK_3_CON_EN); + } else { + reg = mmio_read_32(SPM_ACK_CHK_CON_3); + + if ((reg & SPM_ACK_CHK_3_CON_RESULT) != 0U) { + if (status != NULL) { + *status |= SPM_INTERNAL_STATUS_HW_S1; + } + } + + mmio_clrsetbits_32(SPM_ACK_CHK_CON_3, SPM_ACK_CHK_3_CON_EN, + (SPM_ACK_CHK_3_CON_HW_MODE_TRIG | SPM_ACK_CHK_3_CON_CLR_ALL)); + } +} diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.h b/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.h new file mode 100644 index 0000000..5e3390f --- /dev/null +++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.h @@ -0,0 +1,676 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_SPM_INTERNAL_H +#define MT_SPM_INTERNAL_H + +#include <mt_spm.h> + +/* PCM_WDT_VAL */ +#define PCM_WDT_TIMEOUT (30 * 32768) /* 30s */ +/* PCM_TIMER_VAL */ +#define PCM_TIMER_MAX (0xffffffff - PCM_WDT_TIMEOUT) + +/* PCM_PWR_IO_EN */ +#define PCM_PWRIO_EN_R0 BIT(0) +#define PCM_PWRIO_EN_R7 BIT(7) +#define PCM_RF_SYNC_R0 BIT(16) +#define PCM_RF_SYNC_R6 BIT(22) +#define PCM_RF_SYNC_R7 BIT(23) + +/* SPM_SWINT */ +#define PCM_SW_INT0 BIT(0) +#define PCM_SW_INT1 BIT(1) +#define PCM_SW_INT2 BIT(2) +#define PCM_SW_INT3 BIT(3) +#define PCM_SW_INT4 BIT(4) +#define PCM_SW_INT5 BIT(5) +#define PCM_SW_INT6 BIT(6) +#define PCM_SW_INT7 BIT(7) +#define PCM_SW_INT8 BIT(8) +#define PCM_SW_INT9 BIT(9) +#define PCM_SW_INT_ALL (PCM_SW_INT9 | PCM_SW_INT8 | PCM_SW_INT7 | \ + PCM_SW_INT6 | PCM_SW_INT5 | PCM_SW_INT4 | \ + PCM_SW_INT3 | PCM_SW_INT2 | PCM_SW_INT1 | \ + PCM_SW_INT0) + +/* SPM_AP_STANDBY_CON */ +#define WFI_OP_AND (1U) +#define WFI_OP_OR (0U) + +/* SPM_IRQ_MASK */ +#define ISRM_TWAM BIT(2) +#define ISRM_PCM_RETURN BIT(3) +#define ISRM_RET_IRQ0 BIT(8) +#define ISRM_RET_IRQ1 BIT(9) +#define ISRM_RET_IRQ2 BIT(10) +#define ISRM_RET_IRQ3 BIT(11) +#define ISRM_RET_IRQ4 BIT(12) +#define ISRM_RET_IRQ5 BIT(13) +#define ISRM_RET_IRQ6 BIT(14) +#define ISRM_RET_IRQ7 BIT(15) +#define ISRM_RET_IRQ8 BIT(16) +#define ISRM_RET_IRQ9 BIT(17) +#define ISRM_RET_IRQ_AUX ((ISRM_RET_IRQ9) | (ISRM_RET_IRQ8) | \ + (ISRM_RET_IRQ7) | (ISRM_RET_IRQ6) | \ + (ISRM_RET_IRQ5) | (ISRM_RET_IRQ4) | \ + (ISRM_RET_IRQ3) | (ISRM_RET_IRQ2) | \ + (ISRM_RET_IRQ1)) +#define ISRM_ALL_EXC_TWAM ISRM_RET_IRQ_AUX +#define ISRM_ALL (ISRM_ALL_EXC_TWAM | ISRM_TWAM) + +/* SPM_IRQ_STA */ +#define ISRS_TWAM BIT(2) +#define ISRS_PCM_RETURN BIT(3) +#define ISRC_TWAM ISRS_TWAM +#define ISRC_ALL_EXC_TWAM ISRS_PCM_RETURN +#define ISRC_ALL (ISRC_ALL_EXC_TWAM | ISRC_TWAM) + +/* SPM_WAKEUP_MISC */ +#define WAKE_MISC_GIC_WAKEUP (0x3FF) +#define WAKE_MISC_DVFSRC_IRQ DVFSRC_IRQ_LSB +#define WAKE_MISC_REG_CPU_WAKEUP SPM_WAKEUP_MISC_REG_CPU_WAKEUP_LSB +#define WAKE_MISC_PCM_TIMER_EVENT PCM_TIMER_EVENT_LSB +#define WAKE_MISC_TWAM_IRQ_B TWAM_IRQ_B_LSB +#define WAKE_MISC_PMSR_IRQ_B_SET0 PMSR_IRQ_B_SET0_LSB +#define WAKE_MISC_PMSR_IRQ_B_SET1 PMSR_IRQ_B_SET1_LSB +#define WAKE_MISC_PMSR_IRQ_B_SET2 PMSR_IRQ_B_SET2_LSB +#define WAKE_MISC_SPM_ACK_CHK_WAKEUP_0 SPM_ACK_CHK_WAKEUP_0_LSB +#define WAKE_MISC_SPM_ACK_CHK_WAKEUP_1 SPM_ACK_CHK_WAKEUP_1_LSB +#define WAKE_MISC_SPM_ACK_CHK_WAKEUP_2 SPM_ACK_CHK_WAKEUP_2_LSB +#define WAKE_MISC_SPM_ACK_CHK_WAKEUP_3 SPM_ACK_CHK_WAKEUP_3_LSB +#define WAKE_MISC_SPM_ACK_CHK_WAKEUP_ALL SPM_ACK_CHK_WAKEUP_ALL_LSB +#define WAKE_MISC_PMIC_IRQ_ACK PMIC_IRQ_ACK_LSB +#define WAKE_MISC_PMIC_SCP_IRQ PMIC_SCP_IRQ_LSB + +/* MD32PCM ADDR for SPM code fetch */ +#define MD32PCM_BASE (SPM_BASE + 0x0A00) +#define MD32PCM_CFGREG_SW_RSTN (MD32PCM_BASE + 0x0000) +#define MD32PCM_DMA0_SRC (MD32PCM_BASE + 0x0200) +#define MD32PCM_DMA0_DST (MD32PCM_BASE + 0x0204) +#define MD32PCM_DMA0_WPPT (MD32PCM_BASE + 0x0208) +#define MD32PCM_DMA0_WPTO (MD32PCM_BASE + 0x020C) +#define MD32PCM_DMA0_COUNT (MD32PCM_BASE + 0x0210) +#define MD32PCM_DMA0_CON (MD32PCM_BASE + 0x0214) +#define MD32PCM_DMA0_START (MD32PCM_BASE + 0x0218) +#define MD32PCM_DMA0_RLCT (MD32PCM_BASE + 0x0224) +#define MD32PCM_INTC_IRQ_RAW_STA (MD32PCM_BASE + 0x033C) + +/* ABORT MASK for DEBUG FOORTPRINT */ +#define DEBUG_ABORT_MASK (SPM_DBG_DEBUG_IDX_DRAM_SREF_ABORT_IN_APSRC | \ + SPM_DBG_DEBUG_IDX_DRAM_SREF_ABORT_IN_DDREN) + +#define DEBUG_ABORT_MASK_1 (SPM_DBG1_DEBUG_IDX_VRCXO_SLEEP_ABORT | \ + SPM_DBG1_DEBUG_IDX_PWRAP_SLEEP_ACK_LOW_ABORT | \ + SPM_DBG1_DEBUG_IDX_PWRAP_SLEEP_ACK_HIGH_ABORT | \ + SPM_DBG1_DEBUG_IDX_EMI_SLP_IDLE_ABORT | \ + SPM_DBG1_DEBUG_IDX_SCP_SLP_ACK_LOW_ABORT | \ + SPM_DBG1_DEBUG_IDX_SCP_SLP_ACK_HIGH_ABORT | \ + SPM_DBG1_DEBUG_IDX_SPM_DVFS_CMD_RDY_ABORT) + +#define MCUPM_MBOX_WAKEUP_CPU (0x0C55FD10) + +struct pcm_desc { + const char *version; /* PCM code version */ + uint32_t *base; /* binary array base */ + uintptr_t base_dma; /* dma addr of base */ + uint32_t pmem_words; + uint32_t total_words; + uint32_t pmem_start; + uint32_t dmem_start; +}; + +struct pwr_ctrl { + /* for SPM */ + uint32_t pcm_flags; + /* can override pcm_flags */ + uint32_t pcm_flags_cust; + /* set bit of pcm_flags, after pcm_flags_cust */ + uint32_t pcm_flags_cust_set; + /* clr bit of pcm_flags, after pcm_flags_cust */ + uint32_t pcm_flags_cust_clr; + uint32_t pcm_flags1; + /* can override pcm_flags1 */ + uint32_t pcm_flags1_cust; + /* set bit of pcm_flags1, after pcm_flags1_cust */ + uint32_t pcm_flags1_cust_set; + /* clr bit of pcm_flags1, after pcm_flags1_cust */ + uint32_t pcm_flags1_cust_clr; + /* @ 1T 32K */ + uint32_t timer_val; + /* @ 1T 32K, can override timer_val */ + uint32_t timer_val_cust; + /* stress for dpidle */ + uint32_t timer_val_ramp_en; + /* stress for suspend */ + uint32_t timer_val_ramp_en_sec; + uint32_t wake_src; + /* can override wake_src */ + uint32_t wake_src_cust; + /* disable wdt in suspend */ + uint8_t wdt_disable; + + /* SPM_AP_STANDBY_CON */ + /* [0] */ + uint8_t reg_wfi_op; + /* [1] */ + uint8_t reg_wfi_type; + /* [2] */ + uint8_t reg_mp0_cputop_idle_mask; + /* [3] */ + uint8_t reg_mp1_cputop_idle_mask; + /* [4] */ + uint8_t reg_mcusys_idle_mask; + /* [25] */ + uint8_t reg_md_apsrc_1_sel; + /* [26] */ + uint8_t reg_md_apsrc_0_sel; + /* [29] */ + uint8_t reg_conn_apsrc_sel; + + /* SPM_SRC_REQ */ + /* [0] */ + uint8_t reg_spm_apsrc_req; + /* [1] */ + uint8_t reg_spm_f26m_req; + /* [3] */ + uint8_t reg_spm_infra_req; + /* [4] */ + uint8_t reg_spm_vrf18_req; + /* [7] */ + uint8_t reg_spm_ddr_en_req; + /* [8] */ + uint8_t reg_spm_dvfs_req; + /* [9] */ + uint8_t reg_spm_sw_mailbox_req; + /* [10] */ + uint8_t reg_spm_sspm_mailbox_req; + /* [11] */ + uint8_t reg_spm_adsp_mailbox_req; + /* [12] */ + uint8_t reg_spm_scp_mailbox_req; + + /* SPM_SRC_MASK */ + /* [0] */ + uint8_t reg_sspm_srcclkena_0_mask_b; + /* [1] */ + uint8_t reg_sspm_infra_req_0_mask_b; + /* [2] */ + uint8_t reg_sspm_apsrc_req_0_mask_b; + /* [3] */ + uint8_t reg_sspm_vrf18_req_0_mask_b; + /* [4] */ + uint8_t reg_sspm_ddr_en_0_mask_b; + /* [5] */ + uint8_t reg_scp_srcclkena_mask_b; + /* [6] */ + uint8_t reg_scp_infra_req_mask_b; + /* [7] */ + uint8_t reg_scp_apsrc_req_mask_b; + /* [8] */ + uint8_t reg_scp_vrf18_req_mask_b; + /* [9] */ + uint8_t reg_scp_ddr_en_mask_b; + /* [10] */ + uint8_t reg_audio_dsp_srcclkena_mask_b; + /* [11] */ + uint8_t reg_audio_dsp_infra_req_mask_b; + /* [12] */ + uint8_t reg_audio_dsp_apsrc_req_mask_b; + /* [13] */ + uint8_t reg_audio_dsp_vrf18_req_mask_b; + /* [14] */ + uint8_t reg_audio_dsp_ddr_en_mask_b; + /* [15] */ + uint8_t reg_apu_srcclkena_mask_b; + /* [16] */ + uint8_t reg_apu_infra_req_mask_b; + /* [17] */ + uint8_t reg_apu_apsrc_req_mask_b; + /* [18] */ + uint8_t reg_apu_vrf18_req_mask_b; + /* [19] */ + uint8_t reg_apu_ddr_en_mask_b; + /* [20] */ + uint8_t reg_cpueb_srcclkena_mask_b; + /* [21] */ + uint8_t reg_cpueb_infra_req_mask_b; + /* [22] */ + uint8_t reg_cpueb_apsrc_req_mask_b; + /* [23] */ + uint8_t reg_cpueb_vrf18_req_mask_b; + /* [24] */ + uint8_t reg_cpueb_ddr_en_mask_b; + /* [25] */ + uint8_t reg_bak_psri_srcclkena_mask_b; + /* [26] */ + uint8_t reg_bak_psri_infra_req_mask_b; + /* [27] */ + uint8_t reg_bak_psri_apsrc_req_mask_b; + /* [28] */ + uint8_t reg_bak_psri_vrf18_req_mask_b; + /* [29] */ + uint8_t reg_bak_psri_ddr_en_mask_b; + /* [30] */ + uint8_t reg_cam_ddren_req_mask_b; + /* [31] */ + uint8_t reg_img_ddren_req_mask_b; + + /* SPM_SRC2_MASK */ + /* [0] */ + uint8_t reg_msdc0_srcclkena_mask_b; + /* [1] */ + uint8_t reg_msdc0_infra_req_mask_b; + /* [2] */ + uint8_t reg_msdc0_apsrc_req_mask_b; + /* [3] */ + uint8_t reg_msdc0_vrf18_req_mask_b; + /* [4] */ + uint8_t reg_msdc0_ddr_en_mask_b; + /* [5] */ + uint8_t reg_msdc1_srcclkena_mask_b; + /* [6] */ + uint8_t reg_msdc1_infra_req_mask_b; + /* [7] */ + uint8_t reg_msdc1_apsrc_req_mask_b; + /* [8] */ + uint8_t reg_msdc1_vrf18_req_mask_b; + /* [9] */ + uint8_t reg_msdc1_ddr_en_mask_b; + /* [10] */ + uint8_t reg_msdc2_srcclkena_mask_b; + /* [11] */ + uint8_t reg_msdc2_infra_req_mask_b; + /* [12] */ + uint8_t reg_msdc2_apsrc_req_mask_b; + /* [13] */ + uint8_t reg_msdc2_vrf18_req_mask_b; + /* [14] */ + uint8_t reg_msdc2_ddr_en_mask_b; + /* [15] */ + uint8_t reg_ufs_srcclkena_mask_b; + /* [16] */ + uint8_t reg_ufs_infra_req_mask_b; + /* [17] */ + uint8_t reg_ufs_apsrc_req_mask_b; + /* [18] */ + uint8_t reg_ufs_vrf18_req_mask_b; + /* [19] */ + uint8_t reg_ufs_ddr_en_mask_b; + /* [20] */ + uint8_t reg_usb_srcclkena_mask_b; + /* [21] */ + uint8_t reg_usb_infra_req_mask_b; + /* [22] */ + uint8_t reg_usb_apsrc_req_mask_b; + /* [23] */ + uint8_t reg_usb_vrf18_req_mask_b; + /* [24] */ + uint8_t reg_usb_ddr_en_mask_b; + /* [25] */ + uint8_t reg_pextp_p0_srcclkena_mask_b; + /* [26] */ + uint8_t reg_pextp_p0_infra_req_mask_b; + /* [27] */ + uint8_t reg_pextp_p0_apsrc_req_mask_b; + /* [28] */ + uint8_t reg_pextp_p0_vrf18_req_mask_b; + /* [29] */ + uint8_t reg_pextp_p0_ddr_en_mask_b; + + /* SPM_SRC3_MASK */ + /* [0] */ + uint8_t reg_pextp_p1_srcclkena_mask_b; + /* [1] */ + uint8_t reg_pextp_p1_infra_req_mask_b; + /* [2] */ + uint8_t reg_pextp_p1_apsrc_req_mask_b; + /* [3] */ + uint8_t reg_pextp_p1_vrf18_req_mask_b; + /* [4] */ + uint8_t reg_pextp_p1_ddr_en_mask_b; + /* [5] */ + uint8_t reg_gce0_infra_req_mask_b; + /* [6] */ + uint8_t reg_gce0_apsrc_req_mask_b; + /* [7] */ + uint8_t reg_gce0_vrf18_req_mask_b; + /* [8] */ + uint8_t reg_gce0_ddr_en_mask_b; + /* [9] */ + uint8_t reg_gce1_infra_req_mask_b; + /* [10] */ + uint8_t reg_gce1_apsrc_req_mask_b; + /* [11] */ + uint8_t reg_gce1_vrf18_req_mask_b; + /* [12] */ + uint8_t reg_gce1_ddr_en_mask_b; + /* [13] */ + uint8_t reg_spm_srcclkena_reserved_mask_b; + /* [14] */ + uint8_t reg_spm_infra_req_reserved_mask_b; + /* [15] */ + uint8_t reg_spm_apsrc_req_reserved_mask_b; + /* [16] */ + uint8_t reg_spm_vrf18_req_reserved_mask_b; + /* [17] */ + uint8_t reg_spm_ddr_en_reserved_mask_b; + /* [18] */ + uint8_t reg_disp0_apsrc_req_mask_b; + /* [19] */ + uint8_t reg_disp0_ddr_en_mask_b; + /* [20] */ + uint8_t reg_disp1_apsrc_req_mask_b; + /* [21] */ + uint8_t reg_disp1_ddr_en_mask_b; + /* [22] */ + uint8_t reg_disp2_apsrc_req_mask_b; + /* [23] */ + uint8_t reg_disp2_ddr_en_mask_b; + /* [24] */ + uint8_t reg_disp3_apsrc_req_mask_b; + /* [25] */ + uint8_t reg_disp3_ddr_en_mask_b; + /* [26] */ + uint8_t reg_infrasys_apsrc_req_mask_b; + /* [27] */ + uint8_t reg_infrasys_ddr_en_mask_b; + /* [28] */ + uint8_t reg_cg_check_srcclkena_mask_b; + /* [29] */ + uint8_t reg_cg_check_apsrc_req_mask_b; + /* [30] */ + uint8_t reg_cg_check_vrf18_req_mask_b; + /* [31] */ + uint8_t reg_cg_check_ddr_en_mask_b; + + /* SPM_SRC4_MASK */ + /* [8:0] */ + uint32_t reg_mcusys_merge_apsrc_req_mask_b; + /* [17:9] */ + uint32_t reg_mcusys_merge_ddr_en_mask_b; + /* [19:18] */ + uint8_t reg_dramc_md32_infra_req_mask_b; + /* [21:20] */ + uint8_t reg_dramc_md32_vrf18_req_mask_b; + /* [23:22] */ + uint8_t reg_dramc_md32_ddr_en_mask_b; + /* [24] */ + uint8_t reg_dvfsrc_event_trigger_mask_b; + + /* SPM_WAKEUP_EVENT_MASK2 */ + /* [3:0] */ + uint8_t reg_sc_sw2spm_wakeup_mask_b; + /* [4] */ + uint8_t reg_sc_adsp2spm_wakeup_mask_b; + /* [8:5] */ + uint8_t reg_sc_sspm2spm_wakeup_mask_b; + /* [9] */ + uint8_t reg_sc_scp2spm_wakeup_mask_b; + /* [10] */ + uint8_t reg_csyspwrup_ack_mask; + /* [11] */ + uint8_t reg_csyspwrup_req_mask; + + /* SPM_WAKEUP_EVENT_MASK */ + /* [31:0] */ + uint32_t reg_wakeup_event_mask; + + /* SPM_WAKEUP_EVENT_EXT_MASK */ + /* [31:0] */ + uint32_t reg_ext_wakeup_event_mask; +}; + +/* code gen by spm_pwr_ctrl_atf.pl, need struct pwr_ctrl */ +enum pwr_ctrl_enum { + PW_PCM_FLAGS, + PW_PCM_FLAGS_CUST, + PW_PCM_FLAGS_CUST_SET, + PW_PCM_FLAGS_CUST_CLR, + PW_PCM_FLAGS1, + PW_PCM_FLAGS1_CUST, + PW_PCM_FLAGS1_CUST_SET, + PW_PCM_FLAGS1_CUST_CLR, + PW_TIMER_VAL, + PW_TIMER_VAL_CUST, + PW_TIMER_VAL_RAMP_EN, + PW_TIMER_VAL_RAMP_EN_SEC, + PW_WAKE_SRC, + PW_WAKE_SRC_CUST, + PW_WDT_DISABLE, + + /* SPM_AP_STANDBY_CON */ + PW_REG_WFI_OP, + PW_REG_WFI_TYPE, + PW_REG_MP0_CPUTOP_IDLE_MASK, + PW_REG_MP1_CPUTOP_IDLE_MASK, + PW_REG_MCUSYS_IDLE_MASK, + PW_REG_MD_APSRC_1_SEL, + PW_REG_MD_APSRC_0_SEL, + PW_REG_CONN_APSRC_SEL, + + /* SPM_SRC_REQ */ + PW_REG_SPM_APSRC_REQ, + PW_REG_SPM_F26M_REQ, + PW_REG_SPM_INFRA_REQ, + PW_REG_SPM_VRF18_REQ, + PW_REG_SPM_DDR_EN_REQ, + PW_REG_SPM_DVFS_REQ, + PW_REG_SPM_SW_MAILBOX_REQ, + PW_REG_SPM_SSPM_MAILBOX_REQ, + PW_REG_SPM_ADSP_MAILBOX_REQ, + PW_REG_SPM_SCP_MAILBOX_REQ, + + /* SPM_SRC_MASK */ + PW_REG_SSPM_SRCCLKENA_0_MASK_B, + PW_REG_SSPM_INFRA_REQ_0_MASK_B, + PW_REG_SSPM_APSRC_REQ_0_MASK_B, + PW_REG_SSPM_VRF18_REQ_0_MASK_B, + PW_REG_SSPM_DDR_EN_0_MASK_B, + PW_REG_SCP_SRCCLKENA_MASK_B, + PW_REG_SCP_INFRA_REQ_MASK_B, + PW_REG_SCP_APSRC_REQ_MASK_B, + PW_REG_SCP_VRF18_REQ_MASK_B, + PW_REG_SCP_DDR_EN_MASK_B, + PW_REG_AUDIO_DSP_SRCCLKENA_MASK_B, + PW_REG_AUDIO_DSP_INFRA_REQ_MASK_B, + PW_REG_AUDIO_DSP_APSRC_REQ_MASK_B, + PW_REG_AUDIO_DSP_VRF18_REQ_MASK_B, + PW_REG_AUDIO_DSP_DDR_EN_MASK_B, + PW_REG_APU_SRCCLKENA_MASK_B, + PW_REG_APU_INFRA_REQ_MASK_B, + PW_REG_APU_APSRC_REQ_MASK_B, + PW_REG_APU_VRF18_REQ_MASK_B, + PW_REG_APU_DDR_EN_MASK_B, + PW_REG_CPUEB_SRCCLKENA_MASK_B, + PW_REG_CPUEB_INFRA_REQ_MASK_B, + PW_REG_CPUEB_APSRC_REQ_MASK_B, + PW_REG_CPUEB_VRF18_REQ_MASK_B, + PW_REG_CPUEB_DDR_EN_MASK_B, + PW_REG_BAK_PSRI_SRCCLKENA_MASK_B, + PW_REG_BAK_PSRI_INFRA_REQ_MASK_B, + PW_REG_BAK_PSRI_APSRC_REQ_MASK_B, + PW_REG_BAK_PSRI_VRF18_REQ_MASK_B, + PW_REG_BAK_PSRI_DDR_EN_MASK_B, + PW_REG_CAM_DDREN_REQ_MASK_B, + PW_REG_IMG_DDREN_REQ_MASK_B, + + /* SPM_SRC2_MASK */ + PW_REG_MSDC0_SRCCLKENA_MASK_B, + PW_REG_MSDC0_INFRA_REQ_MASK_B, + PW_REG_MSDC0_APSRC_REQ_MASK_B, + PW_REG_MSDC0_VRF18_REQ_MASK_B, + PW_REG_MSDC0_DDR_EN_MASK_B, + PW_REG_MSDC1_SRCCLKENA_MASK_B, + PW_REG_MSDC1_INFRA_REQ_MASK_B, + PW_REG_MSDC1_APSRC_REQ_MASK_B, + PW_REG_MSDC1_VRF18_REQ_MASK_B, + PW_REG_MSDC1_DDR_EN_MASK_B, + PW_REG_MSDC2_SRCCLKENA_MASK_B, + PW_REG_MSDC2_INFRA_REQ_MASK_B, + PW_REG_MSDC2_APSRC_REQ_MASK_B, + PW_REG_MSDC2_VRF18_REQ_MASK_B, + PW_REG_MSDC2_DDR_EN_MASK_B, + PW_REG_UFS_SRCCLKENA_MASK_B, + PW_REG_UFS_INFRA_REQ_MASK_B, + PW_REG_UFS_APSRC_REQ_MASK_B, + PW_REG_UFS_VRF18_REQ_MASK_B, + PW_REG_UFS_DDR_EN_MASK_B, + PW_REG_USB_SRCCLKENA_MASK_B, + PW_REG_USB_INFRA_REQ_MASK_B, + PW_REG_USB_APSRC_REQ_MASK_B, + PW_REG_USB_VRF18_REQ_MASK_B, + PW_REG_USB_DDR_EN_MASK_B, + PW_REG_PEXTP_P0_SRCCLKENA_MASK_B, + PW_REG_PEXTP_P0_INFRA_REQ_MASK_B, + PW_REG_PEXTP_P0_APSRC_REQ_MASK_B, + PW_REG_PEXTP_P0_VRF18_REQ_MASK_B, + PW_REG_PEXTP_P0_DDR_EN_MASK_B, + + /* SPM_SRC3_MASK */ + PW_REG_PEXTP_P1_SRCCLKENA_MASK_B, + PW_REG_PEXTP_P1_INFRA_REQ_MASK_B, + PW_REG_PEXTP_P1_APSRC_REQ_MASK_B, + PW_REG_PEXTP_P1_VRF18_REQ_MASK_B, + PW_REG_PEXTP_P1_DDR_EN_MASK_B, + PW_REG_GCE0_INFRA_REQ_MASK_B, + PW_REG_GCE0_APSRC_REQ_MASK_B, + PW_REG_GCE0_VRF18_REQ_MASK_B, + PW_REG_GCE0_DDR_EN_MASK_B, + PW_REG_GCE1_INFRA_REQ_MASK_B, + PW_REG_GCE1_APSRC_REQ_MASK_B, + PW_REG_GCE1_VRF18_REQ_MASK_B, + PW_REG_GCE1_DDR_EN_MASK_B, + PW_REG_SPM_SRCCLKENA_RESERVED_MASK_B, + PW_REG_SPM_INFRA_REQ_RESERVED_MASK_B, + PW_REG_SPM_APSRC_REQ_RESERVED_MASK_B, + PW_REG_SPM_VRF18_REQ_RESERVED_MASK_B, + PW_REG_SPM_DDR_EN_RESERVED_MASK_B, + PW_REG_DISP0_APSRC_REQ_MASK_B, + PW_REG_DISP0_DDR_EN_MASK_B, + PW_REG_DISP1_APSRC_REQ_MASK_B, + PW_REG_DISP1_DDR_EN_MASK_B, + PW_REG_DISP2_APSRC_REQ_MASK_B, + PW_REG_DISP2_DDR_EN_MASK_B, + PW_REG_DISP3_APSRC_REQ_MASK_B, + PW_REG_DISP3_DDR_EN_MASK_B, + PW_REG_INFRASYS_APSRC_REQ_MASK_B, + PW_REG_INFRASYS_DDR_EN_MASK_B, + PW_REG_CG_CHECK_SRCCLKENA_MASK_B, + PW_REG_CG_CHECK_APSRC_REQ_MASK_B, + PW_REG_CG_CHECK_VRF18_REQ_MASK_B, + PW_REG_CG_CHECK_DDR_EN_MASK_B, + + /* SPM_SRC4_MASK */ + PW_REG_MCUSYS_MERGE_APSRC_REQ_MASK_B, + PW_REG_MCUSYS_MERGE_DDR_EN_MASK_B, + PW_REG_DRAMC_MD32_INFRA_REQ_MASK_B, + PW_REG_DRAMC_MD32_VRF18_REQ_MASK_B, + PW_REG_DRAMC_MD32_DDR_EN_MASK_B, + PW_REG_DVFSRC_EVENT_TRIGGER_MASK_B, + + /* SPM_WAKEUP_EVENT_MASK2 */ + PW_REG_SC_SW2SPM_WAKEUP_MASK_B, + PW_REG_SC_ADSP2SPM_WAKEUP_MASK_B, + PW_REG_SC_SSPM2SPM_WAKEUP_MASK_B, + PW_REG_SC_SCP2SPM_WAKEUP_MASK_B, + PW_REG_CSYSPWRUP_ACK_MASK, + PW_REG_CSYSPWRUP_REQ_MASK, + + /* SPM_WAKEUP_EVENT_MASK */ + PW_REG_WAKEUP_EVENT_MASK, + + /* SPM_WAKEUP_EVENT_EXT_MASK */ + PW_REG_EXT_WAKEUP_EVENT_MASK, + PW_MAX_COUNT, +}; + +/* spm_internal.c internal status */ +#define SPM_INTERNAL_STATUS_HW_S1 BIT(0) +#define SPM_ACK_CHK_3_CON_HW_MODE_TRIG (0x800) +/* BIT[0]: SW_EN, BIT[4]: STA_EN, BIT[8]: HW_EN */ +#define SPM_ACK_CHK_3_CON_EN (0x110) +#define SPM_ACK_CHK_3_CON_CLR_ALL (0x2) +/* BIT[15]: RESULT */ +#define SPM_ACK_CHK_3_CON_RESULT (0x8000) + +struct wake_status_trace_comm { + uint32_t debug_flag; /* PCM_WDT_LATCH_SPARE_0 */ + uint32_t debug_flag1; /* PCM_WDT_LATCH_SPARE_1 */ + uint32_t timer_out; /* SPM_SW_RSV_6*/ + uint32_t b_sw_flag0; /* SPM_SW_RSV_7 */ + uint32_t b_sw_flag1; /* SPM_SW_RSV_7 */ + uint32_t r12; /* SPM_SW_RSV_0 */ + uint32_t r13; /* PCM_REG13_DATA */ + uint32_t req_sta0; /* SRC_REQ_STA_0 */ + uint32_t req_sta1; /* SRC_REQ_STA_1 */ + uint32_t req_sta2; /* SRC_REQ_STA_2 */ + uint32_t req_sta3; /* SRC_REQ_STA_3 */ + uint32_t req_sta4; /* SRC_REQ_STA_4 */ + uint32_t raw_sta; /* SPM_WAKEUP_STA */ + uint32_t times_h; /* timestamp high bits */ + uint32_t times_l; /* timestamp low bits */ + uint32_t resumetime; /* timestamp low bits */ +}; + +struct wake_status_trace { + struct wake_status_trace_comm comm; +}; + +struct wake_status { + struct wake_status_trace tr; + uint32_t r12_ext; /* SPM_WAKEUP_EXT_STA */ + uint32_t raw_ext_sta; /* SPM_WAKEUP_EXT_STA */ + uint32_t md32pcm_wakeup_sta; /* MD32PCM_WAKEUP_STA */ + uint32_t md32pcm_event_sta; /* MD32PCM_EVENT_STA */ + uint32_t wake_misc; /* SPM_SW_RSV_5 */ + uint32_t idle_sta; /* SUBSYS_IDLE_STA */ + uint32_t cg_check_sta; /* SPM_CG_CHECK_STA */ + uint32_t sw_flag0; /* SPM_SW_FLAG_0 */ + uint32_t sw_flag1; /* SPM_SW_FLAG_1 */ + uint32_t isr; /* SPM_IRQ_STA */ + uint32_t clk_settle; /* SPM_CLK_SETTLE */ + uint32_t src_req; /* SPM_SRC_REQ */ + uint32_t log_index; + uint32_t is_abort; + uint32_t rt_req_sta0; /* SPM_SW_RSV_2 */ + uint32_t rt_req_sta1; /* SPM_SW_RSV_3 */ + uint32_t rt_req_sta2; /* SPM_SW_RSV_4 */ + uint32_t rt_req_sta3; /* SPM_SW_RSV_5 */ + uint32_t rt_req_sta4; /* SPM_SW_RSV_6 */ +}; + +struct spm_lp_scen { + struct pcm_desc *pcmdesc; + struct pwr_ctrl *pwrctrl; +}; + +void __spm_set_cpu_status(unsigned int cpu); +void __spm_src_req_update(const struct pwr_ctrl *pwrctrl, unsigned int resource_usage); +void __spm_set_power_control(const struct pwr_ctrl *pwrctrl); +void __spm_set_wakeup_event(const struct pwr_ctrl *pwrctrl); +void __spm_set_pcm_flags(struct pwr_ctrl *pwrctrl); +void __spm_send_cpu_wakeup_event(void); +void __spm_get_wakeup_status(struct wake_status *wakesta, unsigned int ext_status); +void __spm_clean_after_wakeup(void); +wake_reason_t __spm_output_wake_reason(const struct wake_status *wakesta); +void __spm_set_pcm_wdt(int en); +void __spm_ext_int_wakeup_req_clr(void); +void __spm_hw_s1_state_monitor(int en, unsigned int *status); + +static inline void spm_hw_s1_state_monitor_resume(void) +{ + __spm_hw_s1_state_monitor(1, NULL); +} + +static inline void spm_hw_s1_state_monitor_pause(unsigned int *status) +{ + __spm_hw_s1_state_monitor(0, status); +} + +void __spm_clean_before_wfi(void); + +#endif /* MT_SPM_INTERNAL */ diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_pmic_wrap.c b/plat/mediatek/drivers/spm/mt8188/mt_spm_pmic_wrap.c new file mode 100644 index 0000000..97dedf9 --- /dev/null +++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_pmic_wrap.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stddef.h> +#include <stdio.h> +#include <string.h> + +#include <common/debug.h> +#include <lib/mmio.h> +#include <plat/common/platform.h> + +#include <lib/pm/mtk_pm.h> +#include "mt_spm.h" +#include "mt_spm_internal.h" +#include "mt_spm_pmic_wrap.h" +#include "mt_spm_reg.h" +#include <platform_def.h> + +/* BIT operation */ +#define _BITS_(h, l, v) ((GENMASK(h, l) & ((v) << (l)))) + +/* PMIC_WRAP */ +#define VCORE_BASE_UV (40000) /* PMIC MT6359 */ +#define VOLT_TO_PMIC_VAL(volt) (((volt) - VCORE_BASE_UV + 625 - 1) / 625) + +#define NR_PMIC_WRAP_CMD (NR_IDX_ALL) +#define SPM_DATA_SHIFT (16) + +#define BUCK_VGPU11_ELR0 (0x15B4) +#define TOP_SPI_CON0 (0x0456) +#define BUCK_TOP_CON1 (0x1443) /* PMIC MT6315 */ +#define TOP_CON (0x0013) /* PMIC MT6315 */ +#define TOP_DIG_WPK (0x03a9) +#define TOP_CON_LOCK (0x03a8) +#define TOP_CLK_CON0 (0x0134) /* PMIC MT6359*/ + +struct pmic_wrap_cmd { + uint32_t cmd_addr; + uint32_t cmd_wdata; +}; + +struct pmic_wrap_setting { + enum pmic_wrap_phase_id phase; + struct pmic_wrap_cmd addr[NR_PMIC_WRAP_CMD]; + struct { + struct { + uint32_t cmd_addr; + uint32_t cmd_wdata; + } _[NR_PMIC_WRAP_CMD]; + const int nr_idx; + } set[NR_PMIC_WRAP_PHASE]; +}; + +static struct pmic_wrap_setting pw = { + .phase = NR_PMIC_WRAP_PHASE, /* invalid setting for init */ + .addr = {{0, 0} }, + .set[PMIC_WRAP_PHASE_ALLINONE] = { + ._[CMD_0] = {BUCK_VGPU11_ELR0, _BITS_(6, 0, VOLT_TO_PMIC_VAL(75000)),}, + ._[CMD_1] = {BUCK_VGPU11_ELR0, _BITS_(6, 0, VOLT_TO_PMIC_VAL(65000)),}, + ._[CMD_2] = {BUCK_VGPU11_ELR0, _BITS_(6, 0, VOLT_TO_PMIC_VAL(60000)),}, + ._[CMD_3] = {BUCK_VGPU11_ELR0, _BITS_(6, 0, VOLT_TO_PMIC_VAL(55000)),}, + ._[CMD_4] = {TOP_SPI_CON0, _BITS_(0, 0, 1),}, + ._[CMD_5] = {TOP_SPI_CON0, _BITS_(0, 0, 0),}, + ._[CMD_6] = {BUCK_TOP_CON1, 0x0,}, /* MT6315-3: VMD NO LP */ + ._[CMD_7] = {BUCK_TOP_CON1, 0xF,}, /* MT6315-3: VMD LP */ + ._[CMD_8] = {TOP_CON, 0x3,}, /* MT6315-3: PMIC NO LP */ + ._[CMD_9] = {TOP_CON, 0x0,}, /* MT6315-3: PMIC LP */ + ._[CMD_10] = {TOP_DIG_WPK, 0x63,}, /* MT6315-2: PMIC_CON_DIG_WPK */ + ._[CMD_11] = {TOP_CON_LOCK, 0x15,}, /* MT6315-2: PMIC_CON_UNLOCK */ + ._[CMD_12] = {TOP_DIG_WPK, 0x0,}, /* MT6315-2: PMIC_CON_DIG_WPK */ + ._[CMD_13] = {TOP_CON_LOCK, 0x0,}, /* MT6315-2: PMIC_CON_LOCK */ + ._[CMD_14] = {TOP_CLK_CON0, 0x0040,}, /* MT6359: 6359_LDO_SW_SEL_H */ + ._[CMD_15] = {TOP_CLK_CON0, 0x0000,}, /* MT6359: 6359_LDO_SW_SEL_L */ + .nr_idx = NR_IDX_ALL, + }, +}; + +void _mt_spm_pmic_table_init(void) +{ + struct pmic_wrap_cmd pwrap_cmd_default[NR_PMIC_WRAP_CMD] = { + { (uint32_t)SPM_DVFS_CMD0, (uint32_t)SPM_DVFS_CMD0, }, + { (uint32_t)SPM_DVFS_CMD1, (uint32_t)SPM_DVFS_CMD1, }, + { (uint32_t)SPM_DVFS_CMD2, (uint32_t)SPM_DVFS_CMD2, }, + { (uint32_t)SPM_DVFS_CMD3, (uint32_t)SPM_DVFS_CMD3, }, + { (uint32_t)SPM_DVFS_CMD4, (uint32_t)SPM_DVFS_CMD4, }, + { (uint32_t)SPM_DVFS_CMD5, (uint32_t)SPM_DVFS_CMD5, }, + { (uint32_t)SPM_DVFS_CMD6, (uint32_t)SPM_DVFS_CMD6, }, + { (uint32_t)SPM_DVFS_CMD7, (uint32_t)SPM_DVFS_CMD7, }, + { (uint32_t)SPM_DVFS_CMD8, (uint32_t)SPM_DVFS_CMD8, }, + { (uint32_t)SPM_DVFS_CMD9, (uint32_t)SPM_DVFS_CMD9, }, + { (uint32_t)SPM_DVFS_CMD10, (uint32_t)SPM_DVFS_CMD10, }, + { (uint32_t)SPM_DVFS_CMD11, (uint32_t)SPM_DVFS_CMD11, }, + { (uint32_t)SPM_DVFS_CMD12, (uint32_t)SPM_DVFS_CMD12, }, + { (uint32_t)SPM_DVFS_CMD13, (uint32_t)SPM_DVFS_CMD13, }, + { (uint32_t)SPM_DVFS_CMD14, (uint32_t)SPM_DVFS_CMD14, }, + { (uint32_t)SPM_DVFS_CMD15, (uint32_t)SPM_DVFS_CMD15, }, + }; + + memcpy(pw.addr, pwrap_cmd_default, sizeof(pwrap_cmd_default)); +} + +void mt_spm_pmic_wrap_set_phase(enum pmic_wrap_phase_id phase) +{ + int idx; + + if ((phase >= NR_PMIC_WRAP_PHASE) || (pw.phase == phase)) { + return; + } + + if (pw.addr[0].cmd_addr == 0) { + _mt_spm_pmic_table_init(); + } + + pw.phase = phase; + + mmio_write_32(POWERON_CONFIG_EN, SPM_REGWR_CFG_KEY | BCLK_CG_EN_LSB); + for (idx = 0; idx < pw.set[phase].nr_idx; idx++) { + mmio_write_32(pw.addr[idx].cmd_addr, + (pw.set[phase]._[idx].cmd_addr << SPM_DATA_SHIFT) | + (pw.set[phase]._[idx].cmd_wdata)); + } +} + +void mt_spm_pmic_wrap_set_cmd(enum pmic_wrap_phase_id phase, unsigned int idx, + unsigned int cmd_wdata) +{ + /* just set wdata value */ + if ((phase >= NR_PMIC_WRAP_PHASE) || (idx >= pw.set[phase].nr_idx)) { + return; + } + + pw.set[phase]._[idx].cmd_wdata = cmd_wdata; + + mmio_write_32(POWERON_CONFIG_EN, SPM_REGWR_CFG_KEY | BCLK_CG_EN_LSB); + if (pw.phase == phase) { + mmio_write_32(pw.addr[idx].cmd_addr, + (pw.set[phase]._[idx].cmd_addr << SPM_DATA_SHIFT) | cmd_wdata); + } +} + +uint64_t mt_spm_pmic_wrap_get_cmd(enum pmic_wrap_phase_id phase, unsigned int idx) +{ + /* just get wdata value */ + if ((phase >= NR_PMIC_WRAP_PHASE) || (idx >= pw.set[phase].nr_idx)) { + return 0; + } + + return pw.set[phase]._[idx].cmd_wdata; +} diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_pmic_wrap.h b/plat/mediatek/drivers/spm/mt8188/mt_spm_pmic_wrap.h new file mode 100644 index 0000000..3043d36 --- /dev/null +++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_pmic_wrap.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/**************************************************************** + * Auto generated by DE, please DO NOT modify this file directly. + *****************************************************************/ + +#ifndef MT_SPM_PMIC_WRAP_H +#define MT_SPM_PMIC_WRAP_H + +enum pmic_wrap_phase_id { + PMIC_WRAP_PHASE_ALLINONE = 0, + NR_PMIC_WRAP_PHASE, +}; + +/* IDX mapping */ +enum { + CMD_0 = 0, /* PMIC_WRAP_PHASE_ALLINONE */ + CMD_1, + CMD_2, + CMD_3, + CMD_4, + CMD_5, + CMD_6, + CMD_7, + CMD_8, + CMD_9, + CMD_10, + CMD_11, + CMD_12, + CMD_13, + CMD_14, + CMD_15, + NR_IDX_ALL, +}; + +/* APIs */ +void mt_spm_pmic_wrap_set_phase(enum pmic_wrap_phase_id phase); +void mt_spm_pmic_wrap_set_cmd(enum pmic_wrap_phase_id phase, unsigned int idx, + unsigned int cmd_wdata); +uint64_t mt_spm_pmic_wrap_get_cmd(enum pmic_wrap_phase_id phase, unsigned int idx); +void mt_spm_dump_pmic_warp_reg(void); + +#endif /* MT_SPM_PMIC_WRAP_H */ diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_reg.h b/plat/mediatek/drivers/spm/mt8188/mt_spm_reg.h new file mode 100644 index 0000000..2c29f75 --- /dev/null +++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_reg.h @@ -0,0 +1,2249 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/**************************************************************** + * Auto generated by DE, please DO NOT modify this file directly. + ****************************************************************/ + +#ifndef MT_SPM_REG_H +#define MT_SPM_REG_H + +#include "pcm_def.h" +#include "sleep_def.h" +#include <spm_reg.h> + +/* Define and Declare */ + +/* POWERON_CONFIG_EN (0x10006000+0x000) */ +#define BCLK_CG_EN_LSB (1U << 0) /* 1b */ +#define PROJECT_CODE_LSB (1U << 16) /* 16b */ +/* SPM_POWER_ON_VAL0 (0x10006000+0x004) */ +#define POWER_ON_VAL0_LSB (1U << 0) /* 32b */ +/* SPM_POWER_ON_VAL1 (0x10006000+0x008) */ +#define POWER_ON_VAL1_LSB (1U << 0) /* 32b */ +/* SPM_CLK_CON (0x10006000+0x00C) */ +#define REG_SRCCLKEN0_CTL_LSB (1U << 0) /* 2b */ +#define REG_SRCCLKEN1_CTL_LSB (1U << 2) /* 2b */ +#define SYS_SETTLE_SEL_LSB (1U << 4) /* 1b */ +#define REG_SPM_LOCK_INFRA_DCM_LSB (1U << 5) /* 1b */ +#define REG_SRCCLKEN_MASK_LSB (1U << 6) /* 3b */ +#define REG_MD1_C32RM_EN_LSB (1U << 9) /* 1b */ +#define REG_MD2_C32RM_EN_LSB (1U << 10) /* 1b */ +#define REG_CLKSQ0_SEL_CTRL_LSB (1U << 11) /* 1b */ +#define REG_CLKSQ1_SEL_CTRL_LSB (1U << 12) /* 1b */ +#define REG_SRCCLKEN0_EN_LSB (1U << 13) /* 1b */ +#define REG_SRCCLKEN1_EN_LSB (1U << 14) /* 1b */ +#define SCP_DCM_EN_LSB (1U << 15) /* 1b */ +#define REG_SYSCLK0_SRC_MASK_B_LSB (1U << 16) /* 8b */ +#define REG_SYSCLK1_SRC_MASK_B_LSB (1U << 24) /* 8b */ +/* SPM_CLK_SETTLE (0x10006000+0x010) */ +#define SYSCLK_SETTLE_LSB (1U << 0) /* 28b */ +/* SPM_AP_STANDBY_CON (0x10006000+0x014) */ +#define REG_WFI_OP_LSB (1U << 0) /* 1b */ +#define REG_WFI_TYPE_LSB (1U << 1) /* 1b */ +#define REG_MP0_CPUTOP_IDLE_MASK_LSB (1U << 2) /* 1b */ +#define REG_MP1_CPUTOP_IDLE_MASK_LSB (1U << 3) /* 1b */ +#define REG_MCUSYS_IDLE_MASK_LSB (1U << 4) /* 1b */ +#define REG_MD_APSRC_1_SEL_LSB (1U << 25) /* 1b */ +#define REG_MD_APSRC_0_SEL_LSB (1U << 26) /* 1b */ +#define REG_CONN_APSRC_SEL_LSB (1U << 29) /* 1b */ +/* PCM_CON0 (0x10006000+0x018) */ +#define PCM_CK_EN_LSB (1U << 2) /* 1b */ +#define RG_EN_IM_SLEEP_DVS_LSB (1U << 3) /* 1b */ +#define PCM_CK_FROM_CKSYS_LSB (1U << 4) /* 1b */ +#define PCM_SW_RESET_LSB (1U << 15) /* 1b */ +#define PCM_CON0_PROJECT_CODE_LSB (1U << 16) /* 16b */ +/* PCM_CON1 (0x10006000+0x01C) */ +#define RG_IM_SLAVE_LSB (1U << 0) /* 1b */ +#define RG_IM_SLEEP_LSB (1U << 1) /* 1b */ +#define REG_SPM_SRAM_CTRL_MUX_LSB (1U << 2) /* 1b */ +#define RG_AHBMIF_APBEN_LSB (1U << 3) /* 1b */ +#define RG_IM_PDN_LSB (1U << 4) /* 1b */ +#define RG_PCM_TIMER_EN_LSB (1U << 5) /* 1b */ +#define SPM_EVENT_COUNTER_CLR_LSB (1U << 6) /* 1b */ +#define RG_DIS_MIF_PROT_LSB (1U << 7) /* 1b */ +#define RG_PCM_WDT_EN_LSB (1U << 8) /* 1b */ +#define RG_PCM_WDT_WAKE_LSB (1U << 9) /* 1b */ +#define REG_SPM_SRAM_SLEEP_B_LSB (1U << 10) /* 1b */ +#define REG_SPM_SRAM_ISOINT_B_LSB (1U << 11) /* 1b */ +#define REG_EVENT_LOCK_EN_LSB (1U << 12) /* 1b */ +#define REG_SRCCLKEN_FAST_RESP_LSB (1U << 13) /* 1b */ +#define REG_MD32_APB_INTERNAL_EN_LSB (1U << 14) /* 1b */ +#define RG_PCM_IRQ_MSK_LSB (1U << 15) /* 1b */ +#define PCM_CON1_PROJECT_CODE_LSB (1U << 16) /* 16b */ +/* SPM_POWER_ON_VAL2 (0x10006000+0x020) */ +#define POWER_ON_VAL2_LSB (1U << 0) /* 32b */ +/* SPM_POWER_ON_VAL3 (0x10006000+0x024) */ +#define POWER_ON_VAL3_LSB (1U << 0) /* 32b */ +/* PCM_REG_DATA_INI (0x10006000+0x028) */ +#define PCM_REG_DATA_INI_LSB (1U << 0) /* 32b */ +/* PCM_PWR_IO_EN (0x10006000+0x02C) */ +#define PCM_PWR_IO_EN_LSB (1U << 0) /* 8b */ +#define RG_RF_SYNC_EN_LSB (1U << 16) /* 8b */ +/* PCM_TIMER_VAL (0x10006000+0x030) */ +#define REG_PCM_TIMER_VAL_LSB (1U << 0) /* 32b */ +/* PCM_WDT_VAL (0x10006000+0x034) */ +#define RG_PCM_WDT_VAL_LSB (1U << 0) /* 32b */ +/* SPM_SW_RST_CON (0x10006000+0x040) */ +#define SPM_SW_RST_CON_LSB (1U << 0) /* 16b */ +#define SPM_SW_RST_CON_PROJECT_CODE_LSB (1U << 16) /* 16b */ +/* SPM_SW_RST_CON_SET (0x10006000+0x044) */ +#define SPM_SW_RST_CON_SET_LSB (1U << 0) /* 16b */ +#define SPM_SW_RST_CON_SET_PROJECT_CODE_LSB (1U << 16) /* 16b */ +/* SPM_SW_RST_CON_CLR (0x10006000+0x048) */ +#define SPM_SW_RST_CON_CLR_LSB (1U << 0) /* 16b */ +#define SPM_SW_RST_CON_CLR_PROJECT_CODE_LSB (1U << 16) /* 16b */ +/* VS1_PSR_MASK_B (0x10006000+0x04C) */ +#define VS1_OPP0_PSR_MASK_B_LSB (1U << 0) /* 8b */ +#define VS1_OPP1_PSR_MASK_B_LSB (1U << 8) /* 8b */ +/* VS2_PSR_MASK_B (0x10006000+0x050) */ +#define VS2_OPP0_PSR_MASK_B_LSB (1U << 0) /* 8b */ +#define VS2_OPP1_PSR_MASK_B_LSB (1U << 8) /* 8b */ +#define VS2_OPP2_PSR_MASK_B_LSB (1U << 16) /* 8b */ +/* MD32_CLK_CON (0x10006000+0x084) */ +#define REG_MD32_26M_CK_SEL_LSB (1U << 0) /* 1b */ +#define REG_MD32_DCM_EN_LSB (1U << 1) /* 1b */ +/* SPM_SRAM_RSV_CON (0x10006000+0x088) */ +#define SPM_SRAM_SLEEP_B_ECO_EN_LSB (1U << 0) /* 1b */ +/* SPM_SWINT (0x10006000+0x08C) */ +#define SPM_SWINT_LSB (1U << 0) /* 32b */ +/* SPM_SWINT_SET (0x10006000+0x090) */ +#define SPM_SWINT_SET_LSB (1U << 0) /* 32b */ +/* SPM_SWINT_CLR (0x10006000+0x094) */ +#define SPM_SWINT_CLR_LSB (1U << 0) /* 32b */ +/* SPM_SCP_MAILBOX (0x10006000+0x098) */ +#define SPM_SCP_MAILBOX_LSB (1U << 0) /* 32b */ +/* SCP_SPM_MAILBOX (0x10006000+0x09C) */ +#define SCP_SPM_MAILBOX_LSB (1U << 0) /* 32b */ +/* SPM_TWAM_CON (0x10006000+0x0A0) */ +#define REG_TWAM_ENABLE_LSB (1U << 0) /* 1b */ +#define REG_TWAM_SPEED_MODE_EN_LSB (1U << 1) /* 1b */ +#define REG_TWAM_SW_RST_LSB (1U << 2) /* 1b */ +#define REG_TWAM_IRQ_MASK_LSB (1U << 3) /* 1b */ +#define REG_TWAM_MON_TYPE_0_LSB (1U << 4) /* 2b */ +#define REG_TWAM_MON_TYPE_1_LSB (1U << 6) /* 2b */ +#define REG_TWAM_MON_TYPE_2_LSB (1U << 8) /* 2b */ +#define REG_TWAM_MON_TYPE_3_LSB (1U << 10) /* 2b */ +/* SPM_TWAM_WINDOW_LEN (0x10006000+0x0A4) */ +#define REG_TWAM_WINDOW_LEN_LSB (1U << 0) /* 32b */ +/* SPM_TWAM_IDLE_SEL (0x10006000+0x0A8) */ +#define REG_TWAM_SIG_SEL_0_LSB (1U << 0) /* 7b */ +#define REG_TWAM_SIG_SEL_1_LSB (1U << 8) /* 7b */ +#define REG_TWAM_SIG_SEL_2_LSB (1U << 16) /* 7b */ +#define REG_TWAM_SIG_SEL_3_LSB (1U << 24) /* 7b */ +/* SPM_SCP_IRQ (0x10006000+0x0AC) */ +#define SC_SPM2SCP_WAKEUP_LSB (1U << 0) /* 1b */ +#define SC_SCP2SPM_WAKEUP_LSB (1U << 4) /* 1b */ +/* SPM_CPU_WAKEUP_EVENT (0x10006000+0x0B0) */ +#define REG_CPU_WAKEUP_LSB (1U << 0) /* 1b */ +/* SPM_IRQ_MASK (0x10006000+0x0B4) */ +#define REG_SPM_IRQ_MASK_LSB (1U << 0) /* 32b */ +/* DDR_EN_DBC (0x10006000+0x0B4) */ +#define REG_ALL_DDR_EN_DBC_EN_LSB (1U << 16) /* 1b */ +/* SPM_SRC_REQ (0x10006000+0x0B8) */ +#define REG_SPM_APSRC_REQ_LSB (1U << 0) /* 1b */ +#define REG_SPM_F26M_REQ_LSB (1U << 1) /* 1b */ +#define REG_SPM_INFRA_REQ_LSB (1U << 3) /* 1b */ +#define REG_SPM_VRF18_REQ_LSB (1U << 4) /* 1b */ +#define REG_SPM_DDR_EN_REQ_LSB (1U << 7) /* 1b */ +#define REG_SPM_DVFS_REQ_LSB (1U << 8) /* 1b */ +#define REG_SPM_SW_MAILBOX_REQ_LSB (1U << 9) /* 1b */ +#define REG_SPM_SSPM_MAILBOX_REQ_LSB (1U << 10) /* 1b */ +#define REG_SPM_ADSP_MAILBOX_REQ_LSB (1U << 11) /* 1b */ +#define REG_SPM_SCP_MAILBOX_REQ_LSB (1U << 12) /* 1b */ +/* SPM_SRC_MASK (0x10006000+0x0BC) */ +#define REG_MD_SRCCLKENA_0_MASK_B_LSB (1U << 0) /* 1b */ +#define REG_MD_SRCCLKENA2INFRA_REQ_0_MASK_B_LSB (1U << 1) /* 1b */ +#define REG_MD_APSRC2INFRA_REQ_0_MASK_B_LSB (1U << 2) /* 1b */ +#define REG_MD_APSRC_REQ_0_MASK_B_LSB (1U << 3) /* 1b */ +#define REG_MD_VRF18_REQ_0_MASK_B_LSB (1U << 4) /* 1b */ +#define REG_MD_DDR_EN_0_MASK_B_LSB (1U << 5) /* 1b */ +#define REG_MD_SRCCLKENA_1_MASK_B_LSB (1U << 6) /* 1b */ +#define REG_MD_SRCCLKENA2INFRA_REQ_1_MASK_B_LSB (1U << 7) /* 1b */ +#define REG_MD_APSRC2INFRA_REQ_1_MASK_B_LSB (1U << 8) /* 1b */ +#define REG_MD_APSRC_REQ_1_MASK_B_LSB (1U << 9) /* 1b */ +#define REG_MD_VRF18_REQ_1_MASK_B_LSB (1U << 10) /* 1b */ +#define REG_MD_DDR_EN_1_MASK_B_LSB (1U << 11) /* 1b */ +#define REG_CONN_SRCCLKENA_MASK_B_LSB (1U << 12) /* 1b */ +#define REG_CONN_SRCCLKENB_MASK_B_LSB (1U << 13) /* 1b */ +#define REG_CONN_INFRA_REQ_MASK_B_LSB (1U << 14) /* 1b */ +#define REG_CONN_APSRC_REQ_MASK_B_LSB (1U << 15) /* 1b */ +#define REG_CONN_VRF18_REQ_MASK_B_LSB (1U << 16) /* 1b */ +#define REG_CONN_DDR_EN_MASK_B_LSB (1U << 17) /* 1b */ +#define REG_CONN_VFE28_MASK_B_LSB (1U << 18) /* 1b */ +#define REG_SRCCLKENI0_SRCCLKENA_MASK_B_LSB (1U << 19) /* 1b */ +#define REG_SRCCLKENI0_INFRA_REQ_MASK_B_LSB (1U << 20) /* 1b */ +#define REG_SRCCLKENI1_SRCCLKENA_MASK_B_LSB (1U << 21) /* 1b */ +#define REG_SRCCLKENI1_INFRA_REQ_MASK_B_LSB (1U << 22) /* 1b */ +#define REG_SRCCLKENI2_SRCCLKENA_MASK_B_LSB (1U << 23) /* 1b */ +#define REG_SRCCLKENI2_INFRA_REQ_MASK_B_LSB (1U << 24) /* 1b */ +#define REG_INFRASYS_APSRC_REQ_MASK_B_LSB (1U << 25) /* 1b */ +#define REG_INFRASYS_DDR_EN_MASK_B_LSB (1U << 26) /* 1b */ +#define REG_MD32_SRCCLKENA_MASK_B_LSB (1U << 27) /* 1b */ +#define REG_MD32_INFRA_REQ_MASK_B_LSB (1U << 28) /* 1b */ +#define REG_MD32_APSRC_REQ_MASK_B_LSB (1U << 29) /* 1b */ +#define REG_MD32_VRF18_REQ_MASK_B_LSB (1U << 30) /* 1b */ +#define REG_MD32_DDR_EN_MASK_B_LSB (1U << 31) /* 1b */ +/* SPM_SRC2_MASK (0x10006000+0x0C0) */ +#define REG_SCP_SRCCLKENA_MASK_B_LSB (1U << 0) /* 1b */ +#define REG_SCP_INFRA_REQ_MASK_B_LSB (1U << 1) /* 1b */ +#define REG_SCP_APSRC_REQ_MASK_B_LSB (1U << 2) /* 1b */ +#define REG_SCP_VRF18_REQ_MASK_B_LSB (1U << 3) /* 1b */ +#define REG_SCP_DDR_EN_MASK_B_LSB (1U << 4) /* 1b */ +#define REG_AUDIO_DSP_SRCCLKENA_MASK_B_LSB (1U << 5) /* 1b */ +#define REG_AUDIO_DSP_INFRA_REQ_MASK_B_LSB (1U << 6) /* 1b */ +#define REG_AUDIO_DSP_APSRC_REQ_MASK_B_LSB (1U << 7) /* 1b */ +#define REG_AUDIO_DSP_VRF18_REQ_MASK_B_LSB (1U << 8) /* 1b */ +#define REG_AUDIO_DSP_DDR_EN_MASK_B_LSB (1U << 9) /* 1b */ +#define REG_UFS_SRCCLKENA_MASK_B_LSB (1U << 10) /* 1b */ +#define REG_UFS_INFRA_REQ_MASK_B_LSB (1U << 11) /* 1b */ +#define REG_UFS_APSRC_REQ_MASK_B_LSB (1U << 12) /* 1b */ +#define REG_UFS_VRF18_REQ_MASK_B_LSB (1U << 13) /* 1b */ +#define REG_UFS_DDR_EN_MASK_B_LSB (1U << 14) /* 1b */ +#define REG_DISP0_APSRC_REQ_MASK_B_LSB (1U << 15) /* 1b */ +#define REG_DISP0_DDR_EN_MASK_B_LSB (1U << 16) /* 1b */ +#define REG_DISP1_APSRC_REQ_MASK_B_LSB (1U << 17) /* 1b */ +#define REG_DISP1_DDR_EN_MASK_B_LSB (1U << 18) /* 1b */ +#define REG_GCE_INFRA_REQ_MASK_B_LSB (1U << 19) /* 1b */ +#define REG_GCE_APSRC_REQ_MASK_B_LSB (1U << 20) /* 1b */ +#define REG_GCE_VRF18_REQ_MASK_B_LSB (1U << 21) /* 1b */ +#define REG_GCE_DDR_EN_MASK_B_LSB (1U << 22) /* 1b */ +#define REG_APU_SRCCLKENA_MASK_B_LSB (1U << 23) /* 1b */ +#define REG_APU_INFRA_REQ_MASK_B_LSB (1U << 24) /* 1b */ +#define REG_APU_APSRC_REQ_MASK_B_LSB (1U << 25) /* 1b */ +#define REG_APU_VRF18_REQ_MASK_B_LSB (1U << 26) /* 1b */ +#define REG_APU_DDR_EN_MASK_B_LSB (1U << 27) /* 1b */ +#define REG_CG_CHECK_SRCCLKENA_MASK_B_LSB (1U << 28) /* 1b */ +#define REG_CG_CHECK_APSRC_REQ_MASK_B_LSB (1U << 29) /* 1b */ +#define REG_CG_CHECK_VRF18_REQ_MASK_B_LSB (1U << 30) /* 1b */ +#define REG_CG_CHECK_DDR_EN_MASK_B_LSB (1U << 31) /* 1b */ +/* SPM_SRC3_MASK (0x10006000+0x0C4) */ +#define REG_DVFSRC_EVENT_TRIGGER_MASK_B_LSB (1U << 0) /* 1b */ +#define REG_SW2SPM_INT0_MASK_B_LSB (1U << 1) /* 1b */ +#define REG_SW2SPM_INT1_MASK_B_LSB (1U << 2) /* 1b */ +#define REG_SW2SPM_INT2_MASK_B_LSB (1U << 3) /* 1b */ +#define REG_SW2SPM_INT3_MASK_B_LSB (1U << 4) /* 1b */ +#define REG_SC_ADSP2SPM_WAKEUP_MASK_B_LSB (1U << 5) /* 1b */ +#define REG_SC_SSPM2SPM_WAKEUP_MASK_B_LSB (1U << 6) /* 4b */ +#define REG_SC_SCP2SPM_WAKEUP_MASK_B_LSB (1U << 10) /* 1b */ +#define REG_CSYSPWRREQ_MASK_LSB (1U << 11) /* 1b */ +#define REG_SPM_SRCCLKENA_RESERVED_MASK_B_LSB (1U << 12) /* 1b */ +#define REG_SPM_INFRA_REQ_RESERVED_MASK_B_LSB (1U << 13) /* 1b */ +#define REG_SPM_APSRC_REQ_RESERVED_MASK_B_LSB (1U << 14) /* 1b */ +#define REG_SPM_VRF18_REQ_RESERVED_MASK_B_LSB (1U << 15) /* 1b */ +#define REG_SPM_DDR_EN_RESERVED_MASK_B_LSB (1U << 16) /* 1b */ +#define REG_MCUPM_SRCCLKENA_MASK_B_LSB (1U << 17) /* 1b */ +#define REG_MCUPM_INFRA_REQ_MASK_B_LSB (1U << 18) /* 1b */ +#define REG_MCUPM_APSRC_REQ_MASK_B_LSB (1U << 19) /* 1b */ +#define REG_MCUPM_VRF18_REQ_MASK_B_LSB (1U << 20) /* 1b */ +#define REG_MCUPM_DDR_EN_MASK_B_LSB (1U << 21) /* 1b */ +#define REG_MSDC0_SRCCLKENA_MASK_B_LSB (1U << 22) /* 1b */ +#define REG_MSDC0_INFRA_REQ_MASK_B_LSB (1U << 23) /* 1b */ +#define REG_MSDC0_APSRC_REQ_MASK_B_LSB (1U << 24) /* 1b */ +#define REG_MSDC0_VRF18_REQ_MASK_B_LSB (1U << 25) /* 1b */ +#define REG_MSDC0_DDR_EN_MASK_B_LSB (1U << 26) /* 1b */ +#define REG_MSDC1_SRCCLKENA_MASK_B_LSB (1U << 27) /* 1b */ +#define REG_MSDC1_INFRA_REQ_MASK_B_LSB (1U << 28) /* 1b */ +#define REG_MSDC1_APSRC_REQ_MASK_B_LSB (1U << 29) /* 1b */ +#define REG_MSDC1_VRF18_REQ_MASK_B_LSB (1U << 30) /* 1b */ +#define REG_MSDC1_DDR_EN_MASK_B_LSB (1U << 31) /* 1b */ +/* SPM_SRC4_MASK (0x10006000+0x0C8) */ +#define CCIF_EVENT_MASK_B_LSB (1U << 0) /* 16b */ +#define REG_BAK_PSRI_SRCCLKENA_MASK_B_LSB (1U << 16) /* 1b */ +#define REG_BAK_PSRI_INFRA_REQ_MASK_B_LSB (1U << 17) /* 1b */ +#define REG_BAK_PSRI_APSRC_REQ_MASK_B_LSB (1U << 18) /* 1b */ +#define REG_BAK_PSRI_VRF18_REQ_MASK_B_LSB (1U << 19) /* 1b */ +#define REG_BAK_PSRI_DDR_EN_MASK_B_LSB (1U << 20) /* 1b */ +#define REG_DRAMC0_MD32_INFRA_REQ_MASK_B_LSB (1U << 21) /* 1b */ +#define REG_DRAMC0_MD32_VRF18_REQ_MASK_B_LSB (1U << 22) /* 1b */ +#define REG_DRAMC1_MD32_INFRA_REQ_MASK_B_LSB (1U << 23) /* 1b */ +#define REG_DRAMC1_MD32_VRF18_REQ_MASK_B_LSB (1U << 24) /* 1b */ +#define REG_CONN_SRCCLKENB2PWRAP_MASK_B_LSB (1U << 25) /* 1b */ +#define REG_DRAMC0_MD32_WAKEUP_MASK_LSB (1U << 26) /* 1b */ +#define REG_DRAMC1_MD32_WAKEUP_MASK_LSB (1U << 27) /* 1b */ +/* SPM_SRC5_MASK (0x10006000+0x0CC) */ +#define REG_MCUSYS_MERGE_APSRC_REQ_MASK_B_LSB (1U << 0) /* 9b */ +#define REG_MCUSYS_MERGE_DDR_EN_MASK_B_LSB (1U << 9) /* 9b */ +/* SPM_WAKEUP_EVENT_MASK (0x10006000+0x0D0) */ +#define REG_WAKEUP_EVENT_MASK_LSB (1U << 0) /* 32b */ +/* SPM_WAKEUP_EVENT_EXT_MASK (0x10006000+0x0D4) */ +#define REG_EXT_WAKEUP_EVENT_MASK_LSB (1U << 0) /* 32b */ +/* SPM_TWAM_EVENT_CLEAR (0x10006000+0x0D8) */ +#define SPM_TWAM_EVENT_CLEAR_LSB (1U << 0) /* 1b */ +/* SCP_CLK_CON (0x10006000+0x0DC) */ +#define REG_SCP_26M_CK_SEL_LSB (1U << 0) /* 1b */ +#define REG_SCP_DCM_EN_LSB (1U << 1) /* 1b */ +#define SCP_SECURE_V_REQ_MASK_LSB (1U << 2) /* 1b */ +#define SCP_SLP_REQ_LSB (1U << 3) /* 1b */ +#define SCP_SLP_ACK_LSB (1U << 4) /* 1b */ +/* SPM_RESOURCE_ACK_CON0 (0x10006000+0x0F0) */ +#define REG_MD_SRCCLKENA_ACK_0_MASK_LSB (1U << 0) /* 1b */ +#define REG_MD_INFRA_ACK_0_MASK_LSB (1U << 1) /* 1b */ +#define REG_MD_APSRC_ACK_0_MASK_LSB (1U << 2) /* 1b */ +#define REG_MD_VRF18_ACK_0_MASK_LSB (1U << 3) /* 1b */ +#define REG_MD_DDR_EN_ACK_0_MASK_LSB (1U << 4) /* 1b */ +#define REG_MD_SRCCLKENA_ACK_1_MASK_LSB (1U << 5) /* 1b */ +#define REG_MD_INFRA_ACK_1_MASK_LSB (1U << 6) /* 1b */ +#define REG_MD_APSRC_ACK_1_MASK_LSB (1U << 7) /* 1b */ +#define REG_MD_VRF18_ACK_1_MASK_LSB (1U << 8) /* 1b */ +#define REG_MD_DDR_EN_ACK_1_MASK_LSB (1U << 9) /* 1b */ +#define REG_CONN_SRCCLKENA_ACK_MASK_LSB (1U << 10) /* 1b */ +#define REG_CONN_INFRA_ACK_MASK_LSB (1U << 11) /* 1b */ +#define REG_CONN_APSRC_ACK_MASK_LSB (1U << 12) /* 1b */ +#define REG_CONN_VRF18_ACK_MASK_LSB (1U << 13) /* 1b */ +#define REG_CONN_DDR_EN_ACK_MASK_LSB (1U << 14) /* 1b */ +#define REG_MD32_SRCCLKENA_ACK_MASK_LSB (1U << 15) /* 1b */ +#define REG_MD32_INFRA_ACK_MASK_LSB (1U << 16) /* 1b */ +#define REG_MD32_APSRC_ACK_MASK_LSB (1U << 17) /* 1b */ +#define REG_MD32_VRF18_ACK_MASK_LSB (1U << 18) /* 1b */ +#define REG_MD32_DDR_EN_ACK_MASK_LSB (1U << 19) /* 1b */ +#define REG_SCP_SRCCLKENA_ACK_MASK_LSB (1U << 20) /* 1b */ +#define REG_SCP_INFRA_ACK_MASK_LSB (1U << 21) /* 1b */ +#define REG_SCP_APSRC_ACK_MASK_LSB (1U << 22) /* 1b */ +#define REG_SCP_VRF18_ACK_MASK_LSB (1U << 23) /* 1b */ +#define REG_SCP_DDR_EN_ACK_MASK_LSB (1U << 24) /* 1b */ +#define REG_AUDIO_DSP_SRCCLKENA_ACK_MASK_LSB (1U << 25) /* 1b */ +#define REG_AUDIO_DSP_INFRA_ACK_MASK_LSB (1U << 26) /* 1b */ +#define REG_AUDIO_DSP_APSRC_ACK_MASK_LSB (1U << 27) /* 1b */ +#define REG_AUDIO_DSP_VRF18_ACK_MASK_LSB (1U << 28) /* 1b */ +#define REG_AUDIO_DSP_DDR_EN_ACK_MASK_LSB (1U << 29) /* 1b */ +#define REG_DISP0_DDR_EN_ACK_MASK_LSB (1U << 30) /* 1b */ +#define REG_DISP1_APSRC_ACK_MASK_LSB (1U << 31) /* 1b */ +/* SPM_RESOURCE_ACK_CON1 (0x10006000+0x0F4) */ +#define REG_UFS_SRCCLKENA_ACK_MASK_LSB (1U << 0) /* 1b */ +#define REG_UFS_INFRA_ACK_MASK_LSB (1U << 1) /* 1b */ +#define REG_UFS_APSRC_ACK_MASK_LSB (1U << 2) /* 1b */ +#define REG_UFS_VRF18_ACK_MASK_LSB (1U << 3) /* 1b */ +#define REG_UFS_DDR_EN_ACK_MASK_LSB (1U << 4) /* 1b */ +#define REG_APU_SRCCLKENA_ACK_MASK_LSB (1U << 5) /* 1b */ +#define REG_APU_INFRA_ACK_MASK_LSB (1U << 6) /* 1b */ +#define REG_APU_APSRC_ACK_MASK_LSB (1U << 7) /* 1b */ +#define REG_APU_VRF18_ACK_MASK_LSB (1U << 8) /* 1b */ +#define REG_APU_DDR_EN_ACK_MASK_LSB (1U << 9) /* 1b */ +#define REG_MCUPM_SRCCLKENA_ACK_MASK_LSB (1U << 10) /* 1b */ +#define REG_MCUPM_INFRA_ACK_MASK_LSB (1U << 11) /* 1b */ +#define REG_MCUPM_APSRC_ACK_MASK_LSB (1U << 12) /* 1b */ +#define REG_MCUPM_VRF18_ACK_MASK_LSB (1U << 13) /* 1b */ +#define REG_MCUPM_DDR_EN_ACK_MASK_LSB (1U << 14) /* 1b */ +#define REG_MSDC0_SRCCLKENA_ACK_MASK_LSB (1U << 15) /* 1b */ +#define REG_MSDC0_INFRA_ACK_MASK_LSB (1U << 16) /* 1b */ +#define REG_MSDC0_APSRC_ACK_MASK_LSB (1U << 17) /* 1b */ +#define REG_MSDC0_VRF18_ACK_MASK_LSB (1U << 18) /* 1b */ +#define REG_MSDC0_DDR_EN_ACK_MASK_LSB (1U << 19) /* 1b */ +#define REG_MSDC1_SRCCLKENA_ACK_MASK_LSB (1U << 20) /* 1b */ +#define REG_MSDC1_INFRA_ACK_MASK_LSB (1U << 21) /* 1b */ +#define REG_MSDC1_APSRC_ACK_MASK_LSB (1U << 22) /* 1b */ +#define REG_MSDC1_VRF18_ACK_MASK_LSB (1U << 23) /* 1b */ +#define REG_MSDC1_DDR_EN_ACK_MASK_LSB (1U << 24) /* 1b */ +#define REG_DISP0_APSRC_ACK_MASK_LSB (1U << 25) /* 1b */ +#define REG_DISP1_DDR_EN_ACK_MASK_LSB (1U << 26) /* 1b */ +#define REG_GCE_INFRA_ACK_MASK_LSB (1U << 27) /* 1b */ +#define REG_GCE_APSRC_ACK_MASK_LSB (1U << 28) /* 1b */ +#define REG_GCE_VRF18_ACK_MASK_LSB (1U << 29) /* 1b */ +#define REG_GCE_DDR_EN_ACK_MASK_LSB (1U << 30) /* 1b */ +/* SPM_RESOURCE_ACK_CON2 (0x10006000+0x0F8) */ +#define SPM_F26M_ACK_WAIT_CYCLE_LSB (1U << 0) /* 8b */ +#define SPM_INFRA_ACK_WAIT_CYCLE_LSB (1U << 8) /* 8b */ +#define SPM_APSRC_ACK_WAIT_CYCLE_LSB (1U << 16) /* 8b */ +#define SPM_VRF18_ACK_WAIT_CYCLE_LSB (1U << 24) /* 8b */ +/* SPM_RESOURCE_ACK_CON3 (0x10006000+0x0FC) */ +#define SPM_DDR_EN_ACK_WAIT_CYCLE_LSB (1U << 0) /* 8b */ +#define REG_BAK_PSRI_SRCCLKENA_ACK_MASK_LSB (1U << 8) /* 1b */ +#define REG_BAK_PSRI_INFRA_ACK_MASK_LSB (1U << 9) /* 1b */ +#define REG_BAK_PSRI_APSRC_ACK_MASK_LSB (1U << 10) /* 1b */ +#define REG_BAK_PSRI_VRF18_ACK_MASK_LSB (1U << 11) /* 1b */ +#define REG_BAK_PSRI_DDR_EN_ACK_MASK_LSB (1U << 12) /* 1b */ +/* PCM_REG0_DATA (0x10006000+0x100) */ +#define PCM_REG0_RF_LSB (1U << 0) /* 32b */ +/* PCM_REG2_DATA (0x10006000+0x104) */ +#define PCM_REG2_RF_LSB (1U << 0) /* 32b */ +/* PCM_REG6_DATA (0x10006000+0x108) */ +#define PCM_REG6_RF_LSB (1U << 0) /* 32b */ +/* PCM_REG7_DATA (0x10006000+0x10C) */ +#define PCM_REG7_RF_LSB (1U << 0) /* 32b */ +/* PCM_REG13_DATA (0x10006000+0x110) */ +#define PCM_REG13_RF_LSB (1U << 0) /* 32b */ +/* SRC_REQ_STA_0 (0x10006000+0x114) */ +#define MD_SRCCLKENA_0_LSB (1U << 0) /* 1b */ +#define MD_SRCCLKENA2INFRA_REQ_0_LSB (1U << 1) /* 1b */ +#define MD_APSRC2INFRA_REQ_0_LSB (1U << 2) /* 1b */ +#define MD_APSRC_REQ_0_LSB (1U << 3) /* 1b */ +#define MD_VRF18_REQ_0_LSB (1U << 4) /* 1b */ +#define MD_DDR_EN_0_LSB (1U << 5) /* 1b */ +#define MD_SRCCLKENA_1_LSB (1U << 6) /* 1b */ +#define MD_SRCCLKENA2INFRA_REQ_1_LSB (1U << 7) /* 1b */ +#define MD_APSRC2INFRA_REQ_1_LSB (1U << 8) /* 1b */ +#define MD_APSRC_REQ_1_LSB (1U << 9) /* 1b */ +#define MD_VRF18_REQ_1_LSB (1U << 10) /* 1b */ +#define MD_DDR_EN_1_LSB (1U << 11) /* 1b */ +#define CONN_SRCCLKENA_LSB (1U << 12) /* 1b */ +#define CONN_SRCCLKENB_LSB (1U << 13) /* 1b */ +#define CONN_INFRA_REQ_LSB (1U << 14) /* 1b */ +#define CONN_APSRC_REQ_LSB (1U << 15) /* 1b */ +#define CONN_VRF18_REQ_LSB (1U << 16) /* 1b */ +#define CONN_DDR_EN_LSB (1U << 17) /* 1b */ +#define SRCCLKENI_LSB (1U << 18) /* 3b */ +#define MD32_SRCCLKENA_LSB (1U << 21) /* 1b */ +#define MD32_INFRA_REQ_LSB (1U << 22) /* 1b */ +#define MD32_APSRC_REQ_LSB (1U << 23) /* 1b */ +#define MD32_VRF18_REQ_LSB (1U << 24) /* 1b */ +#define MD32_DDR_EN_LSB (1U << 25) /* 1b */ +#define DISP0_APSRC_REQ_LSB (1U << 26) /* 1b */ +#define DISP0_DDR_EN_LSB (1U << 27) /* 1b */ +#define DISP1_APSRC_REQ_LSB (1U << 28) /* 1b */ +#define DISP1_DDR_EN_LSB (1U << 29) /* 1b */ +#define DVFSRC_EVENT_TRIGGER_LSB (1U << 30) /* 1b */ +/* SRC_REQ_STA_1 (0x10006000+0x118) */ +#define SCP_SRCCLKENA_LSB (1U << 0) /* 1b */ +#define SCP_INFRA_REQ_LSB (1U << 1) /* 1b */ +#define SCP_APSRC_REQ_LSB (1U << 2) /* 1b */ +#define SCP_VRF18_REQ_LSB (1U << 3) /* 1b */ +#define SCP_DDR_EN_LSB (1U << 4) /* 1b */ +#define AUDIO_DSP_SRCCLKENA_LSB (1U << 5) /* 1b */ +#define AUDIO_DSP_INFRA_REQ_LSB (1U << 6) /* 1b */ +#define AUDIO_DSP_APSRC_REQ_LSB (1U << 7) /* 1b */ +#define AUDIO_DSP_VRF18_REQ_LSB (1U << 8) /* 1b */ +#define AUDIO_DSP_DDR_EN_LSB (1U << 9) /* 1b */ +#define UFS_SRCCLKENA_LSB (1U << 10) /* 1b */ +#define UFS_INFRA_REQ_LSB (1U << 11) /* 1b */ +#define UFS_APSRC_REQ_LSB (1U << 12) /* 1b */ +#define UFS_VRF18_REQ_LSB (1U << 13) /* 1b */ +#define UFS_DDR_EN_LSB (1U << 14) /* 1b */ +#define GCE_INFRA_REQ_LSB (1U << 15) /* 1b */ +#define GCE_APSRC_REQ_LSB (1U << 16) /* 1b */ +#define GCE_VRF18_REQ_LSB (1U << 17) /* 1b */ +#define GCE_DDR_EN_LSB (1U << 18) /* 1b */ +#define INFRASYS_APSRC_REQ_LSB (1U << 19) /* 1b */ +#define INFRASYS_DDR_EN_LSB (1U << 20) /* 1b */ +#define MSDC0_SRCCLKENA_LSB (1U << 21) /* 1b */ +#define MSDC0_INFRA_REQ_LSB (1U << 22) /* 1b */ +#define MSDC0_APSRC_REQ_LSB (1U << 23) /* 1b */ +#define MSDC0_VRF18_REQ_LSB (1U << 24) /* 1b */ +#define MSDC0_DDR_EN_LSB (1U << 25) /* 1b */ +#define MSDC1_SRCCLKENA_LSB (1U << 26) /* 1b */ +#define MSDC1_INFRA_REQ_LSB (1U << 27) /* 1b */ +#define MSDC1_APSRC_REQ_LSB (1U << 28) /* 1b */ +#define MSDC1_VRF18_REQ_LSB (1U << 29) /* 1b */ +#define MSDC1_DDR_EN_LSB (1U << 30) /* 1b */ +/* SRC_REQ_STA_2 (0x10006000+0x11C) */ +#define MCUSYS_MERGE_DDR_EN_LSB (1U << 0) /* 9b */ +#define EMI_SELF_REFRESH_CH_LSB (1U << 9) /* 2b */ +#define SW2SPM_INT_LSB (1U << 11) /* 4b */ +#define SC_ADSP2SPM_WAKEUP_LSB (1U << 15) /* 1b */ +#define SC_SSPM2SPM_WAKEUP_LSB (1U << 16) /* 4b */ +#define SRC_REQ_STA_2_SC_SCP2SPM_WAKEUP_LSB (1U << 20) /* 1b */ +#define SPM_SRCCLKENA_RESERVED_LSB (1U << 21) /* 1b */ +#define SPM_INFRA_REQ_RESERVED_LSB (1U << 22) /* 1b */ +#define SPM_APSRC_REQ_RESERVED_LSB (1U << 23) /* 1b */ +#define SPM_VRF18_REQ_RESERVED_LSB (1U << 24) /* 1b */ +#define SPM_DDR_EN_RESERVED_LSB (1U << 25) /* 1b */ +#define MCUPM_SRCCLKENA_LSB (1U << 26) /* 1b */ +#define MCUPM_INFRA_REQ_LSB (1U << 27) /* 1b */ +#define MCUPM_APSRC_REQ_LSB (1U << 28) /* 1b */ +#define MCUPM_VRF18_REQ_LSB (1U << 29) /* 1b */ +#define MCUPM_DDR_EN_LSB (1U << 30) /* 1b */ +/* PCM_TIMER_OUT (0x10006000+0x120) */ +#define PCM_TIMER_LSB (1U << 0) /* 32b */ +/* PCM_WDT_OUT (0x10006000+0x124) */ +#define PCM_WDT_TIMER_VAL_OUT_LSB (1U << 0) /* 32b */ +/* SPM_IRQ_STA (0x10006000+0x128) */ +#define TWAM_IRQ_LSB (1U << 2) /* 1b */ +#define PCM_IRQ_LSB (1U << 3) /* 1b */ +/* SRC_REQ_STA_4 (0x10006000+0x12C) */ +#define APU_SRCCLKENA_LSB (1U << 0) /* 1b */ +#define APU_INFRA_REQ_LSB (1U << 1) /* 1b */ +#define APU_APSRC_REQ_LSB (1U << 2) /* 1b */ +#define APU_VRF18_REQ_LSB (1U << 3) /* 1b */ +#define APU_DDR_EN_LSB (1U << 4) /* 1b */ +#define BAK_PSRI_SRCCLKENA_LSB (1U << 5) /* 1b */ +#define BAK_PSRI_INFRA_REQ_LSB (1U << 6) /* 1b */ +#define BAK_PSRI_APSRC_REQ_LSB (1U << 7) /* 1b */ +#define BAK_PSRI_VRF18_REQ_LSB (1U << 8) /* 1b */ +#define BAK_PSRI_DDR_EN_LSB (1U << 9) /* 1b */ +/* MD32PCM_WAKEUP_STA (0x10006000+0x130) */ +#define MD32PCM_WAKEUP_STA_LSB (1U << 0) /* 32b */ +/* MD32PCM_EVENT_STA (0x10006000+0x134) */ +#define MD32PCM_EVENT_STA_LSB (1U << 0) /* 32b */ +/* SPM_WAKEUP_STA (0x10006000+0x138) */ +#define F32K_WAKEUP_EVENT_L_LSB (1U << 0) /* 16b */ +#define ASYN_WAKEUP_EVENT_L_LSB (1U << 16) /* 16b */ +/* SPM_WAKEUP_EXT_STA (0x10006000+0x13C) */ +#define EXT_WAKEUP_EVENT_LSB (1U << 0) /* 32b */ +/* SPM_WAKEUP_MISC (0x10006000+0x140) */ +#define GIC_WAKEUP_LSB (1U << 0) /* 10b */ +#define DVFSRC_IRQ_LSB (1U << 16) /* 1b */ +#define SPM_WAKEUP_MISC_REG_CPU_WAKEUP_LSB (1U << 17) /* 1b */ +#define PCM_TIMER_EVENT_LSB (1U << 18) /* 1b */ +#define PMIC_EINT_OUT_B_LSB (1U << 19) /* 2b */ +#define TWAM_IRQ_B_LSB (1U << 21) /* 1b */ +#define PMSR_IRQ_B_SET0_LSB (1U << 22) /* 1b */ +#define PMSR_IRQ_B_SET1_LSB (1U << 23) /* 1b */ +#define PMSR_IRQ_B_SET2_LSB (1U << 24) /* 1b */ +#define SPM_ACK_CHK_WAKEUP_0_LSB (1U << 25) /* 1b */ +#define SPM_ACK_CHK_WAKEUP_1_LSB (1U << 26) /* 1b */ +#define SPM_ACK_CHK_WAKEUP_2_LSB (1U << 27) /* 1b */ +#define SPM_ACK_CHK_WAKEUP_3_LSB (1U << 28) /* 1b */ +#define SPM_ACK_CHK_WAKEUP_ALL_LSB (1U << 29) /* 1b */ +#define PMIC_IRQ_ACK_LSB (1U << 30) /* 1b */ +#define PMIC_SCP_IRQ_LSB (1U << 31) /* 1b */ +/* MM_DVFS_HALT (0x10006000+0x144) */ +#define MM_DVFS_HALT_LSB (1U << 0) /* 5b */ +/* BUS_PROTECT_RDY (0x10006000+0x150) */ +#define PROTECT_READY_LSB (1U << 0) /* 32b */ +/* BUS_PROTECT1_RDY (0x10006000+0x154) */ +#define PROTECT1_READY_LSB (1U << 0) /* 32b */ +/* BUS_PROTECT2_RDY (0x10006000+0x158) */ +#define PROTECT2_READY_LSB (1U << 0) /* 32b */ +/* BUS_PROTECT3_RDY (0x10006000+0x15C) */ +#define PROTECT3_READY_LSB (1U << 0) /* 32b */ +/* SUBSYS_IDLE_STA (0x10006000+0x160) */ +#define SUBSYS_IDLE_SIGNALS_LSB (1U << 0) /* 32b */ +/* PCM_STA (0x10006000+0x164) */ +#define PCM_CK_SEL_O_LSB (1U << 0) /* 4b */ +#define EXT_SRC_STA_LSB (1U << 4) /* 3b */ +/* SRC_REQ_STA_3 (0x10006000+0x168) */ +#define CCIF_EVENT_RAW_STATUS_LSB (1U << 0) /* 16b */ +#define F26M_STATE_LSB (1U << 16) /* 1b */ +#define INFRA_STATE_LSB (1U << 17) /* 1b */ +#define APSRC_STATE_LSB (1U << 18) /* 1b */ +#define VRF18_STATE_LSB (1U << 19) /* 1b */ +#define DDR_EN_STATE_LSB (1U << 20) /* 1b */ +#define DVFS_STATE_LSB (1U << 21) /* 1b */ +#define SW_MAILBOX_STATE_LSB (1U << 22) /* 1b */ +#define SSPM_MAILBOX_STATE_LSB (1U << 23) /* 1b */ +#define ADSP_MAILBOX_STATE_LSB (1U << 24) /* 1b */ +#define SCP_MAILBOX_STATE_LSB (1U << 25) /* 1b */ +/* PWR_STATUS (0x10006000+0x16C) */ +#define PWR_STATUS_LSB (1U << 0) /* 32b */ +/* PWR_STATUS_2ND (0x10006000+0x170) */ +#define PWR_STATUS_2ND_LSB (1U << 0) /* 32b */ +/* CPU_PWR_STATUS (0x10006000+0x174) */ +#define MP0_SPMC_PWR_ON_ACK_CPU0_LSB (1U << 0) /* 1b */ +#define MP0_SPMC_PWR_ON_ACK_CPU1_LSB (1U << 1) /* 1b */ +#define MP0_SPMC_PWR_ON_ACK_CPU2_LSB (1U << 2) /* 1b */ +#define MP0_SPMC_PWR_ON_ACK_CPU3_LSB (1U << 3) /* 1b */ +#define MP0_SPMC_PWR_ON_ACK_CPU4_LSB (1U << 4) /* 1b */ +#define MP0_SPMC_PWR_ON_ACK_CPU5_LSB (1U << 5) /* 1b */ +#define MP0_SPMC_PWR_ON_ACK_CPU6_LSB (1U << 6) /* 1b */ +#define MP0_SPMC_PWR_ON_ACK_CPU7_LSB (1U << 7) /* 1b */ +#define MP0_SPMC_PWR_ON_ACK_CPUTOP_LSB (1U << 8) /* 1b */ +#define MCUSYS_SPMC_PWR_ON_ACK_LSB (1U << 9) /* 1b */ +/* OTHER_PWR_STATUS (0x10006000+0x178) */ +#define OTHER_PWR_STATUS_LSB (1U << 0) /* 32b */ +/* SPM_VTCXO_EVENT_COUNT_STA (0x10006000+0x17C) */ +#define SPM_VTCXO_SLEEP_COUNT_LSB (1U << 0) /* 16b */ +#define SPM_VTCXO_WAKE_COUNT_LSB (1U << 16) /* 16b */ +/* SPM_INFRA_EVENT_COUNT_STA (0x10006000+0x180) */ +#define SPM_INFRA_SLEEP_COUNT_LSB (1U << 0) /* 16b */ +#define SPM_INFRA_WAKE_COUNT_LSB (1U << 16) /* 16b */ +/* SPM_VRF18_EVENT_COUNT_STA (0x10006000+0x184) */ +#define SPM_VRF18_SLEEP_COUNT_LSB (1U << 0) /* 16b */ +#define SPM_VRF18_WAKE_COUNT_LSB (1U << 16) /* 16b */ +/* SPM_APSRC_EVENT_COUNT_STA (0x10006000+0x188) */ +#define SPM_APSRC_SLEEP_COUNT_LSB (1U << 0) /* 16b */ +#define SPM_APSRC_WAKE_COUNT_LSB (1U << 16) /* 16b */ +/* SPM_DDREN_EVENT_COUNT_STA (0x10006000+0x18C) */ +#define SPM_DDREN_SLEEP_COUNT_LSB (1U << 0) /* 16b */ +#define SPM_DDREN_WAKE_COUNT_LSB (1U << 16) /* 16b */ +/* MD32PCM_STA (0x10006000+0x190) */ +#define MD32PCM_HALT_LSB (1U << 0) /* 1b */ +#define MD32PCM_GATED_LSB (1U << 1) /* 1b */ +/* MD32PCM_PC (0x10006000+0x194) */ +#define MON_PC_LSB (1U << 0) /* 32b */ +/* DVFSRC_EVENT_STA (0x10006000+0x1A4) */ +#define DVFSRC_EVENT_LSB (1U << 0) /* 32b */ +/* BUS_PROTECT4_RDY (0x10006000+0x1A8) */ +#define PROTECT4_READY_LSB (1U << 0) /* 32b */ +/* BUS_PROTECT5_RDY (0x10006000+0x1AC) */ +#define PROTECT5_READY_LSB (1U << 0) /* 32b */ +/* BUS_PROTECT6_RDY (0x10006000+0x1B0) */ +#define PROTECT6_READY_LSB (1U << 0) /* 32b */ +/* BUS_PROTECT7_RDY (0x10006000+0x1B4) */ +#define PROTECT7_READY_LSB (1U << 0) /* 32b */ +/* BUS_PROTECT8_RDY (0x10006000+0x1B8) */ +#define PROTECT8_READY_LSB (1U << 0) /* 32b */ +/* SPM_TWAM_LAST_STA0 (0x10006000+0x1D0) */ +#define LAST_IDLE_CNT_0_LSB (1U << 0) /* 32b */ +/* SPM_TWAM_LAST_STA1 (0x10006000+0x1D4) */ +#define LAST_IDLE_CNT_1_LSB (1U << 0) /* 32b */ +/* SPM_TWAM_LAST_STA2 (0x10006000+0x1D8) */ +#define LAST_IDLE_CNT_2_LSB (1U << 0) /* 32b */ +/* SPM_TWAM_LAST_STA3 (0x10006000+0x1DC) */ +#define LAST_IDLE_CNT_3_LSB (1U << 0) /* 32b */ +/* SPM_TWAM_CURR_STA0 (0x10006000+0x1E0) */ +#define CURRENT_IDLE_CNT_0_LSB (1U << 0) /* 32b */ +/* SPM_TWAM_CURR_STA1 (0x10006000+0x1E4) */ +#define CURRENT_IDLE_CNT_1_LSB (1U << 0) /* 32b */ +/* SPM_TWAM_CURR_STA2 (0x10006000+0x1E8) */ +#define CURRENT_IDLE_CNT_2_LSB (1U << 0) /* 32b */ +/* SPM_TWAM_CURR_STA3 (0x10006000+0x1EC) */ +#define CURRENT_IDLE_CNT_3_LSB (1U << 0) /* 32b */ +/* SPM_TWAM_TIMER_OUT (0x10006000+0x1F0) */ +#define TWAM_TIMER_LSB (1U << 0) /* 32b */ +/* SPM_CG_CHECK_STA (0x10006000+0x1F4) */ +#define SPM_CG_CHECK_SLEEP_REQ_0_LSB (1U << 0) /* 1b */ +#define SPM_CG_CHECK_SLEEP_REQ_1_LSB (1U << 1) /* 1b */ +#define SPM_CG_CHECK_SLEEP_REQ_2_LSB (1U << 2) /* 1b */ +/* SPM_DVFS_STA (0x10006000+0x1F8) */ +#define TARGET_DVFS_LEVEL_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_OPP_STA (0x10006000+0x1FC) */ +#define TARGET_DVFS_OPP_LSB (1U << 0) /* 5b */ +#define CURRENT_DVFS_OPP_LSB (1U << 5) /* 5b */ +#define RELAY_DVFS_OPP_LSB (1U << 10) /* 5b */ +/* SPM_MCUSYS_PWR_CON (0x10006000+0x200) */ +#define MCUSYS_SPMC_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MCUSYS_SPMC_PWR_ON_LSB (1U << 2) /* 1b */ +#define MCUSYS_SPMC_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MCUSYS_SPMC_RESETPWRON_CONFIG_LSB (1U << 5) /* 1b */ +#define MCUSYS_SPMC_DORMANT_EN_LSB (1U << 6) /* 1b */ +#define MCUSYS_VPROC_EXT_OFF_LSB (1U << 7) /* 1b */ +#define SPM_MCUSYS_PWR_CON_MCUSYS_SPMC_PWR_ON_ACK_LSB (1U << 31) /* 1b */ +/* SPM_CPUTOP_PWR_CON (0x10006000+0x204) */ +#define MP0_SPMC_PWR_RST_B_CPUTOP_LSB (1U << 0) /* 1b */ +#define MP0_SPMC_PWR_ON_CPUTOP_LSB (1U << 2) /* 1b */ +#define MP0_SPMC_PWR_CLK_DIS_CPUTOP_LSB (1U << 4) /* 1b */ +#define MP0_SPMC_RESETPWRON_CONFIG_CPUTOP_LSB (1U << 5) /* 1b */ +#define MP0_SPMC_DORMANT_EN_CPUTOP_LSB (1U << 6) /* 1b */ +#define MP0_VPROC_EXT_OFF_LSB (1U << 7) /* 1b */ +#define MP0_VSRAM_EXT_OFF_LSB (1U << 8) /* 1b */ +#define SPM_CPUTOP_PWR_CON_MP0_SPMC_PWR_ON_ACK_CPUTOP_LSB (1U << 31) /* 1b */ +/* SPM_CPU0_PWR_CON (0x10006000+0x208) */ +#define MP0_SPMC_PWR_RST_B_CPU0_LSB (1U << 0) /* 1b */ +#define MP0_SPMC_PWR_ON_CPU0_LSB (1U << 2) /* 1b */ +#define MP0_SPMC_RESETPWRON_CONFIG_CPU0_LSB (1U << 5) /* 1b */ +#define MP0_VPROC_EXT_OFF_CPU0_LSB (1U << 7) /* 1b */ +#define SPM_CPU0_PWR_CON_MP0_SPMC_PWR_ON_ACK_CPU0_LSB (1U << 31) /* 1b */ +/* SPM_CPU1_PWR_CON (0x10006000+0x20C) */ +#define MP0_SPMC_PWR_RST_B_CPU1_LSB (1U << 0) /* 1b */ +#define MP0_SPMC_PWR_ON_CPU1_LSB (1U << 2) /* 1b */ +#define MP0_SPMC_RESETPWRON_CONFIG_CPU1_LSB (1U << 5) /* 1b */ +#define MP0_VPROC_EXT_OFF_CPU1_LSB (1U << 7) /* 1b */ +#define SPM_CPU1_PWR_CON_MP0_SPMC_PWR_ON_ACK_CPU1_LSB (1U << 31) /* 1b */ +/* SPM_CPU2_PWR_CON (0x10006000+0x210) */ +#define MP0_SPMC_PWR_RST_B_CPU2_LSB (1U << 0) /* 1b */ +#define MP0_SPMC_PWR_ON_CPU2_LSB (1U << 2) /* 1b */ +#define MP0_SPMC_RESETPWRON_CONFIG_CPU2_LSB (1U << 5) /* 1b */ +#define MP0_VPROC_EXT_OFF_CPU2_LSB (1U << 7) /* 1b */ +#define SPM_CPU2_PWR_CON_MP0_SPMC_PWR_ON_ACK_CPU2_LSB (1U << 31) /* 1b */ +/* SPM_CPU3_PWR_CON (0x10006000+0x214) */ +#define MP0_SPMC_PWR_RST_B_CPU3_LSB (1U << 0) /* 1b */ +#define MP0_SPMC_PWR_ON_CPU3_LSB (1U << 2) /* 1b */ +#define MP0_SPMC_RESETPWRON_CONFIG_CPU3_LSB (1U << 5) /* 1b */ +#define MP0_VPROC_EXT_OFF_CPU3_LSB (1U << 7) /* 1b */ +#define SPM_CPU3_PWR_CON_MP0_SPMC_PWR_ON_ACK_CPU3_LSB (1U << 31) /* 1b */ +/* SPM_CPU4_PWR_CON (0x10006000+0x218) */ +#define MP0_SPMC_PWR_RST_B_CPU4_LSB (1U << 0) /* 1b */ +#define MP0_SPMC_PWR_ON_CPU4_LSB (1U << 2) /* 1b */ +#define MP0_SPMC_RESETPWRON_CONFIG_CPU4_LSB (1U << 5) /* 1b */ +#define MP0_VPROC_EXT_OFF_CPU4_LSB (1U << 7) /* 1b */ +#define SPM_CPU4_PWR_CON_MP0_SPMC_PWR_ON_ACK_CPU4_LSB (1U << 31) /* 1b */ +/* SPM_CPU5_PWR_CON (0x10006000+0x21C) */ +#define MP0_SPMC_PWR_RST_B_CPU5_LSB (1U << 0) /* 1b */ +#define MP0_SPMC_PWR_ON_CPU5_LSB (1U << 2) /* 1b */ +#define MP0_SPMC_RESETPWRON_CONFIG_CPU5_LSB (1U << 5) /* 1b */ +#define MP0_VPROC_EXT_OFF_CPU5_LSB (1U << 7) /* 1b */ +#define SPM_CPU5_PWR_CON_MP0_SPMC_PWR_ON_ACK_CPU5_LSB (1U << 31) /* 1b */ +/* SPM_CPU6_PWR_CON (0x10006000+0x220) */ +#define MP0_SPMC_PWR_RST_B_CPU6_LSB (1U << 0) /* 1b */ +#define MP0_SPMC_PWR_ON_CPU6_LSB (1U << 2) /* 1b */ +#define MP0_SPMC_RESETPWRON_CONFIG_CPU6_LSB (1U << 5) /* 1b */ +#define MP0_VPROC_EXT_OFF_CPU6_LSB (1U << 7) /* 1b */ +#define SPM_CPU6_PWR_CON_MP0_SPMC_PWR_ON_ACK_CPU6_LSB (1U << 31) /* 1b */ +/* SPM_CPU7_PWR_CON (0x10006000+0x224) */ +#define MP0_SPMC_PWR_RST_B_CPU7_LSB (1U << 0) /* 1b */ +#define MP0_SPMC_PWR_ON_CPU7_LSB (1U << 2) /* 1b */ +#define MP0_SPMC_RESETPWRON_CONFIG_CPU7_LSB (1U << 5) /* 1b */ +#define MP0_VPROC_EXT_OFF_CPU7_LSB (1U << 7) /* 1b */ +#define SPM_CPU7_PWR_CON_MP0_SPMC_PWR_ON_ACK_CPU7_LSB (1U << 31) /* 1b */ +/* ARMPLL_CLK_CON (0x10006000+0x22C) */ +#define SC_ARM_FHC_PAUSE_LSB (1U << 0) /* 6b */ +#define SC_ARM_CK_OFF_LSB (1U << 6) /* 6b */ +#define SC_ARMPLL_OFF_LSB (1U << 12) /* 1b */ +#define SC_ARMBPLL_OFF_LSB (1U << 13) /* 1b */ +#define SC_ARMBPLL1_OFF_LSB (1U << 14) /* 1b */ +#define SC_ARMBPLL2_OFF_LSB (1U << 15) /* 1b */ +#define SC_ARMBPLL3_OFF_LSB (1U << 16) /* 1b */ +#define SC_CCIPLL_CKOFF_LSB (1U << 17) /* 1b */ +#define SC_ARMDDS_OFF_LSB (1U << 18) /* 1b */ +#define SC_ARMBPLL_S_OFF_LSB (1U << 19) /* 1b */ +#define SC_ARMBPLL1_S_OFF_LSB (1U << 20) /* 1b */ +#define SC_ARMBPLL2_S_OFF_LSB (1U << 21) /* 1b */ +#define SC_ARMBPLL3_S_OFF_LSB (1U << 22) /* 1b */ +#define SC_CCIPLL_PWROFF_LSB (1U << 23) /* 1b */ +#define SC_ARMPLLOUT_OFF_LSB (1U << 24) /* 1b */ +#define SC_ARMBPLLOUT_OFF_LSB (1U << 25) /* 1b */ +#define SC_ARMBPLLOUT1_OFF_LSB (1U << 26) /* 1b */ +#define SC_ARMBPLLOUT2_OFF_LSB (1U << 27) /* 1b */ +#define SC_ARMBPLLOUT3_OFF_LSB (1U << 28) /* 1b */ +#define SC_CCIPLL_OUT_OFF_LSB (1U << 29) /* 1b */ +/* MCUSYS_IDLE_STA (0x10006000+0x230) */ +#define ARMBUS_IDLE_TO_26M_LSB (1U << 0) /* 1b */ +#define MP0_CLUSTER_IDLE_TO_PWR_OFF_LSB (1U << 1) /* 1b */ +#define MCUSYS_DDR_EN_0_LSB (1U << 2) /* 1b */ +#define MCUSYS_DDR_EN_1_LSB (1U << 3) /* 1b */ +#define MCUSYS_DDR_EN_2_LSB (1U << 4) /* 1b */ +#define MCUSYS_DDR_EN_3_LSB (1U << 5) /* 1b */ +#define MCUSYS_DDR_EN_4_LSB (1U << 6) /* 1b */ +#define MCUSYS_DDR_EN_5_LSB (1U << 7) /* 1b */ +#define MCUSYS_DDR_EN_6_LSB (1U << 8) /* 1b */ +#define MCUSYS_DDR_EN_7_LSB (1U << 9) /* 1b */ +#define MP0_CPU_IDLE_TO_PWR_OFF_LSB (1U << 16) /* 8b */ +#define WFI_AF_SEL_LSB (1U << 24) /* 8b */ +/* GIC_WAKEUP_STA (0x10006000+0x234) */ +#define GIC_WAKEUP_STA_GIC_WAKEUP_LSB (1U << 10) /* 10b */ +/* CPU_SPARE_CON (0x10006000+0x238) */ +#define CPU_SPARE_CON_LSB (1U << 0) /* 32b */ +/* CPU_SPARE_CON_SET (0x10006000+0x23C) */ +#define CPU_SPARE_CON_SET_LSB (1U << 0) /* 32b */ +/* CPU_SPARE_CON_CLR (0x10006000+0x240) */ +#define CPU_SPARE_CON_CLR_LSB (1U << 0) /* 32b */ +/* ARMPLL_CLK_SEL (0x10006000+0x244) */ +#define ARMPLL_CLK_SEL_LSB (1U << 0) /* 15b */ +/* EXT_INT_WAKEUP_REQ (0x10006000+0x248) */ +#define EXT_INT_WAKEUP_REQ_LSB (1U << 0) /* 10b */ +/* EXT_INT_WAKEUP_REQ_SET (0x10006000+0x24C) */ +#define EXT_INT_WAKEUP_REQ_SET_LSB (1U << 0) /* 10b */ +/* EXT_INT_WAKEUP_REQ_CLR (0x10006000+0x250) */ +#define EXT_INT_WAKEUP_REQ_CLR_LSB (1U << 0) /* 10b */ +/* MP0_CPU0_IRQ_MASK (0x10006000+0x260) */ +#define MP0_CPU0_IRQ_MASK_LSB (1U << 0) /* 1b */ +#define MP0_CPU0_AUX_LSB (1U << 8) /* 11b */ +/* MP0_CPU1_IRQ_MASK (0x10006000+0x264) */ +#define MP0_CPU1_IRQ_MASK_LSB (1U << 0) /* 1b */ +#define MP0_CPU1_AUX_LSB (1U << 8) /* 11b */ +/* MP0_CPU2_IRQ_MASK (0x10006000+0x268) */ +#define MP0_CPU2_IRQ_MASK_LSB (1U << 0) /* 1b */ +#define MP0_CPU2_AUX_LSB (1U << 8) /* 11b */ +/* MP0_CPU3_IRQ_MASK (0x10006000+0x26C) */ +#define MP0_CPU3_IRQ_MASK_LSB (1U << 0) /* 1b */ +#define MP0_CPU3_AUX_LSB (1U << 8) /* 11b */ +/* MP1_CPU0_IRQ_MASK (0x10006000+0x270) */ +#define MP1_CPU0_IRQ_MASK_LSB (1U << 0) /* 1b */ +#define MP1_CPU0_AUX_LSB (1U << 8) /* 11b */ +/* MP1_CPU1_IRQ_MASK (0x10006000+0x274) */ +#define MP1_CPU1_IRQ_MASK_LSB (1U << 0) /* 1b */ +#define MP1_CPU1_AUX_LSB (1U << 8) /* 11b */ +/* MP1_CPU2_IRQ_MASK (0x10006000+0x278) */ +#define MP1_CPU2_IRQ_MASK_LSB (1U << 0) /* 1b */ +#define MP1_CPU2_AUX_LSB (1U << 8) /* 11b */ +/* MP1_CPU3_IRQ_MASK (0x10006000+0x27C) */ +#define MP1_CPU3_IRQ_MASK_LSB (1U << 0) /* 1b */ +#define MP1_CPU3_AUX_LSB (1U << 8) /* 11b */ +/* MP0_CPU0_WFI_EN (0x10006000+0x280) */ +#define MP0_CPU0_WFI_EN_LSB (1U << 0) /* 1b */ +/* MP0_CPU1_WFI_EN (0x10006000+0x284) */ +#define MP0_CPU1_WFI_EN_LSB (1U << 0) /* 1b */ +/* MP0_CPU2_WFI_EN (0x10006000+0x288) */ +#define MP0_CPU2_WFI_EN_LSB (1U << 0) /* 1b */ +/* MP0_CPU3_WFI_EN (0x10006000+0x28C) */ +#define MP0_CPU3_WFI_EN_LSB (1U << 0) /* 1b */ +/* MP0_CPU4_WFI_EN (0x10006000+0x290) */ +#define MP0_CPU4_WFI_EN_LSB (1U << 0) /* 1b */ +/* MP0_CPU5_WFI_EN (0x10006000+0x294) */ +#define MP0_CPU5_WFI_EN_LSB (1U << 0) /* 1b */ +/* MP0_CPU6_WFI_EN (0x10006000+0x298) */ +#define MP0_CPU6_WFI_EN_LSB (1U << 0) /* 1b */ +/* MP0_CPU7_WFI_EN (0x10006000+0x29C) */ +#define MP0_CPU7_WFI_EN_LSB (1U << 0) /* 1b */ +/* ROOT_CPUTOP_ADDR (0x10006000+0x2A0) */ +#define ROOT_CPUTOP_ADDR_LSB (1U << 0) /* 32b */ +/* ROOT_CORE_ADDR (0x10006000+0x2A4) */ +#define ROOT_CORE_ADDR_LSB (1U << 0) /* 32b */ +/* SPM2SW_MAILBOX_0 (0x10006000+0x2D0) */ +#define SPM2SW_MAILBOX_0_LSB (1U << 0) /* 32b */ +/* SPM2SW_MAILBOX_1 (0x10006000+0x2D4) */ +#define SPM2SW_MAILBOX_1_LSB (1U << 0) /* 32b */ +/* SPM2SW_MAILBOX_2 (0x10006000+0x2D8) */ +#define SPM2SW_MAILBOX_2_LSB (1U << 0) /* 32b */ +/* SPM2SW_MAILBOX_3 (0x10006000+0x2DC) */ +#define SPM2SW_MAILBOX_3_LSB (1U << 0) /* 32b */ +/* SW2SPM_INT (0x10006000+0x2E0) */ +#define SW2SPM_INT_SW2SPM_INT_LSB (1U << 0) /* 4b */ +/* SW2SPM_INT_SET (0x10006000+0x2E4) */ +#define SW2SPM_INT_SET_LSB (1U << 0) /* 4b */ +/* SW2SPM_INT_CLR (0x10006000+0x2E8) */ +#define SW2SPM_INT_CLR_LSB (1U << 0) /* 4b */ +/* SW2SPM_MAILBOX_0 (0x10006000+0x2EC) */ +#define SW2SPM_MAILBOX_0_LSB (1U << 0) /* 32b */ +/* SW2SPM_MAILBOX_1 (0x10006000+0x2F0) */ +#define SW2SPM_MAILBOX_1_LSB (1U << 0) /* 32b */ +/* SW2SPM_MAILBOX_2 (0x10006000+0x2F4) */ +#define SW2SPM_MAILBOX_2_LSB (1U << 0) /* 32b */ +/* SW2SPM_MAILBOX_3 (0x10006000+0x2F8) */ +#define SW2SPM_MAILBOX_3_LSB (1U << 0) /* 32b */ +/* SW2SPM_CFG (0x10006000+0x2FC) */ +#define SWU2SPM_INT_MASK_B_LSB (1U << 0) /* 4b */ +/* MD1_PWR_CON (0x10006000+0x300) */ +#define MD1_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MD1_PWR_ISO_LSB (1U << 1) /* 1b */ +#define MD1_PWR_ON_LSB (1U << 2) /* 1b */ +#define MD1_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define MD1_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MD1_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_MD1_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* CONN_PWR_CON (0x10006000+0x304) */ +#define CONN_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define CONN_PWR_ISO_LSB (1U << 1) /* 1b */ +#define CONN_PWR_ON_LSB (1U << 2) /* 1b */ +#define CONN_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define CONN_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +/* MFG0_PWR_CON (0x10006000+0x308) */ +#define MFG0_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MFG0_PWR_ISO_LSB (1U << 1) /* 1b */ +#define MFG0_PWR_ON_LSB (1U << 2) /* 1b */ +#define MFG0_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define MFG0_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MFG0_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_MFG0_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* MFG1_PWR_CON (0x10006000+0x30C) */ +#define MFG1_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MFG1_PWR_ISO_LSB (1U << 1) /* 1b */ +#define MFG1_PWR_ON_LSB (1U << 2) /* 1b */ +#define MFG1_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define MFG1_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MFG1_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_MFG1_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* MFG2_PWR_CON (0x10006000+0x310) */ +#define MFG2_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MFG2_PWR_ISO_LSB (1U << 1) /* 1b */ +#define MFG2_PWR_ON_LSB (1U << 2) /* 1b */ +#define MFG2_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define MFG2_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MFG2_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_MFG2_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* MFG3_PWR_CON (0x10006000+0x314) */ +#define MFG3_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MFG3_PWR_ISO_LSB (1U << 1) /* 1b */ +#define MFG3_PWR_ON_LSB (1U << 2) /* 1b */ +#define MFG3_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define MFG3_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MFG3_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_MFG3_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* MFG4_PWR_CON (0x10006000+0x318) */ +#define MFG4_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MFG4_PWR_ISO_LSB (1U << 1) /* 1b */ +#define MFG4_PWR_ON_LSB (1U << 2) /* 1b */ +#define MFG4_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define MFG4_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MFG4_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_MFG4_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* MFG5_PWR_CON (0x10006000+0x31C) */ +#define MFG5_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MFG5_PWR_ISO_LSB (1U << 1) /* 1b */ +#define MFG5_PWR_ON_LSB (1U << 2) /* 1b */ +#define MFG5_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define MFG5_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MFG5_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_MFG5_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* MFG6_PWR_CON (0x10006000+0x320) */ +#define MFG6_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MFG6_PWR_ISO_LSB (1U << 1) /* 1b */ +#define MFG6_PWR_ON_LSB (1U << 2) /* 1b */ +#define MFG6_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define MFG6_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MFG6_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_MFG6_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* IFR_PWR_CON (0x10006000+0x324) */ +#define IFR_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define IFR_PWR_ISO_LSB (1U << 1) /* 1b */ +#define IFR_PWR_ON_LSB (1U << 2) /* 1b */ +#define IFR_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define IFR_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define IFR_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_IFR_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* IFR_SUB_PWR_CON (0x10006000+0x328) */ +#define IFR_SUB_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define IFR_SUB_PWR_ISO_LSB (1U << 1) /* 1b */ +#define IFR_SUB_PWR_ON_LSB (1U << 2) /* 1b */ +#define IFR_SUB_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define IFR_SUB_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define IFR_SUB_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_IFR_SUB_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* DPY_PWR_CON (0x10006000+0x32C) */ +#define DPY_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define DPY_PWR_ISO_LSB (1U << 1) /* 1b */ +#define DPY_PWR_ON_LSB (1U << 2) /* 1b */ +#define DPY_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define DPY_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define DPY_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_DPY_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* ISP_PWR_CON (0x10006000+0x330) */ +#define ISP_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define ISP_PWR_ISO_LSB (1U << 1) /* 1b */ +#define ISP_PWR_ON_LSB (1U << 2) /* 1b */ +#define ISP_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define ISP_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define ISP_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_ISP_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* ISP2_PWR_CON (0x10006000+0x334) */ +#define ISP2_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define ISP2_PWR_ISO_LSB (1U << 1) /* 1b */ +#define ISP2_PWR_ON_LSB (1U << 2) /* 1b */ +#define ISP2_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define ISP2_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define ISP2_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_ISP2_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* IPE_PWR_CON (0x10006000+0x338) */ +#define IPE_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define IPE_PWR_ISO_LSB (1U << 1) /* 1b */ +#define IPE_PWR_ON_LSB (1U << 2) /* 1b */ +#define IPE_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define IPE_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define IPE_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_IPE_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* VDE_PWR_CON (0x10006000+0x33C) */ +#define VDE_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define VDE_PWR_ISO_LSB (1U << 1) /* 1b */ +#define VDE_PWR_ON_LSB (1U << 2) /* 1b */ +#define VDE_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define VDE_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define VDE_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_VDE_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* VDE2_PWR_CON (0x10006000+0x340) */ +#define VDE2_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define VDE2_PWR_ISO_LSB (1U << 1) /* 1b */ +#define VDE2_PWR_ON_LSB (1U << 2) /* 1b */ +#define VDE2_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define VDE2_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define VDE2_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_VDE2_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* VEN_PWR_CON (0x10006000+0x344) */ +#define VEN_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define VEN_PWR_ISO_LSB (1U << 1) /* 1b */ +#define VEN_PWR_ON_LSB (1U << 2) /* 1b */ +#define VEN_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define VEN_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define VEN_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_VEN_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* VEN_CORE1_PWR_CON (0x10006000+0x348) */ +#define VEN_CORE1_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define VEN_CORE1_PWR_ISO_LSB (1U << 1) /* 1b */ +#define VEN_CORE1_PWR_ON_LSB (1U << 2) /* 1b */ +#define VEN_CORE1_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define VEN_CORE1_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define VEN_CORE1_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_VEN_CORE1_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* MDP_PWR_CON (0x10006000+0x34C) */ +#define MDP_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MDP_PWR_ISO_LSB (1U << 1) /* 1b */ +#define MDP_PWR_ON_LSB (1U << 2) /* 1b */ +#define MDP_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define MDP_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MDP_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_MDP_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* DIS_PWR_CON (0x10006000+0x350) */ +#define DIS_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define DIS_PWR_ISO_LSB (1U << 1) /* 1b */ +#define DIS_PWR_ON_LSB (1U << 2) /* 1b */ +#define DIS_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define DIS_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define DIS_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_DIS_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* AUDIO_PWR_CON (0x10006000+0x354) */ +#define AUDIO_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define AUDIO_PWR_ISO_LSB (1U << 1) /* 1b */ +#define AUDIO_PWR_ON_LSB (1U << 2) /* 1b */ +#define AUDIO_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define AUDIO_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define AUDIO_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_AUDIO_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* ADSP_PWR_CON (0x10006000+0x358) */ +#define ADSP_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define ADSP_PWR_ISO_LSB (1U << 1) /* 1b */ +#define ADSP_PWR_ON_LSB (1U << 2) /* 1b */ +#define ADSP_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define ADSP_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define ADSP_SRAM_CKISO_LSB (1U << 5) /* 1b */ +#define ADSP_SRAM_ISOINT_B_LSB (1U << 6) /* 1b */ +#define ADSP_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define ADSP_SRAM_SLEEP_B_LSB (1U << 9) /* 1b */ +#define SC_ADSP_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +#define SC_ADSP_SRAM_SLEEP_B_ACK_LSB (1U << 13) /* 1b */ +/* CAM_PWR_CON (0x10006000+0x35C) */ +#define CAM_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define CAM_PWR_ISO_LSB (1U << 1) /* 1b */ +#define CAM_PWR_ON_LSB (1U << 2) /* 1b */ +#define CAM_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define CAM_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define CAM_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_CAM_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* CAM_RAWA_PWR_CON (0x10006000+0x360) */ +#define CAM_RAWA_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define CAM_RAWA_PWR_ISO_LSB (1U << 1) /* 1b */ +#define CAM_RAWA_PWR_ON_LSB (1U << 2) /* 1b */ +#define CAM_RAWA_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define CAM_RAWA_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define CAM_RAWA_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_CAM_RAWA_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* CAM_RAWB_PWR_CON (0x10006000+0x364) */ +#define CAM_RAWB_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define CAM_RAWB_PWR_ISO_LSB (1U << 1) /* 1b */ +#define CAM_RAWB_PWR_ON_LSB (1U << 2) /* 1b */ +#define CAM_RAWB_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define CAM_RAWB_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define CAM_RAWB_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_CAM_RAWB_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* CAM_RAWC_PWR_CON (0x10006000+0x368) */ +#define CAM_RAWC_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define CAM_RAWC_PWR_ISO_LSB (1U << 1) /* 1b */ +#define CAM_RAWC_PWR_ON_LSB (1U << 2) /* 1b */ +#define CAM_RAWC_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define CAM_RAWC_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define CAM_RAWC_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_CAM_RAWC_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* SYSRAM_CON (0x10006000+0x36C) */ +#define SYSRAM_SRAM_CKISO_LSB (1U << 0) /* 1b */ +#define SYSRAM_SRAM_ISOINT_B_LSB (1U << 1) /* 1b */ +#define SYSRAM_SRAM_SLEEP_B_LSB (1U << 4) /* 4b */ +#define SYSRAM_SRAM_PDN_LSB (1U << 16) /* 4b */ +/* SYSROM_CON (0x10006000+0x370) */ +#define SYSROM_SRAM_PDN_LSB (1U << 0) /* 6b */ +/* SSPM_SRAM_CON (0x10006000+0x374) */ +#define SSPM_SRAM_CKISO_LSB (1U << 0) /* 1b */ +#define SSPM_SRAM_ISOINT_B_LSB (1U << 1) /* 1b */ +#define SSPM_SRAM_SLEEP_B_LSB (1U << 4) /* 1b */ +#define SSPM_SRAM_PDN_LSB (1U << 16) /* 1b */ +/* SCP_SRAM_CON (0x10006000+0x378) */ +#define SCP_SRAM_CKISO_LSB (1U << 0) /* 1b */ +#define SCP_SRAM_ISOINT_B_LSB (1U << 1) /* 1b */ +#define SCP_SRAM_SLEEP_B_LSB (1U << 4) /* 1b */ +#define SCP_SRAM_PDN_LSB (1U << 16) /* 1b */ +/* DPY_SHU_SRAM_CON (0x10006000+0x37C) */ +#define DPY_SHU_SRAM_CKISO_LSB (1U << 0) /* 1b */ +#define DPY_SHU_SRAM_ISOINT_B_LSB (1U << 1) /* 1b */ +#define DPY_SHU_SRAM_SLEEP_B_LSB (1U << 4) /* 2b */ +#define DPY_SHU_SRAM_PDN_LSB (1U << 16) /* 2b */ +/* UFS_SRAM_CON (0x10006000+0x380) */ +#define UFS_SRAM_CKISO_LSB (1U << 0) /* 1b */ +#define UFS_SRAM_ISOINT_B_LSB (1U << 1) /* 1b */ +#define UFS_SRAM_SLEEP_B_LSB (1U << 4) /* 5b */ +#define UFS_SRAM_PDN_LSB (1U << 16) /* 5b */ +/* DEVAPC_IFR_SRAM_CON (0x10006000+0x384) */ +#define DEVAPC_IFR_SRAM_CKISO_LSB (1U << 0) /* 1b */ +#define DEVAPC_IFR_SRAM_ISOINT_B_LSB (1U << 1) /* 1b */ +#define DEVAPC_IFR_SRAM_SLEEP_B_LSB (1U << 4) /* 6b */ +#define DEVAPC_IFR_SRAM_PDN_LSB (1U << 16) /* 6b */ +/* DEVAPC_SUBIFR_SRAM_CON (0x10006000+0x388) */ +#define DEVAPC_SUBIFR_SRAM_CKISO_LSB (1U << 0) /* 1b */ +#define DEVAPC_SUBIFR_SRAM_ISOINT_B_LSB (1U << 1) /* 1b */ +#define DEVAPC_SUBIFR_SRAM_SLEEP_B_LSB (1U << 4) /* 6b */ +#define DEVAPC_SUBIFR_SRAM_PDN_LSB (1U << 16) /* 6b */ +/* DEVAPC_ACP_SRAM_CON (0x10006000+0x38C) */ +#define DEVAPC_ACP_SRAM_CKISO_LSB (1U << 0) /* 1b */ +#define DEVAPC_ACP_SRAM_ISOINT_B_LSB (1U << 1) /* 1b */ +#define DEVAPC_ACP_SRAM_SLEEP_B_LSB (1U << 4) /* 6b */ +#define DEVAPC_ACP_SRAM_PDN_LSB (1U << 16) /* 6b */ +/* USB_SRAM_CON (0x10006000+0x390) */ +#define USB_SRAM_PDN_LSB (1U << 0) /* 7b */ +/* DUMMY_SRAM_CON (0x10006000+0x394) */ +#define DUMMY_SRAM_CKISO_LSB (1U << 0) /* 1b */ +#define DUMMY_SRAM_ISOINT_B_LSB (1U << 1) /* 1b */ +#define DUMMY_SRAM_SLEEP_B_LSB (1U << 4) /* 8b */ +#define DUMMY_SRAM_PDN_LSB (1U << 16) /* 8b */ +/* MD_EXT_BUCK_ISO_CON (0x10006000+0x398) */ +#define VMODEM_EXT_BUCK_ISO_LSB (1U << 0) /* 1b */ +#define VMD_EXT_BUCK_ISO_LSB (1U << 1) /* 1b */ +/* EXT_BUCK_ISO (0x10006000+0x39C) */ +#define VIMVO_EXT_BUCK_ISO_LSB (1U << 0) /* 1b */ +#define GPU_EXT_BUCK_ISO_LSB (1U << 1) /* 1b */ +#define IPU_EXT_BUCK_ISO_LSB (1U << 5) /* 3b */ +/* DXCC_SRAM_CON (0x10006000+0x3A0) */ +#define DXCC_SRAM_CKISO_LSB (1U << 0) /* 1b */ +#define DXCC_SRAM_ISOINT_B_LSB (1U << 1) /* 1b */ +#define DXCC_SRAM_SLEEP_B_LSB (1U << 4) /* 1b */ +#define DXCC_SRAM_PDN_LSB (1U << 16) /* 1b */ +/* MSDC_SRAM_CON (0x10006000+0x3A4) */ +#define MSDC_SRAM_CKISO_LSB (1U << 0) /* 1b */ +#define MSDC_SRAM_ISOINT_B_LSB (1U << 1) /* 1b */ +#define MSDC_SRAM_SLEEP_B_LSB (1U << 4) /* 5b */ +#define MSDC_SRAM_PDN_LSB (1U << 16) /* 5b */ +/* DEBUGTOP_SRAM_CON (0x10006000+0x3A8) */ +#define DEBUGTOP_SRAM_PDN_LSB (1U << 0) /* 1b */ +/* DP_TX_PWR_CON (0x10006000+0x3AC) */ +#define DP_TX_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define DP_TX_PWR_ISO_LSB (1U << 1) /* 1b */ +#define DP_TX_PWR_ON_LSB (1U << 2) /* 1b */ +#define DP_TX_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define DP_TX_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define DP_TX_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_DP_TX_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* DPMAIF_SRAM_CON (0x10006000+0x3B0) */ +#define DPMAIF_SRAM_CKISO_LSB (1U << 0) /* 1b */ +#define DPMAIF_SRAM_ISOINT_B_LSB (1U << 1) /* 1b */ +#define DPMAIF_SRAM_SLEEP_B_LSB (1U << 4) /* 1b */ +#define DPMAIF_SRAM_PDN_LSB (1U << 16) /* 1b */ +/* DPY_SHU2_SRAM_CON (0x10006000+0x3B4) */ +#define DPY_SHU2_SRAM_CKISO_LSB (1U << 0) /* 1b */ +#define DPY_SHU2_SRAM_ISOINT_B_LSB (1U << 1) /* 1b */ +#define DPY_SHU2_SRAM_SLEEP_B_LSB (1U << 4) /* 2b */ +#define DPY_SHU2_SRAM_PDN_LSB (1U << 16) /* 2b */ +/* DRAMC_MCU2_SRAM_CON (0x10006000+0x3B8) */ +#define DRAMC_MCU2_SRAM_CKISO_LSB (1U << 0) /* 1b */ +#define DRAMC_MCU2_SRAM_ISOINT_B_LSB (1U << 1) /* 1b */ +#define DRAMC_MCU2_SRAM_SLEEP_B_LSB (1U << 4) /* 1b */ +#define DRAMC_MCU2_SRAM_PDN_LSB (1U << 16) /* 1b */ +/* DRAMC_MCU_SRAM_CON (0x10006000+0x3BC) */ +#define DRAMC_MCU_SRAM_CKISO_LSB (1U << 0) /* 1b */ +#define DRAMC_MCU_SRAM_ISOINT_B_LSB (1U << 1) /* 1b */ +#define DRAMC_MCU_SRAM_SLEEP_B_LSB (1U << 4) /* 1b */ +#define DRAMC_MCU_SRAM_PDN_LSB (1U << 16) /* 1b */ +/* MCUPM_SRAM_CON (0x10006000+0x3C0) */ +#define MCUPM_SRAM_CKISO_LSB (1U << 0) /* 1b */ +#define MCUPM_SRAM_ISOINT_B_LSB (1U << 1) /* 1b */ +#define MCUPM_SRAM_SLEEP_B_LSB (1U << 4) /* 8b */ +#define MCUPM_SRAM_PDN_LSB (1U << 16) /* 8b */ +/* DPY2_PWR_CON (0x10006000+0x3C4) */ +#define DPY2_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define DPY2_PWR_ISO_LSB (1U << 1) /* 1b */ +#define DPY2_PWR_ON_LSB (1U << 2) /* 1b */ +#define DPY2_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define DPY2_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define DPY2_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define SC_DPY2_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* SPM_MEM_CK_SEL (0x10006000+0x400) */ +#define SC_MEM_CK_SEL_LSB (1U << 0) /* 1b */ +#define SPM2CKSYS_MEM_CK_MUX_UPDATE_LSB (1U << 1) /* 1b */ +/* SPM_BUS_PROTECT_MASK_B (0x10006000+0X404) */ +#define SPM_BUS_PROTECT_MASK_B_LSB (1U << 0) /* 32b */ +/* SPM_BUS_PROTECT1_MASK_B (0x10006000+0x408) */ +#define SPM_BUS_PROTECT1_MASK_B_LSB (1U << 0) /* 32b */ +/* SPM_BUS_PROTECT2_MASK_B (0x10006000+0x40C) */ +#define SPM_BUS_PROTECT2_MASK_B_LSB (1U << 0) /* 32b */ +/* SPM_BUS_PROTECT3_MASK_B (0x10006000+0x410) */ +#define SPM_BUS_PROTECT3_MASK_B_LSB (1U << 0) /* 32b */ +/* SPM_BUS_PROTECT4_MASK_B (0x10006000+0x414) */ +#define SPM_BUS_PROTECT4_MASK_B_LSB (1U << 0) /* 32b */ +/* SPM_EMI_BW_MODE (0x10006000+0x418) */ +#define EMI_BW_MODE_LSB (1U << 0) /* 1b */ +#define EMI_BOOST_MODE_LSB (1U << 1) /* 1b */ +#define EMI_BW_MODE_2_LSB (1U << 2) /* 1b */ +#define EMI_BOOST_MODE_2_LSB (1U << 3) /* 1b */ +/* AP2MD_PEER_WAKEUP (0x10006000+0x41C) */ +#define AP2MD_PEER_WAKEUP_LSB (1U << 0) /* 1b */ +/* ULPOSC_CON (0x10006000+0x420) */ +#define ULPOSC_EN_LSB (1U << 0) /* 1b */ +#define ULPOSC_RST_LSB (1U << 1) /* 1b */ +#define ULPOSC_CG_EN_LSB (1U << 2) /* 1b */ +#define ULPOSC_CLK_SEL_LSB (1U << 3) /* 1b */ +/* SPM2MM_CON (0x10006000+0x424) */ +#define SPM2MM_FORCE_ULTRA_LSB (1U << 0) /* 1b */ +#define SPM2MM_DBL_OSTD_ACT_LSB (1U << 1) /* 1b */ +#define SPM2MM_ULTRAREQ_LSB (1U << 2) /* 1b */ +#define SPM2MD_ULTRAREQ_LSB (1U << 3) /* 1b */ +#define SPM2ISP_ULTRAREQ_LSB (1U << 4) /* 1b */ +#define MM2SPM_FORCE_ULTRA_ACK_D2T_LSB (1U << 16) /* 1b */ +#define MM2SPM_DBL_OSTD_ACT_ACK_D2T_LSB (1U << 17) /* 1b */ +#define SPM2ISP_ULTRAACK_D2T_LSB (1U << 18) /* 1b */ +#define SPM2MM_ULTRAACK_D2T_LSB (1U << 19) /* 1b */ +#define SPM2MD_ULTRAACK_D2T_LSB (1U << 20) /* 1b */ +/* SPM_BUS_PROTECT5_MASK_B (0x10006000+0x428) */ +#define SPM_BUS_PROTECT5_MASK_B_LSB (1U << 0) /* 32b */ +/* SPM2MCUPM_CON (0x10006000+0x42C) */ +#define SPM2MCUPM_SW_RST_B_LSB (1U << 0) /* 1b */ +#define SPM2MCUPM_SW_INT_LSB (1U << 1) /* 1b */ +/* AP_MDSRC_REQ (0x10006000+0x430) */ +#define AP_MDSMSRC_REQ_LSB (1U << 0) /* 1b */ +#define AP_L1SMSRC_REQ_LSB (1U << 1) /* 1b */ +#define AP_MD2SRC_REQ_LSB (1U << 2) /* 1b */ +#define AP_MDSMSRC_ACK_LSB (1U << 4) /* 1b */ +#define AP_L1SMSRC_ACK_LSB (1U << 5) /* 1b */ +#define AP_MD2SRC_ACK_LSB (1U << 6) /* 1b */ +/* SPM2EMI_ENTER_ULPM (0x10006000+0x434) */ +#define SPM2EMI_ENTER_ULPM_LSB (1U << 0) /* 1b */ +/* SPM2MD_DVFS_CON (0x10006000+0x438) */ +#define SPM2MD_DVFS_CON_LSB (1U << 0) /* 32b */ +/* MD2SPM_DVFS_CON (0x10006000+0x43C) */ +#define MD2SPM_DVFS_CON_LSB (1U << 0) /* 32b */ +/* SPM_BUS_PROTECT6_MASK_B (0x10006000+0X440) */ +#define SPM_BUS_PROTECT6_MASK_B_LSB (1U << 0) /* 32b */ +/* SPM_BUS_PROTECT7_MASK_B (0x10006000+0x444) */ +#define SPM_BUS_PROTECT7_MASK_B_LSB (1U << 0) /* 32b */ +/* SPM_BUS_PROTECT8_MASK_B (0x10006000+0x448) */ +#define SPM_BUS_PROTECT8_MASK_B_LSB (1U << 0) /* 32b */ +/* SPM_PLL_CON (0x10006000+0x44C) */ +#define SC_MAINPLLOUT_OFF_LSB (1U << 0) /* 1b */ +#define SC_UNIPLLOUT_OFF_LSB (1U << 1) /* 1b */ +#define SC_MAINPLL_OFF_LSB (1U << 4) /* 1b */ +#define SC_UNIPLL_OFF_LSB (1U << 5) /* 1b */ +#define SC_MAINPLL_S_OFF_LSB (1U << 8) /* 1b */ +#define SC_UNIPLL_S_OFF_LSB (1U << 9) /* 1b */ +#define SC_SMI_CK_OFF_LSB (1U << 16) /* 1b */ +#define SC_MD32K_CK_OFF_LSB (1U << 17) /* 1b */ +#define SC_CKSQ1_OFF_LSB (1U << 18) /* 1b */ +#define SC_AXI_MEM_CK_OFF_LSB (1U << 19) /* 1b */ +/* CPU_DVFS_REQ (0x10006000+0x450) */ +#define CPU_DVFS_REQ_LSB (1U << 0) /* 32b */ +/* SPM_DRAM_MCU_SW_CON_0 (0x10006000+0x454) */ +#define SW_DDR_PST_REQ_LSB (1U << 0) /* 2b */ +#define SW_DDR_PST_ABORT_REQ_LSB (1U << 2) /* 2b */ +/* SPM_DRAM_MCU_SW_CON_1 (0x10006000+0x458) */ +#define SW_DDR_PST_CH0_LSB (1U << 0) /* 32b */ +/* SPM_DRAM_MCU_SW_CON_2 (0x10006000+0x45C) */ +#define SW_DDR_PST_CH1_LSB (1U << 0) /* 32b */ +/* SPM_DRAM_MCU_SW_CON_3 (0x10006000+0x460) */ +#define SW_DDR_RESERVED_CH0_LSB (1U << 0) /* 32b */ +/* SPM_DRAM_MCU_SW_CON_4 (0x10006000+0x464) */ +#define SW_DDR_RESERVED_CH1_LSB (1U << 0) /* 32b */ +/* SPM_DRAM_MCU_STA_0 (0x10006000+0x468) */ +#define SC_DDR_PST_ACK_LSB (1U << 0) /* 2b */ +#define SC_DDR_PST_ABORT_ACK_LSB (1U << 2) /* 2b */ +/* SPM_DRAM_MCU_STA_1 (0x10006000+0x46C) */ +#define SC_DDR_CUR_PST_STA_CH0_LSB (1U << 0) /* 32b */ +/* SPM_DRAM_MCU_STA_2 (0x10006000+0x470) */ +#define SC_DDR_CUR_PST_STA_CH1_LSB (1U << 0) /* 32b */ +/* SPM_DRAM_MCU_SW_SEL_0 (0x10006000+0x474) */ +#define SW_DDR_PST_REQ_SEL_LSB (1U << 0) /* 2b */ +#define SW_DDR_PST_SEL_LSB (1U << 2) /* 2b */ +#define SW_DDR_PST_ABORT_REQ_SEL_LSB (1U << 4) /* 2b */ +#define SW_DDR_RESERVED_SEL_LSB (1U << 6) /* 2b */ +#define SW_DDR_PST_ACK_SEL_LSB (1U << 8) /* 2b */ +#define SW_DDR_PST_ABORT_ACK_SEL_LSB (1U << 10) /* 2b */ +/* RELAY_DVFS_LEVEL (0x10006000+0x478) */ +#define RELAY_DVFS_LEVEL_LSB (1U << 0) /* 32b */ +/* DRAMC_DPY_CLK_SW_CON_0 (0x10006000+0x480) */ +#define SW_PHYPLL_EN_LSB (1U << 0) /* 2b */ +#define SW_DPY_VREF_EN_LSB (1U << 2) /* 2b */ +#define SW_DPY_DLL_CK_EN_LSB (1U << 4) /* 2b */ +#define SW_DPY_DLL_EN_LSB (1U << 6) /* 2b */ +#define SW_DPY_2ND_DLL_EN_LSB (1U << 8) /* 2b */ +#define SW_MEM_CK_OFF_LSB (1U << 10) /* 2b */ +#define SW_DMSUS_OFF_LSB (1U << 12) /* 2b */ +#define SW_DPY_MODE_SW_LSB (1U << 14) /* 2b */ +#define SW_EMI_CLK_OFF_LSB (1U << 16) /* 2b */ +#define SW_DDRPHY_FB_CK_EN_LSB (1U << 18) /* 2b */ +#define SW_DR_GATE_RETRY_EN_LSB (1U << 20) /* 2b */ +#define SW_DPHY_PRECAL_UP_LSB (1U << 24) /* 2b */ +#define SW_DPY_BCLK_ENABLE_LSB (1U << 26) /* 2b */ +#define SW_TX_TRACKING_DIS_LSB (1U << 28) /* 2b */ +#define SW_DPHY_RXDLY_TRACKING_EN_LSB (1U << 30) /* 2b */ +/* DRAMC_DPY_CLK_SW_CON_1 (0x10006000+0x484) */ +#define SW_SHU_RESTORE_LSB (1U << 0) /* 2b */ +#define SW_DMYRD_MOD_LSB (1U << 2) /* 2b */ +#define SW_DMYRD_INTV_LSB (1U << 4) /* 2b */ +#define SW_DMYRD_EN_LSB (1U << 6) /* 2b */ +#define SW_DRS_DIS_REQ_LSB (1U << 8) /* 2b */ +#define SW_DR_SRAM_LOAD_LSB (1U << 10) /* 2b */ +#define SW_DR_SRAM_RESTORE_LSB (1U << 12) /* 2b */ +#define SW_DR_SHU_LEVEL_SRAM_LATCH_LSB (1U << 14) /* 2b */ +#define SW_TX_TRACK_RETRY_EN_LSB (1U << 16) /* 2b */ +#define SW_DPY_MIDPI_EN_LSB (1U << 18) /* 2b */ +#define SW_DPY_PI_RESETB_EN_LSB (1U << 20) /* 2b */ +#define SW_DPY_MCK8X_EN_LSB (1U << 22) /* 2b */ +#define SW_DR_SHU_LEVEL_SRAM_CH0_LSB (1U << 24) /* 4b */ +#define SW_DR_SHU_LEVEL_SRAM_CH1_LSB (1U << 28) /* 4b */ +/* DRAMC_DPY_CLK_SW_CON_2 (0x10006000+0x488) */ +#define SW_DR_SHU_LEVEL_LSB (1U << 0) /* 2b */ +#define SW_DR_SHU_EN_LSB (1U << 2) /* 1b */ +#define SW_DR_SHORT_QUEUE_LSB (1U << 3) /* 1b */ +#define SW_PHYPLL_MODE_SW_LSB (1U << 4) /* 1b */ +#define SW_PHYPLL2_MODE_SW_LSB (1U << 5) /* 1b */ +#define SW_PHYPLL_SHU_EN_LSB (1U << 6) /* 1b */ +#define SW_PHYPLL2_SHU_EN_LSB (1U << 7) /* 1b */ +#define SW_DR_RESERVED_0_LSB (1U << 24) /* 2b */ +#define SW_DR_RESERVED_1_LSB (1U << 26) /* 2b */ +#define SW_DR_RESERVED_2_LSB (1U << 28) /* 2b */ +#define SW_DR_RESERVED_3_LSB (1U << 30) /* 2b */ +/* DRAMC_DPY_CLK_SW_CON_3 (0x10006000+0x48C) */ +#define SC_DR_SHU_EN_ACK_LSB (1U << 0) /* 4b */ +#define SC_EMI_CLK_OFF_ACK_LSB (1U << 4) /* 4b */ +#define SC_DR_SHORT_QUEUE_ACK_LSB (1U << 8) /* 4b */ +#define SC_DRAMC_DFS_STA_LSB (1U << 12) /* 4b */ +#define SC_DRS_DIS_ACK_LSB (1U << 16) /* 4b */ +#define SC_DR_SRAM_LOAD_ACK_LSB (1U << 20) /* 4b */ +#define SC_DR_SRAM_PLL_LOAD_ACK_LSB (1U << 24) /* 4b */ +#define SC_DR_SRAM_RESTORE_ACK_LSB (1U << 28) /* 4b */ +/* DRAMC_DPY_CLK_SW_SEL_0 (0x10006000+0x490) */ +#define SW_PHYPLL_EN_SEL_LSB (1U << 0) /* 2b */ +#define SW_DPY_VREF_EN_SEL_LSB (1U << 2) /* 2b */ +#define SW_DPY_DLL_CK_EN_SEL_LSB (1U << 4) /* 2b */ +#define SW_DPY_DLL_EN_SEL_LSB (1U << 6) /* 2b */ +#define SW_DPY_2ND_DLL_EN_SEL_LSB (1U << 8) /* 2b */ +#define SW_MEM_CK_OFF_SEL_LSB (1U << 10) /* 2b */ +#define SW_DMSUS_OFF_SEL_LSB (1U << 12) /* 2b */ +#define SW_DPY_MODE_SW_SEL_LSB (1U << 14) /* 2b */ +#define SW_EMI_CLK_OFF_SEL_LSB (1U << 16) /* 2b */ +#define SW_DDRPHY_FB_CK_EN_SEL_LSB (1U << 18) /* 2b */ +#define SW_DR_GATE_RETRY_EN_SEL_LSB (1U << 20) /* 2b */ +#define SW_DPHY_PRECAL_UP_SEL_LSB (1U << 24) /* 2b */ +#define SW_DPY_BCLK_ENABLE_SEL_LSB (1U << 26) /* 2b */ +#define SW_TX_TRACKING_DIS_SEL_LSB (1U << 28) /* 2b */ +#define SW_DPHY_RXDLY_TRACKING_EN_SEL_LSB (1U << 30) /* 2b */ +/* DRAMC_DPY_CLK_SW_SEL_1 (0x10006000+0x494) */ +#define SW_SHU_RESTORE_SEL_LSB (1U << 0) /* 2b */ +#define SW_DMYRD_MOD_SEL_LSB (1U << 2) /* 2b */ +#define SW_DMYRD_INTV_SEL_LSB (1U << 4) /* 2b */ +#define SW_DMYRD_EN_SEL_LSB (1U << 6) /* 2b */ +#define SW_DRS_DIS_REQ_SEL_LSB (1U << 8) /* 2b */ +#define SW_DR_SRAM_LOAD_SEL_LSB (1U << 10) /* 2b */ +#define SW_DR_SRAM_RESTORE_SEL_LSB (1U << 12) /* 2b */ +#define SW_DR_SHU_LEVEL_SRAM_LATCH_SEL_LSB (1U << 14) /* 2b */ +#define SW_TX_TRACK_RETRY_EN_SEL_LSB (1U << 16) /* 2b */ +#define SW_DPY_MIDPI_EN_SEL_LSB (1U << 18) /* 2b */ +#define SW_DPY_PI_RESETB_EN_SEL_LSB (1U << 20) /* 2b */ +#define SW_DPY_MCK8X_EN_SEL_LSB (1U << 22) /* 2b */ +#define SW_DR_SHU_LEVEL_SRAM_SEL_LSB (1U << 24) /* 2b */ +/* DRAMC_DPY_CLK_SW_SEL_2 (0x10006000+0x498) */ +#define SW_DR_SHU_LEVEL_SEL_LSB (1U << 0) /* 1b */ +#define SW_DR_SHU_EN_SEL_LSB (1U << 2) /* 1b */ +#define SW_DR_SHORT_QUEUE_SEL_LSB (1U << 3) /* 1b */ +#define SW_PHYPLL_MODE_SW_SEL_LSB (1U << 4) /* 1b */ +#define SW_PHYPLL2_MODE_SW_SEL_LSB (1U << 5) /* 1b */ +#define SW_PHYPLL_SHU_EN_SEL_LSB (1U << 6) /* 1b */ +#define SW_PHYPLL2_SHU_EN_SEL_LSB (1U << 7) /* 1b */ +#define SW_DR_RESERVED_0_SEL_LSB (1U << 24) /* 2b */ +#define SW_DR_RESERVED_1_SEL_LSB (1U << 26) /* 2b */ +#define SW_DR_RESERVED_2_SEL_LSB (1U << 28) /* 2b */ +#define SW_DR_RESERVED_3_SEL_LSB (1U << 30) /* 2b */ +/* DRAMC_DPY_CLK_SW_SEL_3 (0x10006000+0x49C) */ +#define SC_DR_SHU_EN_ACK_SEL_LSB (1U << 0) /* 4b */ +#define SC_EMI_CLK_OFF_ACK_SEL_LSB (1U << 4) /* 4b */ +#define SC_DR_SHORT_QUEUE_ACK_SEL_LSB (1U << 8) /* 4b */ +#define SC_DRAMC_DFS_STA_SEL_LSB (1U << 12) /* 4b */ +#define SC_DRS_DIS_ACK_SEL_LSB (1U << 16) /* 4b */ +#define SC_DR_SRAM_LOAD_ACK_SEL_LSB (1U << 20) /* 4b */ +#define SC_DR_SRAM_PLL_LOAD_ACK_SEL_LSB (1U << 24) /* 4b */ +#define SC_DR_SRAM_RESTORE_ACK_SEL_LSB (1U << 28) /* 4b */ +/* DRAMC_DPY_CLK_SPM_CON (0x10006000+0x4A0) */ +#define SC_DMYRD_EN_MOD_SEL_PCM_LSB (1U << 0) /* 1b */ +#define SC_DMYRD_INTV_SEL_PCM_LSB (1U << 1) /* 1b */ +#define SC_DMYRD_EN_PCM_LSB (1U << 2) /* 1b */ +#define SC_DRS_DIS_REQ_PCM_LSB (1U << 3) /* 1b */ +#define SC_DR_SHU_LEVEL_SRAM_PCM_LSB (1U << 4) /* 4b */ +#define SC_DR_GATE_RETRY_EN_PCM_LSB (1U << 8) /* 1b */ +#define SC_DR_SHORT_QUEUE_PCM_LSB (1U << 9) /* 1b */ +#define SC_DPY_MIDPI_EN_PCM_LSB (1U << 10) /* 1b */ +#define SC_DPY_PI_RESETB_EN_PCM_LSB (1U << 11) /* 1b */ +#define SC_DPY_MCK8X_EN_PCM_LSB (1U << 12) /* 1b */ +#define SC_DR_RESERVED_0_PCM_LSB (1U << 13) /* 1b */ +#define SC_DR_RESERVED_1_PCM_LSB (1U << 14) /* 1b */ +#define SC_DR_RESERVED_2_PCM_LSB (1U << 15) /* 1b */ +#define SC_DR_RESERVED_3_PCM_LSB (1U << 16) /* 1b */ +#define SC_DMDRAMCSHU_ACK_ALL_LSB (1U << 24) /* 1b */ +#define SC_EMI_CLK_OFF_ACK_ALL_LSB (1U << 25) /* 1b */ +#define SC_DR_SHORT_QUEUE_ACK_ALL_LSB (1U << 26) /* 1b */ +#define SC_DRAMC_DFS_STA_ALL_LSB (1U << 27) /* 1b */ +#define SC_DRS_DIS_ACK_ALL_LSB (1U << 28) /* 1b */ +#define SC_DR_SRAM_LOAD_ACK_ALL_LSB (1U << 29) /* 1b */ +#define SC_DR_SRAM_PLL_LOAD_ACK_ALL_LSB (1U << 30) /* 1b */ +#define SC_DR_SRAM_RESTORE_ACK_ALL_LSB (1U << 31) /* 1b */ +/* SPM_DVFS_LEVEL (0x10006000+0x4A4) */ +#define SPM_DVFS_LEVEL_LSB (1U << 0) /* 32b */ +/* SPM_CIRQ_CON (0x10006000+0x4A8) */ +#define CIRQ_CLK_SEL_LSB (1U << 0) /* 1b */ +/* SPM_DVFS_MISC (0x10006000+0x4AC) */ +#define MSDC_DVFS_REQUEST_LSB (1U << 0) /* 1b */ +#define SPM2EMI_SLP_PROT_EN_LSB (1U << 1) /* 1b */ +#define SPM_DVFS_FORCE_ENABLE_LSB (1U << 2) /* 1b */ +#define FORCE_DVFS_WAKE_LSB (1U << 3) /* 1b */ +#define SPM_DVFSRC_ENABLE_LSB (1U << 4) /* 1b */ +#define SPM_DVFS_DONE_LSB (1U << 5) /* 1b */ +#define DVFSRC_IRQ_WAKEUP_EVENT_MASK_LSB (1U << 6) /* 1b */ +#define SPM2RC_EVENT_ABORT_LSB (1U << 7) /* 1b */ +#define EMI_SLP_IDLE_LSB (1U << 14) /* 1b */ +#define SDIO_READY_TO_SPM_LSB (1U << 15) /* 1b */ +/* SPM_VS1_VS2_RC_CON (0x10006000+0x4B0) */ +#define VS1_INIT_LEVEL_LSB (1U << 0) /* 2b */ +#define VS1_INIT_LSB (1U << 2) /* 1b */ +#define VS1_CURR_LEVEL_LSB (1U << 3) /* 2b */ +#define VS1_NEXT_LEVEL_LSB (1U << 5) /* 2b */ +#define VS1_VOTE_LEVEL_LSB (1U << 7) /* 2b */ +#define VS1_TRIGGER_LSB (1U << 9) /* 1b */ +#define VS2_INIT_LEVEL_LSB (1U << 10) /* 3b */ +#define VS2_INIT_LSB (1U << 13) /* 1b */ +#define VS2_CURR_LEVEL_LSB (1U << 14) /* 3b */ +#define VS2_NEXT_LEVEL_LSB (1U << 17) /* 3b */ +#define VS2_VOTE_LEVEL_LSB (1U << 20) /* 3b */ +#define VS2_TRIGGER_LSB (1U << 23) /* 1b */ +#define VS1_FORCE_LSB (1U << 24) /* 1b */ +#define VS2_FORCE_LSB (1U << 25) /* 1b */ +#define VS1_VOTE_LEVEL_FORCE_LSB (1U << 26) /* 2b */ +#define VS2_VOTE_LEVEL_FORCE_LSB (1U << 28) /* 3b */ +/* RG_MODULE_SW_CG_0_MASK_REQ_0 (0x10006000+0x4B4) */ +#define RG_MODULE_SW_CG_0_MASK_REQ_0_LSB (1U << 0) /* 32b */ +/* RG_MODULE_SW_CG_0_MASK_REQ_1 (0x10006000+0x4B8) */ +#define RG_MODULE_SW_CG_0_MASK_REQ_1_LSB (1U << 0) /* 32b */ +/* RG_MODULE_SW_CG_0_MASK_REQ_2 (0x10006000+0x4BC) */ +#define RG_MODULE_SW_CG_0_MASK_REQ_2_LSB (1U << 0) /* 32b */ +/* RG_MODULE_SW_CG_1_MASK_REQ_0 (0x10006000+0x4C0) */ +#define RG_MODULE_SW_CG_1_MASK_REQ_0_LSB (1U << 0) /* 32b */ +/* RG_MODULE_SW_CG_1_MASK_REQ_1 (0x10006000+0x4C4) */ +#define RG_MODULE_SW_CG_1_MASK_REQ_1_LSB (1U << 0) /* 32b */ +/* RG_MODULE_SW_CG_1_MASK_REQ_2 (0x10006000+0x4C8) */ +#define RG_MODULE_SW_CG_1_MASK_REQ_2_LSB (1U << 0) /* 32b */ +/* RG_MODULE_SW_CG_2_MASK_REQ_0 (0x10006000+0x4CC) */ +#define RG_MODULE_SW_CG_2_MASK_REQ_0_LSB (1U << 0) /* 32b */ +/* RG_MODULE_SW_CG_2_MASK_REQ_1 (0x10006000+0x4D0) */ +#define RG_MODULE_SW_CG_2_MASK_REQ_1_LSB (1U << 0) /* 32b */ +/* RG_MODULE_SW_CG_2_MASK_REQ_2 (0x10006000+0x4D4) */ +#define RG_MODULE_SW_CG_2_MASK_REQ_2_LSB (1U << 0) /* 32b */ +/* RG_MODULE_SW_CG_3_MASK_REQ_0 (0x10006000+0x4D8) */ +#define RG_MODULE_SW_CG_3_MASK_REQ_0_LSB (1U << 0) /* 32b */ +/* RG_MODULE_SW_CG_3_MASK_REQ_1 (0x10006000+0x4DC) */ +#define RG_MODULE_SW_CG_3_MASK_REQ_1_LSB (1U << 0) /* 32b */ +/* RG_MODULE_SW_CG_3_MASK_REQ_2 (0x10006000+0x4E0) */ +#define RG_MODULE_SW_CG_3_MASK_REQ_2_LSB (1U << 0) /* 32b */ +/* PWR_STATUS_MASK_REQ_0 (0x10006000+0x4E4) */ +#define PWR_STATUS_MASK_REQ_0_LSB (1U << 0) /* 32b */ +/* PWR_STATUS_MASK_REQ_1 (0x10006000+0x4E8) */ +#define PWR_STATUS_MASK_REQ_1_LSB (1U << 0) /* 32b */ +/* PWR_STATUS_MASK_REQ_2 (0x10006000+0x4EC) */ +#define PWR_STATUS_MASK_REQ_2_LSB (1U << 0) /* 32b */ +/* SPM_CG_CHECK_CON (0x10006000+0x4F0) */ +#define APMIXEDSYS_BUSY_MASK_REQ_0_LSB (1U << 0) /* 5b */ +#define APMIXEDSYS_BUSY_MASK_REQ_1_LSB (1U << 8) /* 5b */ +#define APMIXEDSYS_BUSY_MASK_REQ_2_LSB (1U << 16) /* 5b */ +#define AUDIOSYS_BUSY_MASK_REQ_0_LSB (1U << 24) /* 1b */ +#define AUDIOSYS_BUSY_MASK_REQ_1_LSB (1U << 25) /* 1b */ +#define AUDIOSYS_BUSY_MASK_REQ_2_LSB (1U << 26) /* 1b */ +#define SSUSB_BUSY_MASK_REQ_0_LSB (1U << 27) /* 1b */ +#define SSUSB_BUSY_MASK_REQ_1_LSB (1U << 28) /* 1b */ +#define SSUSB_BUSY_MASK_REQ_2_LSB (1U << 29) /* 1b */ +/* SPM_SRC_RDY_STA (0x10006000+0x4F4) */ +#define SPM_INFRA_INTERNAL_ACK_LSB (1U << 0) /* 1b */ +#define SPM_VRF18_INTERNAL_ACK_LSB (1U << 1) /* 1b */ +/* SPM_DVS_DFS_LEVEL (0x10006000+0x4F8) */ +#define SPM_DFS_LEVEL_LSB (1U << 0) /* 16b */ +#define SPM_DVS_LEVEL_LSB (1U << 16) /* 16b */ +/* SPM_FORCE_DVFS (0x10006000+0x4FC) */ +#define FORCE_DVFS_LEVEL_LSB (1U << 0) /* 32b */ +/* SRCLKEN_RC_CFG (0x10006000+0x500) */ +#define SRCLKEN_RC_CFG_LSB (1U << 0) /* 32b */ +/* RC_CENTRAL_CFG1 (0x10006000+0x504) */ +#define RC_CENTRAL_CFG1_LSB (1U << 0) /* 32b */ +/* RC_CENTRAL_CFG2 (0x10006000+0x508) */ +#define RC_CENTRAL_CFG2_LSB (1U << 0) /* 32b */ +/* RC_CMD_ARB_CFG (0x10006000+0x50C) */ +#define RC_CMD_ARB_CFG_LSB (1U << 0) /* 32b */ +/* RC_PMIC_RCEN_ADDR (0x10006000+0x510) */ +#define RC_PMIC_RCEN_ADDR_LSB (1U << 0) /* 16b */ +#define RC_PMIC_RCEN_RESERVE_LSB (1U << 16) /* 16b */ +/* RC_PMIC_RCEN_SET_CLR_ADDR (0x10006000+0x514) */ +#define RC_PMIC_RCEN_SET_ADDR_LSB (1U << 0) /* 16b */ +#define RC_PMIC_RCEN_CLR_ADDR_LSB (1U << 16) /* 16b */ +/* RC_DCXO_FPM_CFG (0x10006000+0x518) */ +#define RC_DCXO_FPM_CFG_LSB (1U << 0) /* 32b */ +/* RC_CENTRAL_CFG3 (0x10006000+0x51C) */ +#define RC_CENTRAL_CFG3_LSB (1U << 0) /* 32b */ +/* RC_M00_SRCLKEN_CFG (0x10006000+0x520) */ +#define RC_M00_SRCLKEN_CFG_LSB (1U << 0) /* 32b */ +/* RC_M01_SRCLKEN_CFG (0x10006000+0x524) */ +#define RC_M01_SRCLKEN_CFG_LSB (1U << 0) /* 32b */ +/* RC_M02_SRCLKEN_CFG (0x10006000+0x528) */ +#define RC_M02_SRCLKEN_CFG_LSB (1U << 0) /* 32b */ +/* RC_M03_SRCLKEN_CFG (0x10006000+0x52C) */ +#define RC_M03_SRCLKEN_CFG_LSB (1U << 0) /* 32b */ +/* RC_M04_SRCLKEN_CFG (0x10006000+0x530) */ +#define RC_M04_SRCLKEN_CFG_LSB (1U << 0) /* 32b */ +/* RC_M05_SRCLKEN_CFG (0x10006000+0x534) */ +#define RC_M05_SRCLKEN_CFG_LSB (1U << 0) /* 32b */ +/* RC_M06_SRCLKEN_CFG (0x10006000+0x538) */ +#define RC_M06_SRCLKEN_CFG_LSB (1U << 0) /* 32b */ +/* RC_M07_SRCLKEN_CFG (0x10006000+0x53C) */ +#define RC_M07_SRCLKEN_CFG_LSB (1U << 0) /* 32b */ +/* RC_M08_SRCLKEN_CFG (0x10006000+0x540) */ +#define RC_M08_SRCLKEN_CFG_LSB (1U << 0) /* 32b */ +/* RC_M09_SRCLKEN_CFG (0x10006000+0x544) */ +#define RC_M09_SRCLKEN_CFG_LSB (1U << 0) /* 32b */ +/* RC_M10_SRCLKEN_CFG (0x10006000+0x548) */ +#define RC_M10_SRCLKEN_CFG_LSB (1U << 0) /* 32b */ +/* RC_M11_SRCLKEN_CFG (0x10006000+0x54C) */ +#define RC_M11_SRCLKEN_CFG_LSB (1U << 0) /* 32b */ +/* RC_M12_SRCLKEN_CFG (0x10006000+0x550) */ +#define RC_M12_SRCLKEN_CFG_LSB (1U << 0) /* 32b */ +/* RC_SRCLKEN_SW_CON_CFG (0x10006000+0x554) */ +#define RC_SRCLKEN_SW_CON_CFG_LSB (1U << 0) /* 32b */ +/* RC_CENTRAL_CFG4 (0x10006000+0x558) */ +#define RC_CENTRAL_CFG4_LSB (1U << 0) /* 32b */ +/* RC_PROTOCOL_CHK_CFG (0x10006000+0x560) */ +#define RC_PROTOCOL_CHK_CFG_LSB (1U << 0) /* 32b */ +/* RC_DEBUG_CFG (0x10006000+0x564) */ +#define RC_DEBUG_CFG_LSB (1U << 0) /* 32b */ +/* RC_MISC_0 (0x10006000+0x5B4) */ +#define SRCCLKENO_LSB (1U << 0) /* 2b */ +#define PCM_SRCCLKENO_LSB (1U << 3) /* 2b */ +#define RC_VREQ_LSB (1U << 5) /* 1b */ +#define RC_SPM_SRCCLKENO_0_ACK_LSB (1U << 6) /* 1b */ +/* RC_SPM_CTRL (0x10006000+0x448) */ +#define SPM_AP_26M_RDY_LSB (1U << 0) /* 1b */ +#define KEEP_RC_SPI_ACTIVE_LSB (1U << 1) /* 1b */ +#define SPM2RC_DMY_CTRL_LSB (1U << 2) /* 6b */ +/* SUBSYS_INTF_CFG (0x10006000+0x5BC) */ +#define SRCLKEN_FPM_MASK_B_LSB (1U << 0) /* 13b */ +#define SRCLKEN_BBLPM_MASK_B_LSB (1U << 16) /* 13b */ +/* PCM_WDT_LATCH_25 (0x10006000+0x5C0) */ +#define PCM_WDT_LATCH_25_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_26 (0x10006000+0x5C4) */ +#define PCM_WDT_LATCH_26_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_27 (0x10006000+0x5C8) */ +#define PCM_WDT_LATCH_27_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_28 (0x10006000+0x5CC) */ +#define PCM_WDT_LATCH_28_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_29 (0x10006000+0x5D0) */ +#define PCM_WDT_LATCH_29_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_30 (0x10006000+0x5D4) */ +#define PCM_WDT_LATCH_30_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_31 (0x10006000+0x5D8) */ +#define PCM_WDT_LATCH_31_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_32 (0x10006000+0x5DC) */ +#define PCM_WDT_LATCH_32_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_33 (0x10006000+0x5E0) */ +#define PCM_WDT_LATCH_33_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_34 (0x10006000+0x5E4) */ +#define PCM_WDT_LATCH_34_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_35 (0x10006000+0x5EC) */ +#define PCM_WDT_LATCH_35_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_36 (0x10006000+0x5F0) */ +#define PCM_WDT_LATCH_36_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_37 (0x10006000+0x5F4) */ +#define PCM_WDT_LATCH_37_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_38 (0x10006000+0x5F8) */ +#define PCM_WDT_LATCH_38_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_39 (0x10006000+0x5FC) */ +#define PCM_WDT_LATCH_39_LSB (1U << 0) /* 32b */ +/* SPM_SW_FLAG_0 (0x10006000+0x600) */ +#define SPM_SW_FLAG_LSB (1U << 0) /* 32b */ +/* SPM_SW_DEBUG_0 (0x10006000+0x604) */ +#define SPM_SW_DEBUG_0_LSB (1U << 0) /* 32b */ +/* SPM_SW_FLAG_1 (0x10006000+0x608) */ +#define SPM_SW_FLAG_1_LSB (1U << 0) /* 32b */ +/* SPM_SW_DEBUG_1 (0x10006000+0x60C) */ +#define SPM_SW_DEBUG_1_LSB (1U << 0) /* 32b */ +/* SPM_SW_RSV_0 (0x10006000+0x610) */ +#define SPM_SW_RSV_0_LSB (1U << 0) /* 32b */ +/* SPM_SW_RSV_1 (0x10006000+0x614) */ +#define SPM_SW_RSV_1_LSB (1U << 0) /* 32b */ +/* SPM_SW_RSV_2 (0x10006000+0x618) */ +#define SPM_SW_RSV_2_LSB (1U << 0) /* 32b */ +/* SPM_SW_RSV_3 (0x10006000+0x61C) */ +#define SPM_SW_RSV_3_LSB (1U << 0) /* 32b */ +/* SPM_SW_RSV_4 (0x10006000+0x620) */ +#define SPM_SW_RSV_4_LSB (1U << 0) /* 32b */ +/* SPM_SW_RSV_5 (0x10006000+0x624) */ +#define SPM_SW_RSV_5_LSB (1U << 0) /* 32b */ +/* SPM_SW_RSV_6 (0x10006000+0x628) */ +#define SPM_SW_RSV_6_LSB (1U << 0) /* 32b */ +/* SPM_SW_RSV_7 (0x10006000+0x62C) */ +#define SPM_SW_RSV_7_LSB (1U << 0) /* 32b */ +/* SPM_SW_RSV_8 (0x10006000+0x630) */ +#define SPM_SW_RSV_8_LSB (1U << 0) /* 32b */ +/* SPM_BK_WAKE_EVENT (0x10006000+0x634) */ +#define SPM_BK_WAKE_EVENT_LSB (1U << 0) /* 32b */ +/* SPM_BK_VTCXO_DUR (0x10006000+0x638) */ +#define SPM_BK_VTCXO_DUR_LSB (1U << 0) /* 32b */ +/* SPM_BK_WAKE_MISC (0x10006000+0x63C) */ +#define SPM_BK_WAKE_MISC_LSB (1U << 0) /* 32b */ +/* SPM_BK_PCM_TIMER (0x10006000+0x640) */ +#define SPM_BK_PCM_TIMER_LSB (1U << 0) /* 32b */ +/* SPM_RSV_CON_0 (0x10006000+0x650) */ +#define SPM_RSV_CON_0_LSB (1U << 0) /* 32b */ +/* SPM_RSV_CON_1 (0x10006000+0x654) */ +#define SPM_RSV_CON_1_LSB (1U << 0) /* 32b */ +/* SPM_RSV_STA_0 (0x10006000+0x658) */ +#define SPM_RSV_STA_0_LSB (1U << 0) /* 32b */ +/* SPM_RSV_STA_1 (0x10006000+0x65C) */ +#define SPM_RSV_STA_1_LSB (1U << 0) /* 32b */ +/* SPM_SPARE_CON (0x10006000+0x660) */ +#define SPM_SPARE_CON_LSB (1U << 0) /* 32b */ +/* SPM_SPARE_CON_SET (0x10006000+0x664) */ +#define SPM_SPARE_CON_SET_LSB (1U << 0) /* 32b */ +/* SPM_SPARE_CON_CLR (0x10006000+0x668) */ +#define SPM_SPARE_CON_CLR_LSB (1U << 0) /* 32b */ +/* SPM_CROSS_WAKE_M00_REQ (0x10006000+0x66C) */ +#define SPM_CROSS_WAKE_M00_REQ_LSB (1U << 0) /* 4b */ +#define SPM_CROSS_WAKE_M00_CHK_LSB (1U << 4) /* 4b */ +/* SPM_CROSS_WAKE_M01_REQ (0x10006000+0x670) */ +#define SPM_CROSS_WAKE_M01_REQ_LSB (1U << 0) /* 4b */ +#define SPM_CROSS_WAKE_M01_CHK_LSB (1U << 4) /* 4b */ +/* SPM_CROSS_WAKE_M02_REQ (0x10006000+0x674) */ +#define SPM_CROSS_WAKE_M02_REQ_LSB (1U << 0) /* 4b */ +#define SPM_CROSS_WAKE_M02_CHK_LSB (1U << 4) /* 4b */ +/* SPM_CROSS_WAKE_M03_REQ (0x10006000+0x678) */ +#define SPM_CROSS_WAKE_M03_REQ_LSB (1U << 0) /* 4b */ +#define SPM_CROSS_WAKE_M03_CHK_LSB (1U << 4) /* 4b */ +/* SCP_VCORE_LEVEL (0x10006000+0x67C) */ +#define SCP_VCORE_LEVEL_LSB (1U << 0) /* 16b */ +/* SC_MM_CK_SEL_CON (0x10006000+0x680) */ +#define SC_MM_CK_SEL_LSB (1U << 0) /* 4b */ +#define SC_MM_CK_SEL_EN_LSB (1U << 4) /* 1b */ +/* SPARE_ACK_MASK (0x10006000+0x684) */ +#define SPARE_ACK_MASK_B_LSB (1U << 0) /* 32b */ +/* SPM_DV_CON_0 (0x10006000+0x68C) */ +#define SPM_DV_CON_0_LSB (1U << 0) /* 32b */ +/* SPM_DV_CON_1 (0x10006000+0x690) */ +#define SPM_DV_CON_1_LSB (1U << 0) /* 32b */ +/* SPM_DV_STA (0x10006000+0x694) */ +#define SPM_DV_STA_LSB (1U << 0) /* 32b */ +/* CONN_XOWCN_DEBUG_EN (0x10006000+0x698) */ +#define CONN_XOWCN_DEBUG_EN_LSB (1U << 0) /* 1b */ +/* SPM_SEMA_M0 (0x10006000+0x69C) */ +#define SPM_SEMA_M0_LSB (1U << 0) /* 8b */ +/* SPM_SEMA_M1 (0x10006000+0x6A0) */ +#define SPM_SEMA_M1_LSB (1U << 0) /* 8b */ +/* SPM_SEMA_M2 (0x10006000+0x6A4) */ +#define SPM_SEMA_M2_LSB (1U << 0) /* 8b */ +/* SPM_SEMA_M3 (0x10006000+0x6A8) */ +#define SPM_SEMA_M3_LSB (1U << 0) /* 8b */ +/* SPM_SEMA_M4 (0x10006000+0x6AC) */ +#define SPM_SEMA_M4_LSB (1U << 0) /* 8b */ +/* SPM_SEMA_M5 (0x10006000+0x6B0) */ +#define SPM_SEMA_M5_LSB (1U << 0) /* 8b */ +/* SPM_SEMA_M6 (0x10006000+0x6B4) */ +#define SPM_SEMA_M6_LSB (1U << 0) /* 8b */ +/* SPM_SEMA_M7 (0x10006000+0x6B8) */ +#define SPM_SEMA_M7_LSB (1U << 0) /* 8b */ +/* SPM2ADSP_MAILBOX (0x10006000+0x6BC) */ +#define SPM2ADSP_MAILBOX_LSB (1U << 0) /* 32b */ +/* ADSP2SPM_MAILBOX (0x10006000+0x6C0) */ +#define ADSP2SPM_MAILBOX_LSB (1U << 0) /* 32b */ +/* SPM_ADSP_IRQ (0x10006000+0x6C4) */ +#define SC_SPM2ADSP_WAKEUP_LSB (1U << 0) /* 1b */ +#define SPM_ADSP_IRQ_SC_ADSP2SPM_WAKEUP_LSB (1U << 4) /* 1b */ +/* SPM_MD32_IRQ (0x10006000+0x6C8) */ +#define SC_SPM2SSPM_WAKEUP_LSB (1U << 0) /* 4b */ +#define SPM_MD32_IRQ_SC_SSPM2SPM_WAKEUP_LSB (1U << 4) /* 4b */ +/* SPM2PMCU_MAILBOX_0 (0x10006000+0x6CC) */ +#define SPM2PMCU_MAILBOX_0_LSB (1U << 0) /* 32b */ +/* SPM2PMCU_MAILBOX_1 (0x10006000+0x6D0) */ +#define SPM2PMCU_MAILBOX_1_LSB (1U << 0) /* 32b */ +/* SPM2PMCU_MAILBOX_2 (0x10006000+0x6D4) */ +#define SPM2PMCU_MAILBOX_2_LSB (1U << 0) /* 32b */ +/* SPM2PMCU_MAILBOX_3 (0x10006000+0x6D8) */ +#define SPM2PMCU_MAILBOX_3_LSB (1U << 0) /* 32b */ +/* PMCU2SPM_MAILBOX_0 (0x10006000+0x6DC) */ +#define PMCU2SPM_MAILBOX_0_LSB (1U << 0) /* 32b */ +/* PMCU2SPM_MAILBOX_1 (0x10006000+0x6E0) */ +#define PMCU2SPM_MAILBOX_1_LSB (1U << 0) /* 32b */ +/* PMCU2SPM_MAILBOX_2 (0x10006000+0x6E4) */ +#define PMCU2SPM_MAILBOX_2_LSB (1U << 0) /* 32b */ +/* PMCU2SPM_MAILBOX_3 (0x10006000+0x6E8) */ +#define PMCU2SPM_MAILBOX_3_LSB (1U << 0) /* 32b */ +/* UFS_PSRI_SW (0x10006000+0x6EC) */ +#define UFS_PSRI_SW_LSB (1U << 0) /* 1b */ +/* UFS_PSRI_SW_SET (0x10006000+0x6F0) */ +#define UFS_PSRI_SW_SET_LSB (1U << 0) /* 1b */ +/* UFS_PSRI_SW_CLR (0x10006000+0x6F4) */ +#define UFS_PSRI_SW_CLR_LSB (1U << 0) /* 1b */ +/* SPM_AP_SEMA (0x10006000+0x6F8) */ +#define SPM_AP_SEMA_LSB (1U << 0) /* 1b */ +/* SPM_SPM_SEMA (0x10006000+0x6FC) */ +#define SPM_SPM_SEMA_LSB (1U << 0) /* 1b */ +/* SPM_DVFS_CON (0x10006000+0x700) */ +#define SPM_DVFS_CON_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CON_STA (0x10006000+0x704) */ +#define SPM_DVFS_CON_STA_LSB (1U << 0) /* 32b */ +/* SPM_PMIC_SPMI_CON (0x10006000+0x708) */ +#define SPM_PMIC_SPMI_CMD_LSB (1U << 0) /* 2b */ +#define SPM_PMIC_SPMI_SLAVEID_LSB (1U << 2) /* 4b */ +#define SPM_PMIC_SPMI_PMIFID_LSB (1U << 6) /* 1b */ +#define SPM_PMIC_SPMI_DBCNT_LSB (1U << 7) /* 1b */ +/* SPM_DVFS_CMD0 (0x10006000+0x710) */ +#define SPM_DVFS_CMD0_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD1 (0x10006000+0x714) */ +#define SPM_DVFS_CMD1_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD2 (0x10006000+0x718) */ +#define SPM_DVFS_CMD2_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD3 (0x10006000+0x71C) */ +#define SPM_DVFS_CMD3_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD4 (0x10006000+0x720) */ +#define SPM_DVFS_CMD4_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD5 (0x10006000+0x724) */ +#define SPM_DVFS_CMD5_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD6 (0x10006000+0x728) */ +#define SPM_DVFS_CMD6_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD7 (0x10006000+0x72C) */ +#define SPM_DVFS_CMD7_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD8 (0x10006000+0x730) */ +#define SPM_DVFS_CMD8_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD9 (0x10006000+0x734) */ +#define SPM_DVFS_CMD9_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD10 (0x10006000+0x738) */ +#define SPM_DVFS_CMD10_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD11 (0x10006000+0x73C) */ +#define SPM_DVFS_CMD11_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD12 (0x10006000+0x740) */ +#define SPM_DVFS_CMD12_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD13 (0x10006000+0x744) */ +#define SPM_DVFS_CMD13_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD14 (0x10006000+0x748) */ +#define SPM_DVFS_CMD14_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD15 (0x10006000+0x74C) */ +#define SPM_DVFS_CMD15_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD16 (0x10006000+0x750) */ +#define SPM_DVFS_CMD16_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD17 (0x10006000+0x754) */ +#define SPM_DVFS_CMD17_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD18 (0x10006000+0x758) */ +#define SPM_DVFS_CMD18_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD19 (0x10006000+0x75C) */ +#define SPM_DVFS_CMD19_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD20 (0x10006000+0x760) */ +#define SPM_DVFS_CMD20_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD21 (0x10006000+0x764) */ +#define SPM_DVFS_CMD21_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD22 (0x10006000+0x768) */ +#define SPM_DVFS_CMD22_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD23 (0x10006000+0x76C) */ +#define SPM_DVFS_CMD23_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_VALUE_L (0x10006000+0x770) */ +#define SYS_TIMER_VALUE_L_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_VALUE_H (0x10006000+0x774) */ +#define SYS_TIMER_VALUE_H_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_START_L (0x10006000+0x778) */ +#define SYS_TIMER_START_L_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_START_H (0x10006000+0x77C) */ +#define SYS_TIMER_START_H_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_L_00 (0x10006000+0x780) */ +#define SYS_TIMER_LATCH_L_00_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_H_00 (0x10006000+0x784) */ +#define SYS_TIMER_LATCH_H_00_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_L_01 (0x10006000+0x788) */ +#define SYS_TIMER_LATCH_L_01_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_H_01 (0x10006000+0x78C) */ +#define SYS_TIMER_LATCH_H_01_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_L_02 (0x10006000+0x790) */ +#define SYS_TIMER_LATCH_L_02_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_H_02 (0x10006000+0x794) */ +#define SYS_TIMER_LATCH_H_02_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_L_03 (0x10006000+0x798) */ +#define SYS_TIMER_LATCH_L_03_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_H_03 (0x10006000+0x79C) */ +#define SYS_TIMER_LATCH_H_03_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_L_04 (0x10006000+0x7A0) */ +#define SYS_TIMER_LATCH_L_04_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_H_04 (0x10006000+0x7A4) */ +#define SYS_TIMER_LATCH_H_04_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_L_05 (0x10006000+0x7A8) */ +#define SYS_TIMER_LATCH_L_05_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_H_05 (0x10006000+0x7AC) */ +#define SYS_TIMER_LATCH_H_05_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_L_06 (0x10006000+0x7B0) */ +#define SYS_TIMER_LATCH_L_06_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_H_06 (0x10006000+0x7B4) */ +#define SYS_TIMER_LATCH_H_06_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_L_07 (0x10006000+0x7B8) */ +#define SYS_TIMER_LATCH_L_07_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_H_07 (0x10006000+0x7BC) */ +#define SYS_TIMER_LATCH_H_07_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_L_08 (0x10006000+0x7C0) */ +#define SYS_TIMER_LATCH_L_08_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_H_08 (0x10006000+0x7C4) */ +#define SYS_TIMER_LATCH_H_08_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_L_09 (0x10006000+0x7C8) */ +#define SYS_TIMER_LATCH_L_09_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_H_09 (0x10006000+0x7CC) */ +#define SYS_TIMER_LATCH_H_09_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_L_10 (0x10006000+0x7D0) */ +#define SYS_TIMER_LATCH_L_10_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_H_10 (0x10006000+0x7D4) */ +#define SYS_TIMER_LATCH_H_10_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_L_11 (0x10006000+0x7D8) */ +#define SYS_TIMER_LATCH_L_11_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_H_11 (0x10006000+0x7DC) */ +#define SYS_TIMER_LATCH_H_11_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_L_12 (0x10006000+0x7E0) */ +#define SYS_TIMER_LATCH_L_12_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_H_12 (0x10006000+0x7E4) */ +#define SYS_TIMER_LATCH_H_12_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_L_13 (0x10006000+0x7E8) */ +#define SYS_TIMER_LATCH_L_13_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_H_13 (0x10006000+0x7EC) */ +#define SYS_TIMER_LATCH_H_13_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_L_14 (0x10006000+0x7F0) */ +#define SYS_TIMER_LATCH_L_14_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_H_14 (0x10006000+0x7F4) */ +#define SYS_TIMER_LATCH_H_14_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_L_15 (0x10006000+0x7F8) */ +#define SYS_TIMER_LATCH_L_15_LSB (1U << 0) /* 32b */ +/* SYS_TIMER_LATCH_H_15 (0x10006000+0x7FC) */ +#define SYS_TIMER_LATCH_H_15_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_0 (0x10006000+0x800) */ +#define PCM_WDT_LATCH_0_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_1 (0x10006000+0x804) */ +#define PCM_WDT_LATCH_1_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_2 (0x10006000+0x808) */ +#define PCM_WDT_LATCH_2_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_3 (0x10006000+0x80C) */ +#define PCM_WDT_LATCH_3_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_4 (0x10006000+0x810) */ +#define PCM_WDT_LATCH_4_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_5 (0x10006000+0x814) */ +#define PCM_WDT_LATCH_5_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_6 (0x10006000+0x818) */ +#define PCM_WDT_LATCH_6_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_7 (0x10006000+0x81C) */ +#define PCM_WDT_LATCH_7_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_8 (0x10006000+0x820) */ +#define PCM_WDT_LATCH_8_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_9 (0x10006000+0x824) */ +#define PCM_WDT_LATCH_9_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_10 (0x10006000+0x828) */ +#define PCM_WDT_LATCH_10_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_11 (0x10006000+0x82C) */ +#define PCM_WDT_LATCH_11_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_12 (0x10006000+0x830) */ +#define PCM_WDT_LATCH_12_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_13 (0x10006000+0x834) */ +#define PCM_WDT_LATCH_13_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_14 (0x10006000+0x838) */ +#define PCM_WDT_LATCH_14_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_15 (0x10006000+0x83C) */ +#define PCM_WDT_LATCH_15_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_16 (0x10006000+0x840) */ +#define PCM_WDT_LATCH_16_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_17 (0x10006000+0x844) */ +#define PCM_WDT_LATCH_17_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_18 (0x10006000+0x848) */ +#define PCM_WDT_LATCH_18_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_SPARE_0 (0x10006000+0x84C) */ +#define PCM_WDT_LATCH_SPARE_0_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_SPARE_1 (0x10006000+0x850) */ +#define PCM_WDT_LATCH_SPARE_1_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_SPARE_2 (0x10006000+0x854) */ +#define PCM_WDT_LATCH_SPARE_2_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_CONN_0 (0x10006000+0x870) */ +#define PCM_WDT_LATCH_CONN_0_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_CONN_1 (0x10006000+0x874) */ +#define PCM_WDT_LATCH_CONN_1_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_CONN_2 (0x10006000+0x878) */ +#define PCM_WDT_LATCH_CONN_2_LSB (1U << 0) /* 32b */ +/* DRAMC_GATING_ERR_LATCH_CH0_0 (0x10006000+0x8A0) */ +#define DRAMC_GATING_ERR_LATCH_CH0_0_LSB (1U << 0) /* 32b */ +/* DRAMC_GATING_ERR_LATCH_CH0_1 (0x10006000+0x8A4) */ +#define DRAMC_GATING_ERR_LATCH_CH0_1_LSB (1U << 0) /* 32b */ +/* DRAMC_GATING_ERR_LATCH_CH0_2 (0x10006000+0x8A8) */ +#define DRAMC_GATING_ERR_LATCH_CH0_2_LSB (1U << 0) /* 32b */ +/* DRAMC_GATING_ERR_LATCH_CH0_3 (0x10006000+0x8AC) */ +#define DRAMC_GATING_ERR_LATCH_CH0_3_LSB (1U << 0) /* 32b */ +/* DRAMC_GATING_ERR_LATCH_CH0_4 (0x10006000+0x8B0) */ +#define DRAMC_GATING_ERR_LATCH_CH0_4_LSB (1U << 0) /* 32b */ +/* DRAMC_GATING_ERR_LATCH_CH0_5 (0x10006000+0x8B4) */ +#define DRAMC_GATING_ERR_LATCH_CH0_5_LSB (1U << 0) /* 32b */ +/* DRAMC_GATING_ERR_LATCH_CH0_6 (0x10006000+0x8B8) */ +#define DRAMC_GATING_ERR_LATCH_CH0_6_LSB (1U << 0) /* 32b */ +/* DRAMC_GATING_ERR_LATCH_SPARE_0 (0x10006000+0x8F4) */ +#define DRAMC_GATING_ERR_LATCH_SPARE_0_LSB (1U << 0) /* 32b */ +/* SPM_ACK_CHK_CON_0 (0x10006000+0x900) */ +#define SPM_ACK_CHK_SW_EN_0_LSB (1U << 0) /* 1b */ +#define SPM_ACK_CHK_CLR_ALL_0_LSB (1U << 1) /* 1b */ +#define SPM_ACK_CHK_CLR_TIMER_0_LSB (1U << 2) /* 1b */ +#define SPM_ACK_CHK_CLR_IRQ_0_LSB (1U << 3) /* 1b */ +#define SPM_ACK_CHK_STA_EN_0_LSB (1U << 4) /* 1b */ +#define SPM_ACK_CHK_WAKEUP_EN_0_LSB (1U << 5) /* 1b */ +#define SPM_ACK_CHK_WDT_EN_0_LSB (1U << 6) /* 1b */ +#define SPM_ACK_CHK_LOCK_PC_TRACE_EN_0_LSB (1U << 7) /* 1b */ +#define SPM_ACK_CHK_HW_EN_0_LSB (1U << 8) /* 1b */ +#define SPM_ACK_CHK_HW_MODE_0_LSB (1U << 9) /* 3b */ +#define SPM_ACK_CHK_FAIL_0_LSB (1U << 15) /* 1b */ +/* SPM_ACK_CHK_PC_0 (0x10006000+0x904) */ +#define SPM_ACK_CHK_HW_TRIG_PC_VAL_0_LSB (1U << 0) /* 16b */ +#define SPM_ACK_CHK_HW_TARG_PC_VAL_0_LSB (1U << 16) /* 16b */ +/* SPM_ACK_CHK_SEL_0 (0x10006000+0x908) */ +#define SPM_ACK_CHK_HW_TRIG_SIGNAL_SEL_0_LSB (1U << 0) /* 5b */ +#define SPM_ACK_CHK_HW_TRIG_GROUP_SEL_0_LSB (1U << 5) /* 3b */ +#define SPM_ACK_CHK_HW_TARG_SIGNAL_SEL_0_LSB (1U << 16) /* 5b */ +#define SPM_ACK_CHK_HW_TARG_GROUP_SEL_0_LSB (1U << 21) /* 3b */ +/* SPM_ACK_CHK_TIMER_0 (0x10006000+0x90C) */ +#define SPM_ACK_CHK_TIMER_VAL_0_LSB (1U << 0) /* 16b */ +#define SPM_ACK_CHK_TIMER_0_LSB (1U << 16) /* 16b */ +/* SPM_ACK_CHK_STA_0 (0x10006000+0x910) */ +#define SPM_ACK_CHK_STA_0_LSB (1U << 0) /* 32b */ +/* SPM_ACK_CHK_SWINT_0 (0x10006000+0x914) */ +#define SPM_ACK_CHK_SWINT_EN_0_LSB (1U << 0) /* 32b */ +/* SPM_ACK_CHK_CON_1 (0x10006000+0x920) */ +#define SPM_ACK_CHK_SW_EN_1_LSB (1U << 0) /* 1b */ +#define SPM_ACK_CHK_CLR_ALL_1_LSB (1U << 1) /* 1b */ +#define SPM_ACK_CHK_CLR_TIMER_1_LSB (1U << 2) /* 1b */ +#define SPM_ACK_CHK_CLR_IRQ_1_LSB (1U << 3) /* 1b */ +#define SPM_ACK_CHK_STA_EN_1_LSB (1U << 4) /* 1b */ +#define SPM_ACK_CHK_WAKEUP_EN_1_LSB (1U << 5) /* 1b */ +#define SPM_ACK_CHK_WDT_EN_1_LSB (1U << 6) /* 1b */ +#define SPM_ACK_CHK_LOCK_PC_TRACE_EN_1_LSB (1U << 7) /* 1b */ +#define SPM_ACK_CHK_HW_EN_1_LSB (1U << 8) /* 1b */ +#define SPM_ACK_CHK_HW_MODE_1_LSB (1U << 9) /* 3b */ +#define SPM_ACK_CHK_FAIL_1_LSB (1U << 15) /* 1b */ +/* SPM_ACK_CHK_PC_1 (0x10006000+0x924) */ +#define SPM_ACK_CHK_HW_TRIG_PC_VAL_1_LSB (1U << 0) /* 16b */ +#define SPM_ACK_CHK_HW_TARG_PC_VAL_1_LSB (1U << 16) /* 16b */ +/* SPM_ACK_CHK_SEL_1 (0x10006000+0x928) */ +#define SPM_ACK_CHK_HW_TRIG_SIGNAL_SEL_1_LSB (1U << 0) /* 5b */ +#define SPM_ACK_CHK_HW_TRIG_GROUP_SEL_1_LSB (1U << 5) /* 3b */ +#define SPM_ACK_CHK_HW_TARG_SIGNAL_SEL_1_LSB (1U << 16) /* 5b */ +#define SPM_ACK_CHK_HW_TARG_GROUP_SEL_1_LSB (1U << 21) /* 3b */ +/* SPM_ACK_CHK_TIMER_1 (0x10006000+0x92C) */ +#define SPM_ACK_CHK_TIMER_VAL_1_LSB (1U << 0) /* 16b */ +#define SPM_ACK_CHK_TIMER_1_LSB (1U << 16) /* 16b */ +/* SPM_ACK_CHK_STA_1 (0x10006000+0x930) */ +#define SPM_ACK_CHK_STA_1_LSB (1U << 0) /* 32b */ +/* SPM_ACK_CHK_SWINT_1 (0x10006000+0x934) */ +#define SPM_ACK_CHK_SWINT_EN_1_LSB (1U << 0) /* 32b */ +/* SPM_ACK_CHK_CON_2 (0x10006000+0x940) */ +#define SPM_ACK_CHK_SW_EN_2_LSB (1U << 0) /* 1b */ +#define SPM_ACK_CHK_CLR_ALL_2_LSB (1U << 1) /* 1b */ +#define SPM_ACK_CHK_CLR_TIMER_2_LSB (1U << 2) /* 1b */ +#define SPM_ACK_CHK_CLR_IRQ_2_LSB (1U << 3) /* 1b */ +#define SPM_ACK_CHK_STA_EN_2_LSB (1U << 4) /* 1b */ +#define SPM_ACK_CHK_WAKEUP_EN_2_LSB (1U << 5) /* 1b */ +#define SPM_ACK_CHK_WDT_EN_2_LSB (1U << 6) /* 1b */ +#define SPM_ACK_CHK_LOCK_PC_TRACE_EN_2_LSB (1U << 7) /* 1b */ +#define SPM_ACK_CHK_HW_EN_2_LSB (1U << 8) /* 1b */ +#define SPM_ACK_CHK_HW_MODE_2_LSB (1U << 9) /* 3b */ +#define SPM_ACK_CHK_FAIL_2_LSB (1U << 15) /* 1b */ +/* SPM_ACK_CHK_PC_2 (0x10006000+0x944) */ +#define SPM_ACK_CHK_HW_TRIG_PC_VAL_2_LSB (1U << 0) /* 16b */ +#define SPM_ACK_CHK_HW_TARG_PC_VAL_2_LSB (1U << 16) /* 16b */ +/* SPM_ACK_CHK_SEL_2 (0x10006000+0x948) */ +#define SPM_ACK_CHK_HW_TRIG_SIGNAL_SEL_2_LSB (1U << 0) /* 5b */ +#define SPM_ACK_CHK_HW_TRIG_GROUP_SEL_2_LSB (1U << 5) /* 3b */ +#define SPM_ACK_CHK_HW_TARG_SIGNAL_SEL_2_LSB (1U << 16) /* 5b */ +#define SPM_ACK_CHK_HW_TARG_GROUP_SEL_2_LSB (1U << 21) /* 3b */ +/* SPM_ACK_CHK_TIMER_2 (0x10006000+0x94C) */ +#define SPM_ACK_CHK_TIMER_VAL_2_LSB (1U << 0) /* 16b */ +#define SPM_ACK_CHK_TIMER_2_LSB (1U << 16) /* 16b */ +/* SPM_ACK_CHK_STA_2 (0x10006000+0x950) */ +#define SPM_ACK_CHK_STA_2_LSB (1U << 0) /* 32b */ +/* SPM_ACK_CHK_SWINT_2 (0x10006000+0x954) */ +#define SPM_ACK_CHK_SWINT_EN_2_LSB (1U << 0) /* 32b */ +/* SPM_ACK_CHK_CON_3 (0x10006000+0x960) */ +#define SPM_ACK_CHK_SW_EN_3_LSB (1U << 0) /* 1b */ +#define SPM_ACK_CHK_CLR_ALL_3_LSB (1U << 1) /* 1b */ +#define SPM_ACK_CHK_CLR_TIMER_3_LSB (1U << 2) /* 1b */ +#define SPM_ACK_CHK_CLR_IRQ_3_LSB (1U << 3) /* 1b */ +#define SPM_ACK_CHK_STA_EN_3_LSB (1U << 4) /* 1b */ +#define SPM_ACK_CHK_WAKEUP_EN_3_LSB (1U << 5) /* 1b */ +#define SPM_ACK_CHK_WDT_EN_3_LSB (1U << 6) /* 1b */ +#define SPM_ACK_CHK_LOCK_PC_TRACE_EN_3_LSB (1U << 7) /* 1b */ +#define SPM_ACK_CHK_HW_EN_3_LSB (1U << 8) /* 1b */ +#define SPM_ACK_CHK_HW_MODE_3_LSB (1U << 9) /* 3b */ +#define SPM_ACK_CHK_FAIL_3_LSB (1U << 15) /* 1b */ +/* SPM_ACK_CHK_PC_3 (0x10006000+0x964) */ +#define SPM_ACK_CHK_HW_TRIG_PC_VAL_3_LSB (1U << 0) /* 16b */ +#define SPM_ACK_CHK_HW_TARG_PC_VAL_3_LSB (1U << 16) /* 16b */ +/* SPM_ACK_CHK_SEL_3 (0x10006000+0x968) */ +#define SPM_ACK_CHK_HW_TRIG_SIGNAL_SEL_3_LSB (1U << 0) /* 5b */ +#define SPM_ACK_CHK_HW_TRIG_GROUP_SEL_3_LSB (1U << 5) /* 3b */ +#define SPM_ACK_CHK_HW_TARG_SIGNAL_SEL_3_LSB (1U << 16) /* 5b */ +#define SPM_ACK_CHK_HW_TARG_GROUP_SEL_3_LSB (1U << 21) /* 3b */ +/* SPM_ACK_CHK_TIMER_3 (0x10006000+0x96C) */ +#define SPM_ACK_CHK_TIMER_VAL_3_LSB (1U << 0) /* 16b */ +#define SPM_ACK_CHK_TIMER_3_LSB (1U << 16) /* 16b */ +/* SPM_ACK_CHK_STA_3 (0x10006000+0x970) */ +#define SPM_ACK_CHK_STA_3_LSB (1U << 0) /* 32b */ +/* SPM_ACK_CHK_SWINT_3 (0x10006000+0x974) */ +#define SPM_ACK_CHK_SWINT_EN_3_LSB (1U << 0) /* 32b */ +/* SPM_COUNTER_0 (0x10006000+0x978) */ +#define SPM_COUNTER_VAL_0_LSB (1U << 0) /* 14b */ +#define SPM_COUNTER_OUT_0_LSB (1U << 14) /* 14b */ +#define SPM_COUNTER_EN_0_LSB (1U << 28) /* 1b */ +#define SPM_COUNTER_CLR_0_LSB (1U << 29) /* 1b */ +#define SPM_COUNTER_TIMEOUT_0_LSB (1U << 30) /* 1b */ +#define SPM_COUNTER_WAKEUP_EN_0_LSB (1U << 31) /* 1b */ +/* SPM_COUNTER_1 (0x10006000+0x97C) */ +#define SPM_COUNTER_VAL_1_LSB (1U << 0) /* 14b */ +#define SPM_COUNTER_OUT_1_LSB (1U << 14) /* 14b */ +#define SPM_COUNTER_EN_1_LSB (1U << 28) /* 1b */ +#define SPM_COUNTER_CLR_1_LSB (1U << 29) /* 1b */ +#define SPM_COUNTER_TIMEOUT_1_LSB (1U << 30) /* 1b */ +#define SPM_COUNTER_WAKEUP_EN_1_LSB (1U << 31) /* 1b */ +/* SPM_COUNTER_2 (0x10006000+0x980) */ +#define SPM_COUNTER_VAL_2_LSB (1U << 0) /* 14b */ +#define SPM_COUNTER_OUT_2_LSB (1U << 14) /* 14b */ +#define SPM_COUNTER_EN_2_LSB (1U << 28) /* 1b */ +#define SPM_COUNTER_CLR_2_LSB (1U << 29) /* 1b */ +#define SPM_COUNTER_TIMEOUT_2_LSB (1U << 30) /* 1b */ +#define SPM_COUNTER_WAKEUP_EN_2_LSB (1U << 31) /* 1b */ +/* SYS_TIMER_CON (0x10006000+0x98C) */ +#define SYS_TIMER_START_EN_LSB (1U << 0) /* 1b */ +#define SYS_TIMER_LATCH_EN_LSB (1U << 1) /* 1b */ +#define SYS_TIMER_ID_LSB (1U << 8) /* 8b */ +#define SYS_TIMER_VALID_LSB (1U << 31) /* 1b */ +/* RC_FSM_STA_0 (0x10006000+0xE00) */ +#define RC_FSM_STA_0_LSB (1U << 0) /* 32b */ +/* RC_CMD_STA_0 (0x10006000+0xE04) */ +#define RC_CMD_STA_0_LSB (1U << 0) /* 32b */ +/* RC_CMD_STA_1 (0x10006000+0xE08) */ +#define RC_CMD_STA_1_LSB (1U << 0) /* 32b */ +/* RC_SPI_STA_0 (0x10006000+0xE0C) */ +#define RC_SPI_STA_0_LSB (1U << 0) /* 32b */ +/* RC_PI_PO_STA_0 (0x10006000+0xE10) */ +#define RC_PI_PO_STA_0_LSB (1U << 0) /* 32b */ +/* RC_M00_REQ_STA_0 (0x10006000+0xE14) */ +#define RC_M00_REQ_STA_0_LSB (1U << 0) /* 32b */ +/* RC_M01_REQ_STA_0 (0x10006000+0xE1C) */ +#define RC_M01_REQ_STA_0_LSB (1U << 0) /* 32b */ +/* RC_M02_REQ_STA_0 (0x10006000+0xE20) */ +#define RC_M02_REQ_STA_0_LSB (1U << 0) /* 32b */ +/* RC_M03_REQ_STA_0 (0x10006000+0xE24) */ +#define RC_M03_REQ_STA_0_LSB (1U << 0) /* 32b */ +/* RC_M04_REQ_STA_0 (0x10006000+0xE28) */ +#define RC_M04_REQ_STA_0_LSB (1U << 0) /* 32b */ +/* RC_M05_REQ_STA_0 (0x10006000+0xE2C) */ +#define RC_M05_REQ_STA_0_LSB (1U << 0) /* 32b */ +/* RC_M06_REQ_STA_0 (0x10006000+0xE30) */ +#define RC_M06_REQ_STA_0_LSB (1U << 0) /* 32b */ +/* RC_M07_REQ_STA_0 (0x10006000+0xE34) */ +#define RC_M07_REQ_STA_0_LSB (1U << 0) /* 32b */ +/* RC_M08_REQ_STA_0 (0x10006000+0xE38) */ +#define RC_M08_REQ_STA_0_LSB (1U << 0) /* 32b */ +/* RC_M09_REQ_STA_0 (0x10006000+0xE3C) */ +#define RC_M09_REQ_STA_0_LSB (1U << 0) /* 32b */ +/* RC_M10_REQ_STA_0 (0x10006000+0xE40) */ +#define RC_M10_REQ_STA_0_LSB (1U << 0) /* 32b */ +/* RC_M11_REQ_STA_0 (0x10006000+0xE44) */ +#define RC_M11_REQ_STA_0_LSB (1U << 0) /* 32b */ +/* RC_M12_REQ_STA_0 (0x10006000+0xE48) */ +#define RC_M12_REQ_STA_0_LSB (1U << 0) /* 32b */ +/* RC_DEBUG_STA_0 (0x10006000+0xE4C) */ +#define RC_DEBUG_STA_0_LSB (1U << 0) /* 32b */ +/* RC_DEBUG_TRACE_0_LSB (0x10006000+0xE50) */ +#define RO_PMRC_TRACE_00_LSB_LSB (1U << 0) /* 32b */ +/* RC_DEBUG_TRACE_0_MSB (0x10006000+0xE54) */ +#define RO_PMRC_TRACE_00_MSB_LSB (1U << 0) /* 32b */ +/* RC_DEBUG_TRACE_1_LSB (0x10006000+0xE5C) */ +#define RO_PMRC_TRACE_01_LSB_LSB (1U << 0) /* 32b */ +/* RC_DEBUG_TRACE_1_MSB (0x10006000+0xE60) */ +#define RO_PMRC_TRACE_01_MSB_LSB (1U << 0) /* 32b */ +/* RC_DEBUG_TRACE_2_LSB (0x10006000+0xE64) */ +#define RO_PMRC_TRACE_02_LSB_LSB (1U << 0) /* 32b */ +/* RC_DEBUG_TRACE_2_MSB (0x10006000+0xE6C) */ +#define RO_PMRC_TRACE_02_MSB_LSB (1U << 0) /* 32b */ +/* RC_DEBUG_TRACE_3_LSB (0x10006000+0xE70) */ +#define RO_PMRC_TRACE_03_LSB_LSB (1U << 0) /* 32b */ +/* RC_DEBUG_TRACE_3_MSB (0x10006000+0xE74) */ +#define RO_PMRC_TRACE_03_MSB_LSB (1U << 0) /* 32b */ +/* RC_DEBUG_TRACE_4_LSB (0x10006000+0xE78) */ +#define RO_PMRC_TRACE_04_LSB_LSB (1U << 0) /* 32b */ +/* RC_DEBUG_TRACE_4_MSB (0x10006000+0xE7C) */ +#define RO_PMRC_TRACE_04_MSB_LSB (1U << 0) /* 32b */ +/* RC_DEBUG_TRACE_5_LSB (0x10006000+0xE80) */ +#define RO_PMRC_TRACE_05_LSB_LSB (1U << 0) /* 32b */ +/* RC_DEBUG_TRACE_5_MSB (0x10006000+0xE84) */ +#define RO_PMRC_TRACE_05_MSB_LSB (1U << 0) /* 32b */ +/* RC_DEBUG_TRACE_6_LSB (0x10006000+0xE88) */ +#define RO_PMRC_TRACE_06_LSB_LSB (1U << 0) /* 32b */ +/* RC_DEBUG_TRACE_6_MSB (0x10006000+0xE8C) */ +#define RO_PMRC_TRACE_06_MSB_LSB (1U << 0) /* 32b */ +/* RC_DEBUG_TRACE_7_LSB (0x10006000+0xE90) */ +#define RO_PMRC_TRACE_07_LSB_LSB (1U << 0) /* 32b */ +/* RC_DEBUG_TRACE_7_MSB (0x10006000+0xE94) */ +#define RO_PMRC_TRACE_07_MSB_LSB (1U << 0) /* 32b */ +/* RC_SYS_TIMER_LATCH_0_LSB (0x10006000+0xE98) */ +#define RC_SYS_TIMER_LATCH_L_00_LSB (1U << 0) /* 32b */ +/* RC_SYS_TIMER_LATCH_0_MSB (0x10006000+0xE9C) */ +#define RC_SYS_TIMER_LATCH_H_00_LSB (1U << 0) /* 32b */ +/* RC_SYS_TIMER_LATCH_1_LSB (0x10006000+0xEA0) */ +#define RC_SYS_TIMER_LATCH_L_01_LSB (1U << 0) /* 32b */ +/* RC_SYS_TIMER_LATCH_1_MSB (0x10006000+0xEA4) */ +#define RC_SYS_TIMER_LATCH_H_01_LSB (1U << 0) /* 32b */ +/* RC_SYS_TIMER_LATCH_2_LSB (0x10006000+0xEA8) */ +#define RC_SYS_TIMER_LATCH_L_02_LSB (1U << 0) /* 32b */ +/* RC_SYS_TIMER_LATCH_2_MSB (0x10006000+0xEAC) */ +#define RC_SYS_TIMER_LATCH_H_02_LSB (1U << 0) /* 32b */ +/* RC_SYS_TIMER_LATCH_3_LSB (0x10006000+0xEB0) */ +#define RC_SYS_TIMER_LATCH_L_03_LSB (1U << 0) /* 32b */ +/* RC_SYS_TIMER_LATCH_3_MSB (0x10006000+0xEB4) */ +#define RC_SYS_TIMER_LATCH_H_03_LSB (1U << 0) /* 32b */ +/* RC_SYS_TIMER_LATCH_4_LSB (0x10006000+0xEB8) */ +#define RC_SYS_TIMER_LATCH_L_04_LSB (1U << 0) /* 32b */ +/* RC_SYS_TIMER_LATCH_4_MSB (0x10006000+0xEBC) */ +#define RC_SYS_TIMER_LATCH_H_04_LSB (1U << 0) /* 32b */ +/* RC_SYS_TIMER_LATCH_5_LSB (0x10006000+0xEC0) */ +#define RC_SYS_TIMER_LATCH_L_05_LSB (1U << 0) /* 32b */ +/* RC_SYS_TIMER_LATCH_5_MSB (0x10006000+0xEC4) */ +#define RC_SYS_TIMER_LATCH_H_05_LSB (1U << 0) /* 32b */ +/* RC_SYS_TIMER_LATCH_6_LSB (0x10006000+0xEC8) */ +#define RC_SYS_TIMER_LATCH_L_06_LSB (1U << 0) /* 32b */ +/* RC_SYS_TIMER_LATCH_6_MSB (0x10006000+0xECC) */ +#define RC_SYS_TIMER_LATCH_H_06_LSB (1U << 0) /* 32b */ +/* RC_SYS_TIMER_LATCH_7_LSB (0x10006000+0xED0) */ +#define RC_SYS_TIMER_LATCH_L_07_LSB (1U << 0) /* 32b */ +/* RC_SYS_TIMER_LATCH_7_MSB (0x10006000+0xED4) */ +#define RC_SYS_TIMER_LATCH_H_07_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_19 (0x10006000+0xED8) */ +#define PCM_WDT_LATCH_19_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_20 (0x10006000+0xEDC) */ +#define PCM_WDT_LATCH_20_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_21 (0x10006000+0xEE0) */ +#define PCM_WDT_LATCH_21_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_22 (0x10006000+0xEE4) */ +#define PCM_WDT_LATCH_22_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_23 (0x10006000+0xEE8) */ +#define PCM_WDT_LATCH_23_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_24 (0x10006000+0xEEC) */ +#define PCM_WDT_LATCH_24_LSB (1U << 0) /* 32b */ +/* PMSR_LAST_DAT (0x10006000+0xF00) */ +#define PMSR_LAST_DAT_LSB (1U << 0) /* 32b */ +/* PMSR_LAST_CNT (0x10006000+0xF04) */ +#define PMSR_LAST_CMD_LSB (1U << 0) /* 30b */ +#define PMSR_LAST_REQ_LSB (1U << 30) /* 1b */ +/* PMSR_LAST_ACK (0x10006000+0xF08) */ +#define PMSR_LAST_ACK_LSB (1U << 0) /* 1b */ +/* SPM_PMSR_SEL_CON0 (0x10006000+0xF10) */ +#define REG_PMSR_SIG_SEL_0_LSB (1U << 0) /* 8b */ +#define REG_PMSR_SIG_SEL_1_LSB (1U << 8) /* 8b */ +#define REG_PMSR_SIG_SEL_2_LSB (1U << 16) /* 8b */ +#define REG_PMSR_SIG_SEL_3_LSB (1U << 24) /* 8b */ +/* SPM_PMSR_SEL_CON1 (0x10006000+0xF14) */ +#define REG_PMSR_SIG_SEL_4_LSB (1U << 0) /* 8b */ +#define REG_PMSR_SIG_SEL_5_LSB (1U << 8) /* 8b */ +#define REG_PMSR_SIG_SEL_6_LSB (1U << 16) /* 8b */ +#define REG_PMSR_SIG_SEL_7_LSB (1U << 24) /* 8b */ +/* SPM_PMSR_SEL_CON2 (0x10006000+0xF18) */ +#define REG_PMSR_SIG_SEL_8_LSB (1U << 0) /* 8b */ +#define REG_PMSR_SIG_SEL_9_LSB (1U << 8) /* 8b */ +#define REG_PMSR_SIG_SEL_10_LSB (1U << 16) /* 8b */ +#define REG_PMSR_SIG_SEL_11_LSB (1U << 24) /* 8b */ +/* SPM_PMSR_SEL_CON3 (0x10006000+0xF1C) */ +#define REG_PMSR_SIG_SEL_12_LSB (1U << 0) /* 8b */ +#define REG_PMSR_SIG_SEL_13_LSB (1U << 8) /* 8b */ +#define REG_PMSR_SIG_SEL_14_LSB (1U << 16) /* 8b */ +#define REG_PMSR_SIG_SEL_15_LSB (1U << 24) /* 8b */ +/* SPM_PMSR_SEL_CON4 (0x10006000+0xF20) */ +#define REG_PMSR_SIG_SEL_16_LSB (1U << 0) /* 8b */ +#define REG_PMSR_SIG_SEL_17_LSB (1U << 8) /* 8b */ +#define REG_PMSR_SIG_SEL_18_LSB (1U << 16) /* 8b */ +#define REG_PMSR_SIG_SEL_19_LSB (1U << 24) /* 8b */ +/* SPM_PMSR_SEL_CON5 (0x10006000+0xF24) */ +#define REG_PMSR_SIG_SEL_20_LSB (1U << 0) /* 8b */ +#define REG_PMSR_SIG_SEL_21_LSB (1U << 8) /* 8b */ +#define REG_PMSR_SIG_SEL_22_LSB (1U << 16) /* 8b */ +#define REG_PMSR_SIG_SEL_23_LSB (1U << 24) /* 8b */ +/* SPM_PMSR_SEL_CON6 (0x10006000+0xF28) */ +#define REG_PMSR_SIG_SEL_24_LSB (1U << 0) /* 8b */ +#define REG_PMSR_SIG_SEL_25_LSB (1U << 8) /* 8b */ +#define REG_PMSR_SIG_SEL_26_LSB (1U << 16) /* 8b */ +#define REG_PMSR_SIG_SEL_27_LSB (1U << 24) /* 8b */ +/* SPM_PMSR_SEL_CON7 (0x10006000+0xF2C) */ +#define REG_PMSR_SIG_SEL_28_LSB (1U << 0) /* 8b */ +#define REG_PMSR_SIG_SEL_29_LSB (1U << 8) /* 8b */ +#define REG_PMSR_SIG_SEL_30_LSB (1U << 16) /* 8b */ +#define REG_PMSR_SIG_SEL_31_LSB (1U << 24) /* 8b */ +/* SPM_PMSR_SEL_CON8 (0x10006000+0xF30) */ +#define REG_PMSR_SIG_SEL_32_LSB (1U << 0) /* 8b */ +#define REG_PMSR_SIG_SEL_33_LSB (1U << 8) /* 8b */ +#define REG_PMSR_SIG_SEL_34_LSB (1U << 16) /* 8b */ +#define REG_PMSR_SIG_SEL_35_LSB (1U << 24) /* 8b */ +/* SPM_PMSR_SEL_CON9 (0x10006000+0xF34) */ +#define REG_PMSR_SIG_SEL_36_LSB (1U << 0) /* 8b */ +#define REG_PMSR_SIG_SEL_37_LSB (1U << 8) /* 8b */ +#define REG_PMSR_SIG_SEL_38_LSB (1U << 16) /* 8b */ +#define REG_PMSR_SIG_SEL_39_LSB (1U << 24) /* 8b */ +/* SPM_PMSR_SEL_CON10 (0x10006000+0xF3C) */ +#define REG_PMSR_SIG_SEL_40_LSB (1U << 0) /* 8b */ +#define REG_PMSR_SIG_SEL_41_LSB (1U << 8) /* 8b */ +#define REG_PMSR_SIG_SEL_42_LSB (1U << 16) /* 8b */ +#define REG_PMSR_SIG_SEL_43_LSB (1U << 24) /* 8b */ +/* SPM_PMSR_SEL_CON11 (0x10006000+0xF40) */ +#define REG_PMSR_SIG_SEL_44_LSB (1U << 0) /* 8b */ +#define REG_PMSR_SIG_SEL_45_LSB (1U << 8) /* 8b */ +#define REG_PMSR_SIG_SEL_46_LSB (1U << 16) /* 8b */ +#define REG_PMSR_SIG_SEL_47_LSB (1U << 24) /* 8b */ +/* SPM_PMSR_TIEMR_STA0 (0x10006000+0xFB8) */ +#define PMSR_TIMER_SET0_LSB (1U << 0) /* 32b */ +/* SPM_PMSR_TIEMR_STA1 (0x10006000+0xFBC) */ +#define PMSR_TIMER_SET1_LSB (1U << 0) /* 32b */ +/* SPM_PMSR_TIEMR_STA2 (0x10006000+0xFC0) */ +#define PMSR_TIMER_SET2_LSB (1U << 0) /* 32b */ +/* SPM_PMSR_GENERAL_CON0 (0x10006000+0xFC4) */ +#define PMSR_ENABLE_SET0_LSB (1U << 0) /* 1b */ +#define PMSR_ENABLE_SET1_LSB (1U << 1) /* 1b */ +#define PMSR_ENABLE_SET2_LSB (1U << 2) /* 1b */ +#define PMSR_IRQ_CLR_SET0_LSB (1U << 3) /* 1b */ +#define PMSR_IRQ_CLR_SET1_LSB (1U << 4) /* 1b */ +#define PMSR_IRQ_CLR_SET2_LSB (1U << 5) /* 1b */ +#define PMSR_SPEED_MODE_EN_SET0_LSB (1U << 6) /* 1b */ +#define PMSR_SPEED_MODE_EN_SET1_LSB (1U << 7) /* 1b */ +#define PMSR_SPEED_MODE_EN_SET2_LSB (1U << 8) /* 1b */ +#define PMSR_EVENT_CLR_SET0_LSB (1U << 9) /* 1b */ +#define PMSR_EVENT_CLR_SET1_LSB (1U << 10) /* 1b */ +#define PMSR_EVENT_CLR_SET2_LSB (1U << 11) /* 1b */ +#define REG_PMSR_IRQ_MASK_SET0_LSB (1U << 12) /* 1b */ +#define REG_PMSR_IRQ_MASK_SET1_LSB (1U << 13) /* 1b */ +#define REG_PMSR_IRQ_MASK_SET2_LSB (1U << 14) /* 1b */ +#define REG_PMSR_IRQ_WAKEUP_EVENT_MASK_SET0_LSB (1U << 15) /* 1b */ +#define REG_PMSR_IRQ_WAKEUP_EVENT_MASK_SET1_LSB (1U << 16) /* 1b */ +#define REG_PMSR_IRQ_WAKEUP_EVENT_MASK_SET2_LSB (1U << 17) /* 1b */ +#define PMSR_GEN_SW_RST_EN_LSB (1U << 18) /* 1b */ +#define PMSR_MODULE_ENABLE_LSB (1U << 19) /* 1b */ +#define PMSR_MODE_LSB (1U << 20) /* 2b */ +#define SPM_PMSR_GENERAL_CON0_PMSR_IRQ_B_SET0_LSB (1U << 29) /* 1b */ +#define SPM_PMSR_GENERAL_CON0_PMSR_IRQ_B_SET1_LSB (1U << 30) /* 1b */ +#define SPM_PMSR_GENERAL_CON0_PMSR_IRQ_B_SET2_LSB (1U << 31) /* 1b */ +/* SPM_PMSR_GENERAL_CON1 (0x10006000+0xFC8) */ +#define PMSR_COUNTER_THRES_LSB (1U << 0) /* 32b */ +/* SPM_PMSR_GENERAL_CON2 (0x10006000+0xFCC) */ +#define PMSR_DEBUG_IN_0_MASK_B_LSB (1U << 0) /* 32b */ +/* SPM_PMSR_GENERAL_CON3 (0x10006000+0xFD0) */ +#define PMSR_DEBUG_IN_1_MASK_B_LSB (1U << 0) /* 32b */ +/* SPM_PMSR_GENERAL_CON4 (0x10006000+0xFD4) */ +#define PMSR_DEBUG_IN_2_MASK_B_LSB (1U << 0) /* 32b */ +/* SPM_PMSR_GENERAL_CON5 (0x10006000+0xFD8) */ +#define PMSR_DEBUG_IN_3_MASK_B_LSB (1U << 0) /* 32b */ +/* SPM_PMSR_SW_RESET (0x10006000+0xFDC) */ +#define PMSR_SW_RST_EN_SET0_LSB (1U << 0) /* 1b */ +#define PMSR_SW_RST_EN_SET1_LSB (1U << 1) /* 1b */ +#define PMSR_SW_RST_EN_SET2_LSB (1U << 2) /* 1b */ +/* SPM_PMSR_MON_CON0 (0x10006000+0xFE0) */ +#define REG_PMSR_MON_TYPE_0_LSB (1U << 0) /* 2b */ +#define REG_PMSR_MON_TYPE_1_LSB (1U << 2) /* 2b */ +#define REG_PMSR_MON_TYPE_2_LSB (1U << 4) /* 2b */ +#define REG_PMSR_MON_TYPE_3_LSB (1U << 6) /* 2b */ +#define REG_PMSR_MON_TYPE_4_LSB (1U << 8) /* 2b */ +#define REG_PMSR_MON_TYPE_5_LSB (1U << 10) /* 2b */ +#define REG_PMSR_MON_TYPE_6_LSB (1U << 12) /* 2b */ +#define REG_PMSR_MON_TYPE_7_LSB (1U << 14) /* 2b */ +#define REG_PMSR_MON_TYPE_8_LSB (1U << 16) /* 2b */ +#define REG_PMSR_MON_TYPE_9_LSB (1U << 18) /* 2b */ +#define REG_PMSR_MON_TYPE_10_LSB (1U << 20) /* 2b */ +#define REG_PMSR_MON_TYPE_11_LSB (1U << 22) /* 2b */ +#define REG_PMSR_MON_TYPE_12_LSB (1U << 24) /* 2b */ +#define REG_PMSR_MON_TYPE_13_LSB (1U << 26) /* 2b */ +#define REG_PMSR_MON_TYPE_14_LSB (1U << 28) /* 2b */ +#define REG_PMSR_MON_TYPE_15_LSB (1U << 30) /* 2b */ +/* SPM_PMSR_MON_CON1 (0x10006000+0xFE4) */ +#define REG_PMSR_MON_TYPE_16_LSB (1U << 0) /* 2b */ +#define REG_PMSR_MON_TYPE_17_LSB (1U << 2) /* 2b */ +#define REG_PMSR_MON_TYPE_18_LSB (1U << 4) /* 2b */ +#define REG_PMSR_MON_TYPE_19_LSB (1U << 6) /* 2b */ +#define REG_PMSR_MON_TYPE_20_LSB (1U << 8) /* 2b */ +#define REG_PMSR_MON_TYPE_21_LSB (1U << 10) /* 2b */ +#define REG_PMSR_MON_TYPE_22_LSB (1U << 12) /* 2b */ +#define REG_PMSR_MON_TYPE_23_LSB (1U << 14) /* 2b */ +#define REG_PMSR_MON_TYPE_24_LSB (1U << 16) /* 2b */ +#define REG_PMSR_MON_TYPE_25_LSB (1U << 18) /* 2b */ +#define REG_PMSR_MON_TYPE_26_LSB (1U << 20) /* 2b */ +#define REG_PMSR_MON_TYPE_27_LSB (1U << 22) /* 2b */ +#define REG_PMSR_MON_TYPE_28_LSB (1U << 24) /* 2b */ +#define REG_PMSR_MON_TYPE_29_LSB (1U << 26) /* 2b */ +#define REG_PMSR_MON_TYPE_30_LSB (1U << 28) /* 2b */ +#define REG_PMSR_MON_TYPE_31_LSB (1U << 30) /* 2b */ +/* SPM_PMSR_MON_CON2 (0x10006000+0xFE8) */ +#define REG_PMSR_MON_TYPE_32_LSB (1U << 0) /* 2b */ +#define REG_PMSR_MON_TYPE_33_LSB (1U << 2) /* 2b */ +#define REG_PMSR_MON_TYPE_34_LSB (1U << 4) /* 2b */ +#define REG_PMSR_MON_TYPE_35_LSB (1U << 6) /* 2b */ +#define REG_PMSR_MON_TYPE_36_LSB (1U << 8) /* 2b */ +#define REG_PMSR_MON_TYPE_37_LSB (1U << 10) /* 2b */ +#define REG_PMSR_MON_TYPE_38_LSB (1U << 12) /* 2b */ +#define REG_PMSR_MON_TYPE_39_LSB (1U << 14) /* 2b */ +#define REG_PMSR_MON_TYPE_40_LSB (1U << 16) /* 2b */ +#define REG_PMSR_MON_TYPE_41_LSB (1U << 18) /* 2b */ +#define REG_PMSR_MON_TYPE_42_LSB (1U << 20) /* 2b */ +#define REG_PMSR_MON_TYPE_43_LSB (1U << 22) /* 2b */ +#define REG_PMSR_MON_TYPE_44_LSB (1U << 24) /* 2b */ +#define REG_PMSR_MON_TYPE_45_LSB (1U << 26) /* 2b */ +#define REG_PMSR_MON_TYPE_46_LSB (1U << 28) /* 2b */ +#define REG_PMSR_MON_TYPE_47_LSB (1U << 30) /* 2b */ +/* SPM_PMSR_LEN_CON0 (0x10006000+0xFEC) */ +#define REG_PMSR_WINDOW_LEN_SET0_LSB (1U << 0) /* 32b */ +/* SPM_PMSR_LEN_CON1 (0x10006000+0xFF0) */ +#define REG_PMSR_WINDOW_LEN_SET1_LSB (1U << 0) /* 32b */ +/* SPM_PMSR_LEN_CON2 (0x10006000+0xFF4) */ +#define REG_PMSR_WINDOW_LEN_SET2_LSB (1U << 0) /* 32b */ + +#define SPM_PROJECT_CODE (0xb16) +#define SPM_REGWR_CFG_KEY (SPM_PROJECT_CODE << 16) + +#endif /* MT_SPM_REG_H */ diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_suspend.c b/plat/mediatek/drivers/spm/mt8188/mt_spm_suspend.c new file mode 100644 index 0000000..18047e6 --- /dev/null +++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_suspend.c @@ -0,0 +1,429 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#ifndef MTK_PLAT_SPM_UART_UNSUPPORT +#include <drivers/uart.h> +#endif +#include <lib/mmio.h> +#ifndef MTK_PLAT_CIRQ_UNSUPPORT +#include <mtk_cirq.h> +#endif +#include <constraints/mt_spm_rc_internal.h> +#include <drivers/spm/mt_spm_resource_req.h> +#include <lib/pm/mtk_pm.h> +#include <lpm/mt_lp_api.h> +#include <mt_spm.h> +#include <mt_spm_conservation.h> +#include <mt_spm_internal.h> +#include <mt_spm_reg.h> +#include <mt_spm_suspend.h> +#include <pcm_def.h> + +#define SPM_SUSPEND_SLEEP_PCM_FLAG \ + (SPM_FLAG_DISABLE_INFRA_PDN | \ + SPM_FLAG_DISABLE_VCORE_DVS | \ + SPM_FLAG_DISABLE_VCORE_DFS | \ + SPM_FLAG_KEEP_CSYSPWRACK_HIGH | \ + SPM_FLAG_DISABLE_DRAMC_MCU_SRAM_SLEEP | \ + SPM_FLAG_SRAM_SLEEP_CTRL) + +#define SPM_SUSPEND_SLEEP_PCM_FLAG1 (SPM_FLAG1_DISABLE_PWRAP_CLK_SWITCH) + +#define SPM_SUSPEND_PCM_FLAG \ + (SPM_FLAG_DISABLE_VCORE_DVS | \ + SPM_FLAG_DISABLE_VCORE_DFS | \ + SPM_FLAG_DISABLE_DRAMC_MCU_SRAM_SLEEP | \ + SPM_FLAG_SRAM_SLEEP_CTRL) + +#define SPM_SUSPEND_PCM_FLAG1 (SPM_FLAG1_DISABLE_PWRAP_CLK_SWITCH) + +/* Suspend spm power control */ +#define __WAKE_SRC_FOR_SUSPEND_COMMON__ ( \ + (R12_PCM_TIMER) | \ + (R12_KP_IRQ_B) | \ + (R12_APWDT_EVENT_B) | \ + (R12_MSDC_WAKEUP_B) | \ + (R12_EINT_EVENT_B) | \ + (R12_SBD_INTR_WAKEUP_B) | \ + (R12_SSPM2SPM_WAKEUP_B) | \ + (R12_SCP2SPM_WAKEUP_B) | \ + (R12_ADSP2SPM_WAKEUP_B) | \ + (R12_USBX_CDSC_B) | \ + (R12_USBX_POWERDWN_B) | \ + (R12_SYS_TIMER_EVENT_B) | \ + (R12_EINT_EVENT_SECURE_B) | \ + (R12_ECE_INT_HDMI_B) | \ + (R12_SYS_CIRQ_IRQ_B) | \ + (R12_PCIE_WAKEUPEVENT_B) | \ + (R12_SPM_CPU_WAKEUPEVENT_B) | \ + (R12_APUSYS_WAKE_HOST_B)) + +#if defined(CFG_MICROTRUST_TEE_SUPPORT) +#define WAKE_SRC_FOR_SUSPEND (__WAKE_SRC_FOR_SUSPEND_COMMON__) +#else +#define WAKE_SRC_FOR_SUSPEND (__WAKE_SRC_FOR_SUSPEND_COMMON__ | R12_SEJ_EVENT_B) +#endif + +static struct pwr_ctrl suspend_ctrl = { + .wake_src = WAKE_SRC_FOR_SUSPEND, + + /* SPM_AP_STANDBY_CON */ + /* [0] */ + .reg_wfi_op = 0, + /* [1] */ + .reg_wfi_type = 0, + /* [2] */ + .reg_mp0_cputop_idle_mask = 0, + /* [3] */ + .reg_mp1_cputop_idle_mask = 0, + /* [4] */ + .reg_mcusys_idle_mask = 0, + /* [25] */ + .reg_md_apsrc_1_sel = 0, + /* [26] */ + .reg_md_apsrc_0_sel = 0, + /* [29] */ + .reg_conn_apsrc_sel = 0, + + /* SPM_SRC_REQ */ + /* [0] */ + .reg_spm_apsrc_req = 0, + /* [1] */ + .reg_spm_f26m_req = 0, + /* [3] */ + .reg_spm_infra_req = 0, + /* [4] */ + .reg_spm_vrf18_req = 0, + /* [7] */ + .reg_spm_ddr_en_req = 0, + /* [8] */ + .reg_spm_dvfs_req = 0, + /* [9] */ + .reg_spm_sw_mailbox_req = 0, + /* [10] */ + .reg_spm_sspm_mailbox_req = 0, + /* [11] */ + .reg_spm_adsp_mailbox_req = 0, + /* [12] */ + .reg_spm_scp_mailbox_req = 0, + + /* SPM_SRC_MASK */ + /* [0] */ + .reg_sspm_srcclkena_0_mask_b = 1, + /* [1] */ + .reg_sspm_infra_req_0_mask_b = 1, + /* [2] */ + .reg_sspm_apsrc_req_0_mask_b = 0, + /* [3] */ + .reg_sspm_vrf18_req_0_mask_b = 0, + /* [4] */ + .reg_sspm_ddr_en_0_mask_b = 0, + /* [5] */ + .reg_scp_srcclkena_mask_b = 1, + /* [6] */ + .reg_scp_infra_req_mask_b = 1, + /* [7] */ + .reg_scp_apsrc_req_mask_b = 1, + /* [8] */ + .reg_scp_vrf18_req_mask_b = 1, + /* [9] */ + .reg_scp_ddr_en_mask_b = 1, + /* [10] */ + .reg_audio_dsp_srcclkena_mask_b = 1, + /* [11] */ + .reg_audio_dsp_infra_req_mask_b = 1, + /* [12] */ + .reg_audio_dsp_apsrc_req_mask_b = 1, + /* [13] */ + .reg_audio_dsp_vrf18_req_mask_b = 1, + /* [14] */ + .reg_audio_dsp_ddr_en_mask_b = 1, + /* [15] */ + .reg_apu_srcclkena_mask_b = 1, + /* [16] */ + .reg_apu_infra_req_mask_b = 1, + /* [17] */ + .reg_apu_apsrc_req_mask_b = 0, + /* [18] */ + .reg_apu_vrf18_req_mask_b = 1, + /* [19] */ + .reg_apu_ddr_en_mask_b = 1, + /* [20] */ + .reg_cpueb_srcclkena_mask_b = 1, + /* [21] */ + .reg_cpueb_infra_req_mask_b = 1, + /* [22] */ + .reg_cpueb_apsrc_req_mask_b = 1, + /* [23] */ + .reg_cpueb_vrf18_req_mask_b = 1, + /* [24] */ + .reg_cpueb_ddr_en_mask_b = 1, + /* [25] */ + .reg_bak_psri_srcclkena_mask_b = 0, + /* [26] */ + .reg_bak_psri_infra_req_mask_b = 0, + /* [27] */ + .reg_bak_psri_apsrc_req_mask_b = 0, + /* [28] */ + .reg_bak_psri_vrf18_req_mask_b = 0, + /* [29] */ + .reg_bak_psri_ddr_en_mask_b = 0, + /* [30] */ + .reg_cam_ddren_req_mask_b = 0, + /* [31] */ + .reg_img_ddren_req_mask_b = 0, + + /* SPM_SRC2_MASK */ + /* [0] */ + .reg_msdc0_srcclkena_mask_b = 1, + /* [1] */ + .reg_msdc0_infra_req_mask_b = 1, + /* [2] */ + .reg_msdc0_apsrc_req_mask_b = 1, + /* [3] */ + .reg_msdc0_vrf18_req_mask_b = 1, + /* [4] */ + .reg_msdc0_ddr_en_mask_b = 1, + /* [5] */ + .reg_msdc1_srcclkena_mask_b = 1, + /* [6] */ + .reg_msdc1_infra_req_mask_b = 1, + /* [7] */ + .reg_msdc1_apsrc_req_mask_b = 1, + /* [8] */ + .reg_msdc1_vrf18_req_mask_b = 1, + /* [9] */ + .reg_msdc1_ddr_en_mask_b = 1, + /* [10] */ + .reg_msdc2_srcclkena_mask_b = 1, + /* [11] */ + .reg_msdc2_infra_req_mask_b = 1, + /* [12] */ + .reg_msdc2_apsrc_req_mask_b = 1, + /* [13] */ + .reg_msdc2_vrf18_req_mask_b = 1, + /* [14] */ + .reg_msdc2_ddr_en_mask_b = 1, + /* [15] */ + .reg_ufs_srcclkena_mask_b = 1, + /* [16] */ + .reg_ufs_infra_req_mask_b = 1, + /* [17] */ + .reg_ufs_apsrc_req_mask_b = 1, + /* [18] */ + .reg_ufs_vrf18_req_mask_b = 1, + /* [19] */ + .reg_ufs_ddr_en_mask_b = 1, + /* [20] */ + .reg_usb_srcclkena_mask_b = 1, + /* [21] */ + .reg_usb_infra_req_mask_b = 1, + /* [22] */ + .reg_usb_apsrc_req_mask_b = 1, + /* [23] */ + .reg_usb_vrf18_req_mask_b = 1, + /* [24] */ + .reg_usb_ddr_en_mask_b = 1, + /* [25] */ + .reg_pextp_p0_srcclkena_mask_b = 1, + /* [26] */ + .reg_pextp_p0_infra_req_mask_b = 1, + /* [27] */ + .reg_pextp_p0_apsrc_req_mask_b = 1, + /* [28] */ + .reg_pextp_p0_vrf18_req_mask_b = 1, + /* [29] */ + .reg_pextp_p0_ddr_en_mask_b = 1, + + /* SPM_SRC3_MASK */ + /* [0] */ + .reg_pextp_p1_srcclkena_mask_b = 1, + /* [1] */ + .reg_pextp_p1_infra_req_mask_b = 1, + /* [2] */ + .reg_pextp_p1_apsrc_req_mask_b = 1, + /* [3] */ + .reg_pextp_p1_vrf18_req_mask_b = 1, + /* [4] */ + .reg_pextp_p1_ddr_en_mask_b = 1, + /* [5] */ + .reg_gce0_infra_req_mask_b = 1, + /* [6] */ + .reg_gce0_apsrc_req_mask_b = 1, + /* [7] */ + .reg_gce0_vrf18_req_mask_b = 1, + /* [8] */ + .reg_gce0_ddr_en_mask_b = 1, + /* [9] */ + .reg_gce1_infra_req_mask_b = 1, + /* [10] */ + .reg_gce1_apsrc_req_mask_b = 1, + /* [11] */ + .reg_gce1_vrf18_req_mask_b = 1, + /* [12] */ + .reg_gce1_ddr_en_mask_b = 1, + /* [13] */ + .reg_spm_srcclkena_reserved_mask_b = 1, + /* [14] */ + .reg_spm_infra_req_reserved_mask_b = 1, + /* [15] */ + .reg_spm_apsrc_req_reserved_mask_b = 1, + /* [16] */ + .reg_spm_vrf18_req_reserved_mask_b = 1, + /* [17] */ + .reg_spm_ddr_en_reserved_mask_b = 1, + /* [18] */ + .reg_disp0_apsrc_req_mask_b = 1, + /* [19] */ + .reg_disp0_ddr_en_mask_b = 1, + /* [20] */ + .reg_disp1_apsrc_req_mask_b = 1, + /* [21] */ + .reg_disp1_ddr_en_mask_b = 1, + /* [22] */ + .reg_disp2_apsrc_req_mask_b = 1, + /* [23] */ + .reg_disp2_ddr_en_mask_b = 1, + /* [24] */ + .reg_disp3_apsrc_req_mask_b = 1, + /* [25] */ + .reg_disp3_ddr_en_mask_b = 1, + /* [26] */ + .reg_infrasys_apsrc_req_mask_b = 0, + /* [27] */ + .reg_infrasys_ddr_en_mask_b = 1, + + /* [28] */ + .reg_cg_check_srcclkena_mask_b = 1, + /* [29] */ + .reg_cg_check_apsrc_req_mask_b = 1, + /* [30] */ + .reg_cg_check_vrf18_req_mask_b = 1, + /* [31] */ + .reg_cg_check_ddr_en_mask_b = 1, + + /* SPM_SRC4_MASK */ + /* [8:0] */ + .reg_mcusys_merge_apsrc_req_mask_b = 0, + /* [17:9] */ + .reg_mcusys_merge_ddr_en_mask_b = 0, + /* [19:18] */ + .reg_dramc_md32_infra_req_mask_b = 3, + /* [21:20] */ + .reg_dramc_md32_vrf18_req_mask_b = 3, + /* [23:22] */ + .reg_dramc_md32_ddr_en_mask_b = 0, + /* [24] */ + .reg_dvfsrc_event_trigger_mask_b = 1, + + /* SPM_WAKEUP_EVENT_MASK2 */ + /* [3:0] */ + .reg_sc_sw2spm_wakeup_mask_b = 0, + /* [4] */ + .reg_sc_adsp2spm_wakeup_mask_b = 0, + /* [8:5] */ + .reg_sc_sspm2spm_wakeup_mask_b = 0, + /* [9] */ + .reg_sc_scp2spm_wakeup_mask_b = 0, + /* [10] */ + .reg_csyspwrup_ack_mask = 0, + /* [11] */ + .reg_csyspwrup_req_mask = 1, + + /* SPM_WAKEUP_EVENT_MASK */ + /* [31:0] */ + .reg_wakeup_event_mask = 0xC1382213, + + /* SPM_WAKEUP_EVENT_EXT_MASK */ + /* [31:0] */ + .reg_ext_wakeup_event_mask = 0xFFFFFFFF, + + /*sw flag setting */ + .pcm_flags = SPM_SUSPEND_PCM_FLAG, + .pcm_flags1 = SPM_SUSPEND_PCM_FLAG1, +}; + +struct spm_lp_scen __spm_suspend = { + .pwrctrl = &suspend_ctrl, +}; + +int mt_spm_suspend_mode_set(int mode, void *prv) +{ + if (mode == MT_SPM_SUSPEND_SLEEP) { + suspend_ctrl.pcm_flags = SPM_SUSPEND_SLEEP_PCM_FLAG; + suspend_ctrl.pcm_flags1 = SPM_SUSPEND_SLEEP_PCM_FLAG1; + } else { + suspend_ctrl.pcm_flags = SPM_SUSPEND_PCM_FLAG; + suspend_ctrl.pcm_flags1 = SPM_SUSPEND_PCM_FLAG1; + } + return 0; +} + +int mt_spm_suspend_enter(int state_id, unsigned int ext_opand, unsigned int reosuce_req) +{ + int ret = 0; + + /* if FMAudio, ADSP is active, change to sleep suspend mode */ + if ((ext_opand & MT_SPM_EX_OP_SET_SUSPEND_MODE) != 0U) { + mt_spm_suspend_mode_set(MT_SPM_SUSPEND_SLEEP, NULL); + } + + if ((ext_opand & MT_SPM_EX_OP_PERI_ON) != 0U) { + suspend_ctrl.pcm_flags |= SPM_FLAG_PERI_ON_IN_SUSPEND; + } else { + suspend_ctrl.pcm_flags &= ~SPM_FLAG_PERI_ON_IN_SUSPEND; + } + + if ((ext_opand & MT_SPM_EX_OP_INFRA_ON) != 0U) { + suspend_ctrl.pcm_flags |= SPM_FLAG_DISABLE_INFRA_PDN; + } else { + suspend_ctrl.pcm_flags &= ~SPM_FLAG_DISABLE_INFRA_PDN; + } + +#ifndef MTK_PLAT_SPM_UART_UNSUPPORT + /* Notify UART to sleep */ + mtk_uart_save(); +#endif + + ret = spm_conservation(state_id, ext_opand, &__spm_suspend, reosuce_req); + if (ret == 0) { + struct mt_lp_publish_event event = { + .id = MT_LPM_PUBEVENTS_SYS_POWER_OFF, + .val.u32 = 0U, + }; + + MT_LP_SUSPEND_PUBLISH_EVENT(&event); + } + return ret; +} + +void mt_spm_suspend_resume(int state_id, unsigned int ext_opand, struct wake_status **status) +{ + struct mt_lp_publish_event event = { + .id = MT_LPM_PUBEVENTS_SYS_POWER_ON, + .val.u32 = 0U, + }; + + struct wake_status *st = NULL; + + spm_conservation_finish(state_id, ext_opand, &__spm_suspend, &st); + +#ifndef MTK_PLAT_SPM_UART_UNSUPPORT + /* Notify UART to wakeup */ + mtk_uart_restore(); +#endif + + /* If FMAudio, ADSP is active, change back to suspend mode and counting in resume */ + if ((ext_opand & MT_SPM_EX_OP_SET_SUSPEND_MODE) != 0U) { + mt_spm_suspend_mode_set(MT_SPM_SUSPEND_SYSTEM_PDN, NULL); + } + + if (status != NULL) { + *status = st; + } + MT_LP_SUSPEND_PUBLISH_EVENT(&event); +} diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_suspend.h b/plat/mediatek/drivers/spm/mt8188/mt_spm_suspend.h new file mode 100644 index 0000000..37f621d --- /dev/null +++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_suspend.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_SPM_SUSPEND_H +#define MT_SPM_SUSPEND_H + +#include <mt_spm_internal.h> + +struct suspend_dbg_ctrl { + uint32_t sleep_suspend_cnt; +}; + +enum mt_spm_suspend_mode { + MT_SPM_SUSPEND_SYSTEM_PDN = 0, + MT_SPM_SUSPEND_SLEEP, +}; + +int mt_spm_suspend_mode_set(int mode, void *prv); +int mt_spm_suspend_enter(int state_id, unsigned int ext_opand, unsigned int reosuce_req); +void mt_spm_suspend_resume(int state_id, unsigned int ext_opand, struct wake_status **status); + +#endif diff --git a/plat/mediatek/drivers/spm/mt8188/pcm_def.h b/plat/mediatek/drivers/spm/mt8188/pcm_def.h new file mode 100644 index 0000000..976c167 --- /dev/null +++ b/plat/mediatek/drivers/spm/mt8188/pcm_def.h @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PCM_DEF_H +#define PCM_DEF_H + +/* + * Auto generated by DE, please DO NOT modify this file directly. + */ + +/* --- R0 Define --- */ +#define R0_SC_26M_CK_OFF (1U << 0) +#define R0_SC_TX_TRACK_RETRY_EN (1U << 1) +#define R0_SC_MEM_CK_OFF (1U << 2) +#define R0_SC_AXI_CK_OFF (1U << 3) +#define R0_SC_DR_SRAM_LOAD (1U << 4) +#define R0_SC_MD26M_CK_OFF (1U << 5) +#define R0_SC_DPY_MODE_SW (1U << 6) +#define R0_SC_DMSUS_OFF (1U << 7) +#define R0_SC_DPY_2ND_DLL_EN (1U << 8) +#define R0_SC_DR_SRAM_RESTORE (1U << 9) +#define R0_SC_MPLLOUT_OFF (1U << 10) +#define R0_SC_TX_TRACKING_DIS (1U << 11) +#define R0_SC_DPY_DLL_EN (1U << 12) +#define R0_SC_DPY_DLL_CK_EN (1U << 13) +#define R0_SC_DPY_VREF_EN (1U << 14) +#define R0_SC_PHYPLL_EN (1U << 15) +#define R0_SC_DDRPHY_FB_CK_EN (1U << 16) +#define R0_SC_DPY_BCLK_ENABLE (1U << 17) +#define R0_SC_MPLL_OFF (1U << 18) +#define R0_SC_SHU_RESTORE (1U << 19) +#define R0_SC_CKSQ0_OFF (1U << 20) +#define R0_SC_DR_SHU_LEVEL_SRAM_LATCH (1U << 21) +#define R0_SC_DR_SHU_EN (1U << 22) +#define R0_SC_DPHY_PRECAL_UP (1U << 23) +#define R0_SC_MPLL_S_OFF (1U << 24) +#define R0_SC_DPHY_RXDLY_TRACKING_EN (1U << 25) +#define R0_SC_PHYPLL_SHU_EN (1U << 26) +#define R0_SC_PHYPLL2_SHU_EN (1U << 27) +#define R0_SC_PHYPLL_MODE_SW (1U << 28) +#define R0_SC_PHYPLL2_MODE_SW (1U << 29) +#define R0_SC_DR_SHU_LEVEL0 (1U << 30) +#define R0_SC_DR_SHU_LEVEL1 (1U << 31) +/* --- R7 Define --- */ +#define R7_PWRAP_SLEEP_REQ (1U << 0) +#define R7_EMI_CLK_OFF_REQ (1U << 1) +#define R7_PCM_BUS_PROTECT_REQ (1U << 2) +#define R7_SPM_CK_UPDATE (1U << 3) +#define R7_SPM_CK_SEL0 (1U << 4) +#define R7_SPM_CK_SEL1 (1U << 5) +#define R7_SPM_LEAVE_DEEPIDLE_REQ (1U << 6) +#define R7_SC_FHC_PAUSE_MPLL (1U << 7) +#define R7_SC_26M_CK_SEL (1U << 8) +#define R7_PCM_TIMER_SET (1U << 9) +#define R7_PCM_TIMER_CLR (1U << 10) +#define R7_SPM_LEAVE_SUSPEND_REQ (1U << 11) +#define R7_CSYSPWRUPACK (1U << 12) +#define R7_PCM_IM_SLP_EN (1U << 13) +#define R7_SRCCLKENO0 (1U << 14) +#define R7_FORCE_DDR_EN_WAKE (1U << 15) +#define R7_SPM_APSRC_INTERNAL_ACK (1U << 16) +#define R7_CPU_SYS_TIMER_CLK_SEL (1U << 17) +#define R7_SC_AXI_DCM_DIS (1U << 18) +#define R7_SC_FHC_PAUSE_MEM (1U << 19) +#define R7_SC_FHC_PAUSE_MAIN (1U << 20) +#define R7_SRCCLKENO1 (1U << 21) +#define R7_PCM_WDT_KICK_P (1U << 22) +#define R7_SPM2EMI_S1_MODE_ASYNC (1U << 23) +#define R7_SC_DDR_PST_REQ_PCM (1U << 24) +#define R7_SC_DDR_PST_ABORT_REQ_PCM (1U << 25) +#define R7_PMIC_IRQ_REQ_EN (1U << 26) +#define R7_FORCE_F26M_WAKE (1U << 27) +#define R7_FORCE_APSRC_WAKE (1U << 28) +#define R7_FORCE_INFRA_WAKE (1U << 29) +#define R7_FORCE_VRF18_WAKE (1U << 30) +#define R7_SPM_DDR_EN_INTERNAL_ACK (1U << 31) +/* --- R12 Define --- */ +#define R12_PCM_TIMER (1U << 0) +#define R12_TWAM_IRQ_B (1U << 1) +#define R12_KP_IRQ_B (1U << 2) +#define R12_APWDT_EVENT_B (1U << 3) +#define R12_APXGPT1_EVENT_B (1U << 4) +#define R12_MSDC_WAKEUP_B (1U << 5) +#define R12_EINT_EVENT_B (1U << 6) +#define R12_NOT_USED_7 (1U << 7) +#define R12_SBD_INTR_WAKEUP_B (1U << 8) +#define R12_LOWBATTERY_IRQ_B (1U << 9) +#define R12_SSPM2SPM_WAKEUP_B (1U << 10) +#define R12_SCP2SPM_WAKEUP_B (1U << 11) +#define R12_ADSP2SPM_WAKEUP_B (1U << 12) +#define R12_PCM_WDT_WAKEUP_B (1U << 13) +#define R12_USBX_CDSC_B (1U << 14) +#define R12_USBX_POWERDWN_B (1U << 15) +#define R12_SYS_TIMER_EVENT_B (1U << 16) +#define R12_EINT_EVENT_SECURE_B (1U << 17) +#define R12_ECE_INT_HDMI_B (1U << 18) +#define R12_I2C_IRQ_B (1U << 19) +#define R12_AFE_IRQ_MCU_B (1U << 20) +#define R12_THERM_CTRL_EVENT_B (1U << 21) +#define R12_SYS_CIRQ_IRQ_B (1U << 22) +#define R12_NOT_USED_23 (1U << 23) +#define R12_CSYSPWREQ_B (1U << 24) +#define R12_NOT_USED_25 (1U << 25) +#define R12_PCIE_WAKEUPEVENT_B (1U << 26) +#define R12_SEJ_EVENT_B (1U << 27) +#define R12_SPM_CPU_WAKEUPEVENT_B (1U << 28) +#define R12_APUSYS_WAKE_HOST_B (1U << 29) +#define R12_NOT_USED_30 (1U << 30) +#define R12_NOT_USED_31 (1U << 31) +/* --- R12ext Define --- */ +#define R12EXT_26M_WAKE (1U << 0) +#define R12EXT_26M_SLEEP (1U << 1) +#define R12EXT_INFRA_WAKE (1U << 2) +#define R12EXT_INFRA_SLEEP (1U << 3) +#define R12EXT_APSRC_WAKE (1U << 4) +#define R12EXT_APSRC_SLEEP (1U << 5) +#define R12EXT_VRF18_WAKE (1U << 6) +#define R12EXT_VRF18_SLEEP (1U << 7) +#define R12EXT_DVFS_WAKE (1U << 8) +#define R12EXT_DDREN_WAKE (1U << 9) +#define R12EXT_DDREN_SLEEP (1U << 10) +#define R12EXT_MCU_PM_WFI (1U << 11) +#define R12EXT_SSPM_IDLE (1U << 12) +#define R12EXT_CONN_SRCCLKENB (1U << 13) +#define R12EXT_DRAMC_SSPM_WFI_MERGE (1U << 14) +#define R12EXT_SW_MAILBOX_WAKE (1U << 15) +#define R12EXT_SSPM_MAILBOX_WAKE (1U << 16) +#define R12EXT_ADSP_MAILBOX_WAKE (1U << 17) +#define R12EXT_SCP_MAILBOX_WAKE (1U << 18) +#define R12EXT_SPM_LEAVE_SUSPEND_ACK (1U << 19) +#define R12EXT_SPM_LEAVE_DEEPIDLE_ACK (1U << 20) +#define R12EXT_VS1_TRIGGER (1U << 21) +#define R12EXT_VS2_TRIGGER (1U << 22) +#define R12EXT_COROSS_REQ_APU (1U << 23) +#define R12EXT_CROSS_REQ_L3 (1U << 24) +#define R12EXT_DDR_PST_ACK (1U << 25) +#define R12EXT_BIT26 (1U << 26) +#define R12EXT_BIT27 (1U << 27) +#define R12EXT_BIT28 (1U << 28) +#define R12EXT_BIT29 (1U << 29) +#define R12EXT_BIT30 (1U << 30) +#define R12EXT_BIT31 (1U << 31) +/* --- R13 Define --- */ +#define R13_SRCCLKENI0 (1U << 0) +#define R13_SRCCLKENI1 (1U << 1) +#define R13_MD_SRCCLKENA_0 (1U << 2) +#define R13_MD_APSRC_REQ_0 (1U << 3) +#define R13_CONN_DDR_EN (1U << 4) +#define R13_MD_SRCCLKENA_1 (1U << 5) +#define R13_SSPM_SRCCLKENA (1U << 6) +#define R13_SSPM_APSRC_REQ (1U << 7) +#define R13_MD1_STATE (1U << 8) +#define R13_BIT9 (1U << 9) +#define R13_MM_STATE (1U << 10) +#define R13_SSPM_STATE (1U << 11) +#define R13_MD_DDR_EN_0 (1U << 12) +#define R13_CONN_STATE (1U << 13) +#define R13_CONN_SRCCLKENA (1U << 14) +#define R13_CONN_APSRC_REQ (1U << 15) +#define R13_SC_DDR_PST_ACK_ALL (1U << 16) +#define R13_SC_DDR_PST_ABORT_ACK_ALL (1U << 17) +#define R13_SCP_STATE (1U << 18) +#define R13_CSYSPWRUPREQ (1U << 19) +#define R13_PWRAP_SLEEP_ACK (1U << 20) +#define R13_SC_EMI_CLK_OFF_ACK_ALL (1U << 21) +#define R13_AUDIO_DSP_STATE (1U << 22) +#define R13_SC_DMDRAMCSHU_ACK_ALL (1U << 23) +#define R13_CONN_SRCCLKENB (1U << 24) +#define R13_SC_DR_SRAM_LOAD_ACK_ALL (1U << 25) +#define R13_SUBSYS_IDLE_SIGNALS0 (1U << 26) +#define R13_DVFS_STATE (1U << 27) +#define R13_SC_DR_SRAM_PLL_LOAD_ACK_ALL (1U << 28) +#define R13_SC_DR_SRAM_RESTORE_ACK_ALL (1U << 29) +#define R13_MD_VRF18_REQ_0 (1U << 30) +#define R13_DDR_EN_STATE (1U << 31) + +#endif /* PCM_DEF_H */ diff --git a/plat/mediatek/drivers/spm/mt8188/rules.mk b/plat/mediatek/drivers/spm/mt8188/rules.mk new file mode 100644 index 0000000..a04e91f --- /dev/null +++ b/plat/mediatek/drivers/spm/mt8188/rules.mk @@ -0,0 +1,64 @@ +# +# Copyright (c) 2023, MediaTek Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +LOCAL_DIR := $(call GET_LOCAL_DIR) +MODULE := spm_${MTK_SOC} + +define GET_UPPER_DIR +$(shell dirname ${LOCAL_DIR}) +endef +UPPER_DIR := $(call GET_UPPER_DIR) + +MT_SPM_FEATURE_SUPPORT := y +MT_SPM_CIRQ_FEATURE_SUPPORT := n +MT_SPMFW_SPM_SRAM_SLEEP_SUPPORT := n +MT_SPM_SSPM_NOTIFIER_SUPPORT := y +MT_SPM_UART_SUSPEND_SUPPORT := n +MT_SPM_RGU_SUPPORT := n + +LOCAL_SRCS-y := ${LOCAL_DIR}/mt_spm.c +LOCAL_SRCS-y += ${LOCAL_DIR}/mt_spm_conservation.c +LOCAL_SRCS-y += ${LOCAL_DIR}/mt_spm_internal.c +LOCAL_SRCS-y += ${LOCAL_DIR}/mt_spm_pmic_wrap.c +LOCAL_SRCS-${MT_SPM_FEATURE_SUPPORT} += ${LOCAL_DIR}/mt_spm_cond.c +LOCAL_SRCS-${MT_SPM_FEATURE_SUPPORT} += ${LOCAL_DIR}/mt_spm_idle.c +LOCAL_SRCS-${MT_SPM_FEATURE_SUPPORT} += ${LOCAL_DIR}/mt_spm_suspend.c +LOCAL_SRCS-${MT_SPM_FEATURE_SUPPORT} += ${LOCAL_DIR}/constraints/mt_spm_rc_api.c +LOCAL_SRCS-${MT_SPM_FEATURE_SUPPORT} += ${LOCAL_DIR}/constraints/mt_spm_rc_bus26m.c +LOCAL_SRCS-${MT_SPM_FEATURE_SUPPORT} += ${LOCAL_DIR}/constraints/mt_spm_rc_cpu_buck_ldo.c +LOCAL_SRCS-${MT_SPM_FEATURE_SUPPORT} += ${LOCAL_DIR}/constraints/mt_spm_rc_dram.c +LOCAL_SRCS-${MT_SPM_FEATURE_SUPPORT} += ${LOCAL_DIR}/constraints/mt_spm_rc_syspll.c +LOCAL_SRCS-${MT_SPM_SSPM_NOTIFIER_SUPPORT} += ${UPPER_DIR}/version/notifier/v1/mt_spm_sspm_notifier.c + +ifeq (${MT_SPM_FEATURE_SUPPORT},n) +$(eval $(call add_define,MTK_PLAT_SPM_UNSUPPORT)) +endif + +ifeq (${MT_SPM_CIRQ_FEATURE_SUPPORT},n) +$(eval $(call add_define,MTK_PLAT_CIRQ_UNSUPPORT)) +endif + +ifeq (${MT_SPMFW_SPM_SRAM_SLEEP_SUPPORT},n) +$(eval $(call add_define,MTK_PLAT_SPM_SRAM_SLP_UNSUPPORT)) +endif + +ifeq (${MT_SPM_SSPM_NOTIFIER_SUPPORT},n) +$(eval $(call add_define,MTK_PLAT_SPM_SSPM_NOTIFIER_UNSUPPORT)) +endif + +ifeq (${MT_SPM_UART_SUSPEND_SUPPORT},n) +$(eval $(call add_define,MTK_PLAT_SPM_UART_UNSUPPORT)) +endif + +ifeq ($(MTK_VOLTAGE_BIN_VCORE),y) +$(eval $(call add_define,MTK_VOLTAGE_BIN_VCORE_SUPPORT)) +endif + +ifeq ($(MT_SPM_RGU_SUPPORT),n) +$(eval $(call add_define,MTK_PLAT_SPM_RGU_UNSUPPORT)) +endif + +$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL))) diff --git a/plat/mediatek/drivers/spm/mt8188/sleep_def.h b/plat/mediatek/drivers/spm/mt8188/sleep_def.h new file mode 100644 index 0000000..09a575b --- /dev/null +++ b/plat/mediatek/drivers/spm/mt8188/sleep_def.h @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SLEEP_DEF_H +#define SLEEP_DEF_H + +/* + * Auto generated by DE, please DO NOT modify this file directly. + */ + +/* --- SPM Flag Define --- */ +#define SPM_FLAG_DISABLE_CPU_PDN (1U << 0) +#define SPM_FLAG_DISABLE_INFRA_PDN (1U << 1) +#define SPM_FLAG_DISABLE_DDRPHY_PDN (1U << 2) +#define SPM_FLAG_DISABLE_VCORE_DVS (1U << 3) +#define SPM_FLAG_DISABLE_VCORE_DFS (1U << 4) +#define SPM_FLAG_DISABLE_COMMON_SCENARIO (1U << 5) +#define SPM_FLAG_DISABLE_BUS_CLK_OFF (1U << 6) +#define SPM_FLAG_DISABLE_ARMPLL_OFF (1U << 7) +#define SPM_FLAG_KEEP_CSYSPWRACK_HIGH (1U << 8) +#define SPM_FLAG_ENABLE_LVTS_WORKAROUND (1U << 9) +#define SPM_FLAG_RUN_COMMON_SCENARIO (1U << 10) +#define SPM_FLAG_PERI_ON_IN_SUSPEND (1U << 11) +#define SPM_FLAG_ENABLE_SPM_DBG_WDT_DUMP (1U << 12) +#define SPM_FLAG_USE_SRCCLKENO2 (1U << 13) +#define SPM_FLAG_ENABLE_6315_CTRL (1U << 14) +#define SPM_FLAG_ENABLE_TIA_WORKAROUND (1U << 15) +#define SPM_FLAG_DISABLE_SYSRAM_SLEEP (1U << 16) +#define SPM_FLAG_DISABLE_SSPM_SRAM_SLEEP (1U << 17) +#define SPM_FLAG_DISABLE_MCUPM_SRAM_SLEEP (1U << 18) +#define SPM_FLAG_DISABLE_DRAMC_ISSUE_CMD (1U << 19) +#define SPM_FLAG_ENABLE_VOLTAGE_BIN (1U << 20) +#define SPM_FLAG_RESERVED_BIT21 (1U << 21) +#define SPM_FLAG_DISABLE_DRAMC_MCU_SRAM_SLEEP (1U << 22) +#define SPM_FLAG_DISABLE_DRAMC_MD32_BACKUP (1U << 23) +#define SPM_FLAG_RESERVED_BIT24 (1U << 24) +#define SPM_FLAG_RESERVED_BIT25 (1U << 25) +#define SPM_FLAG_RESERVED_BIT26 (1U << 26) +#define SPM_FLAG_VTCXO_STATE (1U << 27) +#define SPM_FLAG_INFRA_STATE (1U << 28) +#define SPM_FLAG_APSRC_STATE (1U << 29) +#define SPM_FLAG_VRF18_STATE (1U << 30) +#define SPM_FLAG_DDREN_STATE (1U << 31) +/* --- SPM Flag1 Define --- */ +#define SPM_FLAG1_DISABLE_AXI_BUS_TO_26M (1U << 0) +#define SPM_FLAG1_DISABLE_SYSPLL_OFF (1U << 1) +#define SPM_FLAG1_DISABLE_PWRAP_CLK_SWITCH (1U << 2) +#define SPM_FLAG1_DISABLE_ULPOSC_OFF (1U << 3) +#define SPM_FLAG1_FW_SET_ULPOSC_ON (1U << 4) +#define SPM_FLAG1_RESERVED_BIT5 (1U << 5) +#define SPM_FLAG1_ENABLE_REKICK (1U << 6) +#define SPM_FLAG1_RESERVED_BIT7 (1U << 7) +#define SPM_FLAG1_RESERVED_BIT8 (1U << 8) +#define SPM_FLAG1_RESERVED_BIT9 (1U << 9) +#define SPM_FLAG1_DISABLE_SRCLKEN_LOW (1U << 10) +#define SPM_FLAG1_DISABLE_SCP_CLK_SWITCH (1U << 11) +#define SPM_FLAG1_RESERVED_BIT12 (1U << 12) +#define SPM_FLAG1_RESERVED_BIT13 (1U << 13) +#define SPM_FLAG1_RESERVED_BIT14 (1U << 14) +#define SPM_FLAG1_RESERVED_BIT15 (1U << 15) +#define SPM_FLAG1_RESERVED_BIT16 (1U << 16) +#define SPM_FLAG1_RESERVED_BIT17 (1U << 17) +#define SPM_FLAG1_RESERVED_BIT18 (1U << 18) +#define SPM_FLAG1_RESERVED_BIT19 (1U << 19) +#define SPM_FLAG1_DISABLE_DEVAPC_SRAM_SLEEP (1U << 20) +#define SPM_FLAG1_RESERVED_BIT21 (1U << 21) +#define SPM_FLAG1_ENABLE_VS1_VOTER (1U << 22) +#define SPM_FLAG1_ENABLE_VS2_VOTER (1U << 23) +#define SPM_FLAG1_DISABLE_SCP_VREQ_MASK_CONTROL (1U << 24) +#define SPM_FLAG1_RESERVED_BIT25 (1U << 25) +#define SPM_FLAG1_RESERVED_BIT26 (1U << 26) +#define SPM_FLAG1_RESERVED_BIT27 (1U << 27) +#define SPM_FLAG1_RESERVED_BIT28 (1U << 28) +#define SPM_FLAG1_RESERVED_BIT29 (1U << 29) +#define SPM_FLAG1_RESERVED_BIT30 (1U << 30) +#define SPM_FLAG1_RESERVED_BIT31 (1U << 31) +/* --- SPM DEBUG Define --- */ +#define SPM_DBG_DEBUG_IDX_26M_WAKE (1U << 0) +#define SPM_DBG_DEBUG_IDX_26M_SLEEP (1U << 1) +#define SPM_DBG_DEBUG_IDX_INFRA_WAKE (1U << 2) +#define SPM_DBG_DEBUG_IDX_INFRA_SLEEP (1U << 3) +#define SPM_DBG_DEBUG_IDX_APSRC_WAKE (1U << 4) +#define SPM_DBG_DEBUG_IDX_APSRC_SLEEP (1U << 5) +#define SPM_DBG_DEBUG_IDX_VRF18_WAKE (1U << 6) +#define SPM_DBG_DEBUG_IDX_VRF18_SLEEP (1U << 7) +#define SPM_DBG_DEBUG_IDX_DDREN_WAKE (1U << 8) +#define SPM_DBG_DEBUG_IDX_DDREN_SLEEP (1U << 9) +#define SPM_DBG_DEBUG_IDX_DRAM_SREF_ABORT_IN_APSRC (1U << 10) +#define SPM_DBG_DEBUG_IDX_MCUPM_SRAM_STATE (1U << 11) +#define SPM_DBG_DEBUG_IDX_SSPM_SRAM_STATE (1U << 12) +#define SPM_DBG_DEBUG_IDX_DRAM_SREF_ABORT_IN_DDREN (1U << 13) +#define SPM_DBG_DEBUG_IDX_DRAMC_MCU_SRAM_STATE (1U << 14) +#define SPM_DBG_DEBUG_IDX_SYSRAM_SLP (1U << 15) +#define SPM_DBG_DEBUG_IDX_SYSRAM_ON (1U << 16) +#define SPM_DBG_DEBUG_IDX_MCUPM_SRAM_SLP (1U << 17) +#define SPM_DBG_DEBUG_IDX_MCUPM_SRAM_ON (1U << 18) +#define SPM_DBG_DEBUG_IDX_SSPM_SRAM_SLP (1U << 19) +#define SPM_DBG_DEBUG_IDX_SSPM_SRAM_ON (1U << 20) +#define SPM_DBG_DEBUG_IDX_DRAMC_MCU_SRAM_SLP (1U << 21) +#define SPM_DBG_DEBUG_IDX_DRAMC_MCU_SRAM_ON (1U << 22) +#define SPM_DBG_DEBUG_IDX_SCP_VCORE_0P575V (1U << 23) +#define SPM_DBG_DEBUG_IDX_SCP_VCORE_0P600V (1U << 24) +#define SPM_DBG_DEBUG_IDX_SCP_VCORE_0P650V (1U << 25) +#define SPM_DBG_DEBUG_IDX_SCP_VCORE_0P725V (1U << 26) +#define SPM_DBG_DEBUG_IDX_SPM_GO_WAKEUP_NOW (1U << 27) +#define SPM_DBG_DEBUG_IDX_VTCXO_STATE (1U << 28) +#define SPM_DBG_DEBUG_IDX_INFRA_STATE (1U << 29) +#define SPM_DBG_DEBUG_IDX_VRR18_STATE (1U << 30) +#define SPM_DBG_DEBUG_IDX_APSRC_STATE (1U << 31) +/* --- SPM DEBUG1 Define --- */ +#define SPM_DBG1_DEBUG_IDX_CURRENT_IS_LP (1U << 0) +#define SPM_DBG1_DEBUG_IDX_VCORE_DVFS_START (1U << 1) +#define SPM_DBG1_DEBUG_IDX_SYSPLL_OFF (1U << 2) +#define SPM_DBG1_DEBUG_IDX_SYSPLL_ON (1U << 3) +#define SPM_DBG1_DEBUG_IDX_CURRENT_IS_VCORE_DVFS (1U << 4) +#define SPM_DBG1_DEBUG_IDX_INFRA_MTCMOS_OFF (1U << 5) +#define SPM_DBG1_DEBUG_IDX_INFRA_MTCMOS_ON (1U << 6) +#define SPM_DBG1_DEBUG_IDX_VRCXO_SLEEP_ABORT (1U << 7) +#define SPM_DBG1_RESERVED_BIT8 (1U << 8) +#define SPM_DBG1_DEBUG_IDX_INFRA_SUB_MTCMOS_OFF (1U << 9) +#define SPM_DBG1_DEBUG_IDX_INFRA_SUB_MTCMOS_ON (1U << 10) +#define SPM_DBG1_DEBUG_IDX_PWRAP_CLK_TO_ULPOSC (1U << 11) +#define SPM_DBG1_DEBUG_IDX_PWRAP_CLK_TO_26M (1U << 12) +#define SPM_DBG1_DEBUG_IDX_SCP_CLK_TO_32K (1U << 13) +#define SPM_DBG1_DEBUG_IDX_SCP_CLK_TO_26M (1U << 14) +#define SPM_DBG1_DEBUG_IDX_BUS_CLK_OFF (1U << 15) +#define SPM_DBG1_DEBUG_IDX_BUS_CLK_ON (1U << 16) +#define SPM_DBG1_DEBUG_IDX_SRCLKEN2_LOW (1U << 17) +#define SPM_DBG1_DEBUG_IDX_SRCLKEN2_HIGH (1U << 18) +#define SPM_DBG1_RESERVED_BIT19 (1U << 19) +#define SPM_DBG1_DEBUG_IDX_ULPOSC_IS_OFF_BUT_SHOULD_ON (1U << 20) +#define SPM_DBG1_DEBUG_IDX_6315_LOW (1U << 21) +#define SPM_DBG1_DEBUG_IDX_6315_HIGH (1U << 22) +#define SPM_DBG1_DEBUG_IDX_PWRAP_SLEEP_ACK_LOW_ABORT (1U << 23) +#define SPM_DBG1_DEBUG_IDX_PWRAP_SLEEP_ACK_HIGH_ABORT (1U << 24) +#define SPM_DBG1_DEBUG_IDX_EMI_SLP_IDLE_ABORT (1U << 25) +#define SPM_DBG1_DEBUG_IDX_SCP_SLP_ACK_LOW_ABORT (1U << 26) +#define SPM_DBG1_DEBUG_IDX_SCP_SLP_ACK_HIGH_ABORT (1U << 27) +#define SPM_DBG1_DEBUG_IDX_SPM_DVFS_CMD_RDY_ABORT (1U << 28) +#define SPM_DBG1_RESERVED_BIT29 (1U << 29) +#define SPM_DBG1_RESERVED_BIT30 (1U << 30) +#define SPM_DBG1_RESERVED_BIT31 (1U << 31) + +/* + * Macro and Inline + */ +#define is_cpu_pdn(flags) ((flags) & SPM_FLAG_DIS_CPU_PDN == 0) +#define is_infra_pdn(flags) ((flags) & SPM_FLAG_DIS_INFRA_PDN == 0) +#define is_ddrphy_pdn(flags) ((flags) & SPM_FLAG_DIS_DDRPHY_PDN == 0) + +#endif /* SLEEP_DEF_H */ diff --git a/plat/mediatek/drivers/spm/rules.mk b/plat/mediatek/drivers/spm/rules.mk new file mode 100644 index 0000000..b7128db --- /dev/null +++ b/plat/mediatek/drivers/spm/rules.mk @@ -0,0 +1,20 @@ +# +# Copyright (c) 2023, MediaTek Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +LOCAL_DIR := $(call GET_LOCAL_DIR) +MODULE := spm + +$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL))) + +ifneq ($(CONFIG_MTK_SPM_VERSION),) +PLAT_INCLUDES += -I${LOCAL_DIR}/$(MTK_SOC) +PLAT_INCLUDES += -I${LOCAL_DIR}/version/notifier/inc + +SUB_RULES-y += ${LOCAL_DIR}/$(CONFIG_MTK_SPM_VERSION) +$(eval $(call add_define,SPM_PLAT_IMPL)) +endif + +$(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES-y))) diff --git a/plat/mediatek/drivers/spm/version/notifier/inc/mt_spm_notifier.h b/plat/mediatek/drivers/spm/version/notifier/inc/mt_spm_notifier.h new file mode 100644 index 0000000..4d12624 --- /dev/null +++ b/plat/mediatek/drivers/spm/version/notifier/inc/mt_spm_notifier.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_SPM_NOTIFIER_H +#define MT_SPM_NOTIFIER_H + +enum mt_spm_sspm_notify_id { + MT_SPM_NOTIFY_LP_ENTER = 0, + MT_SPM_NOTIFY_LP_LEAVE, + MT_SPM_NOTIFY_SUSPEND_VCORE_VOLTAGE, +}; + +#ifdef MTK_PLAT_SPM_SSPM_NOTIFIER_UNSUPPORT +static inline int mt_spm_sspm_notify_u32(int type, unsigned int val) +{ + (void)type; + (void)val; + return 0; +} +#else +int mt_spm_sspm_notify_u32(int type, unsigned int val); +#endif + +#endif /* MT_SPM_NOTIFIER_H */ diff --git a/plat/mediatek/drivers/spm/version/notifier/v1/mt_spm_sspm_intc.h b/plat/mediatek/drivers/spm/version/notifier/v1/mt_spm_sspm_intc.h new file mode 100644 index 0000000..e57a966 --- /dev/null +++ b/plat/mediatek/drivers/spm/version/notifier/v1/mt_spm_sspm_intc.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_SPM_SSPM_INTC_H +#define MT_SPM_SSPM_INTC_H + +#include <mt_spm_reg.h> + +#define MT_SPM_SSPM_INTC_SEL_0 (0x10) +#define MT_SPM_SSPM_INTC_SEL_1 (0x20) +#define MT_SPM_SSPM_INTC_SEL_2 (0x40) +#define MT_SPM_SSPM_INTC_SEL_3 (0x80) + +#define MT_SPM_SSPM_INTC_TRIGGER(id, sg) (((0x10 << (id)) | (sg << (id))) & 0xFF) + +#define MT_SPM_SSPM_INTC0_HIGH MT_SPM_SSPM_INTC_TRIGGER(0, 1) +#define MT_SPM_SSPM_INTC0_LOW MT_SPM_SSPM_INTC_TRIGGER(0, 0) + +#define MT_SPM_SSPM_INTC1_HIGH MT_SPM_SSPM_INTC_TRIGGER(1, 1) +#define MT_SPM_SSPM_INTC1_LOW MT_SPM_SSPM_INTC_TRIGGER(1, 0) + +#define MT_SPM_SSPM_INTC2_HIGH MT_SPM_SSPM_INTC_TRIGGER(2, 1) +#define MT_SPM_SSPM_INTC2_LOW MT_SPM_SSPM_INTC_TRIGGER(2, 0) + +#define MT_SPM_SSPM_INTC3_HIGH MT_SPM_SSPM_INTC_TRIGGER(3, 1) +#define MT_SPM_SSPM_INTC3_LOW MT_SPM_SSPM_INTC_TRIGGER(3, 0) + +#define DO_SPM_SSPM_LP_SUSPEND() mmio_write_32(SPM_MD32_IRQ, MT_SPM_SSPM_INTC0_HIGH) + +#define DO_SPM_SSPM_LP_RESUME() mmio_write_32(SPM_MD32_IRQ, MT_SPM_SSPM_INTC0_LOW) + +#endif /* MT_SPM_SSPM_INTC_H */ diff --git a/plat/mediatek/drivers/spm/version/notifier/v1/mt_spm_sspm_notifier.c b/plat/mediatek/drivers/spm/version/notifier/v1/mt_spm_sspm_notifier.c new file mode 100644 index 0000000..081988f --- /dev/null +++ b/plat/mediatek/drivers/spm/version/notifier/v1/mt_spm_sspm_notifier.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#include <lib/mmio.h> +#include "mt_spm_notifier.h" +#include "mt_spm_sspm_intc.h" +#include <platform_def.h> + +#define MT_SPM_SSPM_MBOX_OFF(x) (SSPM_MBOX_3_BASE + x) +#define MT_SPM_MBOX(slot) MT_SPM_SSPM_MBOX_OFF((slot << 2UL)) + +/* LOOKUP SSPM_MBOX_SPM_LP1 */ +#define SSPM_MBOX_SPM_LP_LOOKUP1 MT_SPM_MBOX(0) +/* LOOKUP SSPM_MBOX_SPM_LP2 */ +#define SSPM_MBOX_SPM_LP_LOOKUP2 MT_SPM_MBOX(1) + +#define SSPM_MBOX_SPM_LP1 MT_SPM_MBOX(2) +#define SSPM_MBOX_SPM_LP2 MT_SPM_MBOX(3) + +int mt_spm_sspm_notify_u32(int type, unsigned int val) +{ + switch (type) { + case MT_SPM_NOTIFY_LP_ENTER: + mmio_write_32(SSPM_MBOX_SPM_LP1, val); + DO_SPM_SSPM_LP_SUSPEND(); + break; + case MT_SPM_NOTIFY_LP_LEAVE: + mmio_write_32(SSPM_MBOX_SPM_LP1, val); + DO_SPM_SSPM_LP_RESUME(); + break; + default: + panic(); + break; + } + return 0; +} diff --git a/plat/mediatek/drivers/timer/mt_timer.c b/plat/mediatek/drivers/timer/mt_timer.c new file mode 100644 index 0000000..11e4572 --- /dev/null +++ b/plat/mediatek/drivers/timer/mt_timer.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch_helpers.h> +#include <common/debug.h> +#include <lib/mmio.h> +#include <lib/mtk_init/mtk_init.h> +#include <mt_timer.h> +#include <platform_def.h> + +uint64_t normal_time_base; +uint64_t atf_time_base; + +void sched_clock_init(uint64_t normal_base, uint64_t atf_base) +{ + normal_time_base += normal_base; + atf_time_base = atf_base; +} + +uint64_t sched_clock(void) +{ + uint64_t cval; + uint64_t rel_base; + + rel_base = read_cntpct_el0() - atf_time_base; + cval = ((rel_base * 1000U) / SYS_COUNTER_FREQ_IN_MHZ) + - normal_time_base; + return cval; +} + +int mt_systimer_init(void) +{ + INFO("[%s] systimer initialization\n", __func__); + + /* Enable access in NS mode */ + mmio_write_32(CNTWACR_REG, CNT_WRITE_ACCESS_CTL_MASK); + mmio_write_32(CNTRACR_REG, CNT_READ_ACCESS_CTL_MASK); + + return 0; +} +MTK_PLAT_SETUP_0_INIT(mt_systimer_init); diff --git a/plat/mediatek/drivers/timer/mt_timer.h b/plat/mediatek/drivers/timer/mt_timer.h new file mode 100644 index 0000000..1c08f90 --- /dev/null +++ b/plat/mediatek/drivers/timer/mt_timer.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_TIMER_H +#define MT_TIMER_H + +#define SYSTIMER_BASE (0x10017000) +#define CNTCR_REG (SYSTIMER_BASE + 0x0) +#define CNTSR_REG (SYSTIMER_BASE + 0x4) +#define CNTSYS_L_REG (SYSTIMER_BASE + 0x8) +#define CNTSYS_H_REG (SYSTIMER_BASE + 0xc) +#define CNTWACR_REG (SYSTIMER_BASE + 0x10) +#define CNTRACR_REG (SYSTIMER_BASE + 0x14) + +#define TIEO_EN (1 << 3) +#define COMP_15_EN (1 << 10) +#define COMP_20_EN (1 << 11) +#define COMP_25_EN (1 << 12) + +#define COMP_FEATURE_MASK (COMP_15_EN | COMP_20_EN | COMP_25_EN | TIEO_EN) +#define COMP_15_MASK (COMP_15_EN) +#define COMP_20_MASK (COMP_20_EN | TIEO_EN) +#define COMP_25_MASK (COMP_20_EN | COMP_25_EN) + +#define CNT_WRITE_ACCESS_CTL_MASK (0x3FFFFF0U) +#define CNT_READ_ACCESS_CTL_MASK (0x3FFFFFFU) + +void sched_clock_init(uint64_t normal_base, uint64_t atf_base); +uint64_t sched_clock(void); +int mt_systimer_init(void); + +#endif /* MT_TIMER_H */ diff --git a/plat/mediatek/drivers/timer/rules.mk b/plat/mediatek/drivers/timer/rules.mk new file mode 100644 index 0000000..005cf45 --- /dev/null +++ b/plat/mediatek/drivers/timer/rules.mk @@ -0,0 +1,14 @@ +# +# Copyright (c) 2022, MediaTek Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +LOCAL_DIR := $(call GET_LOCAL_DIR) + +MODULE := timer +LOCAL_SRCS-y := $(LOCAL_DIR)/mt_timer.c + +PLAT_INCLUDES += -I${LOCAL_DIR} + +$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL))) diff --git a/plat/mediatek/drivers/uart/8250_console.S b/plat/mediatek/drivers/uart/8250_console.S new file mode 100644 index 0000000..66f998d --- /dev/null +++ b/plat/mediatek/drivers/uart/8250_console.S @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include <asm_macros.S> +#include <uart8250.h> + + .globl console_core_init + .globl console_core_putc + .globl console_core_getc + .globl console_core_flush + + /* ----------------------------------------------- + * int console_core_init(unsigned long base_addr, + * unsigned int uart_clk, unsigned int baud_rate) + * Function to initialize the console without a + * C Runtime to print debug information. This + * function will be accessed by console_init and + * crash reporting. + * In: x0 - console base address + * w1 - Uart clock in Hz + * w2 - Baud rate + * Out: return 1 on success else 0 on error + * Clobber list : x1, x2, x3 + * ----------------------------------------------- + */ +func console_core_init + /* Check the input base address */ + cbz x0, core_init_fail + /* Check baud rate and uart clock for sanity */ + cbz w1, core_init_fail + cbz w2, core_init_fail + + /* Disable interrupt */ + str wzr, [x0, #UART_IER] + + /* Force DTR and RTS to high */ + mov w3, #(UART_MCR_DTR | UART_MCR_RTS) + str w3, [x0, #UART_MCR] + + /* Check high speed */ + movz w3, #:abs_g1:115200 + movk w3, #:abs_g0_nc:115200 + cmp w2, w3 + b.hi 1f + + /* Non high speed */ + lsl w2, w2, #4 + mov w3, wzr + b 2f + + /* High speed */ +1: lsl w2, w2, #2 + mov w3, #2 + + /* Set high speed UART register */ +2: str w3, [x0, #UART_HIGHSPEED] + + /* Calculate divisor */ + udiv w3, w1, w2 /* divisor = uartclk / (quot * baudrate) */ + msub w1, w3, w2, w1 /* remainder = uartclk % (quot * baudrate) */ + lsr w2, w2, #1 + cmp w1, w2 + cinc w3, w3, hs + + /* Set line configuration, access divisor latches */ + mov w1, #(UART_LCR_DLAB | UART_LCR_WLS_8) + str w1, [x0, #UART_LCR] + + /* Set the divisor */ + and w1, w3, #0xff + str w1, [x0, #UART_DLL] + lsr w1, w3, #8 + and w1, w1, #0xff + str w1, [x0, #UART_DLH] + + /* Hide the divisor latches */ + mov w1, #UART_LCR_WLS_8 + str w1, [x0, #UART_LCR] + + /* Enable FIFOs, and clear receive and transmit */ + mov w1, #(UART_FCR_FIFO_EN | UART_FCR_CLEAR_RCVR | \ + UART_FCR_CLEAR_XMIT) + str w1, [x0, #UART_FCR] + + mov w0, #1 + ret +core_init_fail: + mov w0, wzr + ret +endfunc console_core_init + + /* -------------------------------------------------------- + * int console_core_putc(int c, unsigned long base_addr) + * Function to output a character over the console. It + * returns the character printed on success or -1 on error. + * In : w0 - character to be printed + * x1 - console base address + * Out : return -1 on error else return character. + * Clobber list : x2 + * -------------------------------------------------------- + */ +func console_core_putc + /* Check the input parameter */ + cbz x1, putc_error + /* Prepend '\r' to '\n' */ + cmp w0, #0xA + b.ne 2f + + /* Check if the transmit FIFO is full */ +1: ldr w2, [x1, #UART_LSR] + and w2, w2, #UART_LSR_THRE + cbz w2, 1b + mov w2, #0xD + str w2, [x1, #UART_THR] + + /* Check if the transmit FIFO is full */ +2: ldr w2, [x1, #UART_LSR] + and w2, w2, #UART_LSR_THRE + cbz w2, 2b + str w0, [x1, #UART_THR] + ret +putc_error: + mov w0, #-1 + ret +endfunc console_core_putc + + /* --------------------------------------------- + * int console_core_getc(unsigned long base_addr) + * Function to get a character from the console. + * It returns the character grabbed on success + * or -1 on error. + * In : x0 - console base address + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func console_core_getc + cbz x0, getc_error + + /* Check if the receive FIFO is empty */ +1: ldr w1, [x0, #UART_LSR] + tbz w1, #UART_LSR_DR, 1b + ldr w0, [x0, #UART_RBR] + ret +getc_error: + mov w0, #-1 + ret +endfunc console_core_getc + + /* --------------------------------------------- + * void console_core_flush(uintptr_t base_addr) + * Function to force a write of all buffered + * data that hasn't been output. + * In : x0 - console base address + * Out : void. + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func console_core_flush + /* Placeholder */ + ret +endfunc console_core_flush diff --git a/plat/mediatek/drivers/uart/uart.c b/plat/mediatek/drivers/uart/uart.c new file mode 100644 index 0000000..fdaa793 --- /dev/null +++ b/plat/mediatek/drivers/uart/uart.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <lib/mmio.h> +#include <uart.h> + +static struct mt_uart uart_save_addr[DRV_SUPPORT_UART_PORTS]; + +static const uint32_t uart_base_addr[DRV_SUPPORT_UART_PORTS] = { + UART0_BASE, + UART1_BASE +}; + +void mt_uart_restore(void) +{ + int uart_idx = UART_PORT0; + struct mt_uart *uart; + unsigned long base; + + /* Must NOT print any debug log before UART restore */ + for (uart_idx = UART_PORT0; uart_idx < HW_SUPPORT_UART_PORTS; + uart_idx++) { + + uart = &uart_save_addr[uart_idx]; + base = uart->base; + + mmio_write_32(UART_LCR(base), UART_LCR_MODE_B); + mmio_write_32(UART_EFR(base), uart->registers.efr); + mmio_write_32(UART_LCR(base), uart->registers.lcr); + mmio_write_32(UART_FCR(base), uart->registers.fcr); + + /* baudrate */ + mmio_write_32(UART_HIGHSPEED(base), uart->registers.highspeed); + mmio_write_32(UART_FRACDIV_L(base), uart->registers.fracdiv_l); + mmio_write_32(UART_FRACDIV_M(base), uart->registers.fracdiv_m); + mmio_write_32(UART_LCR(base), + uart->registers.lcr | UART_LCR_DLAB); + mmio_write_32(UART_DLL(base), uart->registers.dll); + mmio_write_32(UART_DLH(base), uart->registers.dlh); + mmio_write_32(UART_LCR(base), uart->registers.lcr); + mmio_write_32(UART_SAMPLE_COUNT(base), + uart->registers.sample_count); + mmio_write_32(UART_SAMPLE_POINT(base), + uart->registers.sample_point); + mmio_write_32(UART_GUARD(base), uart->registers.guard); + + /* flow control */ + mmio_write_32(UART_ESCAPE_EN(base), uart->registers.escape_en); + mmio_write_32(UART_MCR(base), uart->registers.mcr); + mmio_write_32(UART_IER(base), uart->registers.ier); + mmio_write_32(UART_SCR(base), uart->registers.scr); + } +} + +void mt_uart_save(void) +{ + int uart_idx = UART_PORT0; + struct mt_uart *uart; + unsigned long base; + + for (uart_idx = UART_PORT0; uart_idx < HW_SUPPORT_UART_PORTS; + uart_idx++) { + + uart_save_addr[uart_idx].base = uart_base_addr[uart_idx]; + base = uart_base_addr[uart_idx]; + uart = &uart_save_addr[uart_idx]; + uart->registers.lcr = mmio_read_32(UART_LCR(base)); + + mmio_write_32(UART_LCR(base), UART_LCR_MODE_B); + uart->registers.efr = mmio_read_32(UART_EFR(base)); + mmio_write_32(UART_LCR(base), uart->registers.lcr); + uart->registers.fcr = mmio_read_32(UART_FCR_RD(base)); + + /* baudrate */ + uart->registers.highspeed = mmio_read_32(UART_HIGHSPEED(base)); + uart->registers.fracdiv_l = mmio_read_32(UART_FRACDIV_L(base)); + uart->registers.fracdiv_m = mmio_read_32(UART_FRACDIV_M(base)); + mmio_write_32(UART_LCR(base), + uart->registers.lcr | UART_LCR_DLAB); + uart->registers.dll = mmio_read_32(UART_DLL(base)); + uart->registers.dlh = mmio_read_32(UART_DLH(base)); + mmio_write_32(UART_LCR(base), uart->registers.lcr); + uart->registers.sample_count = mmio_read_32( + UART_SAMPLE_COUNT(base)); + uart->registers.sample_point = mmio_read_32( + UART_SAMPLE_POINT(base)); + uart->registers.guard = mmio_read_32(UART_GUARD(base)); + + /* flow control */ + uart->registers.escape_en = mmio_read_32(UART_ESCAPE_EN(base)); + uart->registers.mcr = mmio_read_32(UART_MCR(base)); + uart->registers.ier = mmio_read_32(UART_IER(base)); + uart->registers.scr = mmio_read_32(UART_SCR(base)); + } +} + +void mt_console_uart_cg(int on) +{ + if (on == 1) { + mmio_write_32(UART_CLOCK_GATE_CLR, UART0_CLOCK_GATE_BIT); + } else { + mmio_write_32(UART_CLOCK_GATE_SET, UART0_CLOCK_GATE_BIT); + } +} + +uint32_t mt_console_uart_cg_status(void) +{ + return mmio_read_32(UART_CLOCK_GATE_STA) & UART0_CLOCK_GATE_BIT; +} diff --git a/plat/mediatek/drivers/uart/uart.h b/plat/mediatek/drivers/uart/uart.h new file mode 100644 index 0000000..2ca74fa --- /dev/null +++ b/plat/mediatek/drivers/uart/uart.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef UART_H +#define UART_H + +#include <platform_def.h> + +/* UART HW information */ +#define HW_SUPPORT_UART_PORTS 2 +#define DRV_SUPPORT_UART_PORTS 2 + +/* console UART clock cg */ +#define UART_CLOCK_GATE_SET (INFRACFG_AO_BASE + 0x80) +#define UART_CLOCK_GATE_CLR (INFRACFG_AO_BASE + 0x84) +#define UART_CLOCK_GATE_STA (INFRACFG_AO_BASE + 0x90) +#define UART0_CLOCK_GATE_BIT (1U<<22) +#define UART1_CLOCK_GATE_BIT (1U<<23) + +/* UART registers */ +#define UART_RBR(_baseaddr) (_baseaddr + 0x0) +#define UART_THR(_baseaddr) (_baseaddr + 0x0) +#define UART_IER(_baseaddr) (_baseaddr + 0x4) +#define UART_IIR(_baseaddr) (_baseaddr + 0x8) +#define UART_FCR(_baseaddr) (_baseaddr + 0x8) +#define UART_LCR(_baseaddr) (_baseaddr + 0xc) +#define UART_MCR(_baseaddr) (_baseaddr + 0x10) +#define UART_LSR(_baseaddr) (_baseaddr + 0x14) +#define UART_MSR(_baseaddr) (_baseaddr + 0x18) +#define UART_SCR(_baseaddr) (_baseaddr + 0x1c) +#define UART_DLL(_baseaddr) (_baseaddr + 0x0) +#define UART_DLH(_baseaddr) (_baseaddr + 0x4) +#define UART_EFR(_baseaddr) (_baseaddr + 0x8) +#define UART_XON1(_baseaddr) (_baseaddr + 0x10) +#define UART_XON2(_baseaddr) (_baseaddr + 0x14) +#define UART_XOFF1(_baseaddr) (_baseaddr + 0x18) +#define UART_XOFF2(_baseaddr) (_baseaddr + 0x1c) +#define UART_AUTOBAUD(_baseaddr) (_baseaddr + 0x20) +#define UART_HIGHSPEED(_baseaddr) (_baseaddr + 0x24) +#define UART_SAMPLE_COUNT(_baseaddr) (_baseaddr + 0x28) +#define UART_SAMPLE_POINT(_baseaddr) (_baseaddr + 0x2c) +#define UART_AUTOBAUD_REG(_baseaddr) (_baseaddr + 0x30) +#define UART_RATE_FIX_REG(_baseaddr) (_baseaddr + 0x34) +#define UART_AUTO_BAUDSAMPLE(_baseaddr) (_baseaddr + 0x38) +#define UART_GUARD(_baseaddr) (_baseaddr + 0x3c) +#define UART_ESCAPE_DAT(_baseaddr) (_baseaddr + 0x40) +#define UART_ESCAPE_EN(_baseaddr) (_baseaddr + 0x44) +#define UART_SLEEP_EN(_baseaddr) (_baseaddr + 0x48) +#define UART_DMA_EN(_baseaddr) (_baseaddr + 0x4c) +#define UART_RXTRI_AD(_baseaddr) (_baseaddr + 0x50) +#define UART_FRACDIV_L(_baseaddr) (_baseaddr + 0x54) +#define UART_FRACDIV_M(_baseaddr) (_baseaddr + 0x58) +#define UART_FCR_RD(_baseaddr) (_baseaddr + 0x5C) +#define UART_USB_RX_SEL(_baseaddr) (_baseaddr + 0xB0) +#define UART_SLEEP_REQ(_baseaddr) (_baseaddr + 0xB4) +#define UART_SLEEP_ACK(_baseaddr) (_baseaddr + 0xB8) +#define UART_SPM_SEL(_baseaddr) (_baseaddr + 0xBC) +#define UART_LCR_DLAB 0x0080 +#define UART_LCR_MODE_B 0x00bf + +enum uart_port_ID { + UART_PORT0 = 0, + UART_PORT1 +}; + +struct mt_uart_register { + uint32_t dll; + uint32_t dlh; + uint32_t ier; + uint32_t lcr; + uint32_t mcr; + uint32_t fcr; + uint32_t lsr; + uint32_t scr; + uint32_t efr; + uint32_t highspeed; + uint32_t sample_count; + uint32_t sample_point; + uint32_t fracdiv_l; + uint32_t fracdiv_m; + uint32_t escape_en; + uint32_t guard; + uint32_t rx_sel; +}; + +struct mt_uart { + unsigned long base; + struct mt_uart_register registers; +}; + +/* external API */ +void mt_uart_save(void); +void mt_uart_restore(void); +void mt_console_uart_cg(int on); +uint32_t mt_console_uart_cg_status(void); + +#endif /* __UART_H__ */ diff --git a/plat/mediatek/drivers/uart/uart8250.h b/plat/mediatek/drivers/uart/uart8250.h new file mode 100644 index 0000000..f0541d6 --- /dev/null +++ b/plat/mediatek/drivers/uart/uart8250.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef UART8250_H +#define UART8250_H + +/* UART register */ +#define UART_RBR 0x00 /* Receive buffer register */ +#define UART_DLL 0x00 /* Divisor latch lsb */ +#define UART_THR 0x00 /* Transmit holding register */ +#define UART_DLH 0x04 /* Divisor latch msb */ +#define UART_IER 0x04 /* Interrupt enable register */ +#define UART_FCR 0x08 /* FIFO control register */ +#define UART_LCR 0x0c /* Line control register */ +#define UART_MCR 0x10 /* Modem control register */ +#define UART_LSR 0x14 /* Line status register */ +#define UART_HIGHSPEED 0x24 /* High speed UART */ + +/* FCR */ +#define UART_FCR_FIFO_EN 0x01 /* enable FIFO */ +#define UART_FCR_CLEAR_RCVR 0x02 /* clear the RCVR FIFO */ +#define UART_FCR_CLEAR_XMIT 0x04 /* clear the XMIT FIFO */ + +/* LCR */ +#define UART_LCR_WLS_8 0x03 /* 8 bit character length */ +#define UART_LCR_DLAB 0x80 /* divisor latch access bit */ + +/* MCR */ +#define UART_MCR_DTR 0x01 +#define UART_MCR_RTS 0x02 + +/* LSR */ +#define UART_LSR_DR 0x01 /* Data ready */ +#define UART_LSR_THRE 0x20 /* Xmit holding register empty */ + +#endif /* UART8250_H */ diff --git a/plat/mediatek/drivers/usb/mt8188/mt_usb.c b/plat/mediatek/drivers/usb/mt8188/mt_usb.c new file mode 100644 index 0000000..c9e7a56 --- /dev/null +++ b/plat/mediatek/drivers/usb/mt8188/mt_usb.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch_helpers.h> +#include <common/debug.h> +#include <lib/mtk_init/mtk_init.h> +#include <lpm/mt_lp_api.h> +#include <platform_def.h> + +int mt_usb_init(void) +{ + INFO("[%s] mt_usb initialization\n", __func__); + + /* Keep infra and peri on to support wake-up from USB */ + mtk_usb_update(LPM_USB_ENTER); + + return 0; +} +MTK_PLAT_SETUP_0_INIT(mt_usb_init); diff --git a/plat/mediatek/drivers/usb/rules.mk b/plat/mediatek/drivers/usb/rules.mk new file mode 100644 index 0000000..f8c43f1 --- /dev/null +++ b/plat/mediatek/drivers/usb/rules.mk @@ -0,0 +1,13 @@ +# +# Copyright (c) 2023, MediaTek Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +LOCAL_DIR := $(call GET_LOCAL_DIR) + +MODULE := usb + +LOCAL_SRCS-y := $(LOCAL_DIR)/$(MTK_SOC)/mt_usb.c + +$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL))) |