From 75516c3eb021e91e37e4d3115a0bbab143ddd2ff Mon Sep 17 00:00:00 2001 From: Steven Kao <skao@nvidia.com> Date: Wed, 14 Jun 2017 14:02:23 +0800 Subject: [PATCH] Tegra: read-modify-write ACTLR_ELx registers This patch changes direct writes to ACTLR_ELx registers to use read-modify-write instead. Change-Id: I6e0eaa6974583f3035cb3724088f3f1c849da229 Signed-off-by: Steven Kao <skao@nvidia.com> --- .../tegra/common/aarch64/tegra_helpers.S | 34 +++++++++++++------ plat/nvidia/tegra/include/tegra_private.h | 10 ++++++ .../tegra/soc/t132/plat_psci_handlers.c | 10 ++++-- plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c | 5 ++- 4 files changed, 46 insertions(+), 13 deletions(-) diff --git a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S index 2bf9a225d..4bf1a9df4 100644 --- a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S +++ b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S @@ -18,16 +18,21 @@ /******************************************************************************* * Implementation defined ACTLR_EL3 bit definitions ******************************************************************************/ -#define ACTLR_EL3_L2ACTLR_BIT (1 << 6) -#define ACTLR_EL3_L2ECTLR_BIT (1 << 5) -#define ACTLR_EL3_L2CTLR_BIT (1 << 4) -#define ACTLR_EL3_CPUECTLR_BIT (1 << 1) -#define ACTLR_EL3_CPUACTLR_BIT (1 << 0) +#define ACTLR_EL3_L2ACTLR_BIT (U(1) << 6) +#define ACTLR_EL3_L2ECTLR_BIT (U(1) << 5) +#define ACTLR_EL3_L2CTLR_BIT (U(1) << 4) +#define ACTLR_EL3_CPUECTLR_BIT (U(1) << 1) +#define ACTLR_EL3_CPUACTLR_BIT (U(1) << 0) +#define ACTLR_EL3_ENABLE_ALL_MASK (ACTLR_EL3_L2ACTLR_BIT | \ + ACTLR_EL3_L2ECTLR_BIT | \ + ACTLR_EL3_L2CTLR_BIT | \ + ACTLR_EL3_CPUECTLR_BIT | \ + ACTLR_EL3_CPUACTLR_BIT) #define ACTLR_EL3_ENABLE_ALL_ACCESS (ACTLR_EL3_L2ACTLR_BIT | \ - ACTLR_EL3_L2ECTLR_BIT | \ - ACTLR_EL3_L2CTLR_BIT | \ - ACTLR_EL3_CPUECTLR_BIT | \ - ACTLR_EL3_CPUACTLR_BIT) + ACTLR_EL3_L2ECTLR_BIT | \ + ACTLR_EL3_L2CTLR_BIT | \ + ACTLR_EL3_CPUECTLR_BIT | \ + ACTLR_EL3_CPUACTLR_BIT) /* Global functions */ .globl plat_is_my_cpu_primary @@ -87,8 +92,17 @@ * Enable L2 and CPU ECTLR RW access from non-secure world * ------------------------------------------------------- */ - mov x0, #ACTLR_EL3_ENABLE_ALL_ACCESS + mrs x0, actlr_el3 + mov x1, #ACTLR_EL3_ENABLE_ALL_MASK + bic x0, x0, x1 + mov x1, #ACTLR_EL3_ENABLE_ALL_ACCESS + orr x0, x0, x1 msr actlr_el3, x0 + mrs x0, actlr_el2 + mov x1, #ACTLR_EL3_ENABLE_ALL_MASK + bic x0, x0, x1 + mov x1, #ACTLR_EL3_ENABLE_ALL_ACCESS + orr x0, x0, x1 msr actlr_el2, x0 isb diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h index ff1bd50d9..c7636f61d 100644 --- a/plat/nvidia/tegra/include/tegra_private.h +++ b/plat/nvidia/tegra/include/tegra_private.h @@ -22,6 +22,16 @@ #define TEGRA_DRAM_BASE ULL(0x80000000) #define TEGRA_DRAM_END ULL(0x27FFFFFFF) +/******************************************************************************* + * Implementation defined ACTLR_EL1 bit definitions + ******************************************************************************/ +#define ACTLR_EL1_PMSTATE_MASK (ULL(0xF) << 0) + +/******************************************************************************* + * Implementation defined ACTLR_EL2 bit definitions + ******************************************************************************/ +#define ACTLR_EL2_PMSTATE_MASK (ULL(0xF) << 0) + /******************************************************************************* * Struct for parameters received from BL2 ******************************************************************************/ diff --git a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c index 7226120b0..bd3f46fcc 100644 --- a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c @@ -98,19 +98,24 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state) { + uint64_t val; + tegra_fc_cpu_off(read_mpidr() & MPIDR_CPU_MASK); /* Disable DCO operations */ denver_disable_dco(); /* Power down the CPU */ - write_actlr_el1(DENVER_CPU_STATE_POWER_DOWN); + val = read_actlr_el1() & ~ACTLR_EL1_PMSTATE_MASK; + write_actlr_el1(val | DENVER_CPU_STATE_POWER_DOWN); return PSCI_E_SUCCESS; } int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) { + uint64_t val; + #if ENABLE_ASSERTIONS int cpu = read_mpidr() & MPIDR_CPU_MASK; @@ -128,7 +133,8 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) denver_disable_dco(); /* Program the suspend state ID */ - write_actlr_el1(target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]); + val = read_actlr_el1() & ~ACTLR_EL1_PMSTATE_MASK; + write_actlr_el1(val | target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]); return PSCI_E_SUCCESS; } diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c b/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c index 44ee8fbf6..1e41cb785 100644 --- a/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c +++ b/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c @@ -14,10 +14,12 @@ #include <mce_private.h> #include <t18x_ari.h> +#include <tegra_private.h> int32_t nvg_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time) { int32_t ret = 0; + uint64_t val = 0ULL; (void)ari_base; @@ -31,7 +33,8 @@ int32_t nvg_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time) nvg_set_request_data(TEGRA_NVG_CHANNEL_WAKE_TIME, wake_time); /* set the core cstate */ - write_actlr_el1(state); + val = read_actlr_el1() & ~ACTLR_EL1_PMSTATE_MASK; + write_actlr_el1(val | (uint64_t)state); } return ret; -- GitLab