diff options
author | davidcunado-arm <david.cunado@arm.com> | 2017-03-30 21:43:56 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-30 21:43:56 +0100 |
commit | ddc1c56f0b12af6171c11a5a8073c34becfedde2 (patch) | |
tree | f295ae21bc46b40e4b2f361abba552f188d6bded | |
parent | e422f991df48306cd5d9629c4f1ed230b0807fdb (diff) | |
parent | b8de847359e6446d8b041fbd0ddde8c52e0dc54a (diff) |
Merge pull request #875 from vwadekar/tegra186-platform-support-v2
Tegra186 platform support v2
-rw-r--r-- | plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c | 298 | ||||
-rw-r--r-- | plat/nvidia/tegra/include/drivers/memctrl_v2.h | 264 | ||||
-rw-r--r-- | plat/nvidia/tegra/include/drivers/smmu.h | 2 | ||||
-rw-r--r-- | plat/nvidia/tegra/include/t186/tegra_def.h | 15 | ||||
-rw-r--r-- | plat/nvidia/tegra/include/tegra_private.h | 3 | ||||
-rw-r--r-- | plat/nvidia/tegra/soc/t186/drivers/include/mce.h | 2 | ||||
-rw-r--r-- | plat/nvidia/tegra/soc/t186/drivers/mce/mce.c | 72 | ||||
-rw-r--r-- | plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c | 23 | ||||
-rw-r--r-- | plat/nvidia/tegra/soc/t186/plat_psci_handlers.c | 127 | ||||
-rw-r--r-- | plat/nvidia/tegra/soc/t186/plat_secondary.c | 31 | ||||
-rw-r--r-- | plat/nvidia/tegra/soc/t186/plat_setup.c | 11 | ||||
-rw-r--r-- | plat/nvidia/tegra/soc/t186/plat_sip_calls.c | 2 | ||||
-rw-r--r-- | plat/nvidia/tegra/soc/t186/plat_trampoline.S | 109 | ||||
-rw-r--r-- | plat/nvidia/tegra/soc/t186/platform_t186.mk | 14 |
14 files changed, 897 insertions, 76 deletions
diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c index f0202041..a03b6ef7 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[] = { @@ -144,8 +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(APEDMAW, NON_SECURE, NO_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), @@ -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(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), 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[] = { @@ -234,6 +241,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. */ @@ -243,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"); @@ -281,12 +533,22 @@ void tegra_memctrl_setup(void) 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. */ - 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); @@ -322,13 +584,21 @@ 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, (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 @@ -436,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 diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v2.h b/plat/nvidia/tegra/include/drivers/memctrl_v2.h index 9623e25f..a7ab6503 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 <mmio.h> #include <tegra_def.h> /******************************************************************************* @@ -283,6 +282,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 @@ -293,6 +296,10 @@ #define MC_TXN_OVERRIDE_CGID_TAG_ADR 3 #define MC_TXN_OVERRIDE_CGID_TAG_MASK 3 +#ifndef __ASSEMBLY__ + +#include <sys/types.h> + /******************************************************************************* * Structure to hold the transaction override settings to use to override * client inputs @@ -327,12 +334,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) \ { \ @@ -343,30 +350,209 @@ typedef struct mc_streamid_security_cfg { .override_enable = OVERRIDE_ ## access \ } +#endif /* __ASSMEBLY__ */ + /******************************************************************************* * 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) + +#ifndef __ASSEMBLY__ + +#include <mmio.h> static inline uint32_t tegra_mc_read_32(uint32_t off) { @@ -388,4 +574,42 @@ 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 /* __ASSMEBLY__ */ + #endif /* __MEMCTRLV2_H__ */ diff --git a/plat/nvidia/tegra/include/drivers/smmu.h b/plat/nvidia/tegra/include/drivers/smmu.h index bb08a559..0867c11a 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/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h index f3fbb891..7f85351e 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 <platform_def.h> - /******************************************************************************* * 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' @@ -78,12 +76,19 @@ ******************************************************************************/ #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 /******************************************************************************* + * Tegra TSA Controller constants + ******************************************************************************/ +#define TEGRA_TSA_BASE 0x02400000 + +/******************************************************************************* * Tegra Memory Controller constants ******************************************************************************/ #define TEGRA_MC_STREAMID_BASE 0x02C00000 diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h index 012bfd77..39006f6f 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/include/mce.h b/plat/nvidia/tegra/soc/t186/drivers/include/mce.h index 7078b8bb..60656923 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; @@ -321,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 745b6f4e..9d0d71fd 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; @@ -429,3 +447,57 @@ __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, chip_minor, chip_major; + + /* 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); + + /* + * 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 + */ + 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/drivers/smmu/smmu.c b/plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c index 2940f583..d1e1804e 100644 --- a/plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c +++ b/plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c @@ -29,9 +29,13 @@ */ #include <assert.h> +#include <bl_common.h> #include <debug.h> #include <memctrl_v2.h> +#include <platform_def.h> #include <smmu.h> +#include <string.h> +#include <tegra_private.h> typedef struct smmu_regs { uint32_t reg; @@ -133,7 +137,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 +425,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 +445,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 +454,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 7e35cc6b..83552700 100644 --- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c @@ -39,18 +39,27 @@ #include <mce.h> #include <psci.h> #include <smmu.h> +#include <string.h> #include <t18x_ari.h> #include <tegra_private.h> 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 /* 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 +#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 +107,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); @@ -115,26 +126,30 @@ 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); } 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); @@ -147,8 +162,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 +176,15 @@ 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 */ + /* 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); @@ -169,6 +196,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; @@ -190,13 +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. + */ + 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, @@ -206,6 +278,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; @@ -225,7 +308,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) @@ -249,6 +332,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, @@ -257,13 +347,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); diff --git a/plat/nvidia/tegra/soc/t186/plat_secondary.c b/plat/nvidia/tegra/soc/t186/plat_secondary.c index df802891..406c1e08 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 <arch_helpers.h> #include <debug.h> #include <mce.h> #include <mmio.h> +#include <string.h> #include <tegra_def.h> +#include <tegra_private.h> #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_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c index d6b8bc3f..49f45892 100644 --- a/plat/nvidia/tegra/soc/t186/plat_setup.c +++ b/plat/nvidia/tegra/soc/t186/plat_setup.c @@ -37,6 +37,7 @@ #include <debug.h> #include <denver.h> #include <interrupt_mgmt.h> +#include <mce.h> #include <platform.h> #include <tegra_def.h> #include <tegra_private.h> @@ -65,6 +66,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 */ @@ -168,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(); +} diff --git a/plat/nvidia/tegra/soc/t186/plat_sip_calls.c b/plat/nvidia/tegra/soc/t186/plat_sip_calls.c index fabab018..c7a2c416 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/plat_trampoline.S b/plat/nvidia/tegra/soc/t186/plat_trampoline.S new file mode 100644 index 00000000..7619ed0c --- /dev/null +++ b/plat/nvidia/tegra/soc/t186/plat_trampoline.S @@ -0,0 +1,109 @@ +/* + * 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 <arch.h> +#include <asm_macros.S> +#include <common_def.h> +#include <memctrl_v2.h> +#include <tegra_def.h> + +#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 adc4a9ee..4a4d9bbd 100644 --- a/plat/nvidia/tegra/soc/t186/platform_t186.mk +++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk @@ -29,8 +29,11 @@ # # 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)) + +ENABLE_CHIP_VERIFICATION_HARNESS := 0 +$(eval $(call add_define,ENABLE_CHIP_VERIFICATION_HARNESS)) # platform settings TZDRAM_BASE := 0x30000000 @@ -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 := 20 $(eval $(call add_define,MAX_XLAT_TABLES)) -MAX_MMAP_REGIONS := 15 +MAX_MMAP_REGIONS := 20 $(eval $(call add_define,MAX_MMAP_REGIONS)) # platform files @@ -62,4 +65,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 |