GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
+231
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <devapc.h>
|
||||
#include <drivers/console.h>
|
||||
#include <lib/mmio.h>
|
||||
|
||||
static void set_master_transaction(uint32_t master_index,
|
||||
enum TRANSACTION transaction_type)
|
||||
{
|
||||
uintptr_t base;
|
||||
uint32_t master_register_index;
|
||||
uint32_t master_set_index;
|
||||
uint32_t set_bit;
|
||||
|
||||
master_register_index = master_index / (MOD_NO_IN_1_DEVAPC * 2);
|
||||
master_set_index = master_index % (MOD_NO_IN_1_DEVAPC * 2);
|
||||
|
||||
base = DEVAPC_INFRA_MAS_SEC_0 + master_register_index * 4;
|
||||
|
||||
set_bit = 0x1 << master_set_index;
|
||||
if (transaction_type == SECURE_TRANSACTION)
|
||||
mmio_setbits_32(base, set_bit);
|
||||
else
|
||||
mmio_clrbits_32(base, set_bit);
|
||||
}
|
||||
|
||||
static void set_master_domain(uint32_t master_index, enum MASK_DOM domain)
|
||||
{
|
||||
uintptr_t base;
|
||||
uint32_t domain_reg;
|
||||
uint32_t domain_index;
|
||||
uint32_t clr_bit;
|
||||
uint32_t set_bit;
|
||||
|
||||
domain_reg = master_index / MASTER_MOD_NO_IN_1_DEVAPC;
|
||||
domain_index = master_index % MASTER_MOD_NO_IN_1_DEVAPC;
|
||||
clr_bit = 0xF << (4 * domain_index);
|
||||
set_bit = domain << (4 * domain_index);
|
||||
|
||||
base = DEVAPC_INFRA_MAS_DOM_0 + domain_reg * 4;
|
||||
mmio_clrsetbits_32(base, clr_bit, set_bit);
|
||||
}
|
||||
|
||||
static void set_master_domain_remap_infra(enum MASK_DOM domain_emi_view,
|
||||
enum MASK_DOM domain_infra_view)
|
||||
{
|
||||
uintptr_t base;
|
||||
uint32_t clr_bit;
|
||||
uint32_t set_bit;
|
||||
|
||||
if (domain_emi_view < DOMAIN_10) {
|
||||
base = DEVAPC_INFRA_DOM_RMP_0;
|
||||
clr_bit = 0x7 << (domain_emi_view * 3);
|
||||
set_bit = domain_infra_view << (domain_emi_view * 3);
|
||||
mmio_clrsetbits_32(base, clr_bit, set_bit);
|
||||
} else if (domain_emi_view > DOMAIN_10) {
|
||||
base = DEVAPC_INFRA_DOM_RMP_1;
|
||||
domain_emi_view = domain_emi_view - DOMAIN_11;
|
||||
clr_bit = 0x7 << (domain_emi_view * 3 + 1);
|
||||
set_bit = domain_infra_view << (domain_emi_view * 3 + 1);
|
||||
mmio_clrsetbits_32(base, clr_bit, set_bit);
|
||||
} else {
|
||||
base = DEVAPC_INFRA_DOM_RMP_0;
|
||||
clr_bit = 0x3 << (domain_emi_view * 3);
|
||||
set_bit = domain_infra_view << (domain_emi_view * 3);
|
||||
mmio_clrsetbits_32(base, clr_bit, set_bit);
|
||||
|
||||
base = DEVAPC_INFRA_DOM_RMP_1;
|
||||
set_bit = (domain_infra_view & 0x4) >> 2;
|
||||
mmio_clrsetbits_32(base, 0x1, set_bit);
|
||||
}
|
||||
}
|
||||
|
||||
static void set_master_domain_remap_mm(enum MASK_DOM domain_emi_view,
|
||||
enum MASK_DOM domain_mm_view)
|
||||
{
|
||||
uintptr_t base;
|
||||
uint32_t clr_bit;
|
||||
uint32_t set_bit;
|
||||
|
||||
base = DEVAPC_MM_DOM_RMP_0;
|
||||
clr_bit = 0x3 << (domain_emi_view * 2);
|
||||
set_bit = domain_mm_view << (domain_emi_view * 2);
|
||||
|
||||
mmio_clrsetbits_32(base, clr_bit, set_bit);
|
||||
}
|
||||
|
||||
static void set_module_apc(enum DAPC_SLAVE_TYPE slave_type, uint32_t module,
|
||||
enum MASK_DOM domain_num,
|
||||
enum APC_ATTR permission_control)
|
||||
{
|
||||
uintptr_t base;
|
||||
uint32_t apc_index;
|
||||
uint32_t apc_set_index;
|
||||
uint32_t clr_bit;
|
||||
uint32_t set_bit;
|
||||
|
||||
apc_index = module / MOD_NO_IN_1_DEVAPC;
|
||||
apc_set_index = module % MOD_NO_IN_1_DEVAPC;
|
||||
clr_bit = 0x3 << (apc_set_index * 2);
|
||||
set_bit = permission_control << (apc_set_index * 2);
|
||||
|
||||
if (slave_type == DAPC_INFRA_SLAVE && module <= SLAVE_INFRA_MAX_INDEX)
|
||||
base = DEVAPC_INFRA_D0_APC_0 + domain_num * 0x100 +
|
||||
apc_index * 4;
|
||||
else if (slave_type == DAPC_MM_SLAVE && module <= SLAVE_MM_MAX_INDEX)
|
||||
base = DEVAPC_MM_D0_APC_0 + domain_num * 0x100 + apc_index * 4;
|
||||
else
|
||||
return;
|
||||
|
||||
mmio_clrsetbits_32(base, clr_bit, set_bit);
|
||||
}
|
||||
|
||||
static void set_default_master_transaction(void)
|
||||
{
|
||||
set_master_transaction(MASTER_SSPM, SECURE_TRANSACTION);
|
||||
}
|
||||
|
||||
static void set_default_master_domain(void)
|
||||
{
|
||||
set_master_domain(MASTER_SCP, DOMAIN_1);
|
||||
set_master_domain_remap_infra(DOMAIN_1, DOMAIN_1);
|
||||
set_master_domain_remap_mm(DOMAIN_1, DOMAIN_1);
|
||||
|
||||
set_master_domain(MASTER_SPM, DOMAIN_2);
|
||||
set_master_domain_remap_infra(DOMAIN_2, DOMAIN_2);
|
||||
set_master_domain_remap_mm(DOMAIN_2, DOMAIN_2);
|
||||
|
||||
set_master_domain(MASTER_SSPM, DOMAIN_2);
|
||||
set_master_domain_remap_infra(DOMAIN_2, DOMAIN_2);
|
||||
set_master_domain_remap_mm(DOMAIN_2, DOMAIN_2);
|
||||
}
|
||||
|
||||
static void set_default_slave_permission(void)
|
||||
{
|
||||
uint32_t module_index;
|
||||
uint32_t infra_size;
|
||||
uint32_t mm_size;
|
||||
|
||||
infra_size = sizeof(D_APC_INFRA_Devices) / sizeof(struct DEVICE_INFO);
|
||||
mm_size = sizeof(D_APC_MM_Devices) / sizeof(struct DEVICE_INFO);
|
||||
|
||||
for (module_index = 0; module_index < infra_size; module_index++) {
|
||||
if (D_APC_INFRA_Devices[module_index].d0_permission > 0) {
|
||||
set_module_apc(DAPC_INFRA_SLAVE, module_index, DOMAIN_0,
|
||||
D_APC_INFRA_Devices[module_index].d0_permission);
|
||||
}
|
||||
if (D_APC_INFRA_Devices[module_index].d1_permission > 0) {
|
||||
set_module_apc(DAPC_INFRA_SLAVE, module_index, DOMAIN_1,
|
||||
D_APC_INFRA_Devices[module_index].d1_permission);
|
||||
}
|
||||
if (D_APC_INFRA_Devices[module_index].d2_permission > 0) {
|
||||
set_module_apc(DAPC_INFRA_SLAVE, module_index, DOMAIN_2,
|
||||
D_APC_INFRA_Devices[module_index].d2_permission);
|
||||
}
|
||||
}
|
||||
|
||||
for (module_index = 0; module_index < mm_size; module_index++) {
|
||||
if (D_APC_MM_Devices[module_index].d0_permission > 0) {
|
||||
set_module_apc(DAPC_MM_SLAVE, module_index, DOMAIN_0,
|
||||
D_APC_MM_Devices[module_index].d0_permission);
|
||||
}
|
||||
if (D_APC_MM_Devices[module_index].d1_permission > 0) {
|
||||
set_module_apc(DAPC_MM_SLAVE, module_index, DOMAIN_1,
|
||||
D_APC_MM_Devices[module_index].d1_permission);
|
||||
}
|
||||
if (D_APC_MM_Devices[module_index].d2_permission > 0) {
|
||||
set_module_apc(DAPC_MM_SLAVE, module_index, DOMAIN_2,
|
||||
D_APC_MM_Devices[module_index].d2_permission);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_devapc(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
INFO("[DEVAPC] dump DEVAPC registers:\n");
|
||||
|
||||
for (i = 0; i < 13; i++) {
|
||||
INFO("[DEVAPC] (INFRA)D0_APC_%d = 0x%x, "
|
||||
"(INFRA)D1_APC_%d = 0x%x, "
|
||||
"(INFRA)D2_APC_%d = 0x%x\n",
|
||||
i, mmio_read_32(DEVAPC_INFRA_D0_APC_0 + i * 4),
|
||||
i, mmio_read_32(DEVAPC_INFRA_D0_APC_0 + 0x100 + i * 4),
|
||||
i, mmio_read_32(DEVAPC_INFRA_D0_APC_0 + 0x200 + i * 4));
|
||||
}
|
||||
|
||||
for (i = 0; i < 9; i++) {
|
||||
INFO("[DEVAPC] (MM)D0_APC_%d = 0x%x, "
|
||||
"(MM)D1_APC_%d = 0x%x, "
|
||||
"(MM)D2_APC_%d = 0x%x\n",
|
||||
i, mmio_read_32(DEVAPC_MM_D0_APC_0 + i * 4),
|
||||
i, mmio_read_32(DEVAPC_MM_D0_APC_0 + 0x100 + i * 4),
|
||||
i, mmio_read_32(DEVAPC_MM_D0_APC_0 + 0x200 + i * 4));
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
INFO("[DEVAPC] MAS_DOM_%d = 0x%x\n", i,
|
||||
mmio_read_32(DEVAPC_INFRA_MAS_DOM_0 + i * 4));
|
||||
}
|
||||
|
||||
INFO("[DEVAPC] MAS_SEC_0 = 0x%x\n",
|
||||
mmio_read_32(DEVAPC_INFRA_MAS_SEC_0));
|
||||
|
||||
INFO("[DEVAPC] (INFRA)MAS_DOMAIN_REMAP_0 = 0x%x, "
|
||||
"(INFRA)MAS_DOMAIN_REMAP_1 = 0x%x\n",
|
||||
mmio_read_32(DEVAPC_INFRA_DOM_RMP_0),
|
||||
mmio_read_32(DEVAPC_INFRA_DOM_RMP_1));
|
||||
|
||||
INFO("[DEVAPC] (MM)MAS_DOMAIN_REMAP_0 = 0x%x\n",
|
||||
mmio_read_32(DEVAPC_MM_DOM_RMP_0));
|
||||
}
|
||||
|
||||
void devapc_init(void)
|
||||
{
|
||||
mmio_write_32(DEVAPC_INFRA_APC_CON, 0x80000001);
|
||||
mmio_write_32(DEVAPC_MM_APC_CON, 0x80000001);
|
||||
mmio_write_32(DEVAPC_MD_APC_CON, 0x80000001);
|
||||
|
||||
set_default_master_transaction();
|
||||
set_default_master_domain();
|
||||
set_default_slave_permission();
|
||||
dump_devapc();
|
||||
}
|
||||
|
||||
+499
@@ -0,0 +1,499 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef DEVAPC_H
|
||||
#define DEVAPC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define DEVAPC_AO_INFRA_BASE 0x1000E000
|
||||
#define DEVAPC_AO_MM_BASE 0x1001C000
|
||||
#define DEVAPC_AO_MD_BASE 0x10019000
|
||||
|
||||
#define DEVAPC_INFRA_D0_APC_0 (DEVAPC_AO_INFRA_BASE + 0x0000)
|
||||
#define DEVAPC_INFRA_MAS_DOM_0 (DEVAPC_AO_INFRA_BASE + 0x0A00)
|
||||
#define DEVAPC_INFRA_MAS_SEC_0 (DEVAPC_AO_INFRA_BASE + 0x0B00)
|
||||
#define DEVAPC_INFRA_DOM_RMP_0 (DEVAPC_AO_INFRA_BASE + 0x0D00)
|
||||
#define DEVAPC_INFRA_DOM_RMP_1 (DEVAPC_AO_INFRA_BASE + 0x0D04)
|
||||
#define DEVAPC_INFRA_APC_CON (DEVAPC_AO_INFRA_BASE + 0x0F00)
|
||||
|
||||
#define DEVAPC_MD_APC_CON (DEVAPC_AO_MD_BASE + 0x0F00)
|
||||
|
||||
#define DEVAPC_MM_D0_APC_0 (DEVAPC_AO_MM_BASE + 0x0000)
|
||||
#define DEVAPC_MM_DOM_RMP_0 (DEVAPC_AO_MM_BASE + 0x0D00)
|
||||
#define DEVAPC_MM_APC_CON (DEVAPC_AO_MM_BASE + 0x0F00)
|
||||
|
||||
#define MOD_NO_IN_1_DEVAPC 16
|
||||
#define MASTER_MOD_NO_IN_1_DEVAPC 8
|
||||
#define SLAVE_INFRA_MAX_INDEX 195
|
||||
#define SLAVE_MM_MAX_INDEX 140
|
||||
|
||||
enum {
|
||||
MASTER_SCP = 0,
|
||||
MASTER_SPM = 10,
|
||||
MASTER_SSPM = 27
|
||||
};
|
||||
|
||||
enum MASK_DOM {
|
||||
DOMAIN_0 = 0,
|
||||
DOMAIN_1,
|
||||
DOMAIN_2,
|
||||
DOMAIN_3,
|
||||
DOMAIN_4,
|
||||
DOMAIN_5,
|
||||
DOMAIN_6,
|
||||
DOMAIN_7,
|
||||
DOMAIN_8,
|
||||
DOMAIN_9,
|
||||
DOMAIN_10,
|
||||
DOMAIN_11
|
||||
};
|
||||
|
||||
enum TRANSACTION {
|
||||
NON_SECURE_TRANSACTION = 0,
|
||||
SECURE_TRANSACTION
|
||||
};
|
||||
|
||||
enum DAPC_SLAVE_TYPE {
|
||||
DAPC_INFRA_SLAVE = 0,
|
||||
DAPC_MM_SLAVE
|
||||
};
|
||||
|
||||
enum APC_ATTR {
|
||||
NO_SEC = 0,
|
||||
S_RW_ONLY,
|
||||
S_RW_NS_R,
|
||||
FORBID,
|
||||
};
|
||||
|
||||
struct DEVICE_INFO {
|
||||
uint8_t d0_permission;
|
||||
uint8_t d1_permission;
|
||||
uint8_t d2_permission;
|
||||
};
|
||||
|
||||
#define PERMISSION(DEV_NAME, ATTR1, ATTR2, ATTR3) \
|
||||
{(uint8_t)ATTR1, (uint8_t)ATTR2, (uint8_t)ATTR3}
|
||||
|
||||
static const struct DEVICE_INFO D_APC_INFRA_Devices[] = {
|
||||
/* module, domain0, domain1, domain2 */
|
||||
|
||||
/* 0 */
|
||||
PERMISSION("INFRA_AO_TOPCKGEN", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("INFRA_AO_INFRASYS_CONFIG_REGS", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("IO_CFG", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_PERICFG", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_EFUSE_AO_DEBUG", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_GPIO", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_SLEEP_CONTROLLER", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_TOPRGU", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_APXGPT", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_RESERVE", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 10 */
|
||||
PERMISSION("INFRA_AO_SEJ", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_AP_CIRQ_EINT", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_APMIXEDSYS", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("INFRA_AO_PMIC_WRAP", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_DEVICE_APC_AO_INFRA_PERI", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_SLEEP_CONTROLLER_MD", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_KEYPAD", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_TOP_MISC", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_DVFS_CTRL_PROC", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_MBIST_AO_REG", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 20 */
|
||||
PERMISSION("INFRA_AO_CLDMA_AO_AP", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_DEVICE_MPU", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_AES_TOP_0", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_SYS_TIMER", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_MDEM_TEMP_SHARE", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_DEVICE_APC_AO_MD", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_SECURITY_AO", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_TOPCKGEN_REG", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_DEVICE_APC_AO_MM", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_RESERVE", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 30 */
|
||||
PERMISSION("INFRASYS_RESERVE", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_RESERVE", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_RESERVE", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_SYS_CIRQ", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_MM_IOMMU", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_EFUSE_PDN_DEBUG", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_DEVICE_APC", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_DBG_TRACKER", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_CCIF0_AP", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_CCIF0_MD", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 40 */
|
||||
PERMISSION("INFRASYS_CCIF1_AP", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_CCIF1_MD", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_MBIST", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_INFRA_PDN_REGISTER", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_TRNG", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_DX_CC", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("MD_CCIF_MD1", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_CQ_DMA", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("MD_CCIF_MD2", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_SRAMROM", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 50 */
|
||||
PERMISSION("ANA_MIPI_DSI0", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_RESERVE", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("ANA_MIPI_CSI0", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("ANA_MIPI_CSI1", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_EMI", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_RESERVE", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_CLDMA_PDN", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CLDMA_PDN_MD_MISC", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_MD", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("BPI_BSI_SLV0", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 60 */
|
||||
PERMISSION("BPI_BSI_SLV1", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("BPI_BSI_SLV2", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_EMI_MPU", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_DVFS_PROC", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_DRAMC_CH0_TOP0", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_DRAMC_CH0_TOP1", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_DRAMC_CH0_TOP2", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_DRAMC_CH0_TOP3", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_DRAMC_CH0_TOP4", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_DRAMC_CH1_TOP0", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 70 */
|
||||
PERMISSION("INFRASYS_DRAMC_CH1_TOP1", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_DRAMC_CH1_TOP2", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_DRAMC_CH1_TOP3", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_DRAMC_CH1_TOP4", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_GCE", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_CCIF2_AP", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_CCIF2_MD", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_CCIF3_AP", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_CCIF3_MD", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_PWRMCU Partition 1", S_RW_NS_R, FORBID, NO_SEC),
|
||||
|
||||
/* 80 */
|
||||
PERMISSION("INFRA_AO_PWRMCU Partition 2", S_RW_NS_R, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_PWRMCU Partition 3", S_RW_NS_R, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_PWRMCU Partition 4", S_RW_NS_R, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_PWRMCU Partition 5", S_RW_NS_R, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_PWRMCU Partition 6", S_RW_NS_R, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_PWRMCU Partition 7", S_RW_NS_R, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_PWRMCU Partition 8", S_RW_NS_R, FORBID, NO_SEC),
|
||||
PERMISSION("INFRA_AO_SCP", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("INFRA_AO_MCUCFG", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("INFRASYS_DBUGSYS", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 90 */
|
||||
PERMISSION("PERISYS_APDMA", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_AUXADC", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_UART0", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("PERISYS_UART1", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_UART2", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_I2C6", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_PWM", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_I2C0", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_I2C1", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_I2C2", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 100 */
|
||||
PERMISSION("PERISYS_SPI0", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_PTP", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_BTIF", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("RESERVE", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_DISP_PWM", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_I2C3", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_SPI1", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_I2C4", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_SPI2", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_SPI3", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 110 */
|
||||
PERMISSION("PERISYS_I2C1_IMM", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_I2C2_IMM", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_I2C5", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_I2C5_IMM", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_SPI4", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_SPI5", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_I2C7", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_I2C8", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_USB", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_USB_2_0_SUB", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 120 */
|
||||
PERMISSION("PERISYS_AUDIO", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_MSDC0", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_MSDC1", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_MSDC2", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("RESERVE", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_UFS", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("RESERVE", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("RESERVE", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_RESERVE", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("EAST_RESERVE_0", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 130 */
|
||||
PERMISSION("EAST_RESERVE_1", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("EAST_RESERVE_2", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("EAST_RESERVE_3", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("EAST_RESERVE_4", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("EAST_IO_CFG_RT", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("EAST_RESERVE_6", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("EAST_RESERVE_7", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("EAST_CSI0_TOP_AO", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("RESERVE", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("EAST_RESERVE_A", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 140 */
|
||||
PERMISSION("EAST_RESERVE_B", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("EAST_RESERVE_C", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("EAST_RESERVE_D", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("EAST_RESERVE_E", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("EAST_RESERVE_F", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("SOUTH_RESERVE_0", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("SOUTH_RESERVE_1", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("SOUTH_IO_CFG_RM", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("SOUTH_IO_CFG_RB", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("SOUTH_EFUSE", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 150 */
|
||||
PERMISSION("SOUTH_RESERVE_5", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("SOUTH_RESERVE_6", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("SOUTH_RESERVE_7", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("SOUTH_RESERVE_8", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("SOUTH_RESERVE_9", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("SOUTH_RESERVE_A", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("SOUTH_RESERVE_B", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("SOUTH_RESERVE_C", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("SOUTH_RESERVE_D", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("SOUTH_RESERVE_E", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 160 */
|
||||
PERMISSION("SOUTH_RESERVE_F", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("WEST_RESERVE_0", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("WEST_MSDC1_PAD_MACRO", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("WEST_RESERVE_2", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("WEST_RESERVE_3", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("WEST_RESERVE_4", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("WEST_MIPI_TX_CONFIG", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("WEST_RESERVE_6", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("WEST_IO_CFG_LB", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("WEST_IO_CFG_LM", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 170 */
|
||||
PERMISSION("WEST_IO_CFG_BL", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("WEST_RESERVE_A", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("WEST_RESERVE_B", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("WEST_RESERVE_C", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("WEST_RESERVE_D", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("WEST_RESERVE_E", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("WEST_RESERVE_F", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("NORTH_RESERVE_0", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("EFUSE_TOP", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("NORTH_IO_CFG_LT", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 180 */
|
||||
PERMISSION("NORTH_IO_CFG_TL", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("NORTH_USB20 PHY", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("NORTH_MSDC0 PAD MACRO", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("NORTH_RESERVE_6", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("NORTH_RESERVE_7", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("NORTH_RESERVE_8", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("NORTH_RESERVE_9", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("NORTH_UFS_MPHY", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("NORTH_RESERVE_B", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("NORTH_RESERVE_C", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 190 */
|
||||
PERMISSION("NORTH_RESERVE_D", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("NORTH_RESERVE_E", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("NORTH_RESERVE_F", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_CONN", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_MD_VIOLATION", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("PERISYS_RESERVE", NO_SEC, FORBID, NO_SEC)
|
||||
};
|
||||
|
||||
static const struct DEVICE_INFO D_APC_MM_Devices[] = {
|
||||
/* module, domain0, domain1, domain2 */
|
||||
|
||||
/* 0 */
|
||||
PERMISSION("G3D_CONFIG", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("MFG VAD", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("SC0 VAD", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("MFG_OTHERS", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("MMSYS_CONFIG", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("MDP_RDMA0", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("MDP_RDMA1", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("MDP_RSZ0", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("MDP_RSZ1", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("MDP_WROT0", NO_SEC, NO_SEC, NO_SEC),
|
||||
|
||||
/* 10 */
|
||||
PERMISSION("MDP_WDMA", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("MDP_TDSHP", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("DISP_OVL0", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("DISP_OVL0_2L", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("DISP_OVL1_2L", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("DISP_RDMA0", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("DISP_RDMA1", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("DISP_WDMA0", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("DISP_COLOR0", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("DISP_CCORR0", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 20 */
|
||||
PERMISSION("DISP_AAL0", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("DISP_GAMMA0", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("DISP_DITHER0", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("DSI_SPLIT", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("DSI0", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("DPI", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("MM_MUTEX", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("SMI_LARB0", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("SMI_LARB1", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("SMI_COMMON", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 30 */
|
||||
PERMISSION("DISP_RSZ", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("MDP_AAL", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("MDP_CCORR", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("DBI", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("MMSYS_OTHERS", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("IMGSYS_CONFIG", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("IMGSYS_SMI_LARB1", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("IMGSYS_DISP_A0", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("IMGSYS_DISP_A1", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("IMGSYS_DISP_A2", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 40 */
|
||||
PERMISSION("IMGSYS_DISP_A3", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("IMGSYS_DISP_A4", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("IMGSYS_DISP_A5", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("IMGSYS_DPE", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("IMGSYS_RSC", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("IMGSYS_WPEA", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("IMGSYS_FDVT", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("IMGSYS_OWE", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("IMGSYS_WPEB", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("IMGSYS_MFB", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 50 */
|
||||
PERMISSION("IMGSYS_SMI_LARB2", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("IMGSYS_OTHERS", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("VENCSYS_GLOBAL_CON", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("VENCSYSSYS_SMI_LARB4", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("VENCSYS_VENC", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("VENCSYS_JPGENC", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("VENCSYS_MBIST_CTRL", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("VENCSYS_OTHERS", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("VDECSYS_GLOBAL_CON", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("VDECSYS_SMI_LARB1", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 60 */
|
||||
PERMISSION("VDECSYS_FULL_TOP", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("VDECSYS_OTHERS", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAMSYS_TOP", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_LARB6", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("CAMSYS_LARB3", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_TOP", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_A", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_A", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_B", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_B", NO_SEC, NO_SEC, NO_SEC),
|
||||
|
||||
/* 70 */
|
||||
PERMISSION("CAMSYS_CAM_C", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_C", NO_SEC, NO_SEC, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_TOP_SET", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_A_SET", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_A_SET", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_B_SET", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_B_SET", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_C_SET", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_C_SET", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_TOP_INNER", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 80 */
|
||||
PERMISSION("CAMSYS_CAM_A_INNER", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_A_INNER", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_B_INNER", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_B_INNER", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_C_INNER", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_C_INNER", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_A_EXT", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_B_EXT", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_C_EXT", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_TOP_CLR", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 90 */
|
||||
PERMISSION("CAMSYS_CAM_A_CLR", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_A_CLR", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_B_CLR", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_B_CLR", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_C_CLR", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_C_CLR", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_A_EXT", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_B_EXT", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_C_EXT", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAM_RESERVE", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 100 */
|
||||
PERMISSION("CAMSYS_SENINF_A", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_SENINF_B", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_SENINF_C", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_SENINF_D", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_SENINF_E", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_SENINF_F", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_SENINF_G", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_SENINF_H", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAMSV_A", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAMSV_B", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 110 */
|
||||
PERMISSION("CAMSYS_CAMSV_C", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CAMSV_D", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_MD32 DMEM_12", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_RESEVE", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CCU_CTL", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CCU_H2T_A", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CCU_T2H_A", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_RESERVE", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_RESERVE", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_CCU_DMA", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 120 */
|
||||
PERMISSION("CAMSYS_TSF", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_MD32_PMEM_24", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("CAMSYS_OTHERS", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("VPUSYS_CFG", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("VPUSYS_ADL_CTRL", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("VPUSYS_COREA_DMEM_0_128KB", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("VPUSYS_COREA_DMEM_128_256KB", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("VPUSYS_COREA_IMEM_256KB", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("VPUSYS_COREA_CONTROL", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("VPUSYS_COREA_DEBUG", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 130 */
|
||||
PERMISSION("VPUSYS_COREB_DMEM_0_128KB", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("VPUSYS_COREB_DMEM_128_256KB", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("VPUSYS_COREB_IMEM_256KB", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("VPUSYS_COREB_CONTROL", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("VPUSYS_COREB_DEBUG", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("VPUSYS_COREC_DMEM_0_128KB", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("VPUSYS_COREC_DMEM_128_256KB", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("VPUSYS_COREC_IMEM_256KB", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("VPUSYS_COREC_CONTROL", NO_SEC, FORBID, NO_SEC),
|
||||
PERMISSION("VPUSYS_COREC_DEBUG", NO_SEC, FORBID, NO_SEC),
|
||||
|
||||
/* 140 */
|
||||
PERMISSION("VPUSYS_OTHERS", NO_SEC, FORBID, NO_SEC)
|
||||
};
|
||||
|
||||
void devapc_init(void);
|
||||
|
||||
#endif /* DEVAPC_H */
|
||||
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <emi_mpu.h>
|
||||
|
||||
int is_4GB(void)
|
||||
{
|
||||
return 0; /* 8183 doesn't use 4GB */
|
||||
}
|
||||
|
||||
/*
|
||||
* emi_mpu_set_region_protection: protect a region.
|
||||
* @start: start address of the region
|
||||
* @end: end address of the region
|
||||
* @region: EMI MPU region id
|
||||
* @access_permission: EMI MPU access permission
|
||||
* Return 0 for success, otherwise negative status code.
|
||||
*/
|
||||
int emi_mpu_set_region_protection(
|
||||
unsigned long start, unsigned long end,
|
||||
int region,
|
||||
unsigned int access_permission)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (end <= start) {
|
||||
ERROR("[EMI][MTEE][MPU] Invalid address!.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (is_4GB()) {
|
||||
/* 4GB mode: emi_addr = phy_addr & 0xffff */
|
||||
start = EMI_PHY_OFFSET & 0xffff;
|
||||
end = EMI_PHY_OFFSET & 0xffff;
|
||||
} else {
|
||||
/* non-4GB mode: emi_addr = phy_addr - MEM_OFFSET */
|
||||
start = start - EMI_PHY_OFFSET;
|
||||
end = end - EMI_PHY_OFFSET;
|
||||
}
|
||||
|
||||
/*Address 64KB alignment*/
|
||||
start = start >> 16;
|
||||
end = end >> 16;
|
||||
|
||||
switch (region) {
|
||||
case 0:
|
||||
mmio_write_32(EMI_MPU_APC0, 0);
|
||||
mmio_write_32(EMI_MPU_SA0, start);
|
||||
mmio_write_32(EMI_MPU_EA0, end);
|
||||
mmio_write_32(EMI_MPU_APC0, access_permission);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
mmio_write_32(EMI_MPU_APC1, 0);
|
||||
mmio_write_32(EMI_MPU_SA1, start);
|
||||
mmio_write_32(EMI_MPU_EA1, end);
|
||||
mmio_write_32(EMI_MPU_APC1, access_permission);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
mmio_write_32(EMI_MPU_APC2, 0);
|
||||
mmio_write_32(EMI_MPU_SA2, start);
|
||||
mmio_write_32(EMI_MPU_EA2, end);
|
||||
mmio_write_32(EMI_MPU_APC2, access_permission);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
mmio_write_32(EMI_MPU_APC3, 0);
|
||||
mmio_write_32(EMI_MPU_SA3, start);
|
||||
mmio_write_32(EMI_MPU_EA3, end);
|
||||
mmio_write_32(EMI_MPU_APC3, access_permission);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
mmio_write_32(EMI_MPU_APC4, 0);
|
||||
mmio_write_32(EMI_MPU_SA4, start);
|
||||
mmio_write_32(EMI_MPU_EA4, end);
|
||||
mmio_write_32(EMI_MPU_APC4, access_permission);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
mmio_write_32(EMI_MPU_APC5, 0);
|
||||
mmio_write_32(EMI_MPU_SA5, start);
|
||||
mmio_write_32(EMI_MPU_EA5, end);
|
||||
mmio_write_32(EMI_MPU_APC5, access_permission);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
mmio_write_32(EMI_MPU_APC6, 0);
|
||||
mmio_write_32(EMI_MPU_SA6, start);
|
||||
mmio_write_32(EMI_MPU_EA6, end);
|
||||
mmio_write_32(EMI_MPU_APC6, access_permission);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
mmio_write_32(EMI_MPU_APC7, 0);
|
||||
mmio_write_32(EMI_MPU_SA7, start);
|
||||
mmio_write_32(EMI_MPU_EA7, end);
|
||||
mmio_write_32(EMI_MPU_APC7, access_permission);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void dump_emi_mpu_regions(void)
|
||||
{
|
||||
unsigned int apc, sa, ea;
|
||||
unsigned int apc_addr = EMI_MPU_APC0;
|
||||
unsigned int sa_addr = EMI_MPU_SA0;
|
||||
unsigned int ea_addr = EMI_MPU_EA0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
apc = mmio_read_32(apc_addr + i * 4);
|
||||
sa = mmio_read_32(sa_addr + i * 4);
|
||||
ea = mmio_read_32(ea_addr + i * 4);
|
||||
WARN("region %d:\n", i);
|
||||
WARN("\tapc:0x%x, sa:0x%x, ea:0x%x\n", apc, sa, ea);
|
||||
}
|
||||
}
|
||||
|
||||
void emi_mpu_init(void)
|
||||
{
|
||||
/* Set permission */
|
||||
emi_mpu_set_region_protection(0x40000000UL, 0x4FFFFFFFUL, 0,
|
||||
(FORBIDDEN << 3 | FORBIDDEN << 6));
|
||||
emi_mpu_set_region_protection(0x50000000UL, 0x528FFFFFUL, 1,
|
||||
(FORBIDDEN << 6));
|
||||
emi_mpu_set_region_protection(0x52900000UL, 0x5FFFFFFFUL, 2,
|
||||
(FORBIDDEN << 3 | FORBIDDEN << 6));
|
||||
emi_mpu_set_region_protection(0x60000000UL, 0xFFFFFFFFUL, 3,
|
||||
(FORBIDDEN << 3 | FORBIDDEN << 6));
|
||||
emi_mpu_set_region_protection(0x100000000UL, 0x23FFFFFFFUL, 4,
|
||||
(FORBIDDEN << 3 | FORBIDDEN << 6));
|
||||
dump_emi_mpu_regions();
|
||||
}
|
||||
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef __EMI_MPU_H
|
||||
#define __EMI_MPU_H
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#define EMI_MPUP (EMI_BASE + 0x01D8)
|
||||
#define EMI_MPUQ (EMI_BASE + 0x01E0)
|
||||
#define EMI_MPUR (EMI_BASE + 0x01E8)
|
||||
#define EMI_MPUS (EMI_BASE + 0x01F0)
|
||||
#define EMI_MPUT (EMI_BASE + 0x01F8)
|
||||
#define EMI_MPUY (EMI_BASE + 0x0220)
|
||||
#define EMI_MPU_CTRL (EMI_MPU_BASE + 0x0000)
|
||||
#define EMI_MPUD0_ST (EMI_BASE + 0x0160)
|
||||
#define EMI_MPUD1_ST (EMI_BASE + 0x0164)
|
||||
#define EMI_MPUD2_ST (EMI_BASE + 0x0168)
|
||||
#define EMI_MPUD3_ST (EMI_BASE + 0x016C)
|
||||
#define EMI_MPUD0_ST2 (EMI_BASE + 0x0200)
|
||||
#define EMI_MPUD1_ST2 (EMI_BASE + 0x0204)
|
||||
#define EMI_MPUD2_ST2 (EMI_BASE + 0x0208)
|
||||
#define EMI_MPUD3_ST2 (EMI_BASE + 0x020C)
|
||||
|
||||
#define EMI_PHY_OFFSET (0x40000000UL)
|
||||
#define EIGHT_DOMAIN
|
||||
|
||||
#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 SECURE_OS_MPU_REGION_ID (0)
|
||||
#define ATF_MPU_REGION_ID (1)
|
||||
|
||||
#ifdef EIGHT_DOMAIN
|
||||
#define SET_ACCESS_PERMISSON(d7, d6, d5, d4, d3, d2, d1, d0) \
|
||||
(((d7) << 21) | ((d6) << 18) | ((d5) << 15) | ((d4) << 12) \
|
||||
| ((d3) << 9) | ((d2) << 6) | ((d1) << 3) | (d0))
|
||||
#else
|
||||
#define SET_ACCESS_PERMISSON(d3, d2, d1, d0) \
|
||||
(((d3) << 9) | ((d2) << 6) | ((d1) << 3) | (d0))
|
||||
#endif
|
||||
|
||||
//#define EMI_MPU_BASE (0x1020E000U)
|
||||
|
||||
#define EMI_MPU_SA0 (EMI_MPU_BASE + 0x100)
|
||||
#define EMI_MPU_SA1 (EMI_MPU_BASE + 0x104)
|
||||
#define EMI_MPU_SA2 (EMI_MPU_BASE + 0x108)
|
||||
#define EMI_MPU_SA3 (EMI_MPU_BASE + 0x10C)
|
||||
#define EMI_MPU_SA4 (EMI_MPU_BASE + 0x110)
|
||||
#define EMI_MPU_SA5 (EMI_MPU_BASE + 0x114)
|
||||
#define EMI_MPU_SA6 (EMI_MPU_BASE + 0x118)
|
||||
#define EMI_MPU_SA7 (EMI_MPU_BASE + 0x11C)
|
||||
|
||||
#define EMI_MPU_EA0 (EMI_MPU_BASE + 0x200)
|
||||
#define EMI_MPU_EA1 (EMI_MPU_BASE + 0x204)
|
||||
#define EMI_MPU_EA2 (EMI_MPU_BASE + 0x208)
|
||||
#define EMI_MPU_EA3 (EMI_MPU_BASE + 0x20C)
|
||||
#define EMI_MPU_EA4 (EMI_MPU_BASE + 0x210)
|
||||
#define EMI_MPU_EA5 (EMI_MPU_BASE + 0x214)
|
||||
#define EMI_MPU_EA6 (EMI_MPU_BASE + 0x218)
|
||||
#define EMI_MPU_EA7 (EMI_MPU_BASE + 0x21C)
|
||||
|
||||
#define EMI_MPU_APC0 (EMI_MPU_BASE + 0x300)
|
||||
#define EMI_MPU_APC1 (EMI_MPU_BASE + 0x304)
|
||||
#define EMI_MPU_APC2 (EMI_MPU_BASE + 0x308)
|
||||
#define EMI_MPU_APC3 (EMI_MPU_BASE + 0x30C)
|
||||
#define EMI_MPU_APC4 (EMI_MPU_BASE + 0x310)
|
||||
#define EMI_MPU_APC5 (EMI_MPU_BASE + 0x314)
|
||||
#define EMI_MPU_APC6 (EMI_MPU_BASE + 0x318)
|
||||
#define EMI_MPU_APC7 (EMI_MPU_BASE + 0x31C)
|
||||
|
||||
#define EMI_MPU_CTRL_D0 (EMI_MPU_BASE + 0x800)
|
||||
#define EMI_MPU_CTRL_D1 (EMI_MPU_BASE + 0x804)
|
||||
#define EMI_MPU_CTRL_D2 (EMI_MPU_BASE + 0x808)
|
||||
#define EMI_MPU_CTRL_D3 (EMI_MPU_BASE + 0x80C)
|
||||
#define EMI_MPU_CTRL_D4 (EMI_MPU_BASE + 0x810)
|
||||
#define EMI_MPU_CTRL_D5 (EMI_MPU_BASE + 0x814)
|
||||
#define EMI_MPU_CTRL_D6 (EMI_MPU_BASE + 0x818)
|
||||
#define EMI_MPU_CTRL_D7 (EMI_MPU_BASE + 0x81C)
|
||||
|
||||
#define EMI_MPU_MASK_D0 (EMI_MPU_BASE + 0x900)
|
||||
#define EMI_MPU_MASK_D1 (EMI_MPU_BASE + 0x904)
|
||||
#define EMI_MPU_MASK_D2 (EMI_MPU_BASE + 0x908)
|
||||
#define EMI_MPU_MASK_D3 (EMI_MPU_BASE + 0x90C)
|
||||
#define EMI_MPU_MASK_D4 (EMI_MPU_BASE + 0x910)
|
||||
#define EMI_MPU_MASK_D5 (EMI_MPU_BASE + 0x914)
|
||||
#define EMI_MPU_MASK_D6 (EMI_MPU_BASE + 0x918)
|
||||
#define EMI_MPU_MASK_D7 (EMI_MPU_BASE + 0x91C)
|
||||
|
||||
int emi_mpu_set_region_protection(
|
||||
unsigned long start, unsigned long end,
|
||||
int region,
|
||||
unsigned int access_permission);
|
||||
|
||||
void dump_emi_mpu_regions(void);
|
||||
void emi_mpu_init(void);
|
||||
|
||||
#endif /* __EMI_MPU_H */
|
||||
+439
@@ -0,0 +1,439 @@
|
||||
/*
|
||||
* Copyright (c) 2019, MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <common/debug.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <gpio/mtgpio.h>
|
||||
#include <gpio/mtgpio_cfg.h>
|
||||
#include <drivers/gpio.h>
|
||||
#include <mcucfg.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <platform_def.h>
|
||||
#include <spm.h>
|
||||
#include <stdbool.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
|
||||
#define PULLEN_ADDR_OFFSET 0x060
|
||||
#define PULLSEL_ADDR_OFFSET 0x080
|
||||
|
||||
void mt_set_gpio_dir_chip(uint32_t pin, int dir)
|
||||
{
|
||||
uint32_t pos, bit;
|
||||
|
||||
assert(pin < MAX_GPIO_PIN);
|
||||
assert(dir < GPIO_DIR_MAX);
|
||||
|
||||
pos = pin / MAX_GPIO_REG_BITS;
|
||||
bit = pin % MAX_GPIO_REG_BITS;
|
||||
|
||||
if (dir == GPIO_DIR_IN)
|
||||
mmio_write_32(DIR_BASE + 0x10 * pos + CLR, 1U << bit);
|
||||
else
|
||||
mmio_write_32(DIR_BASE + 0x10 * pos + SET, 1U << bit);
|
||||
}
|
||||
|
||||
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 + 0x10 * pos);
|
||||
return (((reg & (1U << bit)) != 0) ? GPIO_DIR_OUT : GPIO_DIR_IN);
|
||||
}
|
||||
|
||||
void mt_set_gpio_out_chip(uint32_t pin, int output)
|
||||
{
|
||||
uint32_t pos, bit;
|
||||
|
||||
assert(pin < MAX_GPIO_PIN);
|
||||
assert(output < GPIO_OUT_MAX);
|
||||
|
||||
pos = pin / MAX_GPIO_REG_BITS;
|
||||
bit = pin % MAX_GPIO_REG_BITS;
|
||||
|
||||
if (output == GPIO_OUT_ZERO)
|
||||
mmio_write_32(DOUT_BASE + 0x10 * pos + CLR, 1U << bit);
|
||||
else
|
||||
mmio_write_32(DOUT_BASE + 0x10 * pos + SET, 1U << bit);
|
||||
}
|
||||
|
||||
int mt_get_gpio_out_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(DOUT_BASE + 0x10 * pos);
|
||||
return (((reg & (1U << bit)) != 0) ? 1 : 0);
|
||||
}
|
||||
|
||||
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 + 0x10 * pos);
|
||||
return (((reg & (1U << bit)) != 0) ? 1 : 0);
|
||||
}
|
||||
|
||||
void mt_set_gpio_mode_chip(uint32_t pin, int mode)
|
||||
{
|
||||
uint32_t pos, bit;
|
||||
uint32_t data;
|
||||
uint32_t mask;
|
||||
|
||||
assert(pin < MAX_GPIO_PIN);
|
||||
assert(mode < GPIO_MODE_MAX);
|
||||
|
||||
mask = (1U << GPIO_MODE_BITS) - 1;
|
||||
|
||||
mode = mode & mask;
|
||||
pos = pin / MAX_GPIO_MODE_PER_REG;
|
||||
bit = (pin % MAX_GPIO_MODE_PER_REG) * GPIO_MODE_BITS;
|
||||
|
||||
data = mmio_read_32(MODE_BASE + 0x10 * pos);
|
||||
data &= (~(mask << bit));
|
||||
data |= (mode << bit);
|
||||
mmio_write_32(MODE_BASE + 0x10 * pos, data);
|
||||
}
|
||||
|
||||
int mt_get_gpio_mode_chip(uint32_t pin)
|
||||
{
|
||||
uint32_t pos, bit;
|
||||
uint32_t data;
|
||||
uint32_t mask;
|
||||
|
||||
assert(pin < MAX_GPIO_PIN);
|
||||
|
||||
mask = (1U << GPIO_MODE_BITS) - 1;
|
||||
|
||||
pos = pin / MAX_GPIO_MODE_PER_REG;
|
||||
bit = (pin % MAX_GPIO_MODE_PER_REG) * GPIO_MODE_BITS;
|
||||
|
||||
data = mmio_read_32(MODE_BASE + 0x10 * pos);
|
||||
return (data >> bit) & mask;
|
||||
}
|
||||
|
||||
int32_t gpio_get_pull_iocfg(uint32_t pin)
|
||||
{
|
||||
switch (pin) {
|
||||
case 0 ... 10:
|
||||
return IOCFG_5_BASE;
|
||||
case 11 ... 12:
|
||||
return IOCFG_0_BASE;
|
||||
case 13 ... 28:
|
||||
return IOCFG_1_BASE;
|
||||
case 43 ... 49:
|
||||
return IOCFG_2_BASE;
|
||||
case 50 ... 60:
|
||||
return IOCFG_3_BASE;
|
||||
case 61 ... 88:
|
||||
return IOCFG_4_BASE;
|
||||
case 89 ... 90:
|
||||
return IOCFG_5_BASE;
|
||||
case 95 ... 106:
|
||||
return IOCFG_5_BASE;
|
||||
case 107 ... 121:
|
||||
return IOCFG_6_BASE;
|
||||
case 134 ... 160:
|
||||
return IOCFG_0_BASE;
|
||||
case 161 ... 166:
|
||||
return IOCFG_1_BASE;
|
||||
case 167 ... 176:
|
||||
return IOCFG_3_BASE;
|
||||
case 177 ... 179:
|
||||
return IOCFG_5_BASE;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t gpio_get_pupd_iocfg(uint32_t pin)
|
||||
{
|
||||
const int32_t offset = 0x0c0;
|
||||
|
||||
switch (pin) {
|
||||
case 29 ... 34:
|
||||
return IOCFG_1_BASE + offset;
|
||||
case 35 ... 42:
|
||||
return IOCFG_2_BASE + offset;
|
||||
case 91 ... 94:
|
||||
return IOCFG_5_BASE + offset;
|
||||
case 122 ... 133:
|
||||
return IOCFG_7_BASE + offset;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int gpio_get_pupd_offset(uint32_t pin)
|
||||
{
|
||||
switch (pin) {
|
||||
case 29 ... 34:
|
||||
return (pin - 29) * 4 % 32;
|
||||
case 35 ... 42:
|
||||
return (pin - 35) * 4 % 32;
|
||||
case 91 ... 94:
|
||||
return (pin - 91) * 4 % 32;
|
||||
case 122 ... 129:
|
||||
return (pin - 122) * 4 % 32;
|
||||
case 130 ... 133:
|
||||
return (pin - 130) * 4 % 32;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void mt_set_gpio_pull_enable_chip(uint32_t pin, int en)
|
||||
{
|
||||
int pullen_addr = gpio_get_pull_iocfg(pin) + PULLEN_ADDR_OFFSET;
|
||||
int pupd_addr = gpio_get_pupd_iocfg(pin);
|
||||
int pupd_offset = gpio_get_pupd_offset(pin);
|
||||
|
||||
assert(pin < MAX_GPIO_PIN);
|
||||
|
||||
assert(!((PULL_offset[pin].offset == (int8_t)-1) &&
|
||||
(pupd_offset == (int8_t)-1)));
|
||||
|
||||
if (en == GPIO_PULL_DISABLE) {
|
||||
if (PULL_offset[pin].offset == (int8_t)-1)
|
||||
mmio_clrbits_32(pupd_addr, 3U << pupd_offset);
|
||||
else
|
||||
mmio_clrbits_32(pullen_addr,
|
||||
1U << PULL_offset[pin].offset);
|
||||
} else if (en == GPIO_PULL_ENABLE) {
|
||||
if (PULL_offset[pin].offset == (int8_t)-1) {
|
||||
/* For PUPD+R0+R1 Type, mt_set_gpio_pull_enable
|
||||
* does not know
|
||||
* which one between PU and PD shall be enabled.
|
||||
* Use R0 to guarantee at one resistor is set when lk
|
||||
* apply default setting
|
||||
*/
|
||||
mmio_setbits_32(pupd_addr, 1U << pupd_offset);
|
||||
mmio_clrbits_32(pupd_addr, 1U << (pupd_offset + 1));
|
||||
} else {
|
||||
/* For PULLEN + PULLSEL Type */
|
||||
mmio_setbits_32(pullen_addr,
|
||||
1U << PULL_offset[pin].offset);
|
||||
}
|
||||
} else if (en == GPIO_PULL_ENABLE_R0) {
|
||||
assert(!(pupd_offset == (int8_t)-1));
|
||||
mmio_setbits_32(pupd_addr, 1U << pupd_offset);
|
||||
mmio_clrbits_32(pupd_addr, 1U << (pupd_offset + 1));
|
||||
} else if (en == GPIO_PULL_ENABLE_R1) {
|
||||
assert(!(pupd_offset == (int8_t)-1));
|
||||
|
||||
mmio_clrbits_32(pupd_addr, 1U << pupd_offset);
|
||||
mmio_setbits_32(pupd_addr, 1U << (pupd_offset + 1));
|
||||
} else if (en == GPIO_PULL_ENABLE_R0R1) {
|
||||
assert(!(pupd_offset == (int8_t)-1));
|
||||
mmio_setbits_32(pupd_addr, 3U << pupd_offset);
|
||||
}
|
||||
}
|
||||
|
||||
int mt_get_gpio_pull_enable_chip(uint32_t pin)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
int pullen_addr = gpio_get_pull_iocfg(pin) + PULLEN_ADDR_OFFSET;
|
||||
int pupd_addr = gpio_get_pupd_iocfg(pin);
|
||||
int pupd_offset = gpio_get_pupd_offset(pin);
|
||||
|
||||
assert(pin < MAX_GPIO_PIN);
|
||||
|
||||
assert(!((PULL_offset[pin].offset == (int8_t)-1) &&
|
||||
(pupd_offset == (int8_t)-1)));
|
||||
|
||||
if (PULL_offset[pin].offset == (int8_t)-1) {
|
||||
reg = mmio_read_32(pupd_addr);
|
||||
return ((reg & (3U << pupd_offset)) ? 1 : 0);
|
||||
} else if (pupd_offset == (int8_t)-1) {
|
||||
reg = mmio_read_32(pullen_addr);
|
||||
return ((reg & (1U << PULL_offset[pin].offset)) ? 1 : 0);
|
||||
}
|
||||
|
||||
return -ERINVAL;
|
||||
}
|
||||
|
||||
void mt_set_gpio_pull_select_chip(uint32_t pin, int sel)
|
||||
{
|
||||
int pullsel_addr = gpio_get_pull_iocfg(pin) + PULLSEL_ADDR_OFFSET;
|
||||
int pupd_addr = gpio_get_pupd_iocfg(pin);
|
||||
int pupd_offset = gpio_get_pupd_offset(pin);
|
||||
|
||||
assert(pin < MAX_GPIO_PIN);
|
||||
|
||||
assert(!((PULL_offset[pin].offset == (int8_t) -1) &&
|
||||
(pupd_offset == (int8_t)-1)));
|
||||
|
||||
if (sel == GPIO_PULL_NONE) {
|
||||
/* Regard No PULL as PULL disable + pull down */
|
||||
mt_set_gpio_pull_enable_chip(pin, GPIO_PULL_DISABLE);
|
||||
if (PULL_offset[pin].offset == (int8_t)-1)
|
||||
mmio_setbits_32(pupd_addr, 1U << (pupd_offset + 2));
|
||||
else
|
||||
mmio_clrbits_32(pullsel_addr,
|
||||
1U << PULL_offset[pin].offset);
|
||||
} else if (sel == GPIO_PULL_UP) {
|
||||
mt_set_gpio_pull_enable_chip(pin, GPIO_PULL_ENABLE);
|
||||
if (PULL_offset[pin].offset == (int8_t)-1)
|
||||
mmio_clrbits_32(pupd_addr, 1U << (pupd_offset + 2));
|
||||
else
|
||||
mmio_setbits_32(pullsel_addr,
|
||||
1U << PULL_offset[pin].offset);
|
||||
} else if (sel == GPIO_PULL_DOWN) {
|
||||
mt_set_gpio_pull_enable_chip(pin, GPIO_PULL_ENABLE);
|
||||
if (PULL_offset[pin].offset == -1)
|
||||
mmio_setbits_32(pupd_addr, 1U << (pupd_offset + 2));
|
||||
else
|
||||
mmio_clrbits_32(pullsel_addr,
|
||||
1U << PULL_offset[pin].offset);
|
||||
}
|
||||
}
|
||||
|
||||
/* get pull-up or pull-down, regardless of resistor value */
|
||||
int mt_get_gpio_pull_select_chip(uint32_t pin)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
int pullen_addr = gpio_get_pull_iocfg(pin) + PULLEN_ADDR_OFFSET;
|
||||
int pullsel_addr = gpio_get_pull_iocfg(pin) + PULLSEL_ADDR_OFFSET;
|
||||
int pupd_addr = gpio_get_pupd_iocfg(pin);
|
||||
int pupd_offset = gpio_get_pupd_offset(pin);
|
||||
|
||||
assert(pin < MAX_GPIO_PIN);
|
||||
|
||||
assert(!((PULL_offset[pin].offset == (int8_t)-1) &&
|
||||
(pupd_offset == (int8_t)-1)));
|
||||
|
||||
if (PULL_offset[pin].offset == (int8_t)-1) {
|
||||
reg = mmio_read_32(pupd_addr);
|
||||
if (reg & (3U << pupd_offset)) {
|
||||
reg = mmio_read_32(pupd_addr);
|
||||
/* Reg value: 0 for PU, 1 for PD -->
|
||||
* reverse return value */
|
||||
return ((reg & (1U << (pupd_offset + 2))) ?
|
||||
GPIO_PULL_DOWN : GPIO_PULL_UP);
|
||||
} else {
|
||||
return GPIO_PULL_NONE;
|
||||
}
|
||||
} else if (pupd_offset == (int8_t)-1) {
|
||||
reg = mmio_read_32(pullen_addr);
|
||||
if ((reg & (1U << PULL_offset[pin].offset))) {
|
||||
reg = mmio_read_32(pullsel_addr);
|
||||
return ((reg & (1U << PULL_offset[pin].offset)) ?
|
||||
GPIO_PULL_UP : GPIO_PULL_DOWN);
|
||||
} else {
|
||||
return GPIO_PULL_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
return -ERINVAL;
|
||||
}
|
||||
|
||||
void mt_set_gpio_dir(int gpio, int direction)
|
||||
{
|
||||
mt_set_gpio_dir_chip((uint32_t)gpio, direction);
|
||||
}
|
||||
|
||||
int mt_get_gpio_dir(int gpio)
|
||||
{
|
||||
uint32_t pin;
|
||||
|
||||
pin = (uint32_t)gpio;
|
||||
return mt_get_gpio_dir_chip(pin);
|
||||
}
|
||||
|
||||
void mt_set_gpio_pull(int gpio, int pull)
|
||||
{
|
||||
uint32_t pin;
|
||||
|
||||
pin = (uint32_t)gpio;
|
||||
mt_set_gpio_pull_select_chip(pin, pull);
|
||||
}
|
||||
|
||||
int mt_get_gpio_pull(int gpio)
|
||||
{
|
||||
uint32_t pin;
|
||||
|
||||
pin = (uint32_t)gpio;
|
||||
return mt_get_gpio_pull_select_chip(pin);
|
||||
}
|
||||
|
||||
void mt_set_gpio_out(int gpio, int value)
|
||||
{
|
||||
uint32_t pin;
|
||||
|
||||
pin = (uint32_t)gpio;
|
||||
mt_set_gpio_out_chip(pin, value);
|
||||
}
|
||||
|
||||
int mt_get_gpio_out(int gpio)
|
||||
{
|
||||
uint32_t pin;
|
||||
|
||||
pin = (uint32_t)gpio;
|
||||
return mt_get_gpio_out_chip(pin);
|
||||
}
|
||||
|
||||
int mt_get_gpio_in(int gpio)
|
||||
{
|
||||
uint32_t pin;
|
||||
|
||||
pin = (uint32_t)gpio;
|
||||
return mt_get_gpio_in_chip(pin);
|
||||
}
|
||||
|
||||
void mt_set_gpio_mode(int gpio, int mode)
|
||||
{
|
||||
uint32_t pin;
|
||||
|
||||
pin = (uint32_t)gpio;
|
||||
mt_set_gpio_mode_chip(pin, mode);
|
||||
}
|
||||
|
||||
int mt_get_gpio_mode(int gpio)
|
||||
{
|
||||
uint32_t pin;
|
||||
|
||||
pin = (uint32_t)gpio;
|
||||
return mt_get_gpio_mode_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,
|
||||
};
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (c) 2019, MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef MT_GPIO_H
|
||||
#define MT_GPIO_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
|
||||
|
||||
/* 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, GPIO177, GPIO178, GPIO179,
|
||||
MT_GPIO_BASE_MAX
|
||||
} GPIO_PIN;
|
||||
|
||||
/* 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 {
|
||||
GPIO_DIR_UNSUPPORTED = -1,
|
||||
GPIO_DIR_OUT = 0,
|
||||
GPIO_DIR_IN = 1,
|
||||
GPIO_DIR_MAX,
|
||||
GPIO_DIR_DEFAULT = GPIO_DIR_IN,
|
||||
} GPIO_DIR;
|
||||
|
||||
/* GPIO PULL ENABLE*/
|
||||
typedef enum {
|
||||
GPIO_PULL_EN_UNSUPPORTED = -1,
|
||||
GPIO_PULL_DISABLE = 0,
|
||||
GPIO_PULL_ENABLE = 1,
|
||||
GPIO_PULL_ENABLE_R0 = 2,
|
||||
GPIO_PULL_ENABLE_R1 = 3,
|
||||
GPIO_PULL_ENABLE_R0R1 = 4,
|
||||
|
||||
GPIO_PULL_EN_MAX,
|
||||
GPIO_PULL_EN_DEFAULT = GPIO_PULL_ENABLE,
|
||||
} GPIO_PULL_EN;
|
||||
|
||||
/* GPIO PULL-UP/PULL-DOWN*/
|
||||
typedef enum {
|
||||
GPIO_PULL_UNSUPPORTED = -1,
|
||||
GPIO_PULL_NONE = 0,
|
||||
GPIO_PULL_UP = 1,
|
||||
GPIO_PULL_DOWN = 2,
|
||||
GPIO_PULL_MAX,
|
||||
GPIO_PULL_DEFAULT = GPIO_PULL_DOWN
|
||||
} GPIO_PULL;
|
||||
|
||||
/* GPIO OUTPUT */
|
||||
typedef enum {
|
||||
GPIO_OUT_UNSUPPORTED = -1,
|
||||
GPIO_OUT_ZERO = 0,
|
||||
GPIO_OUT_ONE = 1,
|
||||
|
||||
GPIO_OUT_MAX,
|
||||
GPIO_OUT_DEFAULT = GPIO_OUT_ZERO,
|
||||
GPIO_DATA_OUT_DEFAULT = GPIO_OUT_ZERO, /*compatible with DCT*/
|
||||
} GPIO_OUT;
|
||||
|
||||
/* GPIO INPUT */
|
||||
typedef enum {
|
||||
GPIO_IN_UNSUPPORTED = -1,
|
||||
GPIO_IN_ZERO = 0,
|
||||
GPIO_IN_ONE = 1,
|
||||
|
||||
GPIO_IN_MAX,
|
||||
} GPIO_IN;
|
||||
|
||||
typedef struct {
|
||||
uint32_t val;
|
||||
uint32_t set;
|
||||
uint32_t rst;
|
||||
uint32_t _align1;
|
||||
} VAL_REGS;
|
||||
|
||||
typedef struct {
|
||||
VAL_REGS dir[6]; /*0x0000 ~ 0x005F: 96 bytes */
|
||||
uint8_t rsv00[160]; /*0x0060 ~ 0x00FF: 160 bytes */
|
||||
VAL_REGS dout[6]; /*0x0100 ~ 0x015F: 96 bytes */
|
||||
uint8_t rsv01[160]; /*0x0160 ~ 0x01FF: 160 bytes */
|
||||
VAL_REGS din[6]; /*0x0200 ~ 0x025F: 96 bytes */
|
||||
uint8_t rsv02[160]; /*0x0260 ~ 0x02FF: 160 bytes */
|
||||
VAL_REGS mode[23]; /*0x0300 ~ 0x046F: 368 bytes */
|
||||
} GPIO_REGS;
|
||||
|
||||
/* GPIO Driver interface */
|
||||
/*direction*/
|
||||
void mt_set_gpio_dir(int gpio, int direction);
|
||||
int mt_get_gpio_dir(int gpio);
|
||||
|
||||
/*pull select*/
|
||||
void mt_set_gpio_pull(int gpio, int pull);
|
||||
int mt_get_gpio_pull(int gpio);
|
||||
|
||||
/*input/output*/
|
||||
void mt_set_gpio_out(int gpio, int value);
|
||||
int mt_get_gpio_out(int gpio);
|
||||
int mt_get_gpio_in(int gpio);
|
||||
|
||||
/*mode control*/
|
||||
void mt_set_gpio_mode(int gpio, int mode);
|
||||
int mt_get_gpio_mode(int gpio);
|
||||
|
||||
#endif /* MT_GPIO_H */
|
||||
+208
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (c) 2019, MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef MT_GPIO_CFG_H
|
||||
#define MT_GPIO_CFG_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <plat/common/common_def.h>
|
||||
|
||||
#define IOCFG_0_BASE 0x11F20000
|
||||
#define IOCFG_1_BASE 0x11E80000
|
||||
#define IOCFG_2_BASE 0x11E70000
|
||||
#define IOCFG_3_BASE 0x11E90000
|
||||
#define IOCFG_4_BASE 0x11D30000
|
||||
#define IOCFG_5_BASE 0x11D20000
|
||||
#define IOCFG_6_BASE 0x11C50000
|
||||
#define IOCFG_7_BASE 0x11F30000
|
||||
|
||||
typedef struct {
|
||||
int8_t offset;
|
||||
} PIN_offset;
|
||||
|
||||
PIN_offset PULL_offset[] = {
|
||||
/* 0 */ {6},
|
||||
/* 1 */ {7},
|
||||
/* 2 */ {8},
|
||||
/* 3 */ {9},
|
||||
/* 4 */ {11},
|
||||
/* 5 */ {12},
|
||||
/* 6 */ {13},
|
||||
/* 7 */ {14},
|
||||
/* 8 */ {0},
|
||||
/* 9 */ {26},
|
||||
/* 10 */ {27},
|
||||
/* 11 */ {10},
|
||||
/* 12 */ {17},
|
||||
/* 13 */ {6},
|
||||
/* 14 */ {7},
|
||||
/* 15 */ {8},
|
||||
/* 16 */ {9},
|
||||
/* 17 */ {10},
|
||||
/* 18 */ {11},
|
||||
/* 19 */ {12},
|
||||
/* 20 */ {13},
|
||||
/* 21 */ {14},
|
||||
/* 22 */ {15},
|
||||
/* 23 */ {16},
|
||||
/* 24 */ {17},
|
||||
/* 25 */ {18},
|
||||
/* 26 */ {19},
|
||||
/* 27 */ {20},
|
||||
/* 28 */ {21},
|
||||
/* 29 */ {-1},
|
||||
/* 30 */ {-1},
|
||||
/* 31 */ {-1},
|
||||
/* 32 */ {-1},
|
||||
/* 33 */ {-1},
|
||||
/* 34 */ {-1},
|
||||
/* 35 */ {-1},
|
||||
/* 36 */ {-1},
|
||||
/* 37 */ {-1},
|
||||
/* 38 */ {-1},
|
||||
/* 39 */ {-1},
|
||||
/* 40 */ {-1},
|
||||
/* 41 */ {-1},
|
||||
/* 42 */ {-1},
|
||||
/* 43 */ {8},
|
||||
/* 44 */ {9},
|
||||
/* 45 */ {10},
|
||||
/* 46 */ {11},
|
||||
/* 47 */ {12},
|
||||
/* 48 */ {13},
|
||||
/* 49 */ {14},
|
||||
/* 50 */ {0},
|
||||
/* 51 */ {1},
|
||||
/* 52 */ {2},
|
||||
/* 53 */ {3},
|
||||
/* 54 */ {4},
|
||||
/* 55 */ {5},
|
||||
/* 56 */ {6},
|
||||
/* 57 */ {7},
|
||||
/* 58 */ {8},
|
||||
/* 59 */ {9},
|
||||
/* 60 */ {10},
|
||||
/* 61 */ {0},
|
||||
/* 62 */ {1},
|
||||
/* 63 */ {2},
|
||||
/* 64 */ {3},
|
||||
/* 65 */ {4},
|
||||
/* 66 */ {5},
|
||||
/* 67 */ {6},
|
||||
/* 68 */ {7},
|
||||
/* 69 */ {8},
|
||||
/* 70 */ {9},
|
||||
/* 71 */ {10},
|
||||
/* 72 */ {11},
|
||||
/* 73 */ {12},
|
||||
/* 74 */ {13},
|
||||
/* 75 */ {14},
|
||||
/* 76 */ {15},
|
||||
/* 77 */ {16},
|
||||
/* 78 */ {17},
|
||||
/* 79 */ {18},
|
||||
/* 80 */ {19},
|
||||
/* 81 */ {20},
|
||||
/* 82 */ {21},
|
||||
/* 83 */ {22},
|
||||
/* 84 */ {23},
|
||||
/* 85 */ {24},
|
||||
/* 86 */ {25},
|
||||
/* 87 */ {26},
|
||||
/* 88 */ {27},
|
||||
/* 89 */ {24},
|
||||
/* 90 */ {1},
|
||||
/* 91 */ {-1},
|
||||
/* 92 */ {-1},
|
||||
/* 93 */ {-1},
|
||||
/* 94 */ {-1},
|
||||
/* 95 */ {15},
|
||||
/* 96 */ {17},
|
||||
/* 97 */ {18},
|
||||
/* 98 */ {19},
|
||||
/* 99 */ {20},
|
||||
/* 100 */ {21},
|
||||
/* 101 */ {22},
|
||||
/* 102 */ {23},
|
||||
/* 103 */ {28},
|
||||
/* 104 */ {29},
|
||||
/* 105 */ {30},
|
||||
/* 106 */ {31},
|
||||
/* 107 */ {0},
|
||||
/* 108 */ {1},
|
||||
/* 109 */ {2},
|
||||
/* 110 */ {3},
|
||||
/* 111 */ {4},
|
||||
/* 112 */ {5},
|
||||
/* 113 */ {6},
|
||||
/* 114 */ {7},
|
||||
/* 115 */ {8},
|
||||
/* 116 */ {9},
|
||||
/* 117 */ {10},
|
||||
/* 118 */ {11},
|
||||
/* 119 */ {12},
|
||||
/* 120 */ {13},
|
||||
/* 121 */ {14},
|
||||
/* 122 */ {-1},
|
||||
/* 123 */ {-1},
|
||||
/* 124 */ {-1},
|
||||
/* 125 */ {-1},
|
||||
/* 126 */ {-1},
|
||||
/* 127 */ {-1},
|
||||
/* 128 */ {-1},
|
||||
/* 129 */ {-1},
|
||||
/* 130 */ {-1},
|
||||
/* 131 */ {-1},
|
||||
/* 132 */ {-1},
|
||||
/* 133 */ {-1},
|
||||
/* 134 */ {0},
|
||||
/* 135 */ {1},
|
||||
/* 136 */ {2},
|
||||
/* 137 */ {3},
|
||||
/* 138 */ {4},
|
||||
/* 139 */ {5},
|
||||
/* 140 */ {6},
|
||||
/* 141 */ {7},
|
||||
/* 142 */ {8},
|
||||
/* 143 */ {9},
|
||||
/* 144 */ {11},
|
||||
/* 145 */ {12},
|
||||
/* 146 */ {13},
|
||||
/* 147 */ {14},
|
||||
/* 148 */ {15},
|
||||
/* 149 */ {16},
|
||||
/* 150 */ {18},
|
||||
/* 151 */ {19},
|
||||
/* 152 */ {20},
|
||||
/* 153 */ {21},
|
||||
/* 154 */ {22},
|
||||
/* 155 */ {23},
|
||||
/* 156 */ {24},
|
||||
/* 157 */ {25},
|
||||
/* 158 */ {26},
|
||||
/* 159 */ {27},
|
||||
/* 160 */ {28},
|
||||
/* 161 */ {0},
|
||||
/* 162 */ {1},
|
||||
/* 163 */ {2},
|
||||
/* 164 */ {3},
|
||||
/* 165 */ {4},
|
||||
/* 166 */ {5},
|
||||
/* 167 */ {11},
|
||||
/* 168 */ {12},
|
||||
/* 169 */ {13},
|
||||
/* 170 */ {14},
|
||||
/* 171 */ {15},
|
||||
/* 172 */ {16},
|
||||
/* 173 */ {17},
|
||||
/* 174 */ {18},
|
||||
/* 175 */ {19},
|
||||
/* 176 */ {20},
|
||||
/* 177 */ {10},
|
||||
/* 178 */ {16},
|
||||
/* 179 */ {25}
|
||||
};
|
||||
#endif /* MT_GPIO_CFG_H */
|
||||
+259
@@ -0,0 +1,259 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <sspm_reg.h>
|
||||
#include <mtk_mcdi.h>
|
||||
|
||||
static inline uint32_t mcdi_mbox_read(uint32_t id)
|
||||
{
|
||||
return mmio_read_32(SSPM_MBOX_3_BASE + (id << 2));
|
||||
}
|
||||
|
||||
static inline void mcdi_mbox_write(uint32_t id, uint32_t val)
|
||||
{
|
||||
mmio_write_32(SSPM_MBOX_3_BASE + (id << 2), val);
|
||||
}
|
||||
|
||||
void sspm_set_bootaddr(uint32_t bootaddr)
|
||||
{
|
||||
mcdi_mbox_write(MCDI_MBOX_BOOTADDR, bootaddr);
|
||||
}
|
||||
|
||||
void sspm_cluster_pwr_off_notify(uint32_t cluster)
|
||||
{
|
||||
mcdi_mbox_write(MCDI_MBOX_CLUSTER_0_ATF_ACTION_DONE + cluster, 1);
|
||||
}
|
||||
|
||||
void sspm_cluster_pwr_on_notify(uint32_t cluster)
|
||||
{
|
||||
mcdi_mbox_write(MCDI_MBOX_CLUSTER_0_ATF_ACTION_DONE + cluster, 0);
|
||||
}
|
||||
|
||||
void sspm_standbywfi_irq_enable(uint32_t cpu_idx)
|
||||
{
|
||||
mmio_write_32(SSPM_CFGREG_ACAO_INT_SET, STANDBYWFI_EN(cpu_idx));
|
||||
}
|
||||
|
||||
uint32_t mcdi_avail_cpu_mask_read(void)
|
||||
{
|
||||
return mcdi_mbox_read(MCDI_MBOX_AVAIL_CPU_MASK);
|
||||
}
|
||||
|
||||
uint32_t mcdi_avail_cpu_mask_write(uint32_t mask)
|
||||
{
|
||||
mcdi_mbox_write(MCDI_MBOX_AVAIL_CPU_MASK, mask);
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
uint32_t mcdi_avail_cpu_mask_set(uint32_t mask)
|
||||
{
|
||||
uint32_t m;
|
||||
|
||||
m = mcdi_mbox_read(MCDI_MBOX_AVAIL_CPU_MASK);
|
||||
m |= mask;
|
||||
mcdi_mbox_write(MCDI_MBOX_AVAIL_CPU_MASK, m);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
uint32_t mcdi_avail_cpu_mask_clr(uint32_t mask)
|
||||
{
|
||||
uint32_t m;
|
||||
|
||||
m = mcdi_mbox_read(MCDI_MBOX_AVAIL_CPU_MASK);
|
||||
m &= ~mask;
|
||||
mcdi_mbox_write(MCDI_MBOX_AVAIL_CPU_MASK, m);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
uint32_t mcdi_cpu_cluster_pwr_stat_read(void)
|
||||
{
|
||||
return mcdi_mbox_read(MCDI_MBOX_CPU_CLUSTER_PWR_STAT);
|
||||
}
|
||||
|
||||
#define PAUSE_BIT 1
|
||||
#define CLUSTER_OFF_OFS 20
|
||||
#define CPU_OFF_OFS 24
|
||||
#define CLUSTER_ON_OFS 4
|
||||
#define CPU_ON_OFS 8
|
||||
|
||||
static uint32_t target_mask(int cluster, int cpu_idx, bool on)
|
||||
{
|
||||
uint32_t t = 0;
|
||||
|
||||
if (on) {
|
||||
if (cluster >= 0)
|
||||
t |= BIT(cluster + CLUSTER_ON_OFS);
|
||||
|
||||
if (cpu_idx >= 0)
|
||||
t |= BIT(cpu_idx + CPU_ON_OFS);
|
||||
} else {
|
||||
if (cluster >= 0)
|
||||
t |= BIT(cluster + CLUSTER_OFF_OFS);
|
||||
|
||||
if (cpu_idx >= 0)
|
||||
t |= BIT(cpu_idx + CPU_OFF_OFS);
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
void mcdi_pause_clr(int cluster, int cpu_idx, bool on)
|
||||
{
|
||||
uint32_t tgt = target_mask(cluster, cpu_idx, on);
|
||||
uint32_t m = mcdi_mbox_read(MCDI_MBOX_PAUSE_ACTION);
|
||||
|
||||
m &= ~tgt;
|
||||
mcdi_mbox_write(MCDI_MBOX_PAUSE_ACTION, m);
|
||||
}
|
||||
|
||||
void mcdi_pause_set(int cluster, int cpu_idx, bool on)
|
||||
{
|
||||
uint32_t tgt = target_mask(cluster, cpu_idx, on);
|
||||
uint32_t m = mcdi_mbox_read(MCDI_MBOX_PAUSE_ACTION);
|
||||
uint32_t tgtn = target_mask(-1, cpu_idx, !on);
|
||||
|
||||
/* request on and off at the same time to ensure it can be paused */
|
||||
m |= tgt | tgtn;
|
||||
mcdi_mbox_write(MCDI_MBOX_PAUSE_ACTION, m);
|
||||
|
||||
/* wait pause_ack */
|
||||
while (!mcdi_mbox_read(MCDI_MBOX_PAUSE_ACK))
|
||||
;
|
||||
|
||||
/* clear non-requested operation */
|
||||
m &= ~tgtn;
|
||||
mcdi_mbox_write(MCDI_MBOX_PAUSE_ACTION, m);
|
||||
}
|
||||
|
||||
void mcdi_pause(void)
|
||||
{
|
||||
uint32_t m = mcdi_mbox_read(MCDI_MBOX_PAUSE_ACTION) | BIT(PAUSE_BIT);
|
||||
|
||||
mcdi_mbox_write(MCDI_MBOX_PAUSE_ACTION, m);
|
||||
|
||||
/* wait pause_ack */
|
||||
while (!mcdi_mbox_read(MCDI_MBOX_PAUSE_ACK))
|
||||
;
|
||||
}
|
||||
|
||||
void mcdi_unpause(void)
|
||||
{
|
||||
uint32_t m = mcdi_mbox_read(MCDI_MBOX_PAUSE_ACTION) & ~BIT(PAUSE_BIT);
|
||||
|
||||
mcdi_mbox_write(MCDI_MBOX_PAUSE_ACTION, m);
|
||||
}
|
||||
|
||||
void mcdi_hotplug_wait_ack(int cluster, int cpu_idx, bool on)
|
||||
{
|
||||
uint32_t tgt = target_mask(cluster, cpu_idx, on);
|
||||
uint32_t ack = mcdi_mbox_read(MCDI_MBOX_HP_ACK);
|
||||
|
||||
/* wait until ack */
|
||||
while (!(ack & tgt))
|
||||
ack = mcdi_mbox_read(MCDI_MBOX_HP_ACK);
|
||||
}
|
||||
|
||||
void mcdi_hotplug_clr(int cluster, int cpu_idx, bool on)
|
||||
{
|
||||
uint32_t tgt = target_mask(cluster, cpu_idx, on);
|
||||
uint32_t tgt_cpu = target_mask(-1, cpu_idx, on);
|
||||
uint32_t cmd = mcdi_mbox_read(MCDI_MBOX_HP_CMD);
|
||||
uint32_t ack = mcdi_mbox_read(MCDI_MBOX_HP_ACK);
|
||||
|
||||
if (!(cmd & tgt))
|
||||
return;
|
||||
|
||||
/* wait until ack */
|
||||
while (!(ack & tgt_cpu))
|
||||
ack = mcdi_mbox_read(MCDI_MBOX_HP_ACK);
|
||||
|
||||
cmd &= ~tgt;
|
||||
mcdi_mbox_write(MCDI_MBOX_HP_CMD, cmd);
|
||||
}
|
||||
|
||||
void mcdi_hotplug_set(int cluster, int cpu_idx, bool on)
|
||||
{
|
||||
uint32_t tgt = target_mask(cluster, cpu_idx, on);
|
||||
uint32_t tgt_cpu = target_mask(-1, cpu_idx, on);
|
||||
uint32_t cmd = mcdi_mbox_read(MCDI_MBOX_HP_CMD);
|
||||
uint32_t ack = mcdi_mbox_read(MCDI_MBOX_HP_ACK);
|
||||
|
||||
if ((cmd & tgt) == tgt)
|
||||
return;
|
||||
|
||||
/* wait until ack clear */
|
||||
while (ack & tgt_cpu)
|
||||
ack = mcdi_mbox_read(MCDI_MBOX_HP_ACK);
|
||||
|
||||
cmd |= tgt;
|
||||
mcdi_mbox_write(MCDI_MBOX_HP_CMD, cmd);
|
||||
}
|
||||
|
||||
bool check_mcdi_ctl_stat(void)
|
||||
{
|
||||
uint32_t clk_regs[] = {0x100010ac, 0x100010c8};
|
||||
uint32_t clk_mask[] = {0x00028000, 0x00000018};
|
||||
uint32_t tgt = target_mask(0, 0, true);
|
||||
uint32_t m;
|
||||
int i;
|
||||
|
||||
/* check clk status */
|
||||
for (i = 0; i < ARRAY_SIZE(clk_regs); i++) {
|
||||
if (mmio_read_32(clk_regs[i]) & clk_mask[i]) {
|
||||
WARN("mcdi: clk check fail.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* check mcdi cmd handling */
|
||||
m = mcdi_mbox_read(MCDI_MBOX_PAUSE_ACTION) | BIT(PAUSE_BIT);
|
||||
mcdi_mbox_write(MCDI_MBOX_PAUSE_ACTION, m);
|
||||
|
||||
i = 500;
|
||||
while (!mcdi_mbox_read(MCDI_MBOX_PAUSE_ACK) && --i > 0)
|
||||
udelay(10);
|
||||
|
||||
m = mcdi_mbox_read(MCDI_MBOX_PAUSE_ACTION) & ~BIT(PAUSE_BIT);
|
||||
mcdi_mbox_write(MCDI_MBOX_PAUSE_ACTION, m);
|
||||
|
||||
if (i == 0) {
|
||||
WARN("mcdi: pause_action fail.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* check mcdi cmd handling */
|
||||
if (mcdi_mbox_read(MCDI_MBOX_HP_CMD) ||
|
||||
mcdi_mbox_read(MCDI_MBOX_HP_ACK)) {
|
||||
WARN("mcdi: hp_cmd fail.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
mcdi_mbox_write(MCDI_MBOX_HP_CMD, tgt);
|
||||
|
||||
i = 500;
|
||||
while ((mcdi_mbox_read(MCDI_MBOX_HP_ACK) & tgt) != tgt && --i > 0)
|
||||
udelay(10);
|
||||
|
||||
mcdi_mbox_write(MCDI_MBOX_HP_CMD, 0);
|
||||
|
||||
if (i == 0) {
|
||||
WARN("mcdi: hp_ack fail.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void mcdi_init(void)
|
||||
{
|
||||
mcdi_avail_cpu_mask_write(0x01); /* cpu0 default on */
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef __MTK_MCDI_H__
|
||||
#define __MTK_MCDI_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
void sspm_set_bootaddr(uint32_t bootaddr);
|
||||
void sspm_standbywfi_irq_enable(uint32_t cpu_idx);
|
||||
void sspm_cluster_pwr_off_notify(uint32_t cluster);
|
||||
void sspm_cluster_pwr_on_notify(uint32_t cluster);
|
||||
|
||||
uint32_t mcdi_avail_cpu_mask_read(void);
|
||||
uint32_t mcdi_avail_cpu_mask_write(uint32_t mask);
|
||||
uint32_t mcdi_avail_cpu_mask_set(uint32_t mask);
|
||||
uint32_t mcdi_avail_cpu_mask_clr(uint32_t mask);
|
||||
uint32_t mcdi_cpu_cluster_pwr_stat_read(void);
|
||||
|
||||
void mcdi_pause(void);
|
||||
void mcdi_unpause(void);
|
||||
void mcdi_pause_set(int cluster, int cpu_idx, bool on);
|
||||
void mcdi_pause_clr(int cluster, int cpu_idx, bool on);
|
||||
void mcdi_hotplug_set(int cluster, int cpu_idx, bool on);
|
||||
void mcdi_hotplug_clr(int cluster, int cpu_idx, bool on);
|
||||
void mcdi_hotplug_wait_ack(int cluster, int cpu_idx, bool on);
|
||||
|
||||
bool check_mcdi_ctl_stat(void);
|
||||
void mcdi_init(void);
|
||||
|
||||
#endif /* __MTK_MCDI_H__ */
|
||||
+211
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <arch.h>
|
||||
#include <arch_helpers.h>
|
||||
#include <assert.h>
|
||||
#include <common/debug.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <scu.h>
|
||||
#include <mcucfg.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <mcsi/mcsi.h>
|
||||
|
||||
#define MAX_CLUSTERS 5
|
||||
|
||||
static unsigned long cci_base_addr;
|
||||
static unsigned int cci_cluster_ix_to_iface[MAX_CLUSTERS];
|
||||
|
||||
void mcsi_init(unsigned long cci_base,
|
||||
unsigned int num_cci_masters)
|
||||
{
|
||||
int i;
|
||||
|
||||
assert(cci_base);
|
||||
assert(num_cci_masters < MAX_CLUSTERS);
|
||||
|
||||
cci_base_addr = cci_base;
|
||||
|
||||
for (i = 0; i < num_cci_masters; i++)
|
||||
cci_cluster_ix_to_iface[i] = SLAVE_IFACE_OFFSET(i);
|
||||
}
|
||||
|
||||
void mcsi_cache_flush(void)
|
||||
{
|
||||
/* timeout is 10ms */
|
||||
int timeout = 10000;
|
||||
|
||||
/* to make flush by SF safe, need to disable BIU DCM */
|
||||
mmio_clrbits_32(CCI_CLK_CTRL, 1 << 8);
|
||||
mmio_write_32(cci_base_addr + FLUSH_SF, 0x1);
|
||||
|
||||
for (; timeout; timeout--, udelay(1)) {
|
||||
if ((mmio_read_32(cci_base_addr + FLUSH_SF) & 0x1) == 0x0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!timeout) {
|
||||
INFO("SF lush timeout\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* enable BIU DCM as it was */
|
||||
mmio_setbits_32(CCI_CLK_CTRL, 1 << 8);
|
||||
}
|
||||
|
||||
static inline unsigned long get_slave_iface_base(unsigned long mpidr)
|
||||
{
|
||||
/*
|
||||
* We assume the TF topology code allocates affinity instances
|
||||
* consecutively from zero.
|
||||
* It is a programming error if this is called without initializing
|
||||
* the slave interface to use for this cluster.
|
||||
*/
|
||||
unsigned int cluster_id =
|
||||
(mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
|
||||
|
||||
assert(cluster_id < MAX_CLUSTERS);
|
||||
assert(cci_cluster_ix_to_iface[cluster_id] != 0);
|
||||
|
||||
return cci_base_addr + cci_cluster_ix_to_iface[cluster_id];
|
||||
}
|
||||
|
||||
void cci_enable_cluster_coherency(unsigned long mpidr)
|
||||
{
|
||||
unsigned long slave_base;
|
||||
unsigned int support_ability;
|
||||
unsigned int config = 0;
|
||||
unsigned int pending = 0;
|
||||
|
||||
assert(cci_base_addr);
|
||||
slave_base = get_slave_iface_base(mpidr);
|
||||
support_ability = mmio_read_32(slave_base);
|
||||
|
||||
pending = (mmio_read_32(
|
||||
cci_base_addr + SNP_PENDING_REG)) >> SNP_PENDING;
|
||||
while (pending) {
|
||||
pending = (mmio_read_32(
|
||||
cci_base_addr + SNP_PENDING_REG)) >> SNP_PENDING;
|
||||
}
|
||||
|
||||
if (support_ability & SNP_SUPPORT)
|
||||
config |= SNOOP_EN_BIT;
|
||||
if (support_ability & DVM_SUPPORT)
|
||||
config |= DVM_EN_BIT;
|
||||
|
||||
mmio_write_32(slave_base, support_ability | config);
|
||||
|
||||
/* Wait for the dust to settle down */
|
||||
while (mmio_read_32(cci_base_addr + SNP_PENDING_REG) >> SNP_PENDING)
|
||||
;
|
||||
}
|
||||
|
||||
#if ERRATA_MCSIB_SW
|
||||
#pragma weak mcsib_sw_workaround_main
|
||||
#endif
|
||||
|
||||
void cci_disable_cluster_coherency(unsigned long mpidr)
|
||||
{
|
||||
unsigned long slave_base;
|
||||
unsigned int config = 0;
|
||||
|
||||
assert(cci_base_addr);
|
||||
slave_base = get_slave_iface_base(mpidr);
|
||||
|
||||
while (mmio_read_32(cci_base_addr + SNP_PENDING_REG) >> SNP_PENDING)
|
||||
;
|
||||
|
||||
config = mmio_read_32(slave_base);
|
||||
config &= ~(DVM_EN_BIT | SNOOP_EN_BIT);
|
||||
|
||||
/* Disable Snoops and DVM messages */
|
||||
mmio_write_32(slave_base, config);
|
||||
|
||||
#if ERRATA_MCSIB_SW
|
||||
mcsib_sw_workaround_main();
|
||||
#endif
|
||||
|
||||
/* Wait for the dust to settle down */
|
||||
while (mmio_read_32(cci_base_addr + SNP_PENDING_REG) >> SNP_PENDING)
|
||||
;
|
||||
}
|
||||
|
||||
void cci_secure_switch(unsigned int status)
|
||||
{
|
||||
unsigned int config;
|
||||
|
||||
config = mmio_read_32(cci_base_addr + CENTRAL_CTRL_REG);
|
||||
if (status == NS_ACC)
|
||||
config |= SECURE_ACC_EN;
|
||||
else
|
||||
config &= ~SECURE_ACC_EN;
|
||||
mmio_write_32(cci_base_addr + CENTRAL_CTRL_REG, config);
|
||||
}
|
||||
|
||||
void cci_pmu_secure_switch(unsigned int status)
|
||||
{
|
||||
unsigned int config;
|
||||
|
||||
config = mmio_read_32(cci_base_addr + CENTRAL_CTRL_REG);
|
||||
if (status == NS_ACC)
|
||||
config |= PMU_SECURE_ACC_EN;
|
||||
else
|
||||
config &= ~PMU_SECURE_ACC_EN;
|
||||
mmio_write_32(cci_base_addr + CENTRAL_CTRL_REG, config);
|
||||
}
|
||||
|
||||
void cci_init_sf(void)
|
||||
{
|
||||
while (mmio_read_32(cci_base_addr + SNP_PENDING_REG) >> SNP_PENDING)
|
||||
;
|
||||
/* init sf1 */
|
||||
mmio_write_32(cci_base_addr + SF_INIT_REG, TRIG_SF1_INIT);
|
||||
while (mmio_read_32(cci_base_addr + SF_INIT_REG) & TRIG_SF1_INIT)
|
||||
;
|
||||
while (!(mmio_read_32(cci_base_addr + SF_INIT_REG) & SF1_INIT_DONE))
|
||||
;
|
||||
/* init sf2 */
|
||||
mmio_write_32(cci_base_addr + SF_INIT_REG, TRIG_SF2_INIT);
|
||||
while (mmio_read_32(cci_base_addr + SF_INIT_REG) & TRIG_SF2_INIT)
|
||||
;
|
||||
while (!(mmio_read_32(cci_base_addr + SF_INIT_REG) & SF2_INIT_DONE))
|
||||
;
|
||||
}
|
||||
|
||||
void cci_interrupt_en(void)
|
||||
{
|
||||
mmio_setbits_32(cci_base_addr + CENTRAL_CTRL_REG, INT_EN);
|
||||
}
|
||||
|
||||
unsigned long cci_reg_access(unsigned int op, unsigned long offset,
|
||||
unsigned long val)
|
||||
{
|
||||
unsigned long ret = 0;
|
||||
|
||||
if ((cci_base_addr == 0) || (offset > MSCI_MEMORY_SZ))
|
||||
panic();
|
||||
|
||||
switch (op) {
|
||||
case MCSI_REG_ACCESS_READ:
|
||||
ret = mmio_read_32(cci_base_addr + offset);
|
||||
break;
|
||||
case MCSI_REG_ACCESS_WRITE:
|
||||
mmio_write_32(cci_base_addr + offset, val);
|
||||
dsb();
|
||||
break;
|
||||
case MCSI_REG_ACCESS_SET_BITMASK:
|
||||
mmio_setbits_32(cci_base_addr + offset, val);
|
||||
dsb();
|
||||
break;
|
||||
case MCSI_REG_ACCESS_CLEAR_BITMASK:
|
||||
mmio_clrbits_32(cci_base_addr + offset, val);
|
||||
dsb();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef MCSI_H
|
||||
#define MCSI_H
|
||||
|
||||
#define SLAVE_IFACE7_OFFSET 0x1700
|
||||
#define SLAVE_IFACE6_OFFSET 0x1600
|
||||
#define SLAVE_IFACE5_OFFSET 0x1500
|
||||
#define SLAVE_IFACE4_OFFSET 0x1400
|
||||
#define SLAVE_IFACE3_OFFSET 0x1300
|
||||
#define SLAVE_IFACE2_OFFSET 0x1200
|
||||
#define SLAVE_IFACE1_OFFSET 0x1100
|
||||
#define SLAVE_IFACE0_OFFSET 0x1000
|
||||
#define SLAVE_IFACE_OFFSET(index) (SLAVE_IFACE0_OFFSET + \
|
||||
(0x100 * (index)))
|
||||
/* Control and ID register offsets */
|
||||
#define CENTRAL_CTRL_REG 0x0
|
||||
#define ERR_FLAG_REG 0x4
|
||||
#define SF_INIT_REG 0x10
|
||||
#define SF_CTRL_REG 0x14
|
||||
#define DCM_CTRL_REG 0x18
|
||||
#define ERR_FLAG2_REG 0x20
|
||||
#define SNP_PENDING_REG 0x28
|
||||
#define ACP_PENDING_REG 0x2c
|
||||
#define FLUSH_SF 0x500
|
||||
#define SYS_CCE_CTRL 0x2000
|
||||
#define MST1_CTRL 0x2100
|
||||
#define MTS2_CTRL 0x2200
|
||||
#define XBAR_ARAW_ARB 0x3000
|
||||
#define XBAR_R_ARB 0x3004
|
||||
|
||||
/* Slave interface register offsets */
|
||||
#define SNOOP_CTRL_REG 0x0
|
||||
#define QOS_CTRL_REG 0x4
|
||||
#define QOS_OVERRIDE_REG 0x8
|
||||
#define QOS_TARGET_REG 0xc
|
||||
#define BD_CTRL_REG 0x40
|
||||
|
||||
/* Snoop Control register bit definitions */
|
||||
#define DVM_SUPPORT (1U << 31)
|
||||
#define SNP_SUPPORT (1 << 30)
|
||||
#define SHAREABLE_OVWRT (1 << 2)
|
||||
#define DVM_EN_BIT (1 << 1)
|
||||
#define SNOOP_EN_BIT (1 << 0)
|
||||
#define SF2_INIT_DONE (1 << 17)
|
||||
#define SF1_INIT_DONE (1 << 16)
|
||||
#define TRIG_SF2_INIT (1 << 1)
|
||||
#define TRIG_SF1_INIT (1 << 0)
|
||||
|
||||
/* Status register bit definitions */
|
||||
#define SNP_PENDING 31
|
||||
|
||||
/* Status bit */
|
||||
#define NS_ACC 1
|
||||
#define S_ACC 0
|
||||
|
||||
/* Central control register bit definitions */
|
||||
#define PMU_SECURE_ACC_EN (1 << 4)
|
||||
#define INT_EN (1 << 3)
|
||||
#define SECURE_ACC_EN (1 << 2)
|
||||
#define DVM_DIS (1 << 1)
|
||||
#define SNOOP_DIS (1 << 0)
|
||||
|
||||
#define MSCI_MEMORY_SZ (0x10000)
|
||||
|
||||
#define MCSI_REG_ACCESS_READ (0x0)
|
||||
#define MCSI_REG_ACCESS_WRITE (0x1)
|
||||
#define MCSI_REG_ACCESS_SET_BITMASK (0x2)
|
||||
#define MCSI_REG_ACCESS_CLEAR_BITMASK (0x3)
|
||||
|
||||
#define NR_MAX_SLV (7)
|
||||
|
||||
/* ICCS */
|
||||
#define CACHE_INSTR_EN (1 << 2)
|
||||
#define IDLE_CACHE (1 << 3)
|
||||
#define USE_SHARED_CACHE (1 << 4)
|
||||
#define CACHE_SHARED_PRE_EN (1 << 5)
|
||||
#define CACHE_SHARED_POST_EN (1 << 6)
|
||||
|
||||
#define ACP_PENDING_MASK (0x1007f)
|
||||
|
||||
#define CCI_CLK_CTRL (MCUCFG_BASE + 0x660)
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <plat/common/common_def.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Function declarations */
|
||||
|
||||
/*
|
||||
* The MCSI driver must be initialized with the base address of the
|
||||
* MCSI device in the platform memory map, and the cluster indices for
|
||||
* the MCSI slave interfaces 3 and 4 respectively. These are the fully
|
||||
* coherent ACE slave interfaces of MCSI.
|
||||
* The cluster indices must either be 0 or 1, corresponding to the level 1
|
||||
* affinity instance of the mpidr representing the cluster. A negative cluster
|
||||
* index indicates that no cluster is present on that slave interface.
|
||||
*/
|
||||
void mcsi_init(unsigned long cci_base,
|
||||
unsigned int num_cci_masters);
|
||||
void mcsi_cache_flush(void);
|
||||
|
||||
void cci_enable_cluster_coherency(unsigned long mpidr);
|
||||
void cci_disable_cluster_coherency(unsigned long mpidr);
|
||||
|
||||
void cci_secure_switch(unsigned int ns);
|
||||
void cci_init_sf(void);
|
||||
unsigned long cci_reg_access(unsigned int op, unsigned long offset, unsigned long val);
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
#endif /* MCSI_H */
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2019, MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <pmic_wrap_init.h>
|
||||
#include <pmic.h>
|
||||
|
||||
void bcpu_enable(uint32_t en)
|
||||
{
|
||||
pwrap_write(PMIC_VPROC11_OP_EN, 0x1);
|
||||
if (en)
|
||||
pwrap_write(PMIC_VPROC11_CON0, 1);
|
||||
else
|
||||
pwrap_write(PMIC_VPROC11_CON0, 0);
|
||||
}
|
||||
|
||||
void bcpu_sram_enable(uint32_t en)
|
||||
{
|
||||
pwrap_write(PMIC_VSRAM_PROC11_OP_EN, 0x1);
|
||||
if (en)
|
||||
pwrap_write(PMIC_VSRAM_PROC11_CON0, 1);
|
||||
else
|
||||
pwrap_write(PMIC_VSRAM_PROC11_CON0, 0);
|
||||
}
|
||||
|
||||
void wk_pmic_enable_sdn_delay(void)
|
||||
{
|
||||
uint32_t con;
|
||||
|
||||
pwrap_write(PMIC_TMA_KEY, 0x9CA7);
|
||||
pwrap_read(PMIC_PSEQ_ELR11, &con);
|
||||
con &= ~PMIC_RG_SDN_DLY_ENB;
|
||||
pwrap_write(PMIC_PSEQ_ELR11, con);
|
||||
pwrap_write(PMIC_TMA_KEY, 0);
|
||||
}
|
||||
|
||||
void pmic_power_off(void)
|
||||
{
|
||||
pwrap_write(PMIC_PWRHOLD, 0x0);
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2019, MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef PMIC_H
|
||||
#define PMIC_H
|
||||
|
||||
enum {
|
||||
PMIC_TMA_KEY = 0x03a8,
|
||||
PMIC_PWRHOLD = 0x0a08,
|
||||
PMIC_PSEQ_ELR11 = 0x0a62,
|
||||
PMIC_VPROC11_CON0 = 0x1388,
|
||||
PMIC_VPROC11_OP_EN = 0x1390,
|
||||
PMIC_VSRAM_PROC11_CON0 = 0x1b46,
|
||||
PMIC_VSRAM_PROC11_OP_EN = 0x1b4e
|
||||
};
|
||||
|
||||
enum {
|
||||
PMIC_RG_SDN_DLY_ENB = 1U << 10
|
||||
};
|
||||
|
||||
/* external API */
|
||||
void bcpu_enable(uint32_t en);
|
||||
void bcpu_sram_enable(uint32_t en);
|
||||
void wk_pmic_enable_sdn_delay(void);
|
||||
void pmic_power_off(void);
|
||||
|
||||
#endif /* PMIC_H */
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2019, MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef PMIC_WRAP_INIT_H
|
||||
#define PMIC_WRAP_INIT_H
|
||||
|
||||
#include <platform_def.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* external API */
|
||||
int32_t pwrap_read(uint32_t adr, uint32_t *rdata);
|
||||
int32_t pwrap_write(uint32_t adr, uint32_t wdata);
|
||||
|
||||
static struct mt8183_pmic_wrap_regs *const mtk_pwrap =
|
||||
(void *)PMIC_WRAP_BASE;
|
||||
|
||||
/* timeout setting */
|
||||
enum {
|
||||
TIMEOUT_READ = 255, /* us */
|
||||
TIMEOUT_WAIT_IDLE = 255 /* us */
|
||||
};
|
||||
|
||||
/* PMIC_WRAP registers */
|
||||
struct mt8183_pmic_wrap_regs {
|
||||
uint32_t reserved[776];
|
||||
uint32_t wacs2_cmd;
|
||||
uint32_t wacs2_rdata;
|
||||
uint32_t wacs2_vldclr;
|
||||
uint32_t reserved1[4];
|
||||
};
|
||||
|
||||
enum {
|
||||
RDATA_WACS_RDATA_SHIFT = 0,
|
||||
RDATA_WACS_FSM_SHIFT = 16,
|
||||
RDATA_WACS_REQ_SHIFT = 19,
|
||||
RDATA_SYNC_IDLE_SHIFT,
|
||||
RDATA_INIT_DONE_SHIFT,
|
||||
RDATA_SYS_IDLE_SHIFT,
|
||||
};
|
||||
|
||||
enum {
|
||||
RDATA_WACS_RDATA_MASK = 0xffff,
|
||||
RDATA_WACS_FSM_MASK = 0x7,
|
||||
RDATA_WACS_REQ_MASK = 0x1,
|
||||
RDATA_SYNC_IDLE_MASK = 0x1,
|
||||
RDATA_INIT_DONE_MASK = 0x1,
|
||||
RDATA_SYS_IDLE_MASK = 0x1,
|
||||
};
|
||||
|
||||
/* WACS_FSM */
|
||||
enum {
|
||||
WACS_FSM_IDLE = 0x00,
|
||||
WACS_FSM_REQ = 0x02,
|
||||
WACS_FSM_WFDLE = 0x04,
|
||||
WACS_FSM_WFVLDCLR = 0x06,
|
||||
WACS_INIT_DONE = 0x01,
|
||||
WACS_SYNC_IDLE = 0x01,
|
||||
WACS_SYNC_BUSY = 0x00
|
||||
};
|
||||
|
||||
/* error information flag */
|
||||
enum {
|
||||
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_H */
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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 = 0;
|
||||
|
||||
pmic_reg = RTC_Read(addr);
|
||||
|
||||
pmic_reg &= ~(MASK << SHIFT);
|
||||
pmic_reg |= (data << SHIFT);
|
||||
|
||||
RTC_Write(addr, pmic_reg);
|
||||
}
|
||||
|
||||
static void 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);
|
||||
RTC_Write_Trigger();
|
||||
}
|
||||
|
||||
static void rtc_xosc_write(uint16_t val, bool reload)
|
||||
{
|
||||
uint16_t bbpu;
|
||||
|
||||
RTC_Write(RTC_OSC32CON, RTC_OSC32CON_UNLOCK1);
|
||||
rtc_busy_wait();
|
||||
RTC_Write(RTC_OSC32CON, RTC_OSC32CON_UNLOCK2);
|
||||
rtc_busy_wait();
|
||||
|
||||
RTC_Write(RTC_OSC32CON, val);
|
||||
rtc_busy_wait();
|
||||
|
||||
if (reload) {
|
||||
bbpu = RTC_Read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_RELOAD;
|
||||
RTC_Write(RTC_BBPU, bbpu);
|
||||
RTC_Write_Trigger();
|
||||
}
|
||||
}
|
||||
|
||||
static void rtc_enable_k_eosc(void)
|
||||
{
|
||||
uint16_t osc32;
|
||||
uint16_t rtc_eosc_cali_td = 8; /* eosc cali period time */
|
||||
|
||||
/* Truning on eosc cali mode clock */
|
||||
RTC_Config_Interface(PMIC_RG_TOP_CON, 1,
|
||||
PMIC_RG_SRCLKEN_IN0_HW_MODE_MASK,
|
||||
PMIC_RG_SRCLKEN_IN0_HW_MODE_SHIFT);
|
||||
RTC_Config_Interface(PMIC_RG_TOP_CON, 1,
|
||||
PMIC_RG_SRCLKEN_IN1_HW_MODE_MASK,
|
||||
PMIC_RG_SRCLKEN_IN1_HW_MODE_SHIFT);
|
||||
RTC_Config_Interface(PMIC_RG_SCK_TOP_CKPDN_CON0, 0,
|
||||
PMIC_RG_RTC_EOSC32_CK_PDN_MASK,
|
||||
PMIC_RG_RTC_EOSC32_CK_PDN_SHIFT);
|
||||
|
||||
switch (rtc_eosc_cali_td) {
|
||||
case 1:
|
||||
RTC_Config_Interface(PMIC_RG_EOSC_CALI_CON0, 0x3,
|
||||
PMIC_RG_EOSC_CALI_TD_MASK, PMIC_RG_EOSC_CALI_TD_SHIFT);
|
||||
break;
|
||||
case 2:
|
||||
RTC_Config_Interface(PMIC_RG_EOSC_CALI_CON0, 0x4,
|
||||
PMIC_RG_EOSC_CALI_TD_MASK, PMIC_RG_EOSC_CALI_TD_SHIFT);
|
||||
break;
|
||||
case 4:
|
||||
RTC_Config_Interface(PMIC_RG_EOSC_CALI_CON0, 0x5,
|
||||
PMIC_RG_EOSC_CALI_TD_MASK, PMIC_RG_EOSC_CALI_TD_SHIFT);
|
||||
break;
|
||||
case 16:
|
||||
RTC_Config_Interface(PMIC_RG_EOSC_CALI_CON0, 0x7,
|
||||
PMIC_RG_EOSC_CALI_TD_MASK, PMIC_RG_EOSC_CALI_TD_SHIFT);
|
||||
break;
|
||||
default:
|
||||
RTC_Config_Interface(PMIC_RG_EOSC_CALI_CON0, 0x6,
|
||||
PMIC_RG_EOSC_CALI_TD_MASK, PMIC_RG_EOSC_CALI_TD_SHIFT);
|
||||
break;
|
||||
}
|
||||
/* Switch the DCXO from 32k-less mode to RTC mode,
|
||||
* otherwise, EOSC cali will fail
|
||||
*/
|
||||
/* RTC mode will have only OFF mode and FPM */
|
||||
RTC_Config_Interface(PMIC_RG_DCXO_CW02, 0, PMIC_RG_XO_EN32K_MAN_MASK,
|
||||
PMIC_RG_XO_EN32K_MAN_SHIFT);
|
||||
RTC_Write(RTC_BBPU,
|
||||
RTC_Read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_RELOAD);
|
||||
RTC_Write_Trigger();
|
||||
/* Enable K EOSC mode for normal power off and then plug out battery */
|
||||
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);
|
||||
RTC_Write_Trigger();
|
||||
|
||||
osc32 = RTC_Read(RTC_OSC32CON);
|
||||
rtc_xosc_write(osc32 | RTC_EMBCK_SRC_SEL, true);
|
||||
INFO("[RTC] RTC_enable_k_eosc\n");
|
||||
}
|
||||
|
||||
void rtc_power_off_sequence(void)
|
||||
{
|
||||
uint16_t bbpu;
|
||||
|
||||
rtc_disable_2sec_reboot();
|
||||
rtc_enable_k_eosc();
|
||||
|
||||
/* clear alarm */
|
||||
bbpu = RTC_BBPU_KEY | RTC_BBPU_CLR | RTC_BBPU_PWREN;
|
||||
if (Writeif_unlock()) {
|
||||
RTC_Write(RTC_BBPU, bbpu);
|
||||
|
||||
RTC_Write(RTC_AL_MASK, RTC_AL_MASK_DOW);
|
||||
RTC_Write_Trigger();
|
||||
mdelay(1);
|
||||
|
||||
bbpu = RTC_Read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_RELOAD;
|
||||
RTC_Write(RTC_BBPU, bbpu);
|
||||
RTC_Write_Trigger();
|
||||
INFO("[RTC] BBPU=0x%x, IRQ_EN=0x%x, AL_MSK=0x%x, AL_SEC=0x%x\n",
|
||||
RTC_Read(RTC_BBPU), RTC_Read(RTC_IRQ_EN),
|
||||
RTC_Read(RTC_AL_MASK), RTC_Read(RTC_AL_SEC));
|
||||
}
|
||||
}
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (c) 2019, MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef RTC_H
|
||||
#define RTC_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_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_PROT_UNLOCK1 = 0x586A,
|
||||
RTC_PROT_UNLOCK2 = 0x9136
|
||||
};
|
||||
|
||||
enum {
|
||||
RTC_BBPU_PWREN = 1U << 0,
|
||||
RTC_BBPU_CLR = 1U << 1,
|
||||
RTC_BBPU_INIT = 1U << 2,
|
||||
RTC_BBPU_AUTO = 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
|
||||
};
|
||||
|
||||
/* PMIC TOP Register Definition */
|
||||
enum {
|
||||
PMIC_RG_TOP_CON = 0x001E,
|
||||
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 = 0x051A,
|
||||
PMIC_RG_SCK_TOP_CKPDN_CON0_SET = 0x051C,
|
||||
PMIC_RG_SCK_TOP_CKPDN_CON0_CLR = 0x051E,
|
||||
PMIC_RG_EOSC_CALI_CON0 = 0x540
|
||||
};
|
||||
|
||||
/* PMIC DCXO Register Definition */
|
||||
enum {
|
||||
PMIC_RG_DCXO_CW00 = 0x0788,
|
||||
PMIC_RG_DCXO_CW02 = 0x0790
|
||||
};
|
||||
|
||||
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_H */
|
||||
+363
@@ -0,0 +1,363 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#include <lib/bakery_lock.h>
|
||||
#include <common/debug.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <spm.h>
|
||||
#include <spm_pmic_wrap.h>
|
||||
|
||||
DEFINE_BAKERY_LOCK(spm_lock);
|
||||
|
||||
/* SPM_DVS_LEVEL */
|
||||
#define SPM_VMODEM_LEVEL_MASK (0xff << 16)
|
||||
#define SPM_VMODEM_LEVEL (1U << 18)
|
||||
#define SPM_VCORE_LEVEL_MASK (0xff)
|
||||
#define SPM_VCORE_LEVEL (1U << 1)
|
||||
|
||||
/* CLK_SCP_CFG_0 */
|
||||
#define SPM_CK_OFF_CONTROL (0x3FF)
|
||||
|
||||
/* CLK_SCP_CFG_1 */
|
||||
#define SPM_AXI_26M_SEL (0x1)
|
||||
|
||||
/* AP_PLL_CON3 */
|
||||
#define SPM_PLL_CONTROL (0x7FAAAAF)
|
||||
|
||||
/* AP_PLL_CON4 */
|
||||
#define SPM_PLL_OUT_OFF_CONTROL (0xFA0A)
|
||||
|
||||
/* AP_PLL_CON6 */
|
||||
#define PLL_DLY (0x20000)
|
||||
|
||||
const char *wakeup_src_str[32] = {
|
||||
[0] = "R12_PCM_TIMER",
|
||||
[1] = "R12_SSPM_WDT_EVENT_B",
|
||||
[2] = "R12_KP_IRQ_B",
|
||||
[3] = "R12_APWDT_EVENT_B",
|
||||
[4] = "R12_APXGPT1_EVENT_B",
|
||||
[5] = "R12_CONN2AP_SPM_WAKEUP_B",
|
||||
[6] = "R12_EINT_EVENT_B",
|
||||
[7] = "R12_CONN_WDT_IRQ_B",
|
||||
[8] = "R12_CCIF0_EVENT_B",
|
||||
[9] = "R12_LOWBATTERY_IRQ_B",
|
||||
[10] = "R12_SSPM_SPM_IRQ_B",
|
||||
[11] = "R12_SCP_SPM_IRQ_B",
|
||||
[12] = "R12_SCP_WDT_EVENT_B",
|
||||
[13] = "R12_PCM_WDT_WAKEUP_B",
|
||||
[14] = "R12_USB_CDSC_B ",
|
||||
[15] = "R12_USB_POWERDWN_B",
|
||||
[16] = "R12_SYS_TIMER_EVENT_B",
|
||||
[17] = "R12_EINT_EVENT_SECURE_B",
|
||||
[18] = "R12_CCIF1_EVENT_B",
|
||||
[19] = "R12_UART0_IRQ_B",
|
||||
[20] = "R12_AFE_IRQ_MCU_B",
|
||||
[21] = "R12_THERM_CTRL_EVENT_B",
|
||||
[22] = "R12_SYS_CIRQ_IRQ_B",
|
||||
[23] = "R12_MD2AP_PEER_EVENT_B",
|
||||
[24] = "R12_CSYSPWREQ_B",
|
||||
[25] = "R12_MD1_WDT_B ",
|
||||
[26] = "R12_CLDMA_EVENT_B",
|
||||
[27] = "R12_SEJ_WDT_GPT_B",
|
||||
[28] = "R12_ALL_SSPM_WAKEUP_B",
|
||||
[29] = "R12_CPU_IRQ_B",
|
||||
[30] = "R12_CPU_WFI_AND_B"
|
||||
};
|
||||
|
||||
const char *spm_get_firmware_version(void)
|
||||
{
|
||||
return "DYNAMIC_SPM_FW_VERSION";
|
||||
}
|
||||
|
||||
void spm_lock_init(void)
|
||||
{
|
||||
bakery_lock_init(&spm_lock);
|
||||
}
|
||||
|
||||
void spm_lock_get(void)
|
||||
{
|
||||
bakery_lock_get(&spm_lock);
|
||||
}
|
||||
|
||||
void spm_lock_release(void)
|
||||
{
|
||||
bakery_lock_release(&spm_lock);
|
||||
}
|
||||
|
||||
void spm_set_bootaddr(unsigned long bootaddr)
|
||||
{
|
||||
/* initialize core4~7 boot entry address */
|
||||
mmio_write_32(SW2SPM_MAILBOX_3, bootaddr);
|
||||
}
|
||||
|
||||
void spm_set_cpu_status(int cpu)
|
||||
{
|
||||
if (cpu >= 0 && cpu < 4) {
|
||||
mmio_write_32(ROOT_CPUTOP_ADDR, 0x10006204);
|
||||
mmio_write_32(ROOT_CORE_ADDR, 0x10006208 + (cpu * 0x4));
|
||||
} else if (cpu >= 4 && cpu < 8) {
|
||||
mmio_write_32(ROOT_CPUTOP_ADDR, 0x10006218);
|
||||
mmio_write_32(ROOT_CORE_ADDR, 0x1000621c + ((cpu - 4) * 0x4));
|
||||
} else {
|
||||
ERROR("%s: error cpu number %d\n", __func__, cpu);
|
||||
}
|
||||
}
|
||||
|
||||
void spm_set_power_control(const struct pwr_ctrl *pwrctrl)
|
||||
{
|
||||
mmio_write_32(SPM_AP_STANDBY_CON,
|
||||
((pwrctrl->wfi_op & 0x1) << 0) |
|
||||
((pwrctrl->mp0_cputop_idle_mask & 0x1) << 1) |
|
||||
((pwrctrl->mp1_cputop_idle_mask & 0x1) << 2) |
|
||||
((pwrctrl->mcusys_idle_mask & 0x1) << 4) |
|
||||
((pwrctrl->mm_mask_b & 0x3) << 16) |
|
||||
((pwrctrl->md_ddr_en_0_dbc_en & 0x1) << 18) |
|
||||
((pwrctrl->md_ddr_en_1_dbc_en & 0x1) << 19) |
|
||||
((pwrctrl->md_mask_b & 0x3) << 20) |
|
||||
((pwrctrl->sspm_mask_b & 0x1) << 22) |
|
||||
((pwrctrl->scp_mask_b & 0x1) << 23) |
|
||||
((pwrctrl->srcclkeni_mask_b & 0x1) << 24) |
|
||||
((pwrctrl->md_apsrc_1_sel & 0x1) << 25) |
|
||||
((pwrctrl->md_apsrc_0_sel & 0x1) << 26) |
|
||||
((pwrctrl->conn_ddr_en_dbc_en & 0x1) << 27) |
|
||||
((pwrctrl->conn_mask_b & 0x1) << 28) |
|
||||
((pwrctrl->conn_apsrc_sel & 0x1) << 29));
|
||||
|
||||
mmio_write_32(SPM_SRC_REQ,
|
||||
((pwrctrl->spm_apsrc_req & 0x1) << 0) |
|
||||
((pwrctrl->spm_f26m_req & 0x1) << 1) |
|
||||
((pwrctrl->spm_infra_req & 0x1) << 3) |
|
||||
((pwrctrl->spm_vrf18_req & 0x1) << 4) |
|
||||
((pwrctrl->spm_ddren_req & 0x1) << 7) |
|
||||
((pwrctrl->spm_rsv_src_req & 0x7) << 8) |
|
||||
((pwrctrl->spm_ddren_2_req & 0x1) << 11) |
|
||||
((pwrctrl->cpu_md_dvfs_sop_force_on & 0x1) << 16));
|
||||
|
||||
mmio_write_32(SPM_SRC_MASK,
|
||||
((pwrctrl->csyspwreq_mask & 0x1) << 0) |
|
||||
((pwrctrl->ccif0_md_event_mask_b & 0x1) << 1) |
|
||||
((pwrctrl->ccif0_ap_event_mask_b & 0x1) << 2) |
|
||||
((pwrctrl->ccif1_md_event_mask_b & 0x1) << 3) |
|
||||
((pwrctrl->ccif1_ap_event_mask_b & 0x1) << 4) |
|
||||
((pwrctrl->ccif2_md_event_mask_b & 0x1) << 5) |
|
||||
((pwrctrl->ccif2_ap_event_mask_b & 0x1) << 6) |
|
||||
((pwrctrl->ccif3_md_event_mask_b & 0x1) << 7) |
|
||||
((pwrctrl->ccif3_ap_event_mask_b & 0x1) << 8) |
|
||||
((pwrctrl->md_srcclkena_0_infra_mask_b & 0x1) << 9) |
|
||||
((pwrctrl->md_srcclkena_1_infra_mask_b & 0x1) << 10) |
|
||||
((pwrctrl->conn_srcclkena_infra_mask_b & 0x1) << 11) |
|
||||
((pwrctrl->ufs_infra_req_mask_b & 0x1) << 12) |
|
||||
((pwrctrl->srcclkeni_infra_mask_b & 0x1) << 13) |
|
||||
((pwrctrl->md_apsrc_req_0_infra_mask_b & 0x1) << 14) |
|
||||
((pwrctrl->md_apsrc_req_1_infra_mask_b & 0x1) << 15) |
|
||||
((pwrctrl->conn_apsrcreq_infra_mask_b & 0x1) << 16) |
|
||||
((pwrctrl->ufs_srcclkena_mask_b & 0x1) << 17) |
|
||||
((pwrctrl->md_vrf18_req_0_mask_b & 0x1) << 18) |
|
||||
((pwrctrl->md_vrf18_req_1_mask_b & 0x1) << 19) |
|
||||
((pwrctrl->ufs_vrf18_req_mask_b & 0x1) << 20) |
|
||||
((pwrctrl->gce_vrf18_req_mask_b & 0x1) << 21) |
|
||||
((pwrctrl->conn_infra_req_mask_b & 0x1) << 22) |
|
||||
((pwrctrl->gce_apsrc_req_mask_b & 0x1) << 23) |
|
||||
((pwrctrl->disp0_apsrc_req_mask_b & 0x1) << 24) |
|
||||
((pwrctrl->disp1_apsrc_req_mask_b & 0x1) << 25) |
|
||||
((pwrctrl->mfg_req_mask_b & 0x1) << 26) |
|
||||
((pwrctrl->vdec_req_mask_b & 0x1) << 27));
|
||||
|
||||
mmio_write_32(SPM_SRC2_MASK,
|
||||
((pwrctrl->md_ddr_en_0_mask_b & 0x1) << 0) |
|
||||
((pwrctrl->md_ddr_en_1_mask_b & 0x1) << 1) |
|
||||
((pwrctrl->conn_ddr_en_mask_b & 0x1) << 2) |
|
||||
((pwrctrl->ddren_sspm_apsrc_req_mask_b & 0x1) << 3) |
|
||||
((pwrctrl->ddren_scp_apsrc_req_mask_b & 0x1) << 4) |
|
||||
((pwrctrl->disp0_ddren_mask_b & 0x1) << 5) |
|
||||
((pwrctrl->disp1_ddren_mask_b & 0x1) << 6) |
|
||||
((pwrctrl->gce_ddren_mask_b & 0x1) << 7) |
|
||||
((pwrctrl->ddren_emi_self_refresh_ch0_mask_b & 0x1)
|
||||
<< 8) |
|
||||
((pwrctrl->ddren_emi_self_refresh_ch1_mask_b & 0x1)
|
||||
<< 9));
|
||||
|
||||
mmio_write_32(SPM_WAKEUP_EVENT_MASK,
|
||||
((pwrctrl->spm_wakeup_event_mask & 0xffffffff) << 0));
|
||||
|
||||
mmio_write_32(SPM_WAKEUP_EVENT_EXT_MASK,
|
||||
((pwrctrl->spm_wakeup_event_ext_mask & 0xffffffff)
|
||||
<< 0));
|
||||
|
||||
mmio_write_32(SPM_SRC3_MASK,
|
||||
((pwrctrl->md_ddr_en_2_0_mask_b & 0x1) << 0) |
|
||||
((pwrctrl->md_ddr_en_2_1_mask_b & 0x1) << 1) |
|
||||
((pwrctrl->conn_ddr_en_2_mask_b & 0x1) << 2) |
|
||||
((pwrctrl->ddren2_sspm_apsrc_req_mask_b & 0x1) << 3) |
|
||||
((pwrctrl->ddren2_scp_apsrc_req_mask_b & 0x1) << 4) |
|
||||
((pwrctrl->disp0_ddren2_mask_b & 0x1) << 5) |
|
||||
((pwrctrl->disp1_ddren2_mask_b & 0x1) << 6) |
|
||||
((pwrctrl->gce_ddren2_mask_b & 0x1) << 7) |
|
||||
((pwrctrl->ddren2_emi_self_refresh_ch0_mask_b & 0x1)
|
||||
<< 8) |
|
||||
((pwrctrl->ddren2_emi_self_refresh_ch1_mask_b & 0x1)
|
||||
<< 9));
|
||||
|
||||
mmio_write_32(MP0_CPU0_WFI_EN,
|
||||
((pwrctrl->mp0_cpu0_wfi_en & 0x1) << 0));
|
||||
mmio_write_32(MP0_CPU1_WFI_EN,
|
||||
((pwrctrl->mp0_cpu1_wfi_en & 0x1) << 0));
|
||||
mmio_write_32(MP0_CPU2_WFI_EN,
|
||||
((pwrctrl->mp0_cpu2_wfi_en & 0x1) << 0));
|
||||
mmio_write_32(MP0_CPU3_WFI_EN,
|
||||
((pwrctrl->mp0_cpu3_wfi_en & 0x1) << 0));
|
||||
|
||||
mmio_write_32(MP1_CPU0_WFI_EN,
|
||||
((pwrctrl->mp1_cpu0_wfi_en & 0x1) << 0));
|
||||
mmio_write_32(MP1_CPU1_WFI_EN,
|
||||
((pwrctrl->mp1_cpu1_wfi_en & 0x1) << 0));
|
||||
mmio_write_32(MP1_CPU2_WFI_EN,
|
||||
((pwrctrl->mp1_cpu2_wfi_en & 0x1) << 0));
|
||||
mmio_write_32(MP1_CPU3_WFI_EN,
|
||||
((pwrctrl->mp1_cpu3_wfi_en & 0x1) << 0));
|
||||
}
|
||||
|
||||
void spm_disable_pcm_timer(void)
|
||||
{
|
||||
mmio_clrsetbits_32(PCM_CON1, PCM_TIMER_EN_LSB, SPM_REGWR_CFG_KEY);
|
||||
}
|
||||
|
||||
void spm_set_wakeup_event(const struct pwr_ctrl *pwrctrl)
|
||||
{
|
||||
uint32_t val, mask, isr;
|
||||
|
||||
val = pwrctrl->timer_val ? pwrctrl->timer_val : PCM_TIMER_MAX;
|
||||
mmio_write_32(PCM_TIMER_VAL, val);
|
||||
mmio_setbits_32(PCM_CON1, SPM_REGWR_CFG_KEY | PCM_TIMER_EN_LSB);
|
||||
|
||||
mask = pwrctrl->wake_src;
|
||||
|
||||
if (pwrctrl->csyspwreq_mask)
|
||||
mask &= ~WAKE_SRC_R12_CSYSPWREQ_B;
|
||||
|
||||
mmio_write_32(SPM_WAKEUP_EVENT_MASK, ~mask);
|
||||
|
||||
isr = mmio_read_32(SPM_IRQ_MASK) & SPM_TWAM_IRQ_MASK_LSB;
|
||||
mmio_write_32(SPM_IRQ_MASK, isr | ISRM_RET_IRQ_AUX);
|
||||
}
|
||||
|
||||
void spm_set_pcm_flags(const struct pwr_ctrl *pwrctrl)
|
||||
{
|
||||
mmio_write_32(SPM_SW_FLAG, pwrctrl->pcm_flags);
|
||||
mmio_write_32(SPM_SW_RSV_2, pwrctrl->pcm_flags1);
|
||||
}
|
||||
|
||||
void spm_set_pcm_wdt(int en)
|
||||
{
|
||||
if (en) {
|
||||
mmio_clrsetbits_32(PCM_CON1, PCM_WDT_WAKE_MODE_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 | PCM_WDT_EN_LSB);
|
||||
} else {
|
||||
mmio_clrsetbits_32(PCM_CON1, PCM_WDT_EN_LSB,
|
||||
SPM_REGWR_CFG_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
void spm_send_cpu_wakeup_event(void)
|
||||
{
|
||||
mmio_write_32(PCM_REG_DATA_INI, 0);
|
||||
mmio_write_32(SPM_CPU_WAKEUP_EVENT, 1);
|
||||
}
|
||||
|
||||
void spm_get_wakeup_status(struct wake_status *wakesta)
|
||||
{
|
||||
wakesta->assert_pc = mmio_read_32(PCM_REG_DATA_INI);
|
||||
wakesta->r12 = mmio_read_32(SPM_SW_RSV_0);
|
||||
wakesta->r12_ext = mmio_read_32(PCM_REG12_EXT_DATA);
|
||||
wakesta->raw_sta = mmio_read_32(SPM_WAKEUP_STA);
|
||||
wakesta->raw_ext_sta = mmio_read_32(SPM_WAKEUP_EXT_STA);
|
||||
wakesta->wake_misc = mmio_read_32(SPM_BSI_D0_SR);
|
||||
wakesta->timer_out = mmio_read_32(SPM_BSI_D1_SR);
|
||||
wakesta->r13 = mmio_read_32(PCM_REG13_DATA);
|
||||
wakesta->idle_sta = mmio_read_32(SUBSYS_IDLE_STA);
|
||||
wakesta->req_sta = mmio_read_32(SRC_REQ_STA);
|
||||
wakesta->sw_flag = mmio_read_32(SPM_SW_FLAG);
|
||||
wakesta->sw_flag1 = mmio_read_32(SPM_SW_RSV_2);
|
||||
wakesta->r15 = mmio_read_32(PCM_REG15_DATA);
|
||||
wakesta->debug_flag = mmio_read_32(SPM_SW_DEBUG);
|
||||
wakesta->debug_flag1 = mmio_read_32(WDT_LATCH_SPARE0_FIX);
|
||||
wakesta->event_reg = mmio_read_32(SPM_BSI_D2_SR);
|
||||
wakesta->isr = mmio_read_32(SPM_IRQ_STA);
|
||||
}
|
||||
|
||||
void spm_clean_after_wakeup(void)
|
||||
{
|
||||
mmio_write_32(SPM_SW_RSV_0,
|
||||
mmio_read_32(SPM_WAKEUP_STA) |
|
||||
mmio_read_32(SPM_SW_RSV_0));
|
||||
mmio_write_32(SPM_CPU_WAKEUP_EVENT, 0);
|
||||
mmio_write_32(SPM_WAKEUP_EVENT_MASK, ~0);
|
||||
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_output_wake_reason(struct wake_status *wakesta, const char *scenario)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
if (wakesta->assert_pc != 0) {
|
||||
INFO("%s: PCM ASSERT AT %u, ULPOSC_CON = 0x%x\n",
|
||||
scenario, wakesta->assert_pc, mmio_read_32(ULPOSC_CON));
|
||||
goto spm_debug_flags;
|
||||
}
|
||||
|
||||
for (i = 0; i <= 31; i++) {
|
||||
if (wakesta->r12 & (1U << i)) {
|
||||
INFO("%s: wake up by %s, timer_out = %u\n",
|
||||
scenario, wakeup_src_str[i], wakesta->timer_out);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
spm_debug_flags:
|
||||
INFO("r15 = 0x%x, r13 = 0x%x, debug_flag = 0x%x 0x%x\n",
|
||||
wakesta->r15, wakesta->r13, wakesta->debug_flag,
|
||||
wakesta->debug_flag1);
|
||||
INFO("sw_flag = 0x%x 0x%x, r12 = 0x%x, r12_ext = 0x%x\n",
|
||||
wakesta->sw_flag, wakesta->sw_flag1, wakesta->r12,
|
||||
wakesta->r12_ext);
|
||||
INFO("idle_sta = 0x%x, req_sta = 0x%x, event_reg = 0x%x\n",
|
||||
wakesta->idle_sta, wakesta->req_sta, wakesta->event_reg);
|
||||
INFO("isr = 0x%x, raw_sta = 0x%x, raw_ext_sta = 0x%x\n",
|
||||
wakesta->isr, wakesta->raw_sta, wakesta->raw_ext_sta);
|
||||
INFO("wake_misc = 0x%x\n", wakesta->wake_misc);
|
||||
}
|
||||
|
||||
void spm_boot_init(void)
|
||||
{
|
||||
NOTICE("%s() start\n", __func__);
|
||||
|
||||
spm_lock_init();
|
||||
mt_spm_pmic_wrap_set_phase(PMIC_WRAP_PHASE_ALLINONE);
|
||||
|
||||
/* Set Vmodem / Vcore DVS init level */
|
||||
mmio_clrsetbits_32(SPM_DVS_LEVEL,
|
||||
SPM_VMODEM_LEVEL_MASK | SPM_VCORE_LEVEL_MASK,
|
||||
SPM_VMODEM_LEVEL | SPM_VCORE_LEVEL);
|
||||
|
||||
/* switch ck_off/axi_26m control to SPM */
|
||||
mmio_setbits_32(CLK_SCP_CFG_0, SPM_CK_OFF_CONTROL);
|
||||
mmio_setbits_32(CLK_SCP_CFG_1, SPM_AXI_26M_SEL);
|
||||
|
||||
/* switch PLL/CLKSQ control to SPM */
|
||||
mmio_clrbits_32(AP_PLL_CON3, SPM_PLL_CONTROL);
|
||||
mmio_clrbits_32(AP_PLL_CON4, SPM_PLL_OUT_OFF_CONTROL);
|
||||
mmio_clrbits_32(AP_PLL_CON6, PLL_DLY);
|
||||
|
||||
NOTICE("%s() end\n", __func__);
|
||||
}
|
||||
+2552
File diff suppressed because it is too large
Load Diff
+170
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <platform_def.h>
|
||||
#include <spm.h>
|
||||
#include <spm_pmic_wrap.h>
|
||||
#include <lib/libc/string.h>
|
||||
|
||||
#define SLEEP_REG_MD_SPM_DVFS_CMD20 (SLEEP_REG_MD_BASE + 0x010)
|
||||
#define SLEEP_REG_MD_SPM_DVFS_CMD21 (SLEEP_REG_MD_BASE + 0x014)
|
||||
#define SLEEP_REG_MD_SPM_DVFS_CMD22 (SLEEP_REG_MD_BASE + 0x018)
|
||||
#define SLEEP_REG_MD_SPM_DVFS_CMD23 (SLEEP_REG_MD_BASE + 0x01C)
|
||||
|
||||
/* PMIC_WRAP -> PMIC MT6358 */
|
||||
#define VCORE_BASE_UV 50000
|
||||
#define VOLT_TO_PMIC_VAL(volt) (((volt) - VCORE_BASE_UV + 625 - 1) / 625)
|
||||
#define PMIC_VAL_TO_VOLT(pmic) (((pmic) * 625) + VCORE_BASE_UV)
|
||||
|
||||
#define DEFAULT_VOLT_VSRAM (100000)
|
||||
#define DEFAULT_VOLT_VCORE (100000)
|
||||
#define NR_PMIC_WRAP_CMD (NR_IDX_ALL)
|
||||
#define MAX_RETRY_COUNT (100)
|
||||
#define SPM_DATA_SHIFT (16)
|
||||
|
||||
#define BUCK_VCORE_ELR0 0x14AA
|
||||
#define BUCK_VPROC12_CON0 0x1408
|
||||
#define BUCK_VPROC11_CON0 0x1388
|
||||
#define TOP_SPI_CON0 0x044C
|
||||
#define LDO_VSRAM_PROC12_CON0 0x1B88
|
||||
#define LDO_VSRAM_PROC11_CON0 0x1B46
|
||||
#define BUCK_VMODEM_ELR0 0x15A6
|
||||
|
||||
struct pmic_wrap_cmd {
|
||||
unsigned long cmd_addr;
|
||||
unsigned long cmd_wdata;
|
||||
};
|
||||
|
||||
struct pmic_wrap_setting {
|
||||
enum pmic_wrap_phase_id phase;
|
||||
struct pmic_wrap_cmd addr[NR_PMIC_WRAP_CMD];
|
||||
struct {
|
||||
struct {
|
||||
unsigned long cmd_addr;
|
||||
unsigned long 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,
|
||||
.addr = {{0, 0} },
|
||||
.set[PMIC_WRAP_PHASE_ALLINONE] = {
|
||||
._[CMD_0] = {BUCK_VCORE_ELR0, VOLT_TO_PMIC_VAL(70000),},
|
||||
._[CMD_1] = {BUCK_VCORE_ELR0, VOLT_TO_PMIC_VAL(80000),},
|
||||
._[CMD_2] = {BUCK_VPROC12_CON0, 0x3,},
|
||||
._[CMD_3] = {BUCK_VPROC12_CON0, 0x1,},
|
||||
._[CMD_4] = {BUCK_VPROC11_CON0, 0x3,},
|
||||
._[CMD_5] = {BUCK_VPROC11_CON0, 0x1,},
|
||||
._[CMD_6] = {TOP_SPI_CON0, 0x1,},
|
||||
._[CMD_7] = {TOP_SPI_CON0, 0x0,},
|
||||
._[CMD_8] = {BUCK_VPROC12_CON0, 0x0,},
|
||||
._[CMD_9] = {BUCK_VPROC12_CON0, 0x1,},
|
||||
._[CMD_10] = {BUCK_VPROC11_CON0, 0x0,},
|
||||
._[CMD_11] = {BUCK_VPROC11_CON0, 0x1,},
|
||||
._[CMD_12] = {LDO_VSRAM_PROC12_CON0, 0x0,},
|
||||
._[CMD_13] = {LDO_VSRAM_PROC12_CON0, 0x1,},
|
||||
._[CMD_14] = {LDO_VSRAM_PROC11_CON0, 0x0,},
|
||||
._[CMD_15] = {LDO_VSRAM_PROC11_CON0, 0x1,},
|
||||
._[CMD_20] = {BUCK_VMODEM_ELR0, VOLT_TO_PMIC_VAL(55000),},
|
||||
._[CMD_21] = {BUCK_VCORE_ELR0, VOLT_TO_PMIC_VAL(60000),},
|
||||
._[CMD_22] = {LDO_VSRAM_PROC11_CON0, 0x3,},
|
||||
._[CMD_23] = {LDO_VSRAM_PROC11_CON0, 0x1,},
|
||||
.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,},
|
||||
{(uint32_t)SLEEP_REG_MD_SPM_DVFS_CMD20,
|
||||
(uint32_t)SLEEP_REG_MD_SPM_DVFS_CMD20,},
|
||||
{(uint32_t)SLEEP_REG_MD_SPM_DVFS_CMD21,
|
||||
(uint32_t)SLEEP_REG_MD_SPM_DVFS_CMD21,},
|
||||
{(uint32_t)SLEEP_REG_MD_SPM_DVFS_CMD22,
|
||||
(uint32_t)SLEEP_REG_MD_SPM_DVFS_CMD22,},
|
||||
{(uint32_t)SLEEP_REG_MD_SPM_DVFS_CMD23,
|
||||
(uint32_t)SLEEP_REG_MD_SPM_DVFS_CMD23,}
|
||||
};
|
||||
|
||||
memcpy(pw.addr, pwrap_cmd_default, sizeof(pwrap_cmd_default));
|
||||
}
|
||||
|
||||
void mt_spm_pmic_wrap_set_phase(enum pmic_wrap_phase_id phase)
|
||||
{
|
||||
uint32_t idx, addr, data;
|
||||
|
||||
if (phase >= NR_PMIC_WRAP_PHASE)
|
||||
return;
|
||||
|
||||
if (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 | MD_BCLK_CG_EN_LSB);
|
||||
for (idx = 0; idx < pw.set[phase].nr_idx; idx++) {
|
||||
addr = pw.set[phase]._[idx].cmd_addr << SPM_DATA_SHIFT;
|
||||
data = pw.set[phase]._[idx].cmd_wdata;
|
||||
mmio_write_32(pw.addr[idx].cmd_addr, addr | data);
|
||||
}
|
||||
}
|
||||
|
||||
void mt_spm_pmic_wrap_set_cmd(enum pmic_wrap_phase_id phase, uint32_t idx,
|
||||
uint32_t cmd_wdata)
|
||||
{
|
||||
uint32_t addr;
|
||||
|
||||
if (phase >= NR_PMIC_WRAP_PHASE)
|
||||
return;
|
||||
|
||||
if (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 | MD_BCLK_CG_EN_LSB);
|
||||
if (pw.phase == phase) {
|
||||
addr = pw.set[phase]._[idx].cmd_addr << SPM_DATA_SHIFT;
|
||||
mmio_write_32(pw.addr[idx].cmd_addr, addr | cmd_wdata);
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t mt_spm_pmic_wrap_get_cmd(enum pmic_wrap_phase_id phase, uint32_t idx)
|
||||
{
|
||||
if (phase >= NR_PMIC_WRAP_PHASE)
|
||||
return 0;
|
||||
|
||||
if (idx >= pw.set[phase].nr_idx)
|
||||
return 0;
|
||||
|
||||
return pw.set[phase]._[idx].cmd_wdata;
|
||||
}
|
||||
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/****************************************************************
|
||||
* Auto generated by DE, please DO NOT modify this file directly.
|
||||
*****************************************************************/
|
||||
|
||||
#ifndef SPM_PMIC_WRAP__H
|
||||
#define SPM_PMIC_WRAP__H
|
||||
|
||||
enum pmic_wrap_phase_id {
|
||||
PMIC_WRAP_PHASE_ALLINONE,
|
||||
NR_PMIC_WRAP_PHASE
|
||||
};
|
||||
|
||||
/* IDX mapping */
|
||||
enum {
|
||||
CMD_0, /* 0x0 *//* PMIC_WRAP_PHASE_ALLINONE */
|
||||
CMD_1, /* 0x1 */
|
||||
CMD_2, /* 0x2 */
|
||||
CMD_3, /* 0x3 */
|
||||
CMD_4, /* 0x4 */
|
||||
CMD_5, /* 0x5 */
|
||||
CMD_6, /* 0x6 */
|
||||
CMD_7, /* 0x7 */
|
||||
CMD_8, /* 0x8 */
|
||||
CMD_9, /* 0x9 */
|
||||
CMD_10, /* 0xA */
|
||||
CMD_11, /* 0xB */
|
||||
CMD_12, /* 0xC */
|
||||
CMD_13, /* 0xD */
|
||||
CMD_14, /* 0xE */
|
||||
CMD_15, /* 0xF */
|
||||
CMD_20, /* 0x14 */
|
||||
CMD_21, /* 0x15 */
|
||||
CMD_22, /* 0x16 */
|
||||
CMD_23, /* 0x17 */
|
||||
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,
|
||||
uint32_t idx, uint32_t cmd_wdata);
|
||||
uint64_t mt_spm_pmic_wrap_get_cmd(enum pmic_wrap_phase_id phase, uint32_t idx);
|
||||
#endif /* SPM_PMIC_WRAP__H */
|
||||
|
||||
+255
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <common/debug.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <mt_gic_v3.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <platform_def.h>
|
||||
#include <pmic.h>
|
||||
#include <spm.h>
|
||||
#include <uart.h>
|
||||
|
||||
#define SPM_SYSCLK_SETTLE 99
|
||||
|
||||
#define WAKE_SRC_FOR_SUSPEND \
|
||||
(WAKE_SRC_R12_PCM_TIMER | \
|
||||
WAKE_SRC_R12_SSPM_WDT_EVENT_B | \
|
||||
WAKE_SRC_R12_KP_IRQ_B | \
|
||||
WAKE_SRC_R12_CONN2AP_SPM_WAKEUP_B | \
|
||||
WAKE_SRC_R12_EINT_EVENT_B | \
|
||||
WAKE_SRC_R12_CONN_WDT_IRQ_B | \
|
||||
WAKE_SRC_R12_CCIF0_EVENT_B | \
|
||||
WAKE_SRC_R12_SSPM_SPM_IRQ_B | \
|
||||
WAKE_SRC_R12_SCP_SPM_IRQ_B | \
|
||||
WAKE_SRC_R12_SCP_WDT_EVENT_B | \
|
||||
WAKE_SRC_R12_USB_CDSC_B | \
|
||||
WAKE_SRC_R12_USB_POWERDWN_B | \
|
||||
WAKE_SRC_R12_SYS_TIMER_EVENT_B | \
|
||||
WAKE_SRC_R12_EINT_EVENT_SECURE_B | \
|
||||
WAKE_SRC_R12_CCIF1_EVENT_B | \
|
||||
WAKE_SRC_R12_MD2AP_PEER_EVENT_B | \
|
||||
WAKE_SRC_R12_MD1_WDT_B | \
|
||||
WAKE_SRC_R12_CLDMA_EVENT_B | \
|
||||
WAKE_SRC_R12_SEJ_WDT_GPT_B)
|
||||
|
||||
#define SLP_PCM_FLAGS \
|
||||
(SPM_FLAG_DIS_VCORE_DVS | SPM_FLAG_DIS_VCORE_DFS | \
|
||||
SPM_FLAG_DIS_ATF_ABORT | SPM_FLAG_DISABLE_MMSYS_DVFS | \
|
||||
SPM_FLAG_DIS_INFRA_PDN | SPM_FLAG_SUSPEND_OPTION)
|
||||
|
||||
#define SLP_PCM_FLAGS1 \
|
||||
(SPM_FLAG1_DISABLE_MCDSR)
|
||||
|
||||
static const struct pwr_ctrl suspend_ctrl = {
|
||||
.wake_src = WAKE_SRC_FOR_SUSPEND,
|
||||
.pcm_flags = SLP_PCM_FLAGS,
|
||||
.pcm_flags1 = SLP_PCM_FLAGS1,
|
||||
|
||||
/* SPM_AP_STANDBY_CON */
|
||||
.wfi_op = 0x1,
|
||||
.mp0_cputop_idle_mask = 0,
|
||||
.mp1_cputop_idle_mask = 0,
|
||||
.mcusys_idle_mask = 0,
|
||||
.mm_mask_b = 0,
|
||||
.md_ddr_en_0_dbc_en = 0x1,
|
||||
.md_ddr_en_1_dbc_en = 0,
|
||||
.md_mask_b = 0x1,
|
||||
.sspm_mask_b = 0x1,
|
||||
.scp_mask_b = 0x1,
|
||||
.srcclkeni_mask_b = 0x1,
|
||||
.md_apsrc_1_sel = 0,
|
||||
.md_apsrc_0_sel = 0,
|
||||
.conn_ddr_en_dbc_en = 0x1,
|
||||
.conn_mask_b = 0x1,
|
||||
.conn_apsrc_sel = 0,
|
||||
|
||||
/* SPM_SRC_REQ */
|
||||
.spm_apsrc_req = 0,
|
||||
.spm_f26m_req = 0,
|
||||
.spm_infra_req = 0,
|
||||
.spm_vrf18_req = 0,
|
||||
.spm_ddren_req = 0,
|
||||
.spm_rsv_src_req = 0,
|
||||
.spm_ddren_2_req = 0,
|
||||
.cpu_md_dvfs_sop_force_on = 0,
|
||||
|
||||
/* SPM_SRC_MASK */
|
||||
.csyspwreq_mask = 0x1,
|
||||
.ccif0_md_event_mask_b = 0x1,
|
||||
.ccif0_ap_event_mask_b = 0x1,
|
||||
.ccif1_md_event_mask_b = 0x1,
|
||||
.ccif1_ap_event_mask_b = 0x1,
|
||||
.ccif2_md_event_mask_b = 0x1,
|
||||
.ccif2_ap_event_mask_b = 0x1,
|
||||
.ccif3_md_event_mask_b = 0x1,
|
||||
.ccif3_ap_event_mask_b = 0x1,
|
||||
.md_srcclkena_0_infra_mask_b = 0x1,
|
||||
.md_srcclkena_1_infra_mask_b = 0,
|
||||
.conn_srcclkena_infra_mask_b = 0,
|
||||
.ufs_infra_req_mask_b = 0,
|
||||
.srcclkeni_infra_mask_b = 0,
|
||||
.md_apsrc_req_0_infra_mask_b = 0x1,
|
||||
.md_apsrc_req_1_infra_mask_b = 0x1,
|
||||
.conn_apsrcreq_infra_mask_b = 0x1,
|
||||
.ufs_srcclkena_mask_b = 0,
|
||||
.md_vrf18_req_0_mask_b = 0,
|
||||
.md_vrf18_req_1_mask_b = 0,
|
||||
.ufs_vrf18_req_mask_b = 0,
|
||||
.gce_vrf18_req_mask_b = 0,
|
||||
.conn_infra_req_mask_b = 0x1,
|
||||
.gce_apsrc_req_mask_b = 0,
|
||||
.disp0_apsrc_req_mask_b = 0,
|
||||
.disp1_apsrc_req_mask_b = 0,
|
||||
.mfg_req_mask_b = 0,
|
||||
.vdec_req_mask_b = 0,
|
||||
|
||||
/* SPM_SRC2_MASK */
|
||||
.md_ddr_en_0_mask_b = 0x1,
|
||||
.md_ddr_en_1_mask_b = 0,
|
||||
.conn_ddr_en_mask_b = 0x1,
|
||||
.ddren_sspm_apsrc_req_mask_b = 0x1,
|
||||
.ddren_scp_apsrc_req_mask_b = 0x1,
|
||||
.disp0_ddren_mask_b = 0x1,
|
||||
.disp1_ddren_mask_b = 0x1,
|
||||
.gce_ddren_mask_b = 0x1,
|
||||
.ddren_emi_self_refresh_ch0_mask_b = 0,
|
||||
.ddren_emi_self_refresh_ch1_mask_b = 0,
|
||||
|
||||
/* SPM_WAKEUP_EVENT_MASK */
|
||||
.spm_wakeup_event_mask = 0xF1782218,
|
||||
|
||||
/* SPM_WAKEUP_EVENT_EXT_MASK */
|
||||
.spm_wakeup_event_ext_mask = 0xFFFFFFFF,
|
||||
|
||||
/* SPM_SRC3_MASK */
|
||||
.md_ddr_en_2_0_mask_b = 0x1,
|
||||
.md_ddr_en_2_1_mask_b = 0,
|
||||
.conn_ddr_en_2_mask_b = 0x1,
|
||||
.ddren2_sspm_apsrc_req_mask_b = 0x1,
|
||||
.ddren2_scp_apsrc_req_mask_b = 0x1,
|
||||
.disp0_ddren2_mask_b = 0,
|
||||
.disp1_ddren2_mask_b = 0,
|
||||
.gce_ddren2_mask_b = 0,
|
||||
.ddren2_emi_self_refresh_ch0_mask_b = 0,
|
||||
.ddren2_emi_self_refresh_ch1_mask_b = 0,
|
||||
|
||||
.mp0_cpu0_wfi_en = 0x1,
|
||||
.mp0_cpu1_wfi_en = 0x1,
|
||||
.mp0_cpu2_wfi_en = 0x1,
|
||||
.mp0_cpu3_wfi_en = 0x1,
|
||||
|
||||
.mp1_cpu0_wfi_en = 0x1,
|
||||
.mp1_cpu1_wfi_en = 0x1,
|
||||
.mp1_cpu2_wfi_en = 0x1,
|
||||
.mp1_cpu3_wfi_en = 0x1
|
||||
};
|
||||
|
||||
static uint32_t spm_set_sysclk_settle(void)
|
||||
{
|
||||
mmio_write_32(SPM_CLK_SETTLE, SPM_SYSCLK_SETTLE);
|
||||
return mmio_read_32(SPM_CLK_SETTLE);
|
||||
}
|
||||
|
||||
void go_to_sleep_before_wfi(void)
|
||||
{
|
||||
int cpu = MPIDR_AFFLVL0_VAL(read_mpidr());
|
||||
uint32_t settle;
|
||||
|
||||
settle = spm_set_sysclk_settle();
|
||||
spm_set_cpu_status(cpu);
|
||||
spm_set_power_control(&suspend_ctrl);
|
||||
spm_set_wakeup_event(&suspend_ctrl);
|
||||
spm_set_pcm_flags(&suspend_ctrl);
|
||||
spm_send_cpu_wakeup_event();
|
||||
spm_set_pcm_wdt(0);
|
||||
spm_disable_pcm_timer();
|
||||
|
||||
if (is_infra_pdn(suspend_ctrl.pcm_flags))
|
||||
mt_uart_save();
|
||||
|
||||
if (!mt_console_uart_cg_status())
|
||||
console_switch_state(CONSOLE_FLAG_BOOT);
|
||||
|
||||
INFO("cpu%d: \"%s\", wakesrc = 0x%x, pcm_con1 = 0x%x\n",
|
||||
cpu, spm_get_firmware_version(), suspend_ctrl.wake_src,
|
||||
mmio_read_32(PCM_CON1));
|
||||
INFO("settle = %u, sec = %u, sw_flag = 0x%x 0x%x, src_req = 0x%x\n",
|
||||
settle, mmio_read_32(PCM_TIMER_VAL) / 32768,
|
||||
suspend_ctrl.pcm_flags, suspend_ctrl.pcm_flags1,
|
||||
mmio_read_32(SPM_SRC_REQ));
|
||||
|
||||
if (!mt_console_uart_cg_status())
|
||||
console_switch_state(CONSOLE_FLAG_RUNTIME);
|
||||
}
|
||||
|
||||
static void go_to_sleep_after_wfi(void)
|
||||
{
|
||||
struct wake_status spm_wakesta;
|
||||
|
||||
if (is_infra_pdn(suspend_ctrl.pcm_flags))
|
||||
mt_uart_restore();
|
||||
|
||||
spm_set_pcm_wdt(0);
|
||||
spm_get_wakeup_status(&spm_wakesta);
|
||||
spm_clean_after_wakeup();
|
||||
|
||||
if (!mt_console_uart_cg_status())
|
||||
console_switch_state(CONSOLE_FLAG_BOOT);
|
||||
|
||||
spm_output_wake_reason(&spm_wakesta, "suspend");
|
||||
|
||||
if (!mt_console_uart_cg_status())
|
||||
console_switch_state(CONSOLE_FLAG_RUNTIME);
|
||||
}
|
||||
|
||||
static void spm_enable_armpll_l(void)
|
||||
{
|
||||
/* power on */
|
||||
mmio_setbits_32(ARMPLL_L_PWR_CON0, 0x1);
|
||||
|
||||
/* clear isolation */
|
||||
mmio_clrbits_32(ARMPLL_L_PWR_CON0, 0x2);
|
||||
|
||||
/* enable pll */
|
||||
mmio_setbits_32(ARMPLL_L_CON0, 0x1);
|
||||
|
||||
/* Add 20us delay for turning on PLL */
|
||||
udelay(20);
|
||||
}
|
||||
|
||||
static void spm_disable_armpll_l(void)
|
||||
{
|
||||
/* disable pll */
|
||||
mmio_clrbits_32(ARMPLL_L_CON0, 0x1);
|
||||
|
||||
/* isolation */
|
||||
mmio_setbits_32(ARMPLL_L_PWR_CON0, 0x2);
|
||||
|
||||
/* power off */
|
||||
mmio_clrbits_32(ARMPLL_L_PWR_CON0, 0x1);
|
||||
}
|
||||
|
||||
void spm_system_suspend(void)
|
||||
{
|
||||
spm_disable_armpll_l();
|
||||
bcpu_enable(0);
|
||||
bcpu_sram_enable(0);
|
||||
spm_lock_get();
|
||||
go_to_sleep_before_wfi();
|
||||
spm_lock_release();
|
||||
}
|
||||
|
||||
void spm_system_suspend_finish(void)
|
||||
{
|
||||
spm_lock_get();
|
||||
go_to_sleep_after_wfi();
|
||||
spm_lock_release();
|
||||
spm_enable_armpll_l();
|
||||
bcpu_sram_enable(1);
|
||||
bcpu_enable(1);
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef __SPM_SUSPEND_H__
|
||||
#define __SPM_SUSPEND_H__
|
||||
|
||||
void spm_system_suspend(void);
|
||||
void spm_system_suspend_finish(void);
|
||||
|
||||
#endif /* __SPM_SUSPEND_H__*/
|
||||
+366
@@ -0,0 +1,366 @@
|
||||
/*
|
||||
* Copyright (c) 2019, MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <arch_helpers.h>
|
||||
#include <cortex_a53.h>
|
||||
#include <cortex_a73.h>
|
||||
#include <common/debug.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <platform_def.h>
|
||||
#include <mcucfg.h>
|
||||
#include <spm.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <mtspmc.h>
|
||||
|
||||
#include "mtspmc_private.h"
|
||||
|
||||
|
||||
static void set_retention(int cluster, int tick)
|
||||
{
|
||||
uint64_t cpuectlr;
|
||||
|
||||
if (cluster)
|
||||
cpuectlr = read_a73_cpuectlr_el1();
|
||||
else
|
||||
cpuectlr = read_a53_cpuectlr_el1();
|
||||
|
||||
cpuectlr &= ~0x7ULL;
|
||||
cpuectlr |= tick & 0x7;
|
||||
|
||||
if (cluster)
|
||||
write_a73_cpuectlr_el1(cpuectlr);
|
||||
else
|
||||
write_a53_cpuectlr_el1(cpuectlr);
|
||||
}
|
||||
|
||||
void spm_enable_cpu_auto_off(int cluster, int cpu)
|
||||
{
|
||||
uintptr_t reg = per_cpu(cluster, cpu, MCUCFG_SPARK);
|
||||
|
||||
set_retention(cluster, 1);
|
||||
mmio_clrbits_32(reg, SW_NO_WAIT_Q);
|
||||
}
|
||||
|
||||
void spm_disable_cpu_auto_off(int cluster, int cpu)
|
||||
{
|
||||
uintptr_t reg = per_cpu(cluster, cpu, MCUCFG_SPARK);
|
||||
|
||||
mmio_setbits_32(reg, SW_NO_WAIT_Q);
|
||||
set_retention(cluster, 0);
|
||||
}
|
||||
|
||||
void spm_set_cpu_power_off(int cluster, int cpu)
|
||||
{
|
||||
mmio_clrbits_32(per_cpu(cluster, cpu, SPM_CPU_PWR), PWRCTRL_PWR_ON);
|
||||
}
|
||||
|
||||
void spm_enable_cluster_auto_off(int cluster)
|
||||
{
|
||||
assert(cluster);
|
||||
|
||||
mmio_clrbits_32(MCUCFG_MP2_SPMC, SW_NO_WAIT_Q);
|
||||
mmio_clrbits_32(MCUCFG_MP2_COQ, BIT(0));
|
||||
|
||||
mmio_clrbits_32(SPM_SPMC_DORMANT_ENABLE, MP1_SPMC_SRAM_DORMANT_EN);
|
||||
|
||||
mmio_clrbits_32(per_cluster(cluster, SPM_CLUSTER_PWR), PWRCTRL_PWR_ON);
|
||||
}
|
||||
|
||||
void mcucfg_set_bootaddr(int cluster, int cpu, uintptr_t bootaddr)
|
||||
{
|
||||
uintptr_t reg;
|
||||
const uintptr_t mp2_bootreg[] = {
|
||||
MCUCFG_MP2_RVADDR0, MCUCFG_MP2_RVADDR1,
|
||||
MCUCFG_MP2_RVADDR2, MCUCFG_MP2_RVADDR3 };
|
||||
|
||||
if (cluster) {
|
||||
assert(cpu >= 0 && cpu < 4);
|
||||
reg = mp2_bootreg[cpu];
|
||||
} else {
|
||||
reg = per_cpu(cluster, cpu, MCUCFG_BOOTADDR);
|
||||
}
|
||||
|
||||
mmio_write_32(reg, bootaddr);
|
||||
}
|
||||
|
||||
uintptr_t mcucfg_get_bootaddr(int cluster, int cpu)
|
||||
{
|
||||
uintptr_t reg;
|
||||
const uintptr_t mp2_bootreg[] = {
|
||||
MCUCFG_MP2_RVADDR0, MCUCFG_MP2_RVADDR1,
|
||||
MCUCFG_MP2_RVADDR2, MCUCFG_MP2_RVADDR3 };
|
||||
|
||||
if (cluster) {
|
||||
assert(cpu >= 0 && cpu < 4);
|
||||
reg = mp2_bootreg[cpu];
|
||||
} else {
|
||||
reg = per_cpu(cluster, cpu, MCUCFG_BOOTADDR);
|
||||
}
|
||||
|
||||
return mmio_read_32(reg);
|
||||
}
|
||||
|
||||
void mcucfg_init_archstate(int cluster, int cpu, int arm64)
|
||||
{
|
||||
uintptr_t reg;
|
||||
int i;
|
||||
|
||||
reg = per_cluster(cluster, MCUCFG_INITARCH);
|
||||
i = cluster ? 16 : 12;
|
||||
|
||||
mmio_setbits_32(reg, (arm64 & 1) << (i + cpu));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return power state of specified subsystem
|
||||
*
|
||||
* @mask: mask to SPM_PWR_STATUS to query the power state
|
||||
* of one subsystem.
|
||||
* RETURNS:
|
||||
* 0 (the subsys was powered off)
|
||||
* 1 (the subsys was powered on)
|
||||
*/
|
||||
int spm_get_powerstate(uint32_t mask)
|
||||
{
|
||||
return mmio_read_32(SPM_PWR_STATUS) & mask;
|
||||
}
|
||||
|
||||
int spm_get_cluster_powerstate(int cluster)
|
||||
{
|
||||
uint32_t mask;
|
||||
|
||||
mask = cluster ? PWR_STATUS_MP1_CPUTOP : PWR_STATUS_MP0_CPUTOP;
|
||||
|
||||
return spm_get_powerstate(mask);
|
||||
}
|
||||
|
||||
int spm_get_cpu_powerstate(int cluster, int cpu)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
/*
|
||||
* a quick way to specify the mask of cpu[0-3]/cpu[4-7] in PWR_STATUS
|
||||
* register which are the BITS[9:12](MP0_CPU0~3) and
|
||||
* BITS[16:19](MP1_CPU0~3)
|
||||
*/
|
||||
i = (cluster) ? 16 : 9;
|
||||
i = 1 << (i + cpu);
|
||||
|
||||
return spm_get_powerstate(i);
|
||||
}
|
||||
|
||||
int spmc_init(void)
|
||||
{
|
||||
/* enable SPM register control */
|
||||
mmio_write_32(SPM_POWERON_CONFIG_EN,
|
||||
PROJECT_CODE | MD_BCLK_CG_EN | BCLK_CG_EN);
|
||||
|
||||
#if SPMC_MODE == 1
|
||||
INFO("SPM: enable SPMC mode\n");
|
||||
|
||||
/* 0: SPMC mode 1: Legacy mode */
|
||||
mmio_write_32(SPM_BYPASS_SPMC, 0);
|
||||
|
||||
mmio_clrbits_32(per_cluster(0, SPM_CLUSTER_PWR), PWRCTRL_PWR_ON_2ND);
|
||||
|
||||
mmio_clrbits_32(per_cpu(0, 0, SPM_CPU_PWR), PWRCTRL_PWR_ON_2ND);
|
||||
mmio_clrbits_32(per_cpu(0, 1, SPM_CPU_PWR), PWRCTRL_PWR_ON_2ND);
|
||||
mmio_clrbits_32(per_cpu(0, 2, SPM_CPU_PWR), PWRCTRL_PWR_ON_2ND);
|
||||
mmio_clrbits_32(per_cpu(0, 3, SPM_CPU_PWR), PWRCTRL_PWR_ON_2ND);
|
||||
|
||||
mmio_setbits_32(per_cpu(0, 1, SPM_CPU_PWR), PWRCTRL_PWR_RST_B);
|
||||
mmio_setbits_32(per_cpu(0, 2, SPM_CPU_PWR), PWRCTRL_PWR_RST_B);
|
||||
mmio_setbits_32(per_cpu(0, 3, SPM_CPU_PWR), PWRCTRL_PWR_RST_B);
|
||||
#endif
|
||||
|
||||
mmio_clrbits_32(per_cluster(1, SPM_CLUSTER_PWR), PWRCTRL_PWR_ON_2ND);
|
||||
mmio_setbits_32(per_cluster(1, SPM_CLUSTER_PWR), PWRCTRL_PWR_RST_B);
|
||||
mmio_clrbits_32(per_cluster(1, SPM_CLUSTER_PWR), PWRCTRL_PWR_CLK_DIS);
|
||||
|
||||
mmio_clrbits_32(per_cpu(1, 0, SPM_CPU_PWR), PWRCTRL_PWR_ON_2ND);
|
||||
mmio_clrbits_32(per_cpu(1, 1, SPM_CPU_PWR), PWRCTRL_PWR_ON_2ND);
|
||||
mmio_clrbits_32(per_cpu(1, 2, SPM_CPU_PWR), PWRCTRL_PWR_ON_2ND);
|
||||
mmio_clrbits_32(per_cpu(1, 3, SPM_CPU_PWR), PWRCTRL_PWR_ON_2ND);
|
||||
|
||||
mmio_setbits_32(per_cpu(1, 0, SPM_CPU_PWR), PWRCTRL_PWR_RST_B);
|
||||
mmio_setbits_32(per_cpu(1, 1, SPM_CPU_PWR), PWRCTRL_PWR_RST_B);
|
||||
mmio_setbits_32(per_cpu(1, 2, SPM_CPU_PWR), PWRCTRL_PWR_RST_B);
|
||||
mmio_setbits_32(per_cpu(1, 3, SPM_CPU_PWR), PWRCTRL_PWR_RST_B);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Power on a core with specified cluster and core index
|
||||
*
|
||||
* @cluster: the cluster ID of the CPU which to be powered on
|
||||
* @cpu: the CPU ID of the CPU which to be powered on
|
||||
*/
|
||||
void spm_poweron_cpu(int cluster, int cpu)
|
||||
{
|
||||
INFO("spmc: power on core %d.%d\n", cluster, cpu);
|
||||
|
||||
/* STA_POWER_ON */
|
||||
/* Start to turn on MP0_CPU0 */
|
||||
|
||||
/* Set PWR_RST_B = 1 */
|
||||
mmio_setbits_32(per_cpu(cluster, cpu, SPM_CPU_PWR), PWRCTRL_PWR_RST_B);
|
||||
|
||||
/* Set PWR_ON = 1 */
|
||||
mmio_setbits_32(per_cpu(cluster, cpu, SPM_CPU_PWR), PWRCTRL_PWR_ON);
|
||||
|
||||
/* Wait until MP0_CPU0_PWR_STA_MASK = 1 */
|
||||
while (!spm_get_cpu_powerstate(cluster, cpu))
|
||||
;
|
||||
|
||||
/* Finish to turn on MP0_CPU0 */
|
||||
INFO("spmc: power on core %d.%d successfully\n", cluster, cpu);
|
||||
}
|
||||
|
||||
/**
|
||||
* Power off a core with specified cluster and core index
|
||||
*
|
||||
* @cluster: the cluster ID of the CPU which to be powered off
|
||||
* @cpu: the CPU ID of the CPU which to be powered off
|
||||
*/
|
||||
void spm_poweroff_cpu(int cluster, int cpu)
|
||||
{
|
||||
INFO("spmc: power off core %d.%d\n", cluster, cpu);
|
||||
|
||||
/* Start to turn off MP0_CPU0 */
|
||||
/* Set PWR_ON_2ND = 0 */
|
||||
mmio_clrbits_32(per_cpu(cluster, cpu, SPM_CPU_PWR), PWRCTRL_PWR_ON_2ND);
|
||||
|
||||
/* Set PWR_ON = 0 */
|
||||
mmio_clrbits_32(per_cpu(cluster, cpu, SPM_CPU_PWR), PWRCTRL_PWR_ON);
|
||||
|
||||
/* Wait until MP0_CPU0_PWR_STA_MASK = 0 */
|
||||
while (spm_get_cpu_powerstate(cluster, cpu))
|
||||
;
|
||||
|
||||
/* Set PWR_RST_B = 0 */
|
||||
mmio_clrbits_32(per_cpu(cluster, cpu, SPM_CPU_PWR), PWRCTRL_PWR_RST_B);
|
||||
|
||||
/* Finish to turn off MP0_CPU0 */
|
||||
INFO("spmc: power off core %d.%d successfully\n", cluster, cpu);
|
||||
}
|
||||
|
||||
/**
|
||||
* Power off a cluster with specified index
|
||||
*
|
||||
* @cluster: the cluster index which to be powered off
|
||||
*/
|
||||
void spm_poweroff_cluster(int cluster)
|
||||
{
|
||||
uint32_t mask;
|
||||
uint32_t pwr_rst_ctl;
|
||||
|
||||
INFO("spmc: power off cluster %d\n", cluster);
|
||||
|
||||
/* Start to turn off MP0_CPUTOP */
|
||||
/* Set bus protect - step1 : 0 */
|
||||
mask = (cluster) ? MP1_CPUTOP_PROT_STEP1_0_MASK :
|
||||
MP0_CPUTOP_PROT_STEP1_0_MASK;
|
||||
mmio_write_32(INFRA_TOPAXI_PROTECTEN_1_SET, mask);
|
||||
|
||||
while ((mmio_read_32(INFRA_TOPAXI_PROTECTEN_STA1_1) & mask) != mask)
|
||||
;
|
||||
|
||||
/* Set PWR_ON_2ND = 0 */
|
||||
mmio_clrbits_32(per_cluster(cluster, SPM_CLUSTER_PWR),
|
||||
PWRCTRL_PWR_ON_2ND);
|
||||
|
||||
/* SPMC_DORMANT_ENABLE[0]=0 */
|
||||
mask = (cluster) ? MP1_SPMC_SRAM_DORMANT_EN : MP0_SPMC_SRAM_DORMANT_EN;
|
||||
mmio_clrbits_32(SPM_SPMC_DORMANT_ENABLE, mask);
|
||||
|
||||
/* Set PWR_ON = 0" */
|
||||
mmio_clrbits_32(per_cluster(cluster, SPM_CLUSTER_PWR), PWRCTRL_PWR_ON);
|
||||
|
||||
/* Wait until MP0_CPUTOP_PWR_STA_MASK = 0 */
|
||||
while (spm_get_cluster_powerstate(cluster))
|
||||
;
|
||||
|
||||
/* NOTE
|
||||
* Following flow only for BIG core cluster. It was from
|
||||
* application note but not covered in mtcmos_ctrl.c
|
||||
*/
|
||||
if (cluster) {
|
||||
pwr_rst_ctl = mmio_read_32(MCUCFG_MP2_PWR_RST_CTL);
|
||||
mmio_write_32(MCUCFG_MP2_PWR_RST_CTL,
|
||||
(pwr_rst_ctl & ~SW_RST_B) | TOPAON_APB_MASK);
|
||||
}
|
||||
|
||||
/* CPU_EXT_BUCK_ISO[0]=1 */
|
||||
if (cluster)
|
||||
mmio_setbits_32(SPM_CPU_EXT_BUCK_ISO, MP1_EXT_BUCK_ISO);
|
||||
|
||||
/* Finish to turn off MP0_CPUTOP */
|
||||
INFO("spmc: power off cluster %d successfully\n", cluster);
|
||||
}
|
||||
|
||||
/**
|
||||
* Power on a cluster with specified index
|
||||
*
|
||||
* @cluster: the cluster index which to be powered on
|
||||
*/
|
||||
void spm_poweron_cluster(int cluster)
|
||||
{
|
||||
uint32_t mask;
|
||||
uint32_t pwr_rst_ctl;
|
||||
|
||||
INFO("spmc: power on cluster %d\n", cluster);
|
||||
|
||||
/* Start to turn on MP1_CPUTOP */
|
||||
|
||||
/* NOTE
|
||||
* Following flow only for BIG core cluster. It was from
|
||||
* application note but not covered in mtcmos_ctrl.c
|
||||
*/
|
||||
if (cluster) {
|
||||
mmio_clrbits_32(MCUCFG_MP2_PWR_RST_CTL, SW_RST_B);
|
||||
|
||||
/* CPU_EXT_BUCK_ISO[1]=0 */
|
||||
/* Set mp<n>_vproc_ext_off to 0 to release vproc isolation control */
|
||||
mmio_clrbits_32(SPM_CPU_EXT_BUCK_ISO, MP1_EXT_BUCK_ISO);
|
||||
|
||||
/* NOTE
|
||||
* Following flow only for BIG core cluster. It was from
|
||||
* application note but not covered in mtcmos_ctrl.c
|
||||
*/
|
||||
pwr_rst_ctl = mmio_read_32(MCUCFG_MP2_PWR_RST_CTL);
|
||||
mmio_write_32(MCUCFG_MP2_PWR_RST_CTL,
|
||||
(pwr_rst_ctl | SW_RST_B) & ~TOPAON_APB_MASK);
|
||||
}
|
||||
|
||||
/* Set PWR_ON_2ND = 0 */
|
||||
mmio_clrbits_32(per_cluster(cluster, SPM_CLUSTER_PWR),
|
||||
PWRCTRL_PWR_ON_2ND);
|
||||
|
||||
/* Set PWR_RST_B = 1 */
|
||||
mmio_setbits_32(per_cluster(cluster, SPM_CLUSTER_PWR),
|
||||
PWRCTRL_PWR_RST_B);
|
||||
|
||||
/* Set PWR_CLK_DIS = 0 */
|
||||
mmio_clrbits_32(per_cluster(cluster, SPM_CLUSTER_PWR),
|
||||
PWRCTRL_PWR_CLK_DIS);
|
||||
|
||||
/* Set PWR_ON = 1 */
|
||||
mmio_setbits_32(per_cluster(cluster, SPM_CLUSTER_PWR), PWRCTRL_PWR_ON);
|
||||
|
||||
/* Wait until MP1_CPUTOP_PWR_STA_MASK = 1 */
|
||||
while (!spm_get_cluster_powerstate(cluster))
|
||||
;
|
||||
|
||||
/* Release bus protect - step1 : 0 */
|
||||
mask = (cluster) ? MP1_CPUTOP_PROT_STEP1_0_MASK :
|
||||
MP0_CPUTOP_PROT_STEP1_0_MASK;
|
||||
mmio_write_32(INFRA_TOPAXI_PROTECTEN_1_CLR, mask);
|
||||
|
||||
/* Finish to turn on MP1_CPUTOP */
|
||||
INFO("spmc: power on cluster %d successfully\n", cluster);
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2019, MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef MTSPMC_H
|
||||
#define MTSPMC_H
|
||||
|
||||
/*
|
||||
* CONFIG_SPMC_MODE: Select CPU power control mode.
|
||||
*
|
||||
* 0: Legacy
|
||||
* Control power flow from SW through SPM register (MP*_PWR_CON).
|
||||
* 1: HW
|
||||
* Control power flow from SPMC. Most control flow and timing are handled
|
||||
* by SPMC.
|
||||
*/
|
||||
#define SPMC_MODE 1
|
||||
|
||||
int spmc_init(void);
|
||||
|
||||
void spm_poweron_cpu(int cluster, int cpu);
|
||||
void spm_poweroff_cpu(int cluster, int cpu);
|
||||
|
||||
void spm_poweroff_cluster(int cluster);
|
||||
void spm_poweron_cluster(int cluster);
|
||||
|
||||
int spm_get_cpu_powerstate(int cluster, int cpu);
|
||||
int spm_get_cluster_powerstate(int cluster);
|
||||
int spm_get_powerstate(uint32_t mask);
|
||||
|
||||
void spm_enable_cpu_auto_off(int cluster, int cpu);
|
||||
void spm_disable_cpu_auto_off(int cluster, int cpu);
|
||||
void spm_set_cpu_power_off(int cluster, int cpu);
|
||||
void spm_enable_cluster_auto_off(int cluster);
|
||||
|
||||
void mcucfg_init_archstate(int cluster, int cpu, int arm64);
|
||||
void mcucfg_set_bootaddr(int cluster, int cpu, uintptr_t bootaddr);
|
||||
uintptr_t mcucfg_get_bootaddr(int cluster, int cpu);
|
||||
|
||||
#endif /* MTSPMC_H */
|
||||
+233
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* Copyright (c) 2019, MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef MTSPMC_PRIVATE_H
|
||||
#define MTSPMC_PRIVATE_H
|
||||
|
||||
/*
|
||||
* per_cpu/cluster helper
|
||||
*/
|
||||
struct per_cpu_reg {
|
||||
int cluster_addr;
|
||||
int cpu_stride;
|
||||
};
|
||||
|
||||
#define per_cpu(cluster, cpu, reg) (reg[cluster].cluster_addr + \
|
||||
(cpu << reg[cluster].cpu_stride))
|
||||
#define per_cluster(cluster, reg) (reg[cluster].cluster_addr)
|
||||
|
||||
/* SPMC related registers */
|
||||
#define SPM_POWERON_CONFIG_EN (SPM_BASE + 0x000)
|
||||
/* bit-fields of SPM_POWERON_CONFIG_EN */
|
||||
#define BCLK_CG_EN (1 << 0)
|
||||
#define MD_BCLK_CG_EN (1 << 1)
|
||||
#define PROJECT_CODE (0xb16 << 16)
|
||||
|
||||
#define SPM_PWR_STATUS (SPM_BASE + 0x180)
|
||||
#define SPM_PWR_STATUS_2ND (SPM_BASE + 0x184)
|
||||
|
||||
#define SPM_BYPASS_SPMC (SPM_BASE + 0x2b4)
|
||||
#define SPM_SPMC_DORMANT_ENABLE (SPM_BASE + 0x2b8)
|
||||
|
||||
#define SPM_MP0_CPUTOP_PWR_CON (SPM_BASE + 0x204)
|
||||
#define SPM_MP0_CPU0_PWR_CON (SPM_BASE + 0x208)
|
||||
#define SPM_MP0_CPU1_PWR_CON (SPM_BASE + 0x20C)
|
||||
#define SPM_MP0_CPU2_PWR_CON (SPM_BASE + 0x210)
|
||||
#define SPM_MP0_CPU3_PWR_CON (SPM_BASE + 0x214)
|
||||
#define SPM_MP1_CPUTOP_PWR_CON (SPM_BASE + 0x218)
|
||||
#define SPM_MP1_CPU0_PWR_CON (SPM_BASE + 0x21C)
|
||||
#define SPM_MP1_CPU1_PWR_CON (SPM_BASE + 0x220)
|
||||
#define SPM_MP1_CPU2_PWR_CON (SPM_BASE + 0x224)
|
||||
#define SPM_MP1_CPU3_PWR_CON (SPM_BASE + 0x228)
|
||||
#define SPM_MP0_CPUTOP_L2_PDN (SPM_BASE + 0x240)
|
||||
#define SPM_MP0_CPUTOP_L2_SLEEP_B (SPM_BASE + 0x244)
|
||||
#define SPM_MP0_CPU0_L1_PDN (SPM_BASE + 0x248)
|
||||
#define SPM_MP0_CPU1_L1_PDN (SPM_BASE + 0x24C)
|
||||
#define SPM_MP0_CPU2_L1_PDN (SPM_BASE + 0x250)
|
||||
#define SPM_MP0_CPU3_L1_PDN (SPM_BASE + 0x254)
|
||||
#define SPM_MP1_CPUTOP_L2_PDN (SPM_BASE + 0x258)
|
||||
#define SPM_MP1_CPUTOP_L2_SLEEP_B (SPM_BASE + 0x25C)
|
||||
#define SPM_MP1_CPU0_L1_PDN (SPM_BASE + 0x260)
|
||||
#define SPM_MP1_CPU1_L1_PDN (SPM_BASE + 0x264)
|
||||
#define SPM_MP1_CPU2_L1_PDN (SPM_BASE + 0x268)
|
||||
#define SPM_MP1_CPU3_L1_PDN (SPM_BASE + 0x26C)
|
||||
|
||||
#define SPM_CPU_EXT_BUCK_ISO (SPM_BASE + 0x290)
|
||||
/* bit-fields of SPM_CPU_EXT_BUCK_ISO */
|
||||
#define MP0_EXT_BUCK_ISO (1 << 0)
|
||||
#define MP1_EXT_BUCK_ISO (1 << 1)
|
||||
#define MP_EXT_BUCK_ISO (1 << 2)
|
||||
|
||||
/* bit-fields of SPM_PWR_STATUS */
|
||||
#define PWR_STATUS_MD (1 << 0)
|
||||
#define PWR_STATUS_CONN (1 << 1)
|
||||
#define PWR_STATUS_DDRPHY (1 << 2)
|
||||
#define PWR_STATUS_DISP (1 << 3)
|
||||
#define PWR_STATUS_MFG (1 << 4)
|
||||
#define PWR_STATUS_ISP (1 << 5)
|
||||
#define PWR_STATUS_INFRA (1 << 6)
|
||||
#define PWR_STATUS_VDEC (1 << 7)
|
||||
#define PWR_STATUS_MP0_CPUTOP (1 << 8)
|
||||
#define PWR_STATUS_MP0_CPU0 (1 << 9)
|
||||
#define PWR_STATUS_MP0_CPU1 (1 << 10)
|
||||
#define PWR_STATUS_MP0_CPU2 (1 << 11)
|
||||
#define PWR_STATUS_MP0_CPU3 (1 << 12)
|
||||
#define PWR_STATUS_MCUSYS (1 << 14)
|
||||
#define PWR_STATUS_MP1_CPUTOP (1 << 15)
|
||||
#define PWR_STATUS_MP1_CPU0 (1 << 16)
|
||||
#define PWR_STATUS_MP1_CPU1 (1 << 17)
|
||||
#define PWR_STATUS_MP1_CPU2 (1 << 18)
|
||||
#define PWR_STATUS_MP1_CPU3 (1 << 19)
|
||||
#define PWR_STATUS_VEN (1 << 21)
|
||||
#define PWR_STATUS_MFG_ASYNC (1 << 23)
|
||||
#define PWR_STATUS_AUDIO (1 << 24)
|
||||
#define PWR_STATUS_C2K (1 << 28)
|
||||
#define PWR_STATUS_MD_INFRA (1 << 29)
|
||||
|
||||
|
||||
/* bit-fields of SPM_*_PWR_CON */
|
||||
#define PWRCTRL_PWR_RST_B (1 << 0)
|
||||
#define PWRCTRL_PWR_ISO (1 << 1)
|
||||
#define PWRCTRL_PWR_ON (1 << 2)
|
||||
#define PWRCTRL_PWR_ON_2ND (1 << 3)
|
||||
#define PWRCTRL_PWR_CLK_DIS (1 << 4)
|
||||
#define PWRCTRL_PWR_SRAM_CKISO (1 << 5)
|
||||
#define PWRCTRL_PWR_SRAM_ISOINT_B (1 << 6)
|
||||
#define PWRCTRL_PWR_SRAM_PD_SLPB_CLAMP (1 << 7)
|
||||
#define PWRCTRL_PWR_SRAM_PDN (1 << 8)
|
||||
#define PWRCTRL_PWR_SRAM_SLEEP_B (1 << 12)
|
||||
#define PWRCTRL_PWR_SRAM_PDN_ACK (1 << 24)
|
||||
#define PWRCTRL_PWR_SRAM_SLEEP_B_ACK (1 << 28)
|
||||
|
||||
/* per_cpu registers for SPM_MP?_CPU?_PWR_CON */
|
||||
static const struct per_cpu_reg SPM_CPU_PWR[] = {
|
||||
[0] = { .cluster_addr = SPM_MP0_CPU0_PWR_CON, .cpu_stride = 2 },
|
||||
[1] = { .cluster_addr = SPM_MP1_CPU0_PWR_CON, .cpu_stride = 2 },
|
||||
};
|
||||
|
||||
/* per_cluster registers for SPM_MP?_CPUTOP_PWR_CON */
|
||||
static const struct per_cpu_reg SPM_CLUSTER_PWR[] = {
|
||||
[0] = { .cluster_addr = SPM_MP0_CPUTOP_PWR_CON },
|
||||
[1] = { .cluster_addr = SPM_MP1_CPUTOP_PWR_CON },
|
||||
};
|
||||
|
||||
/* APB Module infracfg_ao */
|
||||
#define INFRA_TOPAXI_PROTECTEN_1 (INFRACFG_AO_BASE + 0x250)
|
||||
#define INFRA_TOPAXI_PROTECTEN_STA1_1 (INFRACFG_AO_BASE + 0x258)
|
||||
#define INFRA_TOPAXI_PROTECTEN_1_SET (INFRACFG_AO_BASE + 0x2A8)
|
||||
#define INFRA_TOPAXI_PROTECTEN_1_CLR (INFRACFG_AO_BASE + 0x2AC)
|
||||
|
||||
/* bit-fields of INFRA_TOPAXI_PROTECTEN_1_SET */
|
||||
#define MP0_CPUTOP_PROT_STEP1_0_MASK ((1 << 10)|(1 << 12)| \
|
||||
(1 << 13)|(1 << 26))
|
||||
#define MP1_CPUTOP_PROT_STEP1_0_MASK ((1 << 11)|(1 << 14)| \
|
||||
(1 << 15)|(1 << 27))
|
||||
|
||||
/* bit-fields of INFRA_TOPAXI_PROTECTEN_STA1_1 */
|
||||
#define MP0_CPUTOP_PROT_STEP1_0_ACK_MASK ((1 << 10)|(1 << 12)| \
|
||||
(1 << 13)|(1 << 26))
|
||||
#define MP1_CPUTOP_PROT_STEP1_0_ACK_MASK ((1 << 11)|(1 << 14)| \
|
||||
(1 << 15)|(1 << 27))
|
||||
|
||||
|
||||
/*
|
||||
* MCU configuration registers
|
||||
*/
|
||||
|
||||
/* bit-fields of MCUCFG_MP?_AXI_CONFIG */
|
||||
#define MCUCFG_AXI_CONFIG_BROADCASTINNER (1 << 0)
|
||||
#define MCUCFG_AXI_CONFIG_BROADCASTOUTER (1 << 1)
|
||||
#define MCUCFG_AXI_CONFIG_BROADCASTCACHEMAINT (1 << 2)
|
||||
#define MCUCFG_AXI_CONFIG_SYSBARDISABLE (1 << 3)
|
||||
#define MCUCFG_AXI_CONFIG_ACINACTM (1 << 4)
|
||||
#define MCUCFG_AXI_CONFIG_AINACTS (1 << 5)
|
||||
|
||||
|
||||
#define MCUCFG_MP0_MISC_CONFIG2 ((uintptr_t)&mt8183_mcucfg->mp0_misc_config[2])
|
||||
#define MCUCFG_MP0_MISC_CONFIG3 ((uintptr_t)&mt8183_mcucfg->mp0_misc_config[3])
|
||||
#define MCUCFG_MP1_MISC_CONFIG2 ((uintptr_t)&mt8183_mcucfg->mp1_misc_config[2])
|
||||
#define MCUCFG_MP1_MISC_CONFIG3 ((uintptr_t)&mt8183_mcucfg->mp1_misc_config[3])
|
||||
|
||||
#define MCUCFG_CPUSYS0_SPARKVRETCNTRL (MCUCFG_BASE + 0x1c00)
|
||||
/* bit-fields of MCUCFG_CPUSYS0_SPARKVRETCNTRL */
|
||||
#define CPU0_SPARK_VRET_CTRL (0x3f << 0)
|
||||
#define CPU1_SPARK_VRET_CTRL (0x3f << 8)
|
||||
#define CPU2_SPARK_VRET_CTRL (0x3f << 16)
|
||||
#define CPU3_SPARK_VRET_CTRL (0x3f << 24)
|
||||
|
||||
/* SPARK control in little cores */
|
||||
#define MCUCFG_CPUSYS0_CPU0_SPMC_CTL (MCUCFG_BASE + 0x1c30)
|
||||
#define MCUCFG_CPUSYS0_CPU1_SPMC_CTL (MCUCFG_BASE + 0x1c34)
|
||||
#define MCUCFG_CPUSYS0_CPU2_SPMC_CTL (MCUCFG_BASE + 0x1c38)
|
||||
#define MCUCFG_CPUSYS0_CPU3_SPMC_CTL (MCUCFG_BASE + 0x1c3c)
|
||||
/* bit-fields of MCUCFG_CPUSYS0_CPU?_SPMC_CTL */
|
||||
#define SW_SPARK_EN (1 << 0)
|
||||
#define SW_NO_WAIT_Q (1 << 1)
|
||||
|
||||
/* the MCUCFG which BIG cores used is at (MCUCFG_BASE + 0x2000) */
|
||||
#define MCUCFG_MP2_BASE (MCUCFG_BASE + 0x2000)
|
||||
#define MCUCFG_MP2_PWR_RST_CTL (MCUCFG_MP2_BASE + 0x8)
|
||||
/* bit-fields of MCUCFG_MP2_PWR_RST_CTL */
|
||||
#define SW_RST_B (1 << 0)
|
||||
#define TOPAON_APB_MASK (1 << 1)
|
||||
|
||||
#define MCUCFG_MP2_CPUCFG (MCUCFG_MP2_BASE + 0x208)
|
||||
|
||||
#define MCUCFG_MP2_RVADDR0 (MCUCFG_MP2_BASE + 0x290)
|
||||
#define MCUCFG_MP2_RVADDR1 (MCUCFG_MP2_BASE + 0x298)
|
||||
#define MCUCFG_MP2_RVADDR2 (MCUCFG_MP2_BASE + 0x2c0)
|
||||
#define MCUCFG_MP2_RVADDR3 (MCUCFG_MP2_BASE + 0x2c8)
|
||||
|
||||
/* SPMC control */
|
||||
#define MCUCFG_MP0_SPMC (MCUCFG_BASE + 0x788)
|
||||
#define MCUCFG_MP2_SPMC (MCUCFG_MP2_BASE + 0x2a0)
|
||||
#define MCUCFG_MP2_COQ (MCUCFG_MP2_BASE + 0x2bC)
|
||||
|
||||
/* per_cpu registers for MCUCFG_MP?_MISC_CONFIG2 */
|
||||
static const struct per_cpu_reg MCUCFG_BOOTADDR[] = {
|
||||
[0] = { .cluster_addr = MCUCFG_MP0_MISC_CONFIG2, .cpu_stride = 3 },
|
||||
};
|
||||
|
||||
/* per_cpu registers for MCUCFG_MP?_MISC_CONFIG3 */
|
||||
static const struct per_cpu_reg MCUCFG_INITARCH[] = {
|
||||
[0] = { .cluster_addr = MCUCFG_MP0_MISC_CONFIG3 },
|
||||
[1] = { .cluster_addr = MCUCFG_MP2_CPUCFG },
|
||||
};
|
||||
|
||||
/* SPARK control in BIG cores */
|
||||
#define MCUCFG_MP2_PTP3_CPU0_SPMC0 (MCUCFG_MP2_BASE + 0x430)
|
||||
#define MCUCFG_MP2_PTP3_CPU0_SPMC1 (MCUCFG_MP2_BASE + 0x434)
|
||||
#define MCUCFG_MP2_PTP3_CPU1_SPMC0 (MCUCFG_MP2_BASE + 0x438)
|
||||
#define MCUCFG_MP2_PTP3_CPU1_SPMC1 (MCUCFG_MP2_BASE + 0x43c)
|
||||
#define MCUCFG_MP2_PTP3_CPU2_SPMC0 (MCUCFG_MP2_BASE + 0x440)
|
||||
#define MCUCFG_MP2_PTP3_CPU2_SPMC1 (MCUCFG_MP2_BASE + 0x444)
|
||||
#define MCUCFG_MP2_PTP3_CPU3_SPMC0 (MCUCFG_MP2_BASE + 0x448)
|
||||
#define MCUCFG_MP2_PTP3_CPU3_SPMC1 (MCUCFG_MP2_BASE + 0x44c)
|
||||
/* bit-fields of MCUCFG_MP2_PTP3_CPU?_SPMC? */
|
||||
#define SW_SPARK_EN (1 << 0)
|
||||
#define SW_NO_WAIT_Q (1 << 1)
|
||||
|
||||
#define MCUCFG_MP2_SPARK2LDO (MCUCFG_MP2_BASE + 0x700)
|
||||
/* bit-fields of MCUCFG_MP2_SPARK2LDO */
|
||||
#define SPARK_VRET_CTRL (0x3f << 0)
|
||||
#define CPU0_SPARK_LDO_AMUXSEL (0xf << 6)
|
||||
#define CPU1_SPARK_LDO_AMUXSEL (0xf << 10)
|
||||
#define CPU2_SPARK_LDO_AMUXSEL (0xf << 14)
|
||||
#define CPU3_SPARK_LDO_AMUXSEL (0xf << 18)
|
||||
|
||||
/* per_cpu registers for SPARK */
|
||||
static const struct per_cpu_reg MCUCFG_SPARK[] = {
|
||||
[0] = { .cluster_addr = MCUCFG_CPUSYS0_CPU0_SPMC_CTL, .cpu_stride = 2 },
|
||||
[1] = { .cluster_addr = MCUCFG_MP2_PTP3_CPU0_SPMC0, .cpu_stride = 3 },
|
||||
};
|
||||
|
||||
/* per_cpu registers for SPARK2LDO */
|
||||
static const struct per_cpu_reg MCUCFG_SPARK2LDO[] = {
|
||||
[0] = { .cluster_addr = MCUCFG_CPUSYS0_SPARKVRETCNTRL },
|
||||
[1] = { .cluster_addr = MCUCFG_MP2_SPARK2LDO },
|
||||
};
|
||||
|
||||
#endif /* MTSPMC_PRIVATE_H */
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#include <arch_helpers.h>
|
||||
#include <common/debug.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <errno.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <sspm.h>
|
||||
|
||||
static void memcpy_to_sspm(uint32_t dst, uint32_t *src, uint32_t len)
|
||||
{
|
||||
while (len--) {
|
||||
mmio_write_32(dst, *src);
|
||||
dst += sizeof(uint32_t);
|
||||
src++;
|
||||
}
|
||||
}
|
||||
|
||||
static void memcpy_from_sspm(uint32_t *dst, uint32_t src, uint32_t len)
|
||||
{
|
||||
while (len--) {
|
||||
*dst = mmio_read_32(src);
|
||||
dst++;
|
||||
src += sizeof(uint32_t);
|
||||
}
|
||||
}
|
||||
|
||||
int sspm_mbox_read(uint32_t slot, uint32_t *data, uint32_t len)
|
||||
{
|
||||
if (slot >= 32) {
|
||||
ERROR("%s:slot = %d\n", __func__, slot);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (data)
|
||||
memcpy_from_sspm(data,
|
||||
MBOX3_BASE + slot * 4,
|
||||
len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sspm_mbox_write(uint32_t slot, uint32_t *data, uint32_t len)
|
||||
{
|
||||
if (slot >= 32) {
|
||||
ERROR("%s:slot = %d\n", __func__, slot);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (data)
|
||||
memcpy_to_sspm(MBOX3_BASE + slot * 4,
|
||||
data,
|
||||
len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sspm_ipi_check_ack(uint32_t id)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (id == IPI_ID_PLATFORM) {
|
||||
if ((mmio_read_32(MBOX0_BASE + MBOX_IN_IRQ_OFS) & 0x1) == 0x1)
|
||||
ret = -EINPROGRESS;
|
||||
} else if (id == IPI_ID_SUSPEND) {
|
||||
if ((mmio_read_32(MBOX1_BASE + MBOX_IN_IRQ_OFS) & 0x2) == 0x2)
|
||||
ret = -EINPROGRESS;
|
||||
} else {
|
||||
ERROR("%s: id = %d\n", __func__, id);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sspm_ipi_send_non_blocking(uint32_t id, uint32_t *data)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = sspm_ipi_check_ack(id);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (id == IPI_ID_PLATFORM) {
|
||||
memcpy_to_sspm(MBOX0_BASE + PINR_OFFSET_PLATFORM * 4,
|
||||
data,
|
||||
PINR_SIZE_PLATFORM);
|
||||
dsb();
|
||||
mmio_write_32(MBOX0_BASE + MBOX_OUT_IRQ_OFS, 0x1);
|
||||
} else if (id == IPI_ID_SUSPEND) {
|
||||
memcpy_to_sspm(MBOX1_BASE + PINR_OFFSET_SUSPEND * 4,
|
||||
data,
|
||||
PINR_SIZE_SUSPEND);
|
||||
dsb();
|
||||
mmio_write_32(MBOX1_BASE + MBOX_OUT_IRQ_OFS,
|
||||
0x2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sspm_ipi_recv_non_blocking(uint32_t id, uint32_t *data, uint32_t len)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = sspm_ipi_check_ack(id);
|
||||
if (ret == -EINPROGRESS) {
|
||||
if (id == IPI_ID_PLATFORM) {
|
||||
memcpy_from_sspm(data,
|
||||
MBOX0_BASE + PINR_OFFSET_PLATFORM * 4,
|
||||
len);
|
||||
dsb();
|
||||
/* clear interrupt bit*/
|
||||
mmio_write_32(MBOX0_BASE + MBOX_IN_IRQ_OFS,
|
||||
0x1);
|
||||
ret = 0;
|
||||
} else if (id == IPI_ID_SUSPEND) {
|
||||
memcpy_from_sspm(data,
|
||||
MBOX1_BASE + PINR_OFFSET_SUSPEND * 4,
|
||||
len);
|
||||
dsb();
|
||||
/* clear interrupt bit*/
|
||||
mmio_write_32(MBOX1_BASE + MBOX_IN_IRQ_OFS,
|
||||
0x2);
|
||||
ret = 0;
|
||||
}
|
||||
} else if (ret == 0) {
|
||||
ret = -EBUSY;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sspm_alive_show(void)
|
||||
{
|
||||
uint32_t ipi_data, count;
|
||||
int ret = 0;
|
||||
|
||||
count = 5;
|
||||
ipi_data = 0xdead;
|
||||
|
||||
if (sspm_ipi_send_non_blocking(IPI_ID_PLATFORM, &ipi_data) != 0) {
|
||||
ERROR("sspm init send fail! ret=%d\n", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (sspm_ipi_recv_non_blocking(IPI_ID_PLATFORM,
|
||||
&ipi_data,
|
||||
sizeof(ipi_data) / sizeof(uint32_t))
|
||||
&& count) {
|
||||
mdelay(100);
|
||||
count--;
|
||||
}
|
||||
|
||||
return (ipi_data == 1) ? 0 : -1;
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef __SSPM_H__
|
||||
#define __SSPM_H__
|
||||
/* These should sync with sspm.bin */
|
||||
#define IPI_ID_PLATFORM 0
|
||||
#define IPI_ID_SUSPEND 6
|
||||
#define PINR_OFFSET_PLATFORM 0
|
||||
#define PINR_SIZE_PLATFORM 3
|
||||
#define PINR_OFFSET_SUSPEND 2
|
||||
#define PINR_SIZE_SUSPEND 8
|
||||
|
||||
#define MBOX0_BASE 0x10450000
|
||||
#define MBOX1_BASE 0x10460000
|
||||
#define MBOX3_BASE 0x10480000
|
||||
#define MBOX_OUT_IRQ_OFS 0x1000
|
||||
#define MBOX_IN_IRQ_OFS 0x1004
|
||||
|
||||
#define SHAREMBOX_OFFSET_MCDI 0
|
||||
#define SHAREMBOX_SIZE_MCDI 20
|
||||
#define SHAREMBOX_OFFSET_SUSPEND 26
|
||||
#define SHAREMBOX_SIZE_SUSPEND 6
|
||||
|
||||
int sspm_mbox_read(uint32_t slot, uint32_t *data, uint32_t len);
|
||||
int sspm_mbox_write(uint32_t slot, uint32_t *data, uint32_t len);
|
||||
int sspm_ipi_send_non_blocking(uint32_t id, uint32_t *data);
|
||||
int sspm_ipi_recv_non_blocking(uint32_t slot, uint32_t *data, uint32_t len);
|
||||
int sspm_alive_show(void);
|
||||
#endif /* __SSPM_H__ */
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2020, MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#include <arch_helpers.h>
|
||||
#include <common/debug.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <mcucfg.h>
|
||||
#include <mt_timer.h>
|
||||
#include <platform_def.h>
|
||||
|
||||
static void enable_systimer_compensation(void)
|
||||
{
|
||||
unsigned int reg;
|
||||
|
||||
reg = mmio_read_32(CNTCR_REG);
|
||||
reg &= ~COMP_15_EN;
|
||||
reg |= COMP_20_EN;
|
||||
mmio_write_32(CNTCR_REG, reg);
|
||||
|
||||
NOTICE("[systimer] CNTCR_REG(0x%x)\n", mmio_read_32(CNTCR_REG));
|
||||
}
|
||||
|
||||
void mt_systimer_init(void)
|
||||
{
|
||||
/* systimer is default on, so we only enable systimer compensation */
|
||||
enable_systimer_compensation();
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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 COMP_15_EN (1 << 10)
|
||||
#define COMP_20_EN (1 << 11)
|
||||
|
||||
void mt_systimer_init(void);
|
||||
|
||||
#endif /* MT_TIMER_H */
|
||||
Reference in New Issue
Block a user