From 650d9c521e271f9802c8c95da456875f348fc8cc Mon Sep 17 00:00:00 2001 From: Harvey Hsieh Date: Mon, 21 Aug 2017 15:01:53 +0800 Subject: [PATCH] Tegra: memctrl: clean MC INT status before exit to bootloader This patch cleans the Memory controller's interrupt status register, before exiting to the non-secure world during cold boot. This is required as we observed that the MC's arbitration bit is set before exiting the secure world. Change-Id: Iacd01994d03b3b9cbd7b8a57fe7ab5b04e607a9f Signed-off-by: Harvey Hsieh --- .../tegra/common/drivers/memctrl/memctrl_v1.c | 13 +++++++++++++ .../tegra/common/drivers/memctrl/memctrl_v2.c | 5 +++++ plat/nvidia/tegra/common/tegra_bl31_setup.c | 9 +++++++++ plat/nvidia/tegra/include/drivers/memctrl.h | 1 + plat/nvidia/tegra/include/t132/tegra_def.h | 3 +++ plat/nvidia/tegra/include/t210/tegra_def.h | 3 +++ 6 files changed, 34 insertions(+) diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c index 27ad563bc..92fa273b5 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c @@ -209,3 +209,16 @@ void tegra_memctrl_disable_ahb_redirection(void) /* lock the aperture registers */ tegra_mc_write_32(MC_IRAM_REG_CTRL, MC_DISABLE_IRAM_CFG_WRITES); } + +void tegra_memctrl_clear_pending_interrupts(void) +{ + uint32_t mcerr; + + /* check if there are any pending interrupts */ + mcerr = mmio_read_32(TEGRA_MC_BASE + MC_INTSTATUS); + + if (mcerr != (uint32_t)0U) { /* should not see error here */ + WARN("MC_INTSTATUS = 0x%x (should be zero)\n", mcerr); + mmio_write_32((TEGRA_MC_BASE + MC_INTSTATUS), mcerr); + } +} diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c index cfa95818e..1b221c2f6 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c @@ -712,3 +712,8 @@ void tegra_memctrl_disable_ahb_redirection(void) { ; /* do nothing */ } + +void tegra_memctrl_clear_pending_interrupts(void) +{ + ; /* do nothing */ +} diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c index 30ff0a38d..afb10fef4 100644 --- a/plat/nvidia/tegra/common/tegra_bl31_setup.c +++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c @@ -341,6 +341,15 @@ void bl31_platform_setup(void) ******************************************************************************/ void bl31_plat_runtime_setup(void) { + /* + * During cold boot, it is observed that the arbitration + * bit is set in the Memory controller leading to false + * error interrupts in the non-secure world. To avoid + * this, clean the interrupt status register before + * booting into the non-secure world + */ + tegra_memctrl_clear_pending_interrupts(); + /* * During boot, USB3 and flash media (SDMMC/SATA) devices need * access to IRAM. Because these clients connect to the MC and diff --git a/plat/nvidia/tegra/include/drivers/memctrl.h b/plat/nvidia/tegra/include/drivers/memctrl.h index 17427cbec..d5ef60d0c 100644 --- a/plat/nvidia/tegra/include/drivers/memctrl.h +++ b/plat/nvidia/tegra/include/drivers/memctrl.h @@ -13,5 +13,6 @@ void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes); void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes); void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes); void tegra_memctrl_disable_ahb_redirection(void); +void tegra_memctrl_clear_pending_interrupts(void); #endif /* MEMCTRL_H */ diff --git a/plat/nvidia/tegra/include/t132/tegra_def.h b/plat/nvidia/tegra/include/t132/tegra_def.h index 1f58caabb..fd75fbce6 100644 --- a/plat/nvidia/tegra/include/t132/tegra_def.h +++ b/plat/nvidia/tegra/include/t132/tegra_def.h @@ -83,6 +83,9 @@ ******************************************************************************/ #define TEGRA_MC_BASE U(0x70019000) +/* Memory Controller Interrupt Status */ +#define MC_INTSTATUS 0x00U + /* TZDRAM carveout configuration registers */ #define MC_SECURITY_CFG0_0 U(0x70) #define MC_SECURITY_CFG1_0 U(0x74) diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h index b16a129da..75919e11e 100644 --- a/plat/nvidia/tegra/include/t210/tegra_def.h +++ b/plat/nvidia/tegra/include/t210/tegra_def.h @@ -163,6 +163,9 @@ ******************************************************************************/ #define TEGRA_MC_BASE U(0x70019000) +/* Memory Controller Interrupt Status */ +#define MC_INTSTATUS 0x00U + /* TZDRAM carveout configuration registers */ #define MC_SECURITY_CFG0_0 U(0x70) #define MC_SECURITY_CFG1_0 U(0x74)