From 1eed3838b37113d11dafd072a25ec8cd8871330b Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 18 May 2016 13:39:16 -0700 Subject: [PATCH] Tegra186: Enable ECC and Parity Protection for A02p SKUs This patch enables ECC and Parity Protection for Cortex-A57 CPUs during boot, for Tegra186 A02p SKUs. Change-Id: I8522a6cb61f5e4fa9e0471f558a0c3ee8078370e Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/include/t186/tegra_def.h | 7 +++ plat/nvidia/tegra/soc/t186/plat_setup.c | 63 +++++++++++++++++++--- 2 files changed, 62 insertions(+), 8 deletions(-) diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h index 7f85351eb..f0bd5d57a 100644 --- a/plat/nvidia/tegra/include/t186/tegra_def.h +++ b/plat/nvidia/tegra/include/t186/tegra_def.h @@ -105,6 +105,13 @@ #define TEGRA_UARTF_BASE 0x03150000 #define TEGRA_UARTG_BASE 0x0C290000 +/******************************************************************************* + * Tegra Fuse Controller related constants + ******************************************************************************/ +#define TEGRA_FUSE_BASE 0x03820000 +#define OPT_SUBREVISION 0x248 +#define SUBREVISION_MASK 0xFF + /******************************************************************************* * GICv2 & interrupt handling related constants ******************************************************************************/ diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c index 49f45892f..1dd0d6ee7 100644 --- a/plat/nvidia/tegra/soc/t186/plat_setup.c +++ b/plat/nvidia/tegra/soc/t186/plat_setup.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -43,6 +44,9 @@ #include #include +DEFINE_RENAME_SYSREG_RW_FUNCS(l2ctlr_el1, L2CTLR_EL1) +extern uint64_t tegra_enable_l2_ecc_parity_prot; + /******************************************************************************* * The Tegra power domain tree has a single system level power domain i.e. a * single root node. The first entry in the power domain descriptor specifies @@ -74,6 +78,8 @@ static const mmap_region_t tegra_mmap[] = { MT_DEVICE | MT_RW | MT_SECURE), MAP_REGION_FLAT(TEGRA_UARTA_BASE, 0x20000, /* 128KB */ MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(TEGRA_FUSE_BASE, 0x10000, /* 64KB */ + MT_DEVICE | MT_RW | MT_SECURE), MAP_REGION_FLAT(TEGRA_GICD_BASE, 0x20000, /* 128KB */ MT_DEVICE | MT_RW | MT_SECURE), MAP_REGION_FLAT(TEGRA_SE0_BASE, 0x10000, /* 64KB */ @@ -142,6 +148,55 @@ 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_minor, chip_major, chip_subrev, val; + + /* sanity check MCE firmware compatibility */ + mce_verify_firmware_version(); + + /* + * Enable ECC and Parity Protection for Cortex-A57 CPUs + * for Tegra A02p SKUs + */ + if (impl != DENVER_IMPL) { + + /* get the major, minor and sub-version values */ + chip_major = (mmio_read_32(TEGRA_MISC_BASE + + HARDWARE_REVISION_OFFSET) >> + MAJOR_VERSION_SHIFT) & MAJOR_VERSION_MASK; + chip_minor = (mmio_read_32(TEGRA_MISC_BASE + + HARDWARE_REVISION_OFFSET) >> + MINOR_VERSION_SHIFT) & MINOR_VERSION_MASK; + chip_subrev = mmio_read_32(TEGRA_FUSE_BASE + OPT_SUBREVISION) & + SUBREVISION_MASK; + + /* prepare chip version number */ + val = (chip_major << 12) | (chip_minor << 8) | chip_subrev; + + /* enable L2 ECC for Tegra186 A02P and beyond */ + if (val >= TEGRA186_VER_A02P) { + + val = read_l2ctlr_el1(); + val |= 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; + } + } +} + /* Secure IRQs for Tegra186 */ static const irq_sec_cfg_t tegra186_sec_irqs[] = { { @@ -171,11 +226,3 @@ void plat_gic_setup(void) if (sizeof(tegra186_sec_irqs) > 0) tegra_fiq_handler_setup(); } - -/******************************************************************************* - * Handler for early platform setup - ******************************************************************************/ -void plat_early_platform_setup(void) -{ - mce_verify_firmware_version(); -}