diff --git a/plat/nvidia/tegra/include/drivers/pmc.h b/plat/nvidia/tegra/include/drivers/pmc.h index 53317de1e..c376440f3 100644 --- a/plat/nvidia/tegra/include/drivers/pmc.h +++ b/plat/nvidia/tegra/include/drivers/pmc.h @@ -14,18 +14,29 @@ #include #define PMC_CONFIG U(0x0) +#define PMC_DPD_ENABLE_0 U(0x24) #define PMC_PWRGATE_STATUS U(0x38) #define PMC_PWRGATE_TOGGLE U(0x30) +#define PMC_SECURE_SCRATCH0 U(0xb0) +#define PMC_SECURE_SCRATCH5 U(0xc4) +#define PMC_CRYPTO_OP_0 U(0xf4) #define PMC_TOGGLE_START U(0x100) #define PMC_SCRATCH39 U(0x138) +#define PMC_SECURE_SCRATCH6 U(0x224) +#define PMC_SECURE_SCRATCH7 U(0x228) #define PMC_SECURE_DISABLE2 U(0x2c4) #define PMC_SECURE_DISABLE2_WRITE22_ON (U(1) << 28) +#define PMC_SECURE_SCRATCH8 U(0x300) +#define PMC_SECURE_SCRATCH79 U(0x41c) +#define PMC_FUSE_CONTROL_0 U(0x450) #define PMC_SECURE_SCRATCH22 U(0x338) #define PMC_SECURE_DISABLE3 U(0x2d8) #define PMC_SECURE_DISABLE3_WRITE34_ON (U(1) << 20) #define PMC_SECURE_DISABLE3_WRITE35_ON (U(1) << 22) #define PMC_SECURE_SCRATCH34 U(0x368) #define PMC_SECURE_SCRATCH35 U(0x36c) +#define PMC_SECURE_SCRATCH80 U(0xa98) +#define PMC_SECURE_SCRATCH119 U(0xb34) #define PMC_SCRATCH201 U(0x844) static inline uint32_t tegra_pmc_read_32(uint32_t off) diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h index eed443d11..0f24f324c 100644 --- a/plat/nvidia/tegra/include/t210/tegra_def.h +++ b/plat/nvidia/tegra/include/t210/tegra_def.h @@ -196,6 +196,7 @@ * Tegra Power Mgmt Controller constants ******************************************************************************/ #define TEGRA_PMC_BASE U(0x7000E400) +#define TEGRA_PMC_SIZE U(0xC00) /* 3k */ /******************************************************************************* * Tegra Atomics constants diff --git a/plat/nvidia/tegra/soc/t210/plat_sip_calls.c b/plat/nvidia/tegra/soc/t210/plat_sip_calls.c new file mode 100644 index 000000000..0e8900ef7 --- /dev/null +++ b/plat/nvidia/tegra/soc/t210/plat_sip_calls.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/******************************************************************************* + * PMC parameters + ******************************************************************************/ +#define PMC_READ U(0xaa) +#define PMC_WRITE U(0xbb) + +/******************************************************************************* + * Tegra210 SiP SMCs + ******************************************************************************/ +#define TEGRA_SIP_PMC_COMMANDS U(0xC2FFFE00) + +/******************************************************************************* + * This function is responsible for handling all T210 SiP calls + ******************************************************************************/ +int plat_sip_handler(uint32_t smc_fid, + uint64_t x1, + uint64_t x2, + uint64_t x3, + uint64_t x4, + const void *cookie, + void *handle, + uint64_t flags) +{ + uint32_t val, ns; + + /* Determine which security state this SMC originated from */ + ns = is_caller_non_secure(flags); + if (!ns) + SMC_RET1(handle, SMC_UNK); + + switch (smc_fid) { + case TEGRA_SIP_PMC_COMMANDS: + + /* check the address is within PMC range and is 4byte aligned */ + if ((x2 >= TEGRA_PMC_SIZE) || (x2 & 0x3)) + return -EINVAL; + + /* pmc_secure_scratch registers are not accessible */ + if (((x2 >= PMC_SECURE_SCRATCH0) && (x2 <= PMC_SECURE_SCRATCH5)) || + ((x2 >= PMC_SECURE_SCRATCH6) && (x2 <= PMC_SECURE_SCRATCH7)) || + ((x2 >= PMC_SECURE_SCRATCH8) && (x2 <= PMC_SECURE_SCRATCH79)) || + ((x2 >= PMC_SECURE_SCRATCH80) && (x2 <= PMC_SECURE_SCRATCH119))) + return -EFAULT; + + /* PMC secure-only registers are not accessible */ + if ((x2 == PMC_DPD_ENABLE_0) || (x2 == PMC_FUSE_CONTROL_0) || + (x2 == PMC_CRYPTO_OP_0)) + return -EFAULT; + + /* Perform PMC read/write */ + if (x1 == PMC_READ) { + val = mmio_read_32((uint32_t)(TEGRA_PMC_BASE + x2)); + write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X1, val); + } else if (x1 == PMC_WRITE) { + mmio_write_32((uint32_t)(TEGRA_PMC_BASE + x2), (uint32_t)x3); + } else { + return -EINVAL; + } + + break; + + default: + ERROR("%s: unsupported function ID\n", __func__); + return -ENOTSUP; + } + + return 0; +} diff --git a/plat/nvidia/tegra/soc/t210/platform_t210.mk b/plat/nvidia/tegra/soc/t210/platform_t210.mk index 723534a1d..d9371ed6b 100644 --- a/plat/nvidia/tegra/soc/t210/platform_t210.mk +++ b/plat/nvidia/tegra/soc/t210/platform_t210.mk @@ -36,7 +36,8 @@ BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \ ${SOC_DIR}/plat_psci_handlers.c \ ${SOC_DIR}/plat_setup.c \ ${SOC_DIR}/drivers/se/security_engine.c \ - ${SOC_DIR}/plat_secondary.c + ${SOC_DIR}/plat_secondary.c \ + ${SOC_DIR}/plat_sip_calls.c # Enable workarounds for selected Cortex-A57 erratas. A57_DISABLE_NON_TEMPORAL_HINT := 1