From b495791ba28ae36078e09d32877fca8e97088410 Mon Sep 17 00:00:00 2001 From: Harvey Hsieh <hhsieh@nvidia.com> Date: Wed, 23 Nov 2016 19:13:08 +0800 Subject: [PATCH] Tegra: support to set the L2 ECC and Parity enable bit This patch adds capability to read the boot flag to enable L2 ECC and Parity Protection bit for the Cortex-A57 CPUs. The previous bootloader sets this flag value for the platform. * with some coverity fix: MISRA C-2012 Directive 4.6 MISRA C-2012 Rule 2.5 MISRA C-2012 Rule 10.3 MISRA C-2012 Rule 10.4 Change-Id: Id7303bbbdc290b52919356c31625847b8904b073 Signed-off-by: Harvey Hsieh <hhsieh@nvidia.com> Signed-off-by: Varun Wadekar <vwadekar@nvidia.com> --- docs/plat/nvidia-tegra.rst | 2 + .../tegra/common/aarch64/tegra_helpers.S | 22 --------- plat/nvidia/tegra/common/tegra_bl31_setup.c | 1 + plat/nvidia/tegra/include/tegra_private.h | 7 +++ .../tegra/soc/t186/plat_psci_handlers.c | 17 +++++++ plat/nvidia/tegra/soc/t186/plat_setup.c | 46 +++++-------------- 6 files changed, 39 insertions(+), 56 deletions(-) diff --git a/docs/plat/nvidia-tegra.rst b/docs/plat/nvidia-tegra.rst index 56dfacfc8..e244c1c99 100644 --- a/docs/plat/nvidia-tegra.rst +++ b/docs/plat/nvidia-tegra.rst @@ -80,6 +80,8 @@ uint64\_t tzdram\_size; uint64\_t tzdram\_base; /* UART port ID \*/ int uart\_id; +/* L2 ECC parity protection disable flag \*/ +int l2\_ecc\_parity\_prot\_dis; } plat\_params\_from\_bl2\_t; Power Management diff --git a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S index 0476ba826..fca2f7e36 100644 --- a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S +++ b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S @@ -45,7 +45,6 @@ .globl ns_image_entrypoint .globl tegra_bl31_phys_base .globl tegra_console_base - .globl tegra_enable_l2_ecc_parity_prot /* --------------------- * Common CPU init code @@ -92,20 +91,6 @@ msr actlr_el2, x0 isb - /* ------------------------------------------------------- - * Enable L2 ECC and Parity Protection - * ------------------------------------------------------- - */ - adr x0, tegra_enable_l2_ecc_parity_prot - ldr x0, [x0] - cbz x0, 1f - mrs x0, CORTEX_A57_L2CTLR_EL1 - and x1, x0, #CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT - cbnz x1, 1f - orr x0, x0, #CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT - msr CORTEX_A57_L2CTLR_EL1, x0 - isb - /* -------------------------------- * Enable the cycle count register * -------------------------------- @@ -460,10 +445,3 @@ tegra_bl31_phys_base: */ tegra_console_base: .quad 0 - - /* -------------------------------------------------- - * Enable L2 ECC and Parity Protection - * -------------------------------------------------- - */ -tegra_enable_l2_ecc_parity_prot: - .quad 0 diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c index 9aacaa058..b1c4016ef 100644 --- a/plat/nvidia/tegra/common/tegra_bl31_setup.c +++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c @@ -157,6 +157,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, plat_bl31_params_from_bl2.tzdram_base = plat_params->tzdram_base; plat_bl31_params_from_bl2.tzdram_size = plat_params->tzdram_size; plat_bl31_params_from_bl2.uart_id = plat_params->uart_id; + plat_bl31_params_from_bl2.l2_ecc_parity_prot_dis = plat_params->l2_ecc_parity_prot_dis; /* * It is very important that we run either from TZDRAM or TZSRAM base. diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h index 93223cc24..1fa04adce 100644 --- a/plat/nvidia/tegra/include/tegra_private.h +++ b/plat/nvidia/tegra/include/tegra_private.h @@ -32,8 +32,15 @@ typedef struct plat_params_from_bl2 { uint64_t tzdram_base; /* UART port ID */ int uart_id; + /* L2 ECC parity protection disable flag */ + int l2_ecc_parity_prot_dis; } plat_params_from_bl2_t; +/******************************************************************************* + * Helper function to access l2ctlr_el1 register on Cortex-A57 CPUs + ******************************************************************************/ +DEFINE_RENAME_SYSREG_RW_FUNCS(l2ctlr_el1, CORTEX_A57_L2CTLR_EL1) + /******************************************************************************* * Struct describing parameters passed to bl31 ******************************************************************************/ diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c index fb94bcedf..06d6cbb21 100644 --- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c @@ -12,6 +12,7 @@ #include <common/bl_common.h> #include <common/debug.h> #include <context.h> +#include <cortex_a57.h> #include <denver.h> #include <lib/el3_runtime/context_mgmt.h> #include <lib/psci/psci.h> @@ -282,6 +283,22 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) int stateid_afflvl2 = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]; int stateid_afflvl0 = target_state->pwr_domain_state[MPIDR_AFFLVL0]; mce_cstate_info_t cstate_info = { 0 }; + uint64_t impl, val; + const plat_params_from_bl2_t *plat_params = bl31_get_plat_params(); + + impl = (read_midr() >> MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK; + + /* + * Enable ECC and Parity Protection for Cortex-A57 CPUs (Tegra186 + * A02p and beyond). + */ + if ((plat_params->l2_ecc_parity_prot_dis != 1) && + (impl != (uint64_t)DENVER_IMPL)) { + + val = read_l2ctlr_el1(); + val |= (uint64_t)CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT; + write_l2ctlr_el1(val); + } /* * Reset power state info for CPUs when onlining, we set diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c index d6513ebc7..50e14469f 100644 --- a/plat/nvidia/tegra/soc/t186/plat_setup.c +++ b/plat/nvidia/tegra/soc/t186/plat_setup.c @@ -27,9 +27,6 @@ #include <tegra_platform.h> #include <tegra_private.h> -DEFINE_RENAME_SYSREG_RW_FUNCS(l2ctlr_el1, CORTEX_A57_L2CTLR_EL1) -extern uint64_t tegra_enable_l2_ecc_parity_prot; - /******************************************************************************* * Tegra186 CPU numbers in cluster #0 ******************************************************************************* @@ -152,48 +149,29 @@ uint32_t plat_get_console_from_id(int id) return tegra186_uart_addresses[id]; } -/* represent chip-version as concatenation of major (15:12), minor (11:8) and subrev (7:0) */ -#define TEGRA186_VER_A02P 0x1201 - /******************************************************************************* * Handler for early platform setup ******************************************************************************/ void plat_early_platform_setup(void) { - int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK; - uint32_t chip_subrev, val; + uint64_t impl, val; + const plat_params_from_bl2_t *plat_params = bl31_get_plat_params(); /* sanity check MCE firmware compatibility */ mce_verify_firmware_version(); + impl = (read_midr() >> MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK; + /* - * Enable ECC and Parity Protection for Cortex-A57 CPUs - * for Tegra A02p SKUs + * Enable ECC and Parity Protection for Cortex-A57 CPUs (Tegra186 + * A02p and beyond). */ - if (impl != DENVER_IMPL) { - - /* get the major, minor and sub-version values */ - chip_subrev = mmio_read_32(TEGRA_FUSE_BASE + OPT_SUBREVISION) & - SUBREVISION_MASK; - - /* prepare chip version number */ - val = (tegra_get_chipid_major() << 12) | - (tegra_get_chipid_minor() << 8) | - chip_subrev; - - /* enable L2 ECC for Tegra186 A02P and beyond */ - if (val >= TEGRA186_VER_A02P) { - - val = read_l2ctlr_el1(); - val |= CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT; - write_l2ctlr_el1(val); - - /* - * Set the flag to enable ECC/Parity Protection - * when we exit System Suspend or Cluster Powerdn - */ - tegra_enable_l2_ecc_parity_prot = 1; - } + if ((plat_params->l2_ecc_parity_prot_dis != 1) && + (impl != (uint64_t)DENVER_IMPL)) { + + val = read_l2ctlr_el1(); + val |= (uint64_t)CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT; + write_l2ctlr_el1(val); } } -- GitLab