diff --git a/docs/plat/nvidia-tegra.rst b/docs/plat/nvidia-tegra.rst index 56dfacf..e244c1c 100644 --- a/docs/plat/nvidia-tegra.rst +++ b/docs/plat/nvidia-tegra.rst @@ -80,6 +80,8 @@ 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 0476ba8..fca2f7e 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_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 9aacaa0..b1c4016 100644 --- a/plat/nvidia/tegra/common/tegra_bl31_setup.c +++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c @@ -157,6 +157,7 @@ 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 93223cc..1fa04ad 100644 --- a/plat/nvidia/tegra/include/tegra_private.h +++ b/plat/nvidia/tegra/include/tegra_private.h @@ -32,9 +32,16 @@ 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 ******************************************************************************/ struct tegra_bl31_params { diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c index fb94bce..06d6cbb 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 #include #include +#include #include #include #include @@ -282,6 +283,22 @@ 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 d6513eb..50e1446 100644 --- a/plat/nvidia/tegra/soc/t186/plat_setup.c +++ b/plat/nvidia/tegra/soc/t186/plat_setup.c @@ -27,9 +27,6 @@ #include #include -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 @@ 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) { + if ((plat_params->l2_ecc_parity_prot_dis != 1) && + (impl != (uint64_t)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; - } + val = read_l2ctlr_el1(); + val |= (uint64_t)CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT; + write_l2ctlr_el1(val); } }