From e64ce3abb3d0c320a5e5293b9864c9762023c5fb Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Fri, 11 Mar 2016 17:18:51 -0800 Subject: [PATCH 01/14] Tegra186: re-configure MSS' client settings This patch reprograms MSS to make ROC deal with ordering of MC traffic after boot and system suspend exit. This is needed as device boots with MSS having all control but POR wants ROC to deal with the ordering. Performance is expected to improve with ROC but since no one has really tested the performance, keep the option configurable for now by introducing a platform level makefile variable. Change-Id: I2e782fea138ccf9d281eb043a6b2c3bb97c839a7 Signed-off-by: Varun Wadekar --- .../tegra/common/drivers/memctrl/memctrl_v2.c | 261 ++++++++++++++++++ .../nvidia/tegra/include/drivers/memctrl_v2.h | 252 +++++++++++++++-- plat/nvidia/tegra/include/t186/tegra_def.h | 5 + plat/nvidia/tegra/soc/t186/plat_setup.c | 2 + plat/nvidia/tegra/soc/t186/platform_t186.mk | 7 +- 5 files changed, 506 insertions(+), 21 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c index e11b8adac..437106b01 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c @@ -234,6 +234,251 @@ const static mc_txn_override_cfg_t mc_override_cfgs[] = { mc_make_txn_override_cfg(SCEW, CGID_TAG_ADR), }; +static void tegra_memctrl_reconfig_mss_clients(void) +{ +#if ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS + uint32_t val, wdata_0, wdata_1; + + /* + * Assert Memory Controller's HOTRESET_FLUSH_ENABLE signal for + * boot and strongly ordered MSS clients to flush existing memory + * traffic and stall future requests. + */ + val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL0); + assert(val == MC_CLIENT_HOTRESET_CTRL0_RESET_VAL); + + wdata_0 = MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB; + tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0); + + /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */ + do { + val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0); + } while ((val & wdata_0) != wdata_0); + + /* Wait one more time due to SW WAR for known legacy issue */ + do { + val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0); + } while ((val & wdata_0) != wdata_0); + + val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL1); + assert(val == MC_CLIENT_HOTRESET_CTRL1_RESET_VAL); + + wdata_1 = MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB; + tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1); + + /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */ + do { + val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1); + } while ((val & wdata_1) != wdata_1); + + /* Wait one more time due to SW WAR for known legacy issue */ + do { + val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1); + } while ((val & wdata_1) != wdata_1); + + /* + * Change MEMTYPE_OVERRIDE from SO_DEV -> PASSTHRU for boot and + * strongly ordered MSS clients. ROC needs to be single point + * of control on overriding the memory type. So, remove TSA's + * memtype override. + */ + mc_set_tsa_passthrough(AFIW); + mc_set_tsa_passthrough(HDAW); + mc_set_tsa_passthrough(SATAW); + mc_set_tsa_passthrough(XUSB_HOSTW); + mc_set_tsa_passthrough(XUSB_DEVW); + mc_set_tsa_passthrough(SDMMCWAB); + mc_set_tsa_passthrough(APEDMAW); + mc_set_tsa_passthrough(SESWR); + mc_set_tsa_passthrough(ETRW); + mc_set_tsa_passthrough(AXISW); + mc_set_tsa_passthrough(EQOSW); + mc_set_tsa_passthrough(UFSHCW); + mc_set_tsa_passthrough(BPMPDMAW); + mc_set_tsa_passthrough(AONDMAW); + mc_set_tsa_passthrough(SCEDMAW); + + /* + * Change COH_PATH_OVERRIDE_SO_DEV from NO_OVERRIDE -> FORCE_COHERENT + * for boot and strongly ordered MSS clients. This steers all sodev + * transactions to ROC. + * + * Change AXID_OVERRIDE/AXID_OVERRIDE_SO_DEV only for some clients + * whose AXI IDs we know and trust. + */ + + /* Match AFIW */ + mc_set_forced_coherent_so_dev_cfg(AFIR); + + /* + * See bug 200131110 comment #35 - there are no normal requests + * and AWID for SO/DEV requests is hardcoded in RTL for a + * particular PCIE controller + */ + mc_set_forced_coherent_so_dev_cfg(AFIW); + mc_set_forced_coherent_cfg(HDAR); + mc_set_forced_coherent_cfg(HDAW); + mc_set_forced_coherent_cfg(SATAR); + mc_set_forced_coherent_cfg(SATAW); + mc_set_forced_coherent_cfg(XUSB_HOSTR); + mc_set_forced_coherent_cfg(XUSB_HOSTW); + mc_set_forced_coherent_cfg(XUSB_DEVR); + mc_set_forced_coherent_cfg(XUSB_DEVW); + mc_set_forced_coherent_cfg(SDMMCRAB); + mc_set_forced_coherent_cfg(SDMMCWAB); + + /* Match APEDMAW */ + mc_set_forced_coherent_axid_so_dev_cfg(APEDMAR); + + /* + * See bug 200131110 comment #35 - AWID for normal requests + * is 0x80 and AWID for SO/DEV requests is 0x01 + */ + mc_set_forced_coherent_axid_so_dev_cfg(APEDMAW); + mc_set_forced_coherent_cfg(SESRD); + mc_set_forced_coherent_cfg(SESWR); + mc_set_forced_coherent_cfg(ETRR); + mc_set_forced_coherent_cfg(ETRW); + mc_set_forced_coherent_cfg(AXISR); + mc_set_forced_coherent_cfg(AXISW); + mc_set_forced_coherent_cfg(EQOSR); + mc_set_forced_coherent_cfg(EQOSW); + mc_set_forced_coherent_cfg(UFSHCR); + mc_set_forced_coherent_cfg(UFSHCW); + mc_set_forced_coherent_cfg(BPMPDMAR); + mc_set_forced_coherent_cfg(BPMPDMAW); + mc_set_forced_coherent_cfg(AONDMAR); + mc_set_forced_coherent_cfg(AONDMAW); + mc_set_forced_coherent_cfg(SCEDMAR); + mc_set_forced_coherent_cfg(SCEDMAW); + + /* + * At this point, ordering can occur at ROC. So, remove PCFIFO's + * control over ordering requests. + * + * Change PCFIFO_*_ORDERED_CLIENT from ORDERED -> UNORDERED for + * boot and strongly ordered MSS clients + */ + val = MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL & + mc_set_pcfifo_unordered_boot_so_mss(1, AFIW) & + mc_set_pcfifo_unordered_boot_so_mss(1, HDAW) & + mc_set_pcfifo_unordered_boot_so_mss(1, SATAW); + tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG1, val); + + val = MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL & + mc_set_pcfifo_unordered_boot_so_mss(2, XUSB_HOSTW) & + mc_set_pcfifo_unordered_boot_so_mss(2, XUSB_DEVW); + tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG2, val); + + val = MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL & + mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCWAB); + tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG3, val); + + val = MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL & + mc_set_pcfifo_unordered_boot_so_mss(4, SESWR) & + mc_set_pcfifo_unordered_boot_so_mss(4, ETRW) & + mc_set_pcfifo_unordered_boot_so_mss(4, AXISW) & + mc_set_pcfifo_unordered_boot_so_mss(4, EQOSW) & + mc_set_pcfifo_unordered_boot_so_mss(4, UFSHCW) & + mc_set_pcfifo_unordered_boot_so_mss(4, BPMPDMAW) & + mc_set_pcfifo_unordered_boot_so_mss(4, AONDMAW) & + mc_set_pcfifo_unordered_boot_so_mss(4, SCEDMAW); + tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG4, val); + + val = MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL & + mc_set_pcfifo_unordered_boot_so_mss(5, APEDMAW); + tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG5, val); + + /* + * At this point, ordering can occur at ROC. SMMU need not + * reorder any requests. + * + * Change SMMU_*_ORDERED_CLIENT from ORDERED -> UNORDERED + * for boot and strongly ordered MSS clients + */ + val = MC_SMMU_CLIENT_CONFIG1_RESET_VAL & + mc_set_smmu_unordered_boot_so_mss(1, AFIW) & + mc_set_smmu_unordered_boot_so_mss(1, HDAW) & + mc_set_smmu_unordered_boot_so_mss(1, SATAW); + tegra_mc_write_32(MC_SMMU_CLIENT_CONFIG1, val); + + val = MC_SMMU_CLIENT_CONFIG2_RESET_VAL & + mc_set_smmu_unordered_boot_so_mss(2, XUSB_HOSTW) & + mc_set_smmu_unordered_boot_so_mss(2, XUSB_DEVW); + tegra_mc_write_32(MC_SMMU_CLIENT_CONFIG2, val); + + val = MC_SMMU_CLIENT_CONFIG3_RESET_VAL & + mc_set_smmu_unordered_boot_so_mss(3, SDMMCWAB); + tegra_mc_write_32(MC_SMMU_CLIENT_CONFIG3, val); + + val = MC_SMMU_CLIENT_CONFIG4_RESET_VAL & + mc_set_smmu_unordered_boot_so_mss(4, SESWR) & + mc_set_smmu_unordered_boot_so_mss(4, ETRW) & + mc_set_smmu_unordered_boot_so_mss(4, AXISW) & + mc_set_smmu_unordered_boot_so_mss(4, EQOSW) & + mc_set_smmu_unordered_boot_so_mss(4, UFSHCW) & + mc_set_smmu_unordered_boot_so_mss(4, BPMPDMAW) & + mc_set_smmu_unordered_boot_so_mss(4, AONDMAW) & + mc_set_smmu_unordered_boot_so_mss(4, SCEDMAW); + tegra_mc_write_32(MC_SMMU_CLIENT_CONFIG4, val); + + val = MC_SMMU_CLIENT_CONFIG5_RESET_VAL & + mc_set_smmu_unordered_boot_so_mss(5, APEDMAW); + tegra_mc_write_32(MC_SMMU_CLIENT_CONFIG5, val); + + /* + * Deassert HOTRESET FLUSH_ENABLE for boot and strongly ordered MSS + * clients to allow memory traffic from all clients to start passing + * through ROC + */ + val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL0); + assert(val == wdata_0); + + wdata_0 = MC_CLIENT_HOTRESET_CTRL0_RESET_VAL; + tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0); + + /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */ + do { + val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0); + } while ((val & wdata_0) != wdata_0); + + /* Wait one more time due to SW WAR for known legacy issue */ + do { + val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0); + } while ((val & wdata_0) != wdata_0); + + val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL1); + assert(val == wdata_1); + + wdata_1 = MC_CLIENT_HOTRESET_CTRL1_RESET_VAL; + tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1); + + /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */ + do { + val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1); + } while ((val & wdata_1) != wdata_1); + + /* Wait one more time due to SW WAR for known legacy issue */ + do { + val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1); + } while ((val & wdata_1) != wdata_1); + +#endif +} + /* * Init Memory controller during boot. */ @@ -280,6 +525,14 @@ void tegra_memctrl_setup(void) tegra_mc_write_32(MC_SMMU_BYPASS_CONFIG, MC_SMMU_BYPASS_CONFIG_SETTINGS); + /* + * Re-configure MSS to allow ROC to deal with ordering of the + * Memory Controller traffic. This is needed as the Memory Controller + * boots with MSS having all control, but ROC provides a performance + * boost as compared to MSS. + */ + tegra_memctrl_reconfig_mss_clients(); + /* * Set the MC_TXN_OVERRIDE registers for write clients. */ @@ -322,6 +575,14 @@ void tegra_memctrl_setup(void) */ void tegra_memctrl_restore_settings(void) { + /* + * Re-configure MSS to allow ROC to deal with ordering of the + * Memory Controller traffic. This is needed as the Memory Controller + * resets during System Suspend with MSS having all control, but ROC + * provides a performance boost as compared to MSS. + */ + tegra_memctrl_reconfig_mss_clients(); + /* video memory carveout region */ if (video_mem_base) { tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v2.h b/plat/nvidia/tegra/include/drivers/memctrl_v2.h index 9623e25f8..fe7f7a021 100644 --- a/plat/nvidia/tegra/include/drivers/memctrl_v2.h +++ b/plat/nvidia/tegra/include/drivers/memctrl_v2.h @@ -283,6 +283,10 @@ #define MC_TXN_OVERRIDE_CONFIG_AFIW 0x1188 #define MC_TXN_OVERRIDE_CONFIG_SCEW 0x14e0 +#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_CGID (1 << 0) +#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV (2 << 4) +#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_CLIENT (1 << 12) + /******************************************************************************* * Non-SO_DEV transactions override values for CGID_TAG bitfield for the * MC_TXN_OVERRIDE_CONFIG_{module} registers @@ -327,12 +331,12 @@ typedef struct mc_streamid_security_cfg { int override_client_ns_flag; } mc_streamid_security_cfg_t; -#define OVERRIDE_DISABLE 1 -#define OVERRIDE_ENABLE 0 -#define CLIENT_FLAG_SECURE 0 -#define CLIENT_FLAG_NON_SECURE 1 -#define CLIENT_INPUTS_OVERRIDE 1 -#define CLIENT_INPUTS_NO_OVERRIDE 0 +#define OVERRIDE_DISABLE 1 +#define OVERRIDE_ENABLE 0 +#define CLIENT_FLAG_SECURE 0 +#define CLIENT_FLAG_NON_SECURE 1 +#define CLIENT_INPUTS_OVERRIDE 1 +#define CLIENT_INPUTS_NO_OVERRIDE 0 #define mc_make_sec_cfg(off, ns, ovrrd, access) \ { \ @@ -346,27 +350,200 @@ typedef struct mc_streamid_security_cfg { /******************************************************************************* * TZDRAM carveout configuration registers ******************************************************************************/ -#define MC_SECURITY_CFG0_0 0x70 -#define MC_SECURITY_CFG1_0 0x74 -#define MC_SECURITY_CFG3_0 0x9BC +#define MC_SECURITY_CFG0_0 0x70 +#define MC_SECURITY_CFG1_0 0x74 +#define MC_SECURITY_CFG3_0 0x9BC /******************************************************************************* * Video Memory carveout configuration registers ******************************************************************************/ -#define MC_VIDEO_PROTECT_BASE_HI 0x978 -#define MC_VIDEO_PROTECT_BASE_LO 0x648 -#define MC_VIDEO_PROTECT_SIZE_MB 0x64c +#define MC_VIDEO_PROTECT_BASE_HI 0x978 +#define MC_VIDEO_PROTECT_BASE_LO 0x648 +#define MC_VIDEO_PROTECT_SIZE_MB 0x64c /******************************************************************************* * TZRAM carveout configuration registers ******************************************************************************/ -#define MC_TZRAM_BASE 0x1850 -#define MC_TZRAM_END 0x1854 -#define MC_TZRAM_HI_ADDR_BITS 0x1588 - #define TZRAM_ADDR_HI_BITS_MASK 0x3 - #define TZRAM_END_HI_BITS_SHIFT 8 -#define MC_TZRAM_REG_CTRL 0x185c - #define DISABLE_TZRAM_ACCESS 1 +#define MC_TZRAM_BASE 0x1850 +#define MC_TZRAM_END 0x1854 +#define MC_TZRAM_HI_ADDR_BITS 0x1588 + #define TZRAM_ADDR_HI_BITS_MASK 0x3 + #define TZRAM_END_HI_BITS_SHIFT 8 +#define MC_TZRAM_REG_CTRL 0x185c + #define DISABLE_TZRAM_ACCESS 1 + +/******************************************************************************* + * Memory Controller Reset Control registers + ******************************************************************************/ +#define MC_CLIENT_HOTRESET_CTRL0 0x200 +#define MC_CLIENT_HOTRESET_CTRL0_RESET_VAL 0 +#define MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB (1 << 0) +#define MC_CLIENT_HOTRESET_CTRL0_HC_FLUSH_ENB (1 << 6) +#define MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB (1 << 7) +#define MC_CLIENT_HOTRESET_CTRL0_ISP2_FLUSH_ENB (1 << 8) +#define MC_CLIENT_HOTRESET_CTRL0_MPCORE_FLUSH_ENB (1 << 9) +#define MC_CLIENT_HOTRESET_CTRL0_NVENC_FLUSH_ENB (1 << 11) +#define MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB (1 << 15) +#define MC_CLIENT_HOTRESET_CTRL0_VI_FLUSH_ENB (1 << 17) +#define MC_CLIENT_HOTRESET_CTRL0_VIC_FLUSH_ENB (1 << 18) +#define MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB (1 << 19) +#define MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB (1 << 20) +#define MC_CLIENT_HOTRESET_CTRL0_TSEC_FLUSH_ENB (1 << 22) +#define MC_CLIENT_HOTRESET_CTRL0_SDMMC1A_FLUSH_ENB (1 << 29) +#define MC_CLIENT_HOTRESET_CTRL0_SDMMC2A_FLUSH_ENB (1 << 30) +#define MC_CLIENT_HOTRESET_CTRL0_SDMMC3A_FLUSH_ENB (1 << 31) +#define MC_CLIENT_HOTRESET_STATUS0 0x204 +#define MC_CLIENT_HOTRESET_CTRL1 0x970 +#define MC_CLIENT_HOTRESET_CTRL1_RESET_VAL 0 +#define MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB (1 << 0) +#define MC_CLIENT_HOTRESET_CTRL1_GPU_FLUSH_ENB (1 << 2) +#define MC_CLIENT_HOTRESET_CTRL1_NVDEC_FLUSH_ENB (1 << 5) +#define MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB (1 << 6) +#define MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB (1 << 7) +#define MC_CLIENT_HOTRESET_CTRL1_NVJPG_FLUSH_ENB (1 << 8) +#define MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB (1 << 12) +#define MC_CLIENT_HOTRESET_CTRL1_TSECB_FLUSH_ENB (1 << 13) +#define MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB (1 << 18) +#define MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB (1 << 19) +#define MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB (1 << 20) +#define MC_CLIENT_HOTRESET_CTRL1_NVDISPLAY_FLUSH_ENB (1 << 21) +#define MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB (1 << 22) +#define MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB (1 << 23) +#define MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB (1 << 24) +#define MC_CLIENT_HOTRESET_STATUS1 0x974 + +/******************************************************************************* + * TSA configuration registers + ******************************************************************************/ +#define TSA_CONFIG_STATIC0_CSW_SESWR 0x4010 +#define TSA_CONFIG_STATIC0_CSW_SESWR_RESET 0x1100 +#define TSA_CONFIG_STATIC0_CSW_ETRW 0x4038 +#define TSA_CONFIG_STATIC0_CSW_ETRW_RESET 0x1100 +#define TSA_CONFIG_STATIC0_CSW_SDMMCWAB 0x5010 +#define TSA_CONFIG_STATIC0_CSW_SDMMCWAB_RESET 0x1100 +#define TSA_CONFIG_STATIC0_CSW_AXISW 0x7008 +#define TSA_CONFIG_STATIC0_CSW_AXISW_RESET 0x1100 +#define TSA_CONFIG_STATIC0_CSW_HDAW 0xA008 +#define TSA_CONFIG_STATIC0_CSW_HDAW_RESET 0x100 +#define TSA_CONFIG_STATIC0_CSW_AONDMAW 0xB018 +#define TSA_CONFIG_STATIC0_CSW_AONDMAW_RESET 0x1100 +#define TSA_CONFIG_STATIC0_CSW_SCEDMAW 0xD018 +#define TSA_CONFIG_STATIC0_CSW_SCEDMAW_RESET 0x1100 +#define TSA_CONFIG_STATIC0_CSW_BPMPDMAW 0xD028 +#define TSA_CONFIG_STATIC0_CSW_BPMPDMAW_RESET 0x1100 +#define TSA_CONFIG_STATIC0_CSW_APEDMAW 0x12018 +#define TSA_CONFIG_STATIC0_CSW_APEDMAW_RESET 0x1100 +#define TSA_CONFIG_STATIC0_CSW_UFSHCW 0x13008 +#define TSA_CONFIG_STATIC0_CSW_UFSHCW_RESET 0x1100 +#define TSA_CONFIG_STATIC0_CSW_AFIW 0x13018 +#define TSA_CONFIG_STATIC0_CSW_AFIW_RESET 0x1100 +#define TSA_CONFIG_STATIC0_CSW_SATAW 0x13028 +#define TSA_CONFIG_STATIC0_CSW_SATAW_RESET 0x1100 +#define TSA_CONFIG_STATIC0_CSW_EQOSW 0x13038 +#define TSA_CONFIG_STATIC0_CSW_EQOSW_RESET 0x1100 +#define TSA_CONFIG_STATIC0_CSW_XUSB_DEVW 0x15008 +#define TSA_CONFIG_STATIC0_CSW_XUSB_DEVW_RESET 0x1100 +#define TSA_CONFIG_STATIC0_CSW_XUSB_HOSTW 0x15018 +#define TSA_CONFIG_STATIC0_CSW_XUSB_HOSTW_RESET 0x1100 + +#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK (0x3 << 11) +#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU (0 << 11) + +/******************************************************************************* + * Memory Controller's PCFIFO client configuration registers + ******************************************************************************/ +#define MC_PCFIFO_CLIENT_CONFIG1 0xdd4 +#define MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL 0x20000 +#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_UNORDERED (0 << 17) +#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_MASK (1 << 17) +#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_UNORDERED (0 << 21) +#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_MASK (1 << 21) +#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_UNORDERED (0 << 29) +#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_MASK (1 << 29) + +#define MC_PCFIFO_CLIENT_CONFIG2 0xdd8 +#define MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL 0x20000 +#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_UNORDERED (0 << 11) +#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_MASK (1 << 11) +#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_UNORDERED (0 << 13) +#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_MASK (1 << 13) + +#define MC_PCFIFO_CLIENT_CONFIG3 0xddc +#define MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL 0 +#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_UNORDERED (0 << 7) +#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_MASK (1 << 7) + +#define MC_PCFIFO_CLIENT_CONFIG4 0xde0 +#define MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL 0 +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_UNORDERED (0 << 1) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_MASK (1 << 1) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_UNORDERED (0 << 5) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_MASK (1 << 5) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_UNORDERED (0 << 13) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_MASK (1 << 13) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_UNORDERED (0 << 15) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_MASK (1 << 15) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_UNORDERED (0 << 17) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_MASK (1 << 17) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_UNORDERED (0 << 22) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_MASK (1 << 22) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_UNORDERED (0 << 26) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_MASK (1 << 26) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_UNORDERED (0 << 30) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_MASK (1 << 30) + +#define MC_PCFIFO_CLIENT_CONFIG5 0xbf4 +#define MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL 0 +#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_UNORDERED (0 << 0) +#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_MASK (1 << 0) + +/******************************************************************************* + * Memory Controller's SMMU client configuration registers + ******************************************************************************/ +#define MC_SMMU_CLIENT_CONFIG1 0x44 +#define MC_SMMU_CLIENT_CONFIG1_RESET_VAL 0x20000 +#define MC_SMMU_CLIENT_CONFIG1_AFIW_UNORDERED (0 << 17) +#define MC_SMMU_CLIENT_CONFIG1_AFIW_MASK (1 << 17) +#define MC_SMMU_CLIENT_CONFIG1_HDAW_UNORDERED (0 << 21) +#define MC_SMMU_CLIENT_CONFIG1_HDAW_MASK (1 << 21) +#define MC_SMMU_CLIENT_CONFIG1_SATAW_UNORDERED (0 << 29) +#define MC_SMMU_CLIENT_CONFIG1_SATAW_MASK (1 << 29) + +#define MC_SMMU_CLIENT_CONFIG2 0x48 +#define MC_SMMU_CLIENT_CONFIG2_RESET_VAL 0x20000 +#define MC_SMMU_CLIENT_CONFIG2_XUSB_HOSTW_UNORDERED (0 << 11) +#define MC_SMMU_CLIENT_CONFIG2_XUSB_HOSTW_MASK (1 << 11) +#define MC_SMMU_CLIENT_CONFIG2_XUSB_DEVW_UNORDERED (0 << 13) +#define MC_SMMU_CLIENT_CONFIG2_XUSB_DEVW_MASK (1 << 13) + +#define MC_SMMU_CLIENT_CONFIG3 0x4c +#define MC_SMMU_CLIENT_CONFIG3_RESET_VAL 0 +#define MC_SMMU_CLIENT_CONFIG3_SDMMCWAB_UNORDERED (0 << 7) +#define MC_SMMU_CLIENT_CONFIG3_SDMMCWAB_MASK (1 << 7) + +#define MC_SMMU_CLIENT_CONFIG4 0xb9c +#define MC_SMMU_CLIENT_CONFIG4_RESET_VAL 0 +#define MC_SMMU_CLIENT_CONFIG4_SESWR_UNORDERED (0 << 1) +#define MC_SMMU_CLIENT_CONFIG4_SESWR_MASK (1 << 1) +#define MC_SMMU_CLIENT_CONFIG4_ETRW_UNORDERED (0 << 5) +#define MC_SMMU_CLIENT_CONFIG4_ETRW_MASK (1 << 5) +#define MC_SMMU_CLIENT_CONFIG4_AXISW_UNORDERED (0 << 13) +#define MC_SMMU_CLIENT_CONFIG4_AXISW_MASK (1 << 13) +#define MC_SMMU_CLIENT_CONFIG4_EQOSW_UNORDERED (0 << 15) +#define MC_SMMU_CLIENT_CONFIG4_EQOSW_MASK (1 << 15) +#define MC_SMMU_CLIENT_CONFIG4_UFSHCW_UNORDERED (0 << 17) +#define MC_SMMU_CLIENT_CONFIG4_UFSHCW_MASK (1 << 17) +#define MC_SMMU_CLIENT_CONFIG4_BPMPDMAW_UNORDERED (0 << 22) +#define MC_SMMU_CLIENT_CONFIG4_BPMPDMAW_MASK (1 << 22) +#define MC_SMMU_CLIENT_CONFIG4_AONDMAW_UNORDERED (0 << 26) +#define MC_SMMU_CLIENT_CONFIG4_AONDMAW_MASK (1 << 26) +#define MC_SMMU_CLIENT_CONFIG4_SCEDMAW_UNORDERED (0 << 30) +#define MC_SMMU_CLIENT_CONFIG4_SCEDMAW_MASK (1 << 30) + +#define MC_SMMU_CLIENT_CONFIG5 0xbac +#define MC_SMMU_CLIENT_CONFIG5_RESET_VAL 0 +#define MC_SMMU_CLIENT_CONFIG5_APEDMAW_UNORDERED (0 << 0) +#define MC_SMMU_CLIENT_CONFIG5_APEDMAW_MASK (1 << 0) static inline uint32_t tegra_mc_read_32(uint32_t off) { @@ -388,4 +565,41 @@ static inline void tegra_mc_streamid_write_32(uint32_t off, uint32_t val) mmio_write_32(TEGRA_MC_STREAMID_BASE + off, val); } +#define mc_set_pcfifo_unordered_boot_so_mss(id, client) \ + (~MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_MASK | \ + MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_UNORDERED) + +#define mc_set_smmu_unordered_boot_so_mss(id, client) \ + (~MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_MASK | \ + MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_UNORDERED) + +#define mc_set_tsa_passthrough(client) \ + { \ + mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \ + (TSA_CONFIG_STATIC0_CSW_##client##_RESET & \ + ~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \ + TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \ + } + +#define mc_set_forced_coherent_cfg(client) \ + { \ + tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_##client, \ + MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV); \ + } + +#define mc_set_forced_coherent_so_dev_cfg(client) \ + { \ + tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_##client, \ + MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV | \ + MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_CLIENT); \ + } + +#define mc_set_forced_coherent_axid_so_dev_cfg(client) \ + { \ + tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_##client, \ + MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV | \ + MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_CGID | \ + MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_CLIENT); \ + } + #endif /* __MEMCTRLV2_H__ */ diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h index f3fbb891e..04a7d0b3b 100644 --- a/plat/nvidia/tegra/include/t186/tegra_def.h +++ b/plat/nvidia/tegra/include/t186/tegra_def.h @@ -83,6 +83,11 @@ #define HARDWARE_REVISION_A01 1 #define MISCREG_PFCFG 0x200C +/******************************************************************************* + * Tegra TSA Controller constants + ******************************************************************************/ +#define TEGRA_TSA_BASE 0x02400000 + /******************************************************************************* * Tegra Memory Controller constants ******************************************************************************/ diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c index d6b8bc3f8..b37bdad6d 100644 --- a/plat/nvidia/tegra/soc/t186/plat_setup.c +++ b/plat/nvidia/tegra/soc/t186/plat_setup.c @@ -65,6 +65,8 @@ const unsigned char tegra_power_domain_tree_desc[] = { static const mmap_region_t tegra_mmap[] = { MAP_REGION_FLAT(TEGRA_MISC_BASE, 0x10000, /* 64KB */ MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(TEGRA_TSA_BASE, 0x20000, /* 128KB */ + MT_DEVICE | MT_RW | MT_SECURE), MAP_REGION_FLAT(TEGRA_MC_STREAMID_BASE, 0x10000, /* 64KB */ MT_DEVICE | MT_RW | MT_SECURE), MAP_REGION_FLAT(TEGRA_MC_BASE, 0x10000, /* 64KB */ diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk index adc4a9ee9..b8eaa7a6f 100644 --- a/plat/nvidia/tegra/soc/t186/platform_t186.mk +++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk @@ -32,6 +32,9 @@ ENABLE_NS_L2_CPUECTRL_RW_ACCESS := 1 $(eval $(call add_define,ENABLE_NS_L2_CPUECTRL_RW_ACCESS)) +ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS := 1 +$(eval $(call add_define,ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS)) + # platform settings TZDRAM_BASE := 0x30000000 $(eval $(call add_define,TZDRAM_BASE)) @@ -42,10 +45,10 @@ $(eval $(call add_define,PLATFORM_CLUSTER_COUNT)) PLATFORM_MAX_CPUS_PER_CLUSTER := 4 $(eval $(call add_define,PLATFORM_MAX_CPUS_PER_CLUSTER)) -MAX_XLAT_TABLES := 15 +MAX_XLAT_TABLES := 16 $(eval $(call add_define,MAX_XLAT_TABLES)) -MAX_MMAP_REGIONS := 15 +MAX_MMAP_REGIONS := 16 $(eval $(call add_define,MAX_MMAP_REGIONS)) # platform files From 68c7de6fa924723df14bf8ff80159c2cda718ed6 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Fri, 18 Mar 2016 13:07:33 -0700 Subject: [PATCH 02/14] Tegra186: save/restore BL31 context to/from TZDRAM This patch adds support to save the BL31 state to the TZDRAM before entering system suspend. The TZRAM loses state during system suspend and so we need to copy the entire BL31 code to TZDRAM before entering the state. In order to restore the state on exiting system suspend, a new CPU reset handler is implemented which gets copied to TZDRAM during boot. TO keep things simple we use this same reset handler for booting secondary CPUs too. Change-Id: I770f799c255d22279b5cdb9b4d587d3a4c54fad7 Signed-off-by: Varun Wadekar --- .../nvidia/tegra/include/drivers/memctrl_v2.h | 10 +- plat/nvidia/tegra/include/drivers/smmu.h | 2 +- plat/nvidia/tegra/include/tegra_private.h | 3 + .../nvidia/tegra/soc/t186/drivers/smmu/smmu.c | 22 +++- .../tegra/soc/t186/plat_psci_handlers.c | 59 +++++++++- plat/nvidia/tegra/soc/t186/plat_secondary.c | 31 ++++- plat/nvidia/tegra/soc/t186/plat_trampoline.S | 108 ++++++++++++++++++ plat/nvidia/tegra/soc/t186/platform_t186.mk | 10 +- 8 files changed, 224 insertions(+), 21 deletions(-) create mode 100644 plat/nvidia/tegra/soc/t186/plat_trampoline.S diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v2.h b/plat/nvidia/tegra/include/drivers/memctrl_v2.h index fe7f7a021..04c0e8d17 100644 --- a/plat/nvidia/tegra/include/drivers/memctrl_v2.h +++ b/plat/nvidia/tegra/include/drivers/memctrl_v2.h @@ -31,7 +31,6 @@ #ifndef __MEMCTRLV2_H__ #define __MEMCTRLV2_H__ -#include #include /******************************************************************************* @@ -297,6 +296,8 @@ #define MC_TXN_OVERRIDE_CGID_TAG_ADR 3 #define MC_TXN_OVERRIDE_CGID_TAG_MASK 3 +#ifndef __ASSEMBLY__ + /******************************************************************************* * Structure to hold the transaction override settings to use to override * client inputs @@ -347,6 +348,8 @@ typedef struct mc_streamid_security_cfg { .override_enable = OVERRIDE_ ## access \ } +#endif /* __ASSMEBLY__ */ + /******************************************************************************* * TZDRAM carveout configuration registers ******************************************************************************/ @@ -545,6 +548,10 @@ typedef struct mc_streamid_security_cfg { #define MC_SMMU_CLIENT_CONFIG5_APEDMAW_UNORDERED (0 << 0) #define MC_SMMU_CLIENT_CONFIG5_APEDMAW_MASK (1 << 0) +#ifndef __ASSEMBLY__ + +#include + static inline uint32_t tegra_mc_read_32(uint32_t off) { return mmio_read_32(TEGRA_MC_BASE + off); @@ -601,5 +608,6 @@ static inline void tegra_mc_streamid_write_32(uint32_t off, uint32_t val) MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_CGID | \ MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_CLIENT); \ } +#endif /* __ASSMEBLY__ */ #endif /* __MEMCTRLV2_H__ */ diff --git a/plat/nvidia/tegra/include/drivers/smmu.h b/plat/nvidia/tegra/include/drivers/smmu.h index bb08a559f..0867c11ad 100644 --- a/plat/nvidia/tegra/include/drivers/smmu.h +++ b/plat/nvidia/tegra/include/drivers/smmu.h @@ -627,6 +627,6 @@ static inline void tegra_smmu_write_32(uint32_t off, uint32_t val) } void tegra_smmu_init(void); -void tegra_smmu_save_context(void); +void tegra_smmu_save_context(uint64_t smmu_ctx_addr); #endif /*__SMMU_H */ diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h index 012bfd77b..39006f6fa 100644 --- a/plat/nvidia/tegra/include/tegra_private.h +++ b/plat/nvidia/tegra/include/tegra_private.h @@ -119,4 +119,7 @@ void plat_early_platform_setup(void); /* Declarations for tegra_delay_timer.c */ void tegra_delay_timer_init(void); +void tegra_secure_entrypoint(void); +void tegra186_cpu_reset_handler(void); + #endif /* __TEGRA_PRIVATE_H__ */ diff --git a/plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c b/plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c index 2940f5837..7f4589595 100644 --- a/plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c +++ b/plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c @@ -31,7 +31,10 @@ #include #include #include +#include #include +#include +#include typedef struct smmu_regs { uint32_t reg; @@ -133,7 +136,7 @@ typedef struct smmu_regs { .val = 0xFFFFFFFF, \ } -static smmu_regs_t smmu_ctx_regs[] = { +static __attribute__((aligned(16))) smmu_regs_t smmu_ctx_regs[] = { _START_OF_TABLE_, mc_make_sid_security_cfg(SCEW), mc_make_sid_security_cfg(AFIR), @@ -421,12 +424,15 @@ static smmu_regs_t smmu_ctx_regs[] = { }; /* - * Save SMMU settings before "System Suspend" + * Save SMMU settings before "System Suspend" to TZDRAM */ -void tegra_smmu_save_context(void) +void tegra_smmu_save_context(uint64_t smmu_ctx_addr) { uint32_t i; #if DEBUG + plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); + uint64_t tzdram_base = params_from_bl2->tzdram_base; + uint64_t tzdram_end = tzdram_base + params_from_bl2->tzdram_size; uint32_t reg_id1, pgshift, cb_size; /* sanity check SMMU settings c*/ @@ -438,6 +444,8 @@ void tegra_smmu_save_context(void) assert(!((pgshift != PGSHIFT) || (cb_size != CB_SIZE))); #endif + assert((smmu_ctx_addr >= tzdram_base) && (smmu_ctx_addr <= tzdram_end)); + /* index of _END_OF_TABLE_ */ smmu_ctx_regs[0].val = ARRAY_SIZE(smmu_ctx_regs) - 1; @@ -445,11 +453,15 @@ void tegra_smmu_save_context(void) for (i = 1; i < ARRAY_SIZE(smmu_ctx_regs) - 1; i++) smmu_ctx_regs[i].val = mmio_read_32(smmu_ctx_regs[i].reg); + /* Save SMMU config settings */ + memcpy16((void *)(uintptr_t)smmu_ctx_addr, (void *)smmu_ctx_regs, + sizeof(smmu_ctx_regs)); + /* save the SMMU table address */ mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV11_LO, - (uint32_t)(unsigned long)smmu_ctx_regs); + (uint32_t)smmu_ctx_addr); mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV11_HI, - (uint32_t)(((unsigned long)smmu_ctx_regs) >> 32)); + (uint32_t)(smmu_ctx_addr >> 32)); } /* diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c index 7e35cc6b2..7c6868c7b 100644 --- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c @@ -39,10 +39,17 @@ #include #include #include +#include #include #include extern void prepare_cpu_pwr_dwn(void); +extern void tegra186_cpu_reset_handler(void); +extern uint32_t __tegra186_cpu_reset_handler_data, + __tegra186_cpu_reset_handler_end; + +/* TZDRAM offset for saving SMMU context */ +#define TEGRA186_SMMU_CTX_OFFSET 16 /* state id mask */ #define TEGRA186_STATE_ID_MASK 0xF @@ -50,7 +57,7 @@ extern void prepare_cpu_pwr_dwn(void); #define TEGRA186_WAKE_TIME_MASK 0xFFFFFF #define TEGRA186_WAKE_TIME_SHIFT 4 /* context size to save during system suspend */ -#define TEGRA186_SE_CONTEXT_SIZE 3 +#define TEGRA186_SE_CONTEXT_SIZE 3 static uint32_t se_regs[TEGRA186_SE_CONTEXT_SIZE]; static unsigned int wake_time[PLATFORM_CORE_COUNT]; @@ -98,6 +105,8 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK; cpu_context_t *ctx = cm_get_context(NON_SECURE); gp_regs_t *gp_regs = get_gpregs_ctx(ctx); + plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); + uint64_t smmu_ctx_base; uint32_t val; assert(ctx); @@ -147,8 +156,12 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) val = mmio_read_32(TEGRA_MISC_BASE + MISCREG_PFCFG); mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV6, val); - /* save SMMU context */ - tegra_smmu_save_context(); + /* save SMMU context to TZDRAM */ + smmu_ctx_base = params_from_bl2->tzdram_base + + ((uintptr_t)&__tegra186_cpu_reset_handler_data - + (uintptr_t)tegra186_cpu_reset_handler) + + TEGRA186_SMMU_CTX_OFFSET; + tegra_smmu_save_context((uintptr_t)smmu_ctx_base); /* Prepare for system suspend */ write_ctx_reg(gp_regs, CTX_GPREG_X4, 1); @@ -157,7 +170,7 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) (void)mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO, TEGRA_ARI_CLUSTER_CC7, 0, TEGRA_ARI_SYSTEM_SC7); - /* Enter system suspend state */ + /* Instruct the MCE to enter system suspend state */ (void)mce_command_handler(MCE_CMD_ENTER_CSTATE, TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0); @@ -169,6 +182,31 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) return PSCI_E_SUCCESS; } +int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state) +{ + const plat_local_state_t *pwr_domain_state = + target_state->pwr_domain_state; + plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); + unsigned int stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] & + TEGRA186_STATE_ID_MASK; + uint32_t val; + + if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) { + /* + * The TZRAM loses power when we enter system suspend. To + * allow graceful exit from system suspend, we need to copy + * BL3-1 over to TZDRAM. + */ + val = params_from_bl2->tzdram_base + + ((uintptr_t)&__tegra186_cpu_reset_handler_end - + (uintptr_t)tegra186_cpu_reset_handler); + memcpy16((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE, + (uintptr_t)&__BL31_END__ - (uintptr_t)BL31_BASE); + } + + return PSCI_E_SUCCESS; +} + int tegra_soc_pwr_domain_on(u_register_t mpidr) { int target_cpu = mpidr & MPIDR_CPU_MASK; @@ -191,6 +229,8 @@ int tegra_soc_pwr_domain_on(u_register_t mpidr) int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) { int state_id = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]; + cpu_context_t *ctx = cm_get_context(NON_SECURE); + gp_regs_t *gp_regs = get_gpregs_ctx(ctx); /* * Check if we are exiting from deep sleep and restore SE @@ -206,6 +246,17 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) /* Init SMMU */ tegra_smmu_init(); + + /* + * Reset power state info for the last core doing SC7 entry and exit, + * we set deepest power state as CC7 and SC7 for SC7 entry which + * may not be requested by non-secure SW which controls idle states. + */ + write_ctx_reg(gp_regs, CTX_GPREG_X4, 0); + write_ctx_reg(gp_regs, CTX_GPREG_X5, 0); + write_ctx_reg(gp_regs, CTX_GPREG_X6, 1); + (void)mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO, + TEGRA_ARI_CLUSTER_CC7, 0, TEGRA_ARI_SYSTEM_SC1); } return PSCI_E_SUCCESS; diff --git a/plat/nvidia/tegra/soc/t186/plat_secondary.c b/plat/nvidia/tegra/soc/t186/plat_secondary.c index df802891a..406c1e08d 100644 --- a/plat/nvidia/tegra/soc/t186/plat_secondary.c +++ b/plat/nvidia/tegra/soc/t186/plat_secondary.c @@ -28,10 +28,13 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include #include +#include #include +#include #define MISCREG_CPU_RESET_VECTOR 0x2000 #define MISCREG_AA64_RST_LOW 0x2004 @@ -42,7 +45,8 @@ #define CPU_RESET_MODE_AA64 1 -extern void tegra_secure_entrypoint(void); +extern uint64_t tegra_bl31_phys_base; +extern uint64_t __tegra186_cpu_reset_handler_end; /******************************************************************************* * Setup secondary CPU vectors @@ -50,12 +54,31 @@ extern void tegra_secure_entrypoint(void); void plat_secondary_setup(void) { uint32_t addr_low, addr_high; - uint64_t reset_addr = (uint64_t)tegra_secure_entrypoint; + plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); + uint64_t cpu_reset_handler_base; INFO("Setting up secondary CPU boot\n"); - addr_low = (uint32_t)reset_addr | CPU_RESET_MODE_AA64; - addr_high = (uint32_t)((reset_addr >> 32) & 0x7ff); + if ((tegra_bl31_phys_base >= TEGRA_TZRAM_BASE) && + (tegra_bl31_phys_base <= (TEGRA_TZRAM_BASE + TEGRA_TZRAM_SIZE))) { + + /* + * The BL31 code resides in the TZSRAM which loses state + * when we enter System Suspend. Copy the wakeup trampoline + * code to TZDRAM to help us exit from System Suspend. + */ + cpu_reset_handler_base = params_from_bl2->tzdram_base; + memcpy16((void *)((uintptr_t)cpu_reset_handler_base), + (void *)(uintptr_t)tegra186_cpu_reset_handler, + (uintptr_t)&__tegra186_cpu_reset_handler_end - + (uintptr_t)tegra186_cpu_reset_handler); + + } else { + cpu_reset_handler_base = (uintptr_t)tegra_secure_entrypoint; + } + + addr_low = (uint32_t)cpu_reset_handler_base | CPU_RESET_MODE_AA64; + addr_high = (uint32_t)((cpu_reset_handler_base >> 32) & 0x7ff); /* write lower 32 bits first, then the upper 11 bits */ mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_LOW, addr_low); diff --git a/plat/nvidia/tegra/soc/t186/plat_trampoline.S b/plat/nvidia/tegra/soc/t186/plat_trampoline.S new file mode 100644 index 000000000..5e0a9d7e5 --- /dev/null +++ b/plat/nvidia/tegra/soc/t186/plat_trampoline.S @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#define TEGRA186_SMMU_CTX_SIZE 0x420 + + .align 4 + .globl tegra186_cpu_reset_handler + +/* CPU reset handler routine */ +func tegra186_cpu_reset_handler + /* + * The Memory Controller loses state during System Suspend. We + * use this information to decide if the reset handler is running + * after a System Suspend. Resume from system suspend requires + * restoring the entire state from TZDRAM to TZRAM. + */ + mov x1, #TEGRA_MC_BASE + ldr w0, [x1, #MC_SECURITY_CFG3_0] + lsl x0, x0, #32 + ldr w0, [x1, #MC_SECURITY_CFG0_0] + adr x1, tegra186_cpu_reset_handler + cmp x0, x1 + beq boot_cpu + + /* resume from system suspend */ + mov x0, #BL31_BASE + adr x1, __tegra186_cpu_reset_handler_end + adr x2, __tegra186_cpu_reset_handler_data + ldr x2, [x2, #8] + + /* memcpy16 */ +m_loop16: + cmp x2, #16 + b.lt m_loop1 + ldp x3, x4, [x1], #16 + stp x3, x4, [x0], #16 + sub x2, x2, #16 + b m_loop16 + /* copy byte per byte */ +m_loop1: + cbz x2, boot_cpu + ldrb w3, [x1], #1 + strb w3, [x0], #1 + subs x2, x2, #1 + b.ne m_loop1 + +boot_cpu: + adr x0, __tegra186_cpu_reset_handler_data + ldr x0, [x0] + br x0 +endfunc tegra186_cpu_reset_handler + + /* + * Tegra186 reset data (offset 0x0 - 0x430) + * + * 0x000: secure world's entrypoint + * 0x008: BL31 size (RO + RW) + * 0x00C: SMMU context start + * 0x42C: SMMU context end + */ + + .align 4 + .type __tegra186_cpu_reset_handler_data, %object + .globl __tegra186_cpu_reset_handler_data +__tegra186_cpu_reset_handler_data: + .quad tegra_secure_entrypoint + .quad __BL31_END__ - BL31_BASE + .rept TEGRA186_SMMU_CTX_SIZE + .quad 0 + .endr + .size __tegra186_cpu_reset_handler_data, \ + . - __tegra186_cpu_reset_handler_data + + .align 4 + .globl __tegra186_cpu_reset_handler_end +__tegra186_cpu_reset_handler_end: diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk index b8eaa7a6f..0387a0a89 100644 --- a/plat/nvidia/tegra/soc/t186/platform_t186.mk +++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk @@ -29,9 +29,6 @@ # # platform configs -ENABLE_NS_L2_CPUECTRL_RW_ACCESS := 1 -$(eval $(call add_define,ENABLE_NS_L2_CPUECTRL_RW_ACCESS)) - ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS := 1 $(eval $(call add_define,ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS)) @@ -45,10 +42,10 @@ $(eval $(call add_define,PLATFORM_CLUSTER_COUNT)) PLATFORM_MAX_CPUS_PER_CLUSTER := 4 $(eval $(call add_define,PLATFORM_MAX_CPUS_PER_CLUSTER)) -MAX_XLAT_TABLES := 16 +MAX_XLAT_TABLES := 20 $(eval $(call add_define,MAX_XLAT_TABLES)) -MAX_MMAP_REGIONS := 16 +MAX_MMAP_REGIONS := 20 $(eval $(call add_define,MAX_MMAP_REGIONS)) # platform files @@ -65,4 +62,5 @@ BL31_SOURCES += lib/cpus/aarch64/denver.S \ ${SOC_DIR}/plat_psci_handlers.c \ ${SOC_DIR}/plat_setup.c \ ${SOC_DIR}/plat_secondary.c \ - ${SOC_DIR}/plat_sip_calls.c + ${SOC_DIR}/plat_sip_calls.c \ + ${SOC_DIR}/plat_trampoline.S From 66ec11259f6546aa53b66e000590816d463c5a7f Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Mon, 28 Mar 2016 13:44:35 -0700 Subject: [PATCH 03/14] Tegra186: mce: enable LATIC for chip verification This patch adds a new interface to allow for making an ARI call that will enable LATIC for the chip verification software harness. LATIC allows some MINI ISMs to be read in the CCPLEX. The ISMs are used for various measurements relevant ot particular locations in Silicon. They are small counters which can be polled to determine how fast a particular location in the Silicon is. Original change by Guy Sotomayor Change-Id: Ifb49b8863a009d4cdd5d1ba38a23b5374500a4b3 Signed-off-by: Varun Wadekar --- .../tegra/soc/t186/drivers/include/mce.h | 1 + plat/nvidia/tegra/soc/t186/drivers/mce/mce.c | 18 ++++++++++++++++++ plat/nvidia/tegra/soc/t186/plat_sip_calls.c | 2 ++ plat/nvidia/tegra/soc/t186/platform_t186.mk | 3 +++ 4 files changed, 24 insertions(+) diff --git a/plat/nvidia/tegra/soc/t186/drivers/include/mce.h b/plat/nvidia/tegra/soc/t186/drivers/include/mce.h index 7078b8bb2..825f81ff2 100644 --- a/plat/nvidia/tegra/soc/t186/drivers/include/mce.h +++ b/plat/nvidia/tegra/soc/t186/drivers/include/mce.h @@ -94,6 +94,7 @@ typedef enum mce_cmd { MCE_CMD_ENUM_WRITE_MCA, MCE_CMD_ROC_FLUSH_CACHE, MCE_CMD_ROC_CLEAN_CACHE, + MCE_CMD_ENABLE_LATIC, MCE_CMD_IS_CCX_ALLOWED = 0xFE, MCE_CMD_MAX = 0xFF, } mce_cmd_t; diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c index 745b6f4e5..d105e36e3 100644 --- a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c +++ b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c @@ -356,6 +356,24 @@ int mce_command_handler(mce_cmd_t cmd, uint64_t arg0, uint64_t arg1, break; +#if ENABLE_CHIP_VERIFICATION_HARNESS + case MCE_CMD_ENABLE_LATIC: + /* + * This call is not for production use. The constant value, + * 0xFFFF0000, is specific to allowing for enabling LATIC on + * pre-production parts for the chip verification harness. + * + * Enabling LATIC allows S/W to read the MINI ISPs in the + * CCPLEX. The ISMs are used for various measurements relevant + * to particular locations in the Silicon. They are small + * counters which can be polled to determine how fast a + * particular location in the Silicon is. + */ + ops->enter_ccplex_state(mce_get_curr_cpu_ari_base(), + 0xFFFF0000); + + break; +#endif default: ERROR("unknown MCE command (%d)\n", cmd); return EINVAL; diff --git a/plat/nvidia/tegra/soc/t186/plat_sip_calls.c b/plat/nvidia/tegra/soc/t186/plat_sip_calls.c index fabab0185..c7a2c4167 100644 --- a/plat/nvidia/tegra/soc/t186/plat_sip_calls.c +++ b/plat/nvidia/tegra/soc/t186/plat_sip_calls.c @@ -64,6 +64,7 @@ extern uint32_t tegra186_system_powerdn_state; #define TEGRA_SIP_MCE_CMD_ENUM_WRITE_MCA 0x82FFFF0D #define TEGRA_SIP_MCE_CMD_ROC_FLUSH_CACHE 0x82FFFF0E #define TEGRA_SIP_MCE_CMD_ROC_CLEAN_CACHE 0x82FFFF0F +#define TEGRA_SIP_MCE_CMD_ENABLE_LATIC 0x82FFFF10 /******************************************************************************* * This function is responsible for handling all T186 SiP calls @@ -100,6 +101,7 @@ int plat_sip_handler(uint32_t smc_fid, case TEGRA_SIP_MCE_CMD_ENUM_WRITE_MCA: case TEGRA_SIP_MCE_CMD_ROC_FLUSH_CACHE: case TEGRA_SIP_MCE_CMD_ROC_CLEAN_CACHE: + case TEGRA_SIP_MCE_CMD_ENABLE_LATIC: /* clean up the high bits */ smc_fid &= MCE_CMD_MASK; diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk index 0387a0a89..4a4d9bbda 100644 --- a/plat/nvidia/tegra/soc/t186/platform_t186.mk +++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk @@ -32,6 +32,9 @@ ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS := 1 $(eval $(call add_define,ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS)) +ENABLE_CHIP_VERIFICATION_HARNESS := 0 +$(eval $(call add_define,ENABLE_CHIP_VERIFICATION_HARNESS)) + # platform settings TZDRAM_BASE := 0x30000000 $(eval $(call add_define,TZDRAM_BASE)) From e8ebf0cbab466da8c16bee5b723ae514b0383c4a Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Mon, 28 Mar 2016 14:28:09 -0700 Subject: [PATCH 04/14] Tegra: memctrl_v2: enable APE overrides for chip verification This patch enables overrides for APE domains to allow the chip verification software harness (MODS) to execute its test cases. Original change by Harvey Hsieh Change-Id: I09b22376068c5b65d89c2a53154ccb2c60d955bd Signed-off-by: Varun Wadekar --- .../tegra/common/drivers/memctrl/memctrl_v2.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c index 437106b01..798dbfa18 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c @@ -144,7 +144,6 @@ const static mc_streamid_security_cfg_t sec_cfgs[] = { mc_make_sec_cfg(SCEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE), mc_make_sec_cfg(UFSHCR, NON_SECURE, OVERRIDE, ENABLE), mc_make_sec_cfg(SDMMCWAA, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(APEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE), mc_make_sec_cfg(SESWR, NON_SECURE, OVERRIDE, ENABLE), mc_make_sec_cfg(MPCORER, NON_SECURE, OVERRIDE, ENABLE), mc_make_sec_cfg(PTCR, NON_SECURE, OVERRIDE, ENABLE), @@ -159,9 +158,7 @@ const static mc_streamid_security_cfg_t sec_cfgs[] = { mc_make_sec_cfg(XUSB_HOSTW, NON_SECURE, OVERRIDE, ENABLE), mc_make_sec_cfg(TSECSWR, NON_SECURE, NO_OVERRIDE, ENABLE), mc_make_sec_cfg(SDMMCRAA, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(APER, NON_SECURE, NO_OVERRIDE, ENABLE), mc_make_sec_cfg(VIW, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(APEW, NON_SECURE, NO_OVERRIDE, ENABLE), mc_make_sec_cfg(AXISR, SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(SDMMCW, NON_SECURE, OVERRIDE, ENABLE), mc_make_sec_cfg(BPMPDMAW, NON_SECURE, NO_OVERRIDE, ENABLE), @@ -191,13 +188,23 @@ const static mc_streamid_security_cfg_t sec_cfgs[] = { mc_make_sec_cfg(SDMMCRAB, NON_SECURE, OVERRIDE, ENABLE), mc_make_sec_cfg(ETRR, NON_SECURE, OVERRIDE, ENABLE), mc_make_sec_cfg(AONR, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(APEDMAR, NON_SECURE, NO_OVERRIDE, ENABLE), mc_make_sec_cfg(SESRD, NON_SECURE, OVERRIDE, ENABLE), mc_make_sec_cfg(NVENCSRD, NON_SECURE, NO_OVERRIDE, ENABLE), mc_make_sec_cfg(GPUSWR, SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(TSECSWRB, NON_SECURE, NO_OVERRIDE, ENABLE), mc_make_sec_cfg(ISPWB, NON_SECURE, OVERRIDE, ENABLE), mc_make_sec_cfg(GPUSRD2, SECURE, NO_OVERRIDE, DISABLE), +#if ENABLE_CHIP_VERIFICATION_HARNESS + mc_make_sec_cfg(APEDMAW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(APER, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(APEW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(APEDMAR, NON_SECURE, OVERRIDE, ENABLE), +#else + mc_make_sec_cfg(APEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(APER, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(APEW, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(APEDMAR, NON_SECURE, NO_OVERRIDE, ENABLE), +#endif }; const static mc_txn_override_cfg_t mc_override_cfgs[] = { From c60f58ef0b1bc39a3b1fee691a28916d1e2b84a8 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Mon, 28 Mar 2016 14:43:03 -0700 Subject: [PATCH 05/14] Tegra186: clear the system cstate for offline core This patch clears the system cstate when offlining a CPU core as we need to update the sytem cstate to SC7 only when we enter system suspend. Original change by Prashant Gaikwad Change-Id: I1cff9bbab4db7d390a491c8939aea5db6c6b5c59 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/soc/t186/plat_psci_handlers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c index 7c6868c7b..9b492fb8c 100644 --- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c @@ -276,7 +276,7 @@ int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state) write_ctx_reg(gp_regs, CTX_GPREG_X5, 0); write_ctx_reg(gp_regs, CTX_GPREG_X6, 1); mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO, TEGRA_ARI_CLUSTER_CC7, - 0, TEGRA_ARI_SYSTEM_SC7); + 0, 0); /* Disable Denver's DCO operations */ if (impl == DENVER_IMPL) From 1b9ab0542e5b7ef1627e46fb6b57f183ff72c135 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Mon, 28 Mar 2016 15:05:03 -0700 Subject: [PATCH 06/14] Tegra186: program default core wake mask during CPU_SUSPEND This patch programs the default CPU wake mask during CPU_SUSPEND. This reduces the CPU_SUSPEND latency as the system has to send one less SMC before issuing the actual suspend request. Original change by Krishna Sitaraman Change-Id: I1f9351dde4ab30936070e9f42c2882fa691cbe46 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/soc/t186/plat_psci_handlers.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c index 9b492fb8c..536ecbf04 100644 --- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c @@ -56,6 +56,8 @@ extern uint32_t __tegra186_cpu_reset_handler_data, /* constants to get power state's wake time */ #define TEGRA186_WAKE_TIME_MASK 0xFFFFFF #define TEGRA186_WAKE_TIME_SHIFT 4 +/* default core wake mask for CPU_SUSPEND */ +#define TEGRA186_CORE_WAKE_MASK 0x180c /* context size to save during system suspend */ #define TEGRA186_SE_CONTEXT_SIZE 3 @@ -124,12 +126,24 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) if (stateid_afflvl0 == PSTATE_ID_CORE_IDLE) { + /* Program default wake mask */ + write_ctx_reg(gp_regs, CTX_GPREG_X4, 0); + write_ctx_reg(gp_regs, CTX_GPREG_X5, TEGRA186_CORE_WAKE_MASK); + write_ctx_reg(gp_regs, CTX_GPREG_X6, 1); + (void)mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO, 0, 0, 0); + /* Prepare for cpu idle */ (void)mce_command_handler(MCE_CMD_ENTER_CSTATE, TEGRA_ARI_CORE_C6, wake_time[cpu], 0); } else if (stateid_afflvl0 == PSTATE_ID_CORE_POWERDN) { + /* Program default wake mask */ + write_ctx_reg(gp_regs, CTX_GPREG_X4, 0); + write_ctx_reg(gp_regs, CTX_GPREG_X5, TEGRA186_CORE_WAKE_MASK); + write_ctx_reg(gp_regs, CTX_GPREG_X6, 1); + (void)mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO, 0, 0, 0); + /* Prepare for cpu powerdn */ (void)mce_command_handler(MCE_CMD_ENTER_CSTATE, TEGRA_ARI_CORE_C7, wake_time[cpu], 0); From 50f38a4a53d4c5804db56cc1c2db2d9e5b443cea Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Mon, 28 Mar 2016 15:11:43 -0700 Subject: [PATCH 07/14] Tegra186: fix programming sequence for SC7/SC8 entry This patch fixes the programming sequence for 'System Suspend' and 'Quasi power down' state entry. The device needs to update the required power state before querying the MCE firmware to see the entry to that power state is allowed. Original change by Allen Yu Change-Id: I65e03754322188af913fabf41f29d1c3595afd85 Signed-off-by: Varun Wadekar --- .../tegra/soc/t186/plat_psci_handlers.c | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c index 536ecbf04..8911e8f61 100644 --- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c @@ -150,14 +150,6 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) } else if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) { - /* loop until SC7 is allowed */ - do { - val = mce_command_handler(MCE_CMD_IS_SC7_ALLOWED, - TEGRA_ARI_CORE_C7, - MCE_CORE_SLEEP_TIME_INFINITE, - 0); - } while (val == 0); - /* save SE registers */ se_regs[0] = mmio_read_32(TEGRA_SE0_BASE + SE_MUTEX_WATCHDOG_NS_LIMIT); @@ -184,6 +176,14 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) (void)mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO, TEGRA_ARI_CLUSTER_CC7, 0, TEGRA_ARI_SYSTEM_SC7); + /* Loop until system suspend is allowed */ + do { + val = mce_command_handler(MCE_CMD_IS_SC7_ALLOWED, + TEGRA_ARI_CORE_C7, + MCE_CORE_SLEEP_TIME_INFINITE, + 0); + } while (val == 0); + /* Instruct the MCE to enter system suspend state */ (void)mce_command_handler(MCE_CMD_ENTER_CSTATE, TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0); @@ -314,6 +314,13 @@ __dead2 void tegra_soc_prepare_system_off(void) } else if (tegra186_system_powerdn_state == TEGRA_ARI_SYSTEM_SC8) { + /* Prepare for quasi power down */ + write_ctx_reg(gp_regs, CTX_GPREG_X4, 1); + write_ctx_reg(gp_regs, CTX_GPREG_X5, 0); + write_ctx_reg(gp_regs, CTX_GPREG_X6, 1); + (void)mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO, + TEGRA_ARI_CLUSTER_CC7, 0, TEGRA_ARI_SYSTEM_SC8); + /* loop until other CPUs power down */ do { val = mce_command_handler(MCE_CMD_IS_SC7_ALLOWED, @@ -322,13 +329,6 @@ __dead2 void tegra_soc_prepare_system_off(void) 0); } while (val == 0); - /* Prepare for quasi power down */ - write_ctx_reg(gp_regs, CTX_GPREG_X4, 1); - write_ctx_reg(gp_regs, CTX_GPREG_X5, 0); - write_ctx_reg(gp_regs, CTX_GPREG_X6, 1); - (void)mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO, - TEGRA_ARI_CLUSTER_CC7, 0, TEGRA_ARI_SYSTEM_SC8); - /* Enter quasi power down state */ (void)mce_command_handler(MCE_CMD_ENTER_CSTATE, TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0); From 5cb89c563726c9efabd7bcd9392a29a9a2a825df Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Mon, 28 Mar 2016 16:00:02 -0700 Subject: [PATCH 08/14] Tegra186: check MCE firmware version during boot This patch checks that the system is running with the supported MCE firmware during boot. In case the firmware version does not match the interface header version, then the system halts. Change-Id: Ib82013fd1c1668efd6f0e4f36cd3662d339ac076 Signed-off-by: Varun Wadekar --- .../tegra/soc/t186/drivers/include/mce.h | 1 + plat/nvidia/tegra/soc/t186/drivers/mce/mce.c | 43 +++++++++++++++++++ plat/nvidia/tegra/soc/t186/plat_setup.c | 9 ++++ 3 files changed, 53 insertions(+) diff --git a/plat/nvidia/tegra/soc/t186/drivers/include/mce.h b/plat/nvidia/tegra/soc/t186/drivers/include/mce.h index 825f81ff2..606569236 100644 --- a/plat/nvidia/tegra/soc/t186/drivers/include/mce.h +++ b/plat/nvidia/tegra/soc/t186/drivers/include/mce.h @@ -322,6 +322,7 @@ int mce_update_gsc_videomem(void); int mce_update_gsc_tzdram(void); int mce_update_gsc_tzram(void); __dead2 void mce_enter_ccplex_state(uint32_t state_idx); +void mce_verify_firmware_version(void); /* declarations for ARI/NVG handler functions */ int ari_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time); diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c index d105e36e3..0e550f5ba 100644 --- a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c +++ b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c @@ -447,3 +447,46 @@ __dead2 void mce_enter_ccplex_state(uint32_t state_idx) panic(); } + +/******************************************************************************* + * Handler to read the MCE firmware version and check if it is compatible + * with interface header the BL3-1 was compiled against + ******************************************************************************/ +void mce_verify_firmware_version(void) +{ + arch_mce_ops_t *ops; + uint32_t cpu_ari_base; + uint64_t version; + uint32_t major, minor; + + /* get a pointer to the CPU's arch_mce_ops_t struct */ + ops = mce_get_curr_cpu_ops(); + + /* get the CPU's ARI base address */ + cpu_ari_base = mce_get_curr_cpu_ari_base(); + + /* + * Read the MCE firmware version and extract the major and minor + * version fields + */ + version = ops->call_enum_misc(cpu_ari_base, TEGRA_ARI_MISC_VERSION, 0); + major = (uint32_t)version; + minor = (uint32_t)(version >> 32); + + INFO("MCE Version - HW=%d:%d, SW=%d:%d\n", major, minor, + TEGRA_ARI_VERSION_MAJOR, TEGRA_ARI_VERSION_MINOR); + + /* + * Verify that the MCE firmware version and the interface header + * match + */ + if (major != TEGRA_ARI_VERSION_MAJOR) { + ERROR("ARI major version mismatch\n"); + panic(); + } + + if (minor < TEGRA_ARI_VERSION_MINOR) { + ERROR("ARI minor version mismatch\n"); + panic(); + } +} diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c index b37bdad6d..49f45892f 100644 --- a/plat/nvidia/tegra/soc/t186/plat_setup.c +++ b/plat/nvidia/tegra/soc/t186/plat_setup.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -170,3 +171,11 @@ 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(); +} From abd3a91d6fed30be47bd47f9ecb914a5917f6784 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Sat, 2 Apr 2016 15:41:20 -0700 Subject: [PATCH 09/14] Tegra186: enable support for simulation environment The Tegra simulation environment has limited capabilities. This patch checks the chip's major and minor versions to decide the features to enable/disable - MCE firmware version checking is disabled and limited Memory Controller settings are enabled Change-Id: I258a807cc3b83cdff14a9975b4ab4f9d1a9d7dcf Signed-off-by: Varun Wadekar --- .../tegra/common/drivers/memctrl/memctrl_v2.c | 10 ++++++---- plat/nvidia/tegra/include/t186/tegra_def.h | 8 +++++--- plat/nvidia/tegra/soc/t186/drivers/mce/mce.c | 13 ++++++++++++- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c index 798dbfa18..2fb9b99f3 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c @@ -495,7 +495,7 @@ void tegra_memctrl_setup(void) uint32_t num_overrides = sizeof(streamid_overrides) / sizeof(uint32_t); uint32_t num_sec_cfgs = sizeof(sec_cfgs) / sizeof(mc_streamid_security_cfg_t); uint32_t num_txn_overrides = sizeof(mc_override_cfgs) / sizeof(mc_txn_override_cfg_t); - uint32_t tegra_rev; + uint32_t chip_minor, chip_major; int i; INFO("Tegra Memory Controller (v2)\n"); @@ -543,10 +543,12 @@ void tegra_memctrl_setup(void) /* * Set the MC_TXN_OVERRIDE registers for write clients. */ - tegra_rev = (mmio_read_32(TEGRA_MISC_BASE + HARDWARE_REVISION_OFFSET) & - HARDWARE_MINOR_REVISION_MASK) >> HARDWARE_MINOR_REVISION_SHIFT; + 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; - if (tegra_rev == HARDWARE_REVISION_A01) { + if ((chip_major == 0) || (chip_major > 0 && chip_minor == 1)) { /* GPU and NVENC settings for rev. A01 */ val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR); diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h index 04a7d0b3b..7f618bdd3 100644 --- a/plat/nvidia/tegra/include/t186/tegra_def.h +++ b/plat/nvidia/tegra/include/t186/tegra_def.h @@ -78,9 +78,11 @@ ******************************************************************************/ #define TEGRA_MISC_BASE 0x00100000 #define HARDWARE_REVISION_OFFSET 0x4 -#define HARDWARE_MINOR_REVISION_MASK 0xf0000 -#define HARDWARE_MINOR_REVISION_SHIFT 0x10 -#define HARDWARE_REVISION_A01 1 +#define MAJOR_VERSION_SHIFT 0x4 +#define MAJOR_VERSION_MASK 0xF +#define MINOR_VERSION_SHIFT 0x10 +#define MINOR_VERSION_MASK 0xF + #define MISCREG_PFCFG 0x200C /******************************************************************************* diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c index 0e550f5ba..9d0d71fd6 100644 --- a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c +++ b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c @@ -457,7 +457,7 @@ void mce_verify_firmware_version(void) arch_mce_ops_t *ops; uint32_t cpu_ari_base; uint64_t version; - uint32_t major, minor; + uint32_t major, minor, chip_minor, chip_major; /* get a pointer to the CPU's arch_mce_ops_t struct */ ops = mce_get_curr_cpu_ops(); @@ -476,6 +476,17 @@ void mce_verify_firmware_version(void) INFO("MCE Version - HW=%d:%d, SW=%d:%d\n", major, minor, TEGRA_ARI_VERSION_MAJOR, TEGRA_ARI_VERSION_MINOR); + /* + * MCE firmware is not running on simulation platforms. Simulation + * platforms are identified by v0.3 from the Tegra Chip ID value. + */ + 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; + if ((chip_major == 0) && (chip_minor == 3)) + return; + /* * Verify that the MCE firmware version and the interface header * match From b46ac6dcc5d20d53a62b02430cafc6aeba154d3b Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Sat, 9 Apr 2016 00:40:45 -0700 Subject: [PATCH 10/14] Tegra186: reset power state info during CPU_ON This patch resets the power state info for CPUs when onlining, as we set deepest power when offlining a core but that may not be requested by non-secure sw which controls idle states. It will re-init this info from non-secure software when the core come online. Original change by Prashant Gaikwad Change-Id: Id6c2fa2b821c7705aafbb561a62348c36fd3abd8 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/soc/t186/plat_psci_handlers.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c index 8911e8f61..b51891831 100644 --- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c @@ -246,6 +246,18 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) cpu_context_t *ctx = cm_get_context(NON_SECURE); gp_regs_t *gp_regs = get_gpregs_ctx(ctx); + /* + * Reset power state info for CPUs when onlining, we set deepest power + * when offlining a core but that may not be requested by non-secure + * sw which controls idle states. It will re-init this info from + * non-secure software when the core come online. + */ + write_ctx_reg(gp_regs, CTX_GPREG_X4, 0); + write_ctx_reg(gp_regs, CTX_GPREG_X5, 0); + write_ctx_reg(gp_regs, CTX_GPREG_X6, 1); + mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO, TEGRA_ARI_CLUSTER_CC1, + 0, 0); + /* * Check if we are exiting from deep sleep and restore SE * context if we are. From 99ef4a5cbc92af7d73798ef0e98dce01756f73c2 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Tue, 19 Apr 2016 14:22:13 -0700 Subject: [PATCH 11/14] Tegra: memctrl_v2: no stream ID override for Security Engine This patch removes stream ID override for the Security Engine hardware block as its stream ID is programmed by the NS world driver. Original change by Mallikarjun Kasoju Change-Id: Ia6523c1a1bb0a82bdeb878feb55670813899bdac Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c index 2fb9b99f3..f41e49d96 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c @@ -144,7 +144,7 @@ const static mc_streamid_security_cfg_t sec_cfgs[] = { mc_make_sec_cfg(SCEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE), mc_make_sec_cfg(UFSHCR, NON_SECURE, OVERRIDE, ENABLE), mc_make_sec_cfg(SDMMCWAA, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(SESWR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(SESWR, NON_SECURE, NO_OVERRIDE, ENABLE), mc_make_sec_cfg(MPCORER, NON_SECURE, OVERRIDE, ENABLE), mc_make_sec_cfg(PTCR, NON_SECURE, OVERRIDE, ENABLE), mc_make_sec_cfg(BPMPW, NON_SECURE, NO_OVERRIDE, ENABLE), @@ -188,7 +188,7 @@ const static mc_streamid_security_cfg_t sec_cfgs[] = { mc_make_sec_cfg(SDMMCRAB, NON_SECURE, OVERRIDE, ENABLE), mc_make_sec_cfg(ETRR, NON_SECURE, OVERRIDE, ENABLE), mc_make_sec_cfg(AONR, NON_SECURE, OVERRIDE, ENABLE), - mc_make_sec_cfg(SESRD, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(SESRD, NON_SECURE, NO_OVERRIDE, ENABLE), mc_make_sec_cfg(NVENCSRD, NON_SECURE, NO_OVERRIDE, ENABLE), mc_make_sec_cfg(GPUSWR, SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(TSECSWRB, NON_SECURE, NO_OVERRIDE, ENABLE), From 3b52fc1f829442322d15dbd3dad4a42a5371e661 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Mon, 25 Apr 2016 09:01:46 -0700 Subject: [PATCH 12/14] Tegra: memctrl_v2: program Video Memory carveout size in MBs This patch fixes the programming logic for the Video memory carveout's size. The Memory Controller expects the size in terms of MBs instead of bytes. Change-Id: Ia8261b737448bae9a435fe21ab336126785d4279 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c index f41e49d96..2d22a586f 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c @@ -45,7 +45,7 @@ /* Video Memory base and size (live values) */ static uint64_t video_mem_base; -static uint64_t video_mem_size; +static uint64_t video_mem_size_mb; /* array to hold stream_id override config register offsets */ const static uint32_t streamid_overrides[] = { @@ -598,7 +598,7 @@ void tegra_memctrl_restore_settings(void) (uint32_t)video_mem_base); tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI, (uint32_t)(video_mem_base >> 32)); - tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size); + tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size_mb); /* * MCE propogates the VideoMem configuration values across the @@ -706,11 +706,11 @@ void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes) tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)phys_base); tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI, (uint32_t)(phys_base >> 32)); - tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, size_in_bytes); + tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, size_in_bytes >> 20); /* store new values */ video_mem_base = phys_base; - video_mem_size = size_in_bytes >> 20; + video_mem_size_mb = size_in_bytes >> 20; /* * MCE propogates the VideoMem configuration values across the From 2079ddd62c8b7f36b808fa416cd34abb74ce59cc Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Tue, 26 Apr 2016 11:34:54 -0700 Subject: [PATCH 13/14] Tegra186: fix recursion in included headers (tegra_def.h/platform_def.h) This patch fixes the "Recursion in included headers" error flagged by Coverity. Fixes coverity errors "31858: Recursion in included headers" and "31857: Recursion in included headers" Change-Id: Icf8838434b1808b396e743e47f59adc452546364 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/include/drivers/memctrl_v2.h | 2 ++ plat/nvidia/tegra/include/t186/tegra_def.h | 2 -- plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c | 1 + plat/nvidia/tegra/soc/t186/plat_trampoline.S | 1 + 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v2.h b/plat/nvidia/tegra/include/drivers/memctrl_v2.h index 04c0e8d17..a7ab6503c 100644 --- a/plat/nvidia/tegra/include/drivers/memctrl_v2.h +++ b/plat/nvidia/tegra/include/drivers/memctrl_v2.h @@ -298,6 +298,8 @@ #ifndef __ASSEMBLY__ +#include + /******************************************************************************* * Structure to hold the transaction override settings to use to override * client inputs diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h index 7f618bdd3..7f85351eb 100644 --- a/plat/nvidia/tegra/include/t186/tegra_def.h +++ b/plat/nvidia/tegra/include/t186/tegra_def.h @@ -31,8 +31,6 @@ #ifndef __TEGRA_DEF_H__ #define __TEGRA_DEF_H__ -#include - /******************************************************************************* * These values are used by the PSCI implementation during the `CPU_SUSPEND` * and `SYSTEM_SUSPEND` calls as the `state-id` field in the 'power state' diff --git a/plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c b/plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c index 7f4589595..d1e1804e1 100644 --- a/plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c +++ b/plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c @@ -29,6 +29,7 @@ */ #include +#include #include #include #include diff --git a/plat/nvidia/tegra/soc/t186/plat_trampoline.S b/plat/nvidia/tegra/soc/t186/plat_trampoline.S index 5e0a9d7e5..7619ed0c9 100644 --- a/plat/nvidia/tegra/soc/t186/plat_trampoline.S +++ b/plat/nvidia/tegra/soc/t186/plat_trampoline.S @@ -30,6 +30,7 @@ #include #include +#include #include #include From b8de847359e6446d8b041fbd0ddde8c52e0dc54a Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Fri, 29 Apr 2016 11:25:46 -0700 Subject: [PATCH 14/14] Tegra186: reset CPU power state info while onlining This patch resets the CPU power state info when we online any CPU. The NS world software would re-init the CPU power state after the CPU gets online anyways. This allows us to maintain proper CPU/cluster power states in the MCE firmware at all times. Change-Id: Ib24054f53df720a4f88d67b2cb5a2e036e475e14 Signed-off-by: Varun Wadekar --- .../tegra/soc/t186/plat_psci_handlers.c | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c index b51891831..835527001 100644 --- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c @@ -242,27 +242,33 @@ int tegra_soc_pwr_domain_on(u_register_t mpidr) int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) { - int state_id = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]; + int stateid_afflvl2 = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]; + int stateid_afflvl0 = target_state->pwr_domain_state[MPIDR_AFFLVL0]; cpu_context_t *ctx = cm_get_context(NON_SECURE); gp_regs_t *gp_regs = get_gpregs_ctx(ctx); /* - * Reset power state info for CPUs when onlining, we set deepest power - * when offlining a core but that may not be requested by non-secure - * sw which controls idle states. It will re-init this info from - * non-secure software when the core come online. + * Reset power state info for CPUs when onlining, we set + * deepest power when offlining a core but that may not be + * requested by non-secure sw which controls idle states. It + * will re-init this info from non-secure software when the + * core come online. */ - write_ctx_reg(gp_regs, CTX_GPREG_X4, 0); - write_ctx_reg(gp_regs, CTX_GPREG_X5, 0); - write_ctx_reg(gp_regs, CTX_GPREG_X6, 1); - mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO, TEGRA_ARI_CLUSTER_CC1, - 0, 0); + if (stateid_afflvl0 == PLAT_MAX_OFF_STATE) { + + write_ctx_reg(gp_regs, CTX_GPREG_X4, 0); + write_ctx_reg(gp_regs, CTX_GPREG_X5, 0); + write_ctx_reg(gp_regs, CTX_GPREG_X6, 1); + mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO, + TEGRA_ARI_CLUSTER_CC1, 0, 0); + } /* * Check if we are exiting from deep sleep and restore SE * context if we are. */ - if (state_id == PSTATE_ID_SOC_POWERDN) { + if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) { + mmio_write_32(TEGRA_SE0_BASE + SE_MUTEX_WATCHDOG_NS_LIMIT, se_regs[0]); mmio_write_32(TEGRA_RNG1_BASE + RNG_MUTEX_WATCHDOG_NS_LIMIT,