From d29d96fb3fbb8900d45e9d3817b7df0366d2ea29 Mon Sep 17 00:00:00 2001 From: Steven Kao Date: Fri, 21 Oct 2016 14:16:59 +0800 Subject: [PATCH 1/7] Tegra: early init the delay timer This patch moves the platform delay timer init to early BL31 platform setup, so that platforms can use the udelay/mdelay routines in the early init code. Change-Id: I6fe20b76176ea22589539c180c5b6f9d09eda8de Signed-off-by: Steven Kao Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/tegra_bl31_setup.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c index 8307af706..a61146d03 100644 --- a/plat/nvidia/tegra/common/tegra_bl31_setup.c +++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c @@ -204,6 +204,11 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2, TEGRA_CONSOLE_BAUDRATE); } + /* + * Initialize delay timer + */ + tegra_delay_timer_init(); + /* * Do initial security configuration to allow DRAM/device access. */ @@ -263,11 +268,6 @@ void bl31_platform_setup(void) /* Initialize the gic cpu and distributor interfaces */ plat_gic_setup(); - /* - * Initialize delay timer - */ - tegra_delay_timer_init(); - /* * Setup secondary CPU POR infrastructure. */ From e99eeec6ff806208f50e4bdd86466694447b38eb Mon Sep 17 00:00:00 2001 From: Steven Kao Date: Fri, 23 Dec 2016 16:05:13 +0800 Subject: [PATCH 2/7] Tegra: memmap Tegra micro-seconds timer controller This patch adds the Tegra micro-seconds controller to the memory map. This allows us to use the delay_timer functionality. Change-Id: Ia8b148a871949bfede539974cacbe0e93ec7e77c Signed-off-by: Steven Kao Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/tegra_bl31_setup.c | 6 ++++++ plat/nvidia/tegra/include/t132/tegra_def.h | 3 ++- plat/nvidia/tegra/include/t186/tegra_def.h | 1 + plat/nvidia/tegra/include/t210/tegra_def.h | 3 ++- plat/nvidia/tegra/soc/t210/platform_t210.mk | 2 +- 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c index a61146d03..ffaa0ba3f 100644 --- a/plat/nvidia/tegra/common/tegra_bl31_setup.c +++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c @@ -354,6 +354,12 @@ void bl31_plat_arch_setup(void) MT_DEVICE | MT_RW | MT_SECURE); #endif + /* map on-chip free running uS timer */ + mmap_add_region(page_align((uint64_t)TEGRA_TMRUS_BASE, 0), + page_align((uint64_t)TEGRA_TMRUS_BASE, 0), + (uint64_t)TEGRA_TMRUS_SIZE, + MT_DEVICE | MT_RO | MT_SECURE); + /* add MMIO space */ plat_mmio_map = plat_get_mmio_map(); if (plat_mmio_map) diff --git a/plat/nvidia/tegra/include/t132/tegra_def.h b/plat/nvidia/tegra/include/t132/tegra_def.h index 4ba4f12c5..e488bd87c 100644 --- a/plat/nvidia/tegra/include/t132/tegra_def.h +++ b/plat/nvidia/tegra/include/t132/tegra_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2017, 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: @@ -58,6 +58,7 @@ * Tegra micro-seconds timer constants ******************************************************************************/ #define TEGRA_TMRUS_BASE 0x60005010 +#define TEGRA_TMRUS_SIZE 0x1000 /******************************************************************************* * Tegra Clock and Reset Controller constants diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h index ae11d2810..6693cb3ae 100644 --- a/plat/nvidia/tegra/include/t186/tegra_def.h +++ b/plat/nvidia/tegra/include/t186/tegra_def.h @@ -237,6 +237,7 @@ * Tegra micro-seconds timer constants ******************************************************************************/ #define TEGRA_TMRUS_BASE 0x0C2E0000 +#define TEGRA_TMRUS_SIZE 0x1000 /******************************************************************************* * Tegra Power Mgmt Controller constants diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h index 096135514..d8ad10c88 100644 --- a/plat/nvidia/tegra/include/t210/tegra_def.h +++ b/plat/nvidia/tegra/include/t210/tegra_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2017, 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: @@ -83,6 +83,7 @@ * Tegra micro-seconds timer constants ******************************************************************************/ #define TEGRA_TMRUS_BASE 0x60005010 +#define TEGRA_TMRUS_SIZE 0x1000 /******************************************************************************* * Tegra Clock and Reset Controller constants diff --git a/plat/nvidia/tegra/soc/t210/platform_t210.mk b/plat/nvidia/tegra/soc/t210/platform_t210.mk index 89468692b..cd26e6e8d 100644 --- a/plat/nvidia/tegra/soc/t210/platform_t210.mk +++ b/plat/nvidia/tegra/soc/t210/platform_t210.mk @@ -40,7 +40,7 @@ $(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 := 3 +MAX_XLAT_TABLES := 4 $(eval $(call add_define,MAX_XLAT_TABLES)) MAX_MMAP_REGIONS := 8 From ab3a33fe5c5e3b5e4aea9d9bd88bef361588828b Mon Sep 17 00:00:00 2001 From: Steven Kao Date: Fri, 23 Dec 2016 16:17:18 +0800 Subject: [PATCH 3/7] Tegra186: mce: max retries for ARI requests This patch adds max retries for all ARI requests and asserts if the ARI request is still busy. Change-Id: I454ad9b557bb59e513e4c0c6f071275c87d0e07a Signed-off-by: Steven Kao Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/soc/t186/drivers/mce/ari.c | 51 ++++++++++++++++---- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c index 7f711a726..87fadbe69 100644 --- a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c +++ b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2017, 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: @@ -30,10 +30,13 @@ #include #include +#include #include +#include #include #include #include +#include #include #include @@ -49,10 +52,13 @@ #define ARI_RESPONSE_DATA_HI 0x18 /* Status values for the current request */ -#define ARI_REQ_PENDING 1 -#define ARI_REQ_ONGOING 3 -#define ARI_REQUEST_VALID_BIT (1 << 8) -#define ARI_EVT_MASK_STANDBYWFI_BIT (1 << 7) +#define ARI_REQ_PENDING 1U +#define ARI_REQ_ONGOING 3U +#define ARI_REQUEST_VALID_BIT (1U << 8) +#define ARI_EVT_MASK_STANDBYWFI_BIT (1U << 7) + +/* default timeout (ms) to wait for ARI completion */ +#define ARI_MAX_RETRY_COUNT 2000 /******************************************************************************* * ARI helper functions @@ -96,7 +102,8 @@ static inline void ari_clobber_response(uint32_t ari_base) static int ari_request_wait(uint32_t ari_base, uint32_t evt_mask, uint32_t req, uint32_t lo, uint32_t hi) { - int status; + uint32_t retries = ARI_MAX_RETRY_COUNT; + uint32_t status; /* program the request, event_mask, hi and lo registers */ ari_write_32(ari_base, lo, ARI_REQUEST_DATA_LO); @@ -112,10 +119,36 @@ static int ari_request_wait(uint32_t ari_base, uint32_t evt_mask, uint32_t req, if (evt_mask) return 0; - /* NOTE: add timeout check if needed */ - status = ari_read_32(ari_base, ARI_STATUS); - while (status & (ARI_REQ_ONGOING | ARI_REQ_PENDING)) + /* For shutdown/reboot commands, we dont have to check for timeouts */ + if ((req == (uint32_t)TEGRA_ARI_MISC_CCPLEX) && + ((lo == (uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF) || + (lo == (uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT))) { + return 0; + } + + /* + * Wait for the command response for not more than the timeout + */ + while (retries != 0U) { + + /* read the command status */ status = ari_read_32(ari_base, ARI_STATUS); + if ((status & (ARI_REQ_ONGOING | ARI_REQ_PENDING)) == 0U) + break; + + /* delay 1 ms */ + mdelay(1); + + /* decrement the retry count */ + retries--; + } + + /* assert if the command timed out */ + if (retries == 0U) { + ERROR("ARI request timed out: req %d on CPU %d\n", + req, plat_my_core_pos()); + assert(retries != 0U); + } return 0; } From e9cb01d96e2615d65885f22731b1ebec0a53fd85 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 6 Apr 2017 17:33:31 -0700 Subject: [PATCH 4/7] Tegra186: calculate proper power state for cluster/system power down Earlier, we were setting "System Suspend" as the power state for all system states. This caused incorrect system state during a cluster power down. This patch fixes this anomaly and sets the correct power state during a cluster/system power down. Change-Id: Ibd002930e0ae103e381e0a19670c3c4d057e7cb7 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/soc/t186/plat_psci_handlers.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c index 9790b817a..a7f41c101 100644 --- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c @@ -188,8 +188,11 @@ plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl, int core_pos = read_mpidr() & MPIDR_CPU_MASK; mce_cstate_info_t cstate_info = { 0 }; - /* get the current core's power state */ - target = *(states + core_pos); + /* get the power state at this level */ + if (lvl == MPIDR_AFFLVL1) + target = *(states + core_pos); + if (lvl == MPIDR_AFFLVL2) + target = *(states + cpu); /* CPU suspend */ if (lvl == MPIDR_AFFLVL1 && target == PSTATE_ID_CORE_POWERDN) { @@ -242,7 +245,8 @@ plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl, } /* System Suspend */ - if ((lvl == MPIDR_AFFLVL2) || (target == PSTATE_ID_SOC_POWERDN)) + if (((lvl == MPIDR_AFFLVL2) || (lvl == MPIDR_AFFLVL1)) && + (target == PSTATE_ID_SOC_POWERDN)) return PSTATE_ID_SOC_POWERDN; /* default state */ From 9d42d23a2cb1394d0c9cf396dda7a362908da020 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 21 Dec 2016 14:50:18 -0800 Subject: [PATCH 5/7] Tegra: memctrl_v2: zero out NS Video memory carveout region The video memory carveout has to be re-sized depending on the Video content. This requires the NS world to send us new base/size values. Before setting up the new region, we must zero out the previous memory region, so that the video frames are not leaked to the outside world. This patch adds the logic to zero out the previous memory carveout region. Change-Id: I471167ef7747154440df5c1a5e015fbeb69d9043 Signed-off-by: Varun Wadekar --- .../tegra/common/drivers/memctrl/memctrl_v2.c | 160 ++++++++++++++++-- plat/nvidia/tegra/include/t186/tegra_def.h | 46 ++--- 2 files changed, 168 insertions(+), 38 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c index 41a4ede80..87c7ed03d 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c @@ -40,7 +40,8 @@ #include #include #include -#include +#include +#include #define TEGRA_GPU_RESET_REG_OFFSET 0x30 #define GPU_RESET_BIT (1 << 0) @@ -450,7 +451,7 @@ void tegra_memctrl_restore_settings(void) tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size_mb); /* - * MCE propogates the VideoMem configuration values across the + * MCE propagates the VideoMem configuration values across the * CCPLEX. */ mce_update_gsc_videomem(); @@ -490,7 +491,7 @@ void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes) tegra_mc_read_32(MC_SECURITY_CFG1_0)); /* - * MCE propogates the security configuration values across the + * MCE propagates the security configuration values across the * CCPLEX. */ mce_update_gsc_tzdram(); @@ -506,25 +507,28 @@ void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes) { uint32_t index; uint32_t total_128kb_blocks = size_in_bytes >> 17; - uint32_t residual_4kb_blocks = (size_in_bytes & 0x1FFFF) >> 12; + uint32_t residual_4kb_blocks = (size_in_bytes & (uint32_t)0x1FFFF) >> 12; uint32_t val; + INFO("Configuring TrustZone SRAM Memory Carveout\n"); + /* * Reset the access configuration registers to restrict access * to the TZRAM aperture */ - for (index = MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG0; - index <= MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS5; - index += 4) + for (index = MC_TZRAM_CLIENT_ACCESS_CFG0; + index < ((uint32_t)MC_TZRAM_CARVEOUT_CFG + (uint32_t)MC_GSC_CONFIG_REGS_SIZE); + index += 4U) { tegra_mc_write_32(index, 0); + } /* * Set the TZRAM base. TZRAM base must be 4k aligned, at least. */ - assert(!(phys_base & 0xFFF)); + assert((phys_base & (uint64_t)0xFFF) == 0U); tegra_mc_write_32(MC_TZRAM_BASE_LO, (uint32_t)phys_base); tegra_mc_write_32(MC_TZRAM_BASE_HI, - (uint32_t)(phys_base >> 32) & TZRAM_BASE_HI_MASK); + (uint32_t)(phys_base >> 32) & MC_GSC_BASE_HI_MASK); /* * Set the TZRAM size @@ -533,7 +537,7 @@ void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes) * blocks) * */ - val = (residual_4kb_blocks << TZRAM_SIZE_RANGE_4KB_SHIFT) | + val = (residual_4kb_blocks << MC_GSC_SIZE_RANGE_4KB_SHIFT) | total_128kb_blocks; tegra_mc_write_32(MC_TZRAM_SIZE, val); @@ -543,17 +547,96 @@ void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes) * at all. */ val = tegra_mc_read_32(MC_TZRAM_CARVEOUT_CFG); - val &= ~TZRAM_ENABLE_TZ_LOCK_BIT; - val |= TZRAM_LOCK_CFG_SETTINGS_BIT; + val &= ~MC_GSC_ENABLE_TZ_LOCK_BIT; + val |= MC_GSC_LOCK_CFG_SETTINGS_BIT; tegra_mc_write_32(MC_TZRAM_CARVEOUT_CFG, val); /* - * MCE propogates the security configuration values across the + * MCE propagates the security configuration values across the * CCPLEX. */ mce_update_gsc_tzram(); } +static void tegra_lock_videomem_nonoverlap(uint64_t phys_base, + uint64_t size_in_bytes) +{ + uint32_t index; + uint64_t total_128kb_blocks = size_in_bytes >> 17; + uint64_t residual_4kb_blocks = (size_in_bytes & (uint32_t)0x1FFFF) >> 12; + uint64_t val; + + /* + * Reset the access configuration registers to restrict access to + * old Videomem aperture + */ + for (index = MC_VIDEO_PROTECT_CLEAR_ACCESS_CFG0; + index < ((uint32_t)MC_VIDEO_PROTECT_CLEAR_ACCESS_CFG0 + (uint32_t)MC_GSC_CONFIG_REGS_SIZE); + index += 4U) { + tegra_mc_write_32(index, 0); + } + + /* + * Set the base. It must be 4k aligned, at least. + */ + assert((phys_base & (uint64_t)0xFFF) == 0U); + tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_BASE_LO, (uint32_t)phys_base); + tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_BASE_HI, + (uint32_t)(phys_base >> 32) & (uint32_t)MC_GSC_BASE_HI_MASK); + + /* + * Set the aperture size + * + * total size = (number of 128KB blocks) + (number of remaining 4KB + * blocks) + * + */ + val = (uint32_t)((residual_4kb_blocks << MC_GSC_SIZE_RANGE_4KB_SHIFT) | + total_128kb_blocks); + tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_SIZE, (uint32_t)val); + + /* + * Lock the configuration settings by enabling TZ-only lock and + * locking the configuration against any future changes from NS + * world. + */ + tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_CFG, + (uint32_t)MC_GSC_ENABLE_TZ_LOCK_BIT); + + /* + * MCE propagates the GSC configuration values across the + * CCPLEX. + */ +} + +static void tegra_unlock_videomem_nonoverlap(void) +{ + /* Clear the base */ + tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_BASE_LO, 0); + tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_BASE_HI, 0); + + /* Clear the size */ + tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_SIZE, 0); +} + +static void tegra_clear_videomem(uintptr_t non_overlap_area_start, + unsigned long long non_overlap_area_size) +{ + /* + * Map the NS memory first, clean it and then unmap it. + */ + mmap_add_dynamic_region(non_overlap_area_start, /* PA */ + non_overlap_area_start, /* VA */ + non_overlap_area_size, /* size */ + MT_NS | MT_RW | MT_EXECUTE_NEVER); /* attrs */ + + zero_normalmem((void *)non_overlap_area_start, non_overlap_area_size); + flush_dcache_range(non_overlap_area_start, non_overlap_area_size); + + mmap_remove_dynamic_region(non_overlap_area_start, + non_overlap_area_size); +} + /* * Program the Video Memory carveout region * @@ -562,7 +645,10 @@ void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes) */ void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes) { + uintptr_t vmem_end_old = video_mem_base + (video_mem_size_mb << 20); + uintptr_t vmem_end_new = phys_base + size_in_bytes; uint32_t regval; + unsigned long long non_overlap_area_size; /* * The GPU is the user of the Video Memory region. In order to @@ -570,7 +656,7 @@ void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes) * new base/size ONLY if the GPU is in reset mode. */ regval = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_GPU_RESET_REG_OFFSET); - if ((regval & GPU_RESET_BIT) == 0) { + if ((regval & GPU_RESET_BIT) == 0U) { ERROR("GPU not in reset! Video Memory setup failed\n"); return; } @@ -581,17 +667,61 @@ void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes) */ INFO("Configuring Video Memory Carveout\n"); + /* + * Configure Memory Controller directly for the first time. + */ + if (video_mem_base == 0U) + goto done; + + /* + * Lock the non overlapping memory being cleared so that other masters + * do not accidently write to it. The memory would be unlocked once + * the non overlapping region is cleared and the new memory + * settings take effect. + */ + tegra_lock_videomem_nonoverlap(video_mem_base, + video_mem_size_mb << 20); + + /* + * Clear the old regions now being exposed. The following cases + * can occur - + * + * 1. clear whole old region (no overlap with new region) + * 2. clear old sub-region below new base + * 3. clear old sub-region above new end + */ + INFO("Cleaning previous Video Memory Carveout\n"); + + if (phys_base > vmem_end_old || video_mem_base > vmem_end_new) { + tegra_clear_videomem(video_mem_base, + (uint64_t)video_mem_size_mb << 20); + } else { + if (video_mem_base < phys_base) { + non_overlap_area_size = phys_base - video_mem_base; + tegra_clear_videomem(video_mem_base, non_overlap_area_size); + } + if (vmem_end_old > vmem_end_new) { + non_overlap_area_size = vmem_end_old - vmem_end_new; + tegra_clear_videomem(vmem_end_new, non_overlap_area_size); + } + } + +done: + /* program the Videomem aperture */ 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 >> 20); + /* unlock the previous locked nonoverlapping aperture */ + tegra_unlock_videomem_nonoverlap(); + /* store new values */ video_mem_base = phys_base; video_mem_size_mb = size_in_bytes >> 20; /* - * MCE propogates the VideoMem configuration values across the + * MCE propagates the VideoMem configuration values across the * CCPLEX. */ mce_update_gsc_videomem(); diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h index 6693cb3ae..8d7ab6eae 100644 --- a/plat/nvidia/tegra/include/t186/tegra_def.h +++ b/plat/nvidia/tegra/include/t186/tegra_def.h @@ -157,6 +157,16 @@ #define TEGRA_MC_STREAMID_BASE 0x02C00000 #define TEGRA_MC_BASE 0x02C10000 +/* General Security Carveout register macros */ +#define MC_GSC_CONFIG_REGS_SIZE 0x40UL +#define MC_GSC_LOCK_CFG_SETTINGS_BIT (1UL << 1) +#define MC_GSC_ENABLE_TZ_LOCK_BIT (1UL << 0) +#define MC_GSC_SIZE_RANGE_4KB_SHIFT 27UL +#define MC_GSC_BASE_LO_SHIFT 12UL +#define MC_GSC_BASE_LO_MASK 0xFFFFFUL +#define MC_GSC_BASE_HI_SHIFT 0UL +#define MC_GSC_BASE_HI_MASK 3UL + /* TZDRAM carveout configuration registers */ #define MC_SECURITY_CFG0_0 0x70 #define MC_SECURITY_CFG1_0 0x74 @@ -165,34 +175,24 @@ /* 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_SIZE_MB 0x64C + +/* + * Carveout (MC_SECURITY_CARVEOUT24) registers used to clear the + * non-overlapping Video memory region + */ +#define MC_VIDEO_PROTECT_CLEAR_CFG 0x25A0 +#define MC_VIDEO_PROTECT_CLEAR_BASE_LO 0x25A4 +#define MC_VIDEO_PROTECT_CLEAR_BASE_HI 0x25A8 +#define MC_VIDEO_PROTECT_CLEAR_SIZE 0x25AC +#define MC_VIDEO_PROTECT_CLEAR_ACCESS_CFG0 0x25B0 /* TZRAM carveout (MC_SECURITY_CARVEOUT11) configuration registers */ +#define MC_TZRAM_CARVEOUT_CFG 0x2190 #define MC_TZRAM_BASE_LO 0x2194 -#define TZRAM_BASE_LO_SHIFT 12 -#define TZRAM_BASE_LO_MASK 0xFFFFF #define MC_TZRAM_BASE_HI 0x2198 -#define TZRAM_BASE_HI_SHIFT 0 -#define TZRAM_BASE_HI_MASK 3 #define MC_TZRAM_SIZE 0x219C -#define TZRAM_SIZE_RANGE_4KB_SHIFT 27 - -#define MC_TZRAM_CARVEOUT_CFG 0x2190 -#define TZRAM_LOCK_CFG_SETTINGS_BIT (1 << 1) -#define TZRAM_ENABLE_TZ_LOCK_BIT (1 << 0) -#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG0 0x21A0 -#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG1 0x21A4 -#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG2 0x21A8 -#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG3 0x21AC -#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG4 0x21B0 -#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG5 0x21B4 - -#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS0 0x21B8 -#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS1 0x21BC -#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS2 0x21C0 -#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS3 0x21C4 -#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS4 0x21C8 -#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS5 0x21CC +#define MC_TZRAM_CLIENT_ACCESS_CFG0 0x21A0 /******************************************************************************* * Tegra UART Controller constants From 14a1c0edf06bfe832ab7ca2d07bcc0547ddf40d5 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 25 Jan 2017 13:35:27 -0800 Subject: [PATCH 6/7] Tegra: fix the NS DRAM address calculation logic This patch fixes the logic used to calculate the end of NS memory aperture. The functions allows zero sized NS apertures as that is a valid requirement for some use cases. e.g. VPR resize. Change-Id: Ie966e0ea2f9c6888d21c38e734003704094b3720 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/tegra_bl31_setup.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c index ffaa0ba3f..1dc806632 100644 --- a/plat/nvidia/tegra/common/tegra_bl31_setup.c +++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c @@ -381,13 +381,12 @@ void bl31_plat_arch_setup(void) ******************************************************************************/ int bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes) { - uint64_t end = base + size_in_bytes - 1; + uint64_t end = base + size_in_bytes; /* * Check if the NS DRAM address is valid */ - if ((base < TEGRA_DRAM_BASE) || (end > TEGRA_DRAM_END) || - (base >= end)) { + if ((base < TEGRA_DRAM_BASE) || (end > TEGRA_DRAM_END)) { ERROR("NS address is out-of-bounds!\n"); return -EFAULT; } From 7c1d43420697e39e5094b24cf7b4fb218e6edce7 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Tue, 18 Apr 2017 11:22:01 -0700 Subject: [PATCH 7/7] Tegra210: implement 'get_target_pwr_state' handler This patch implements the handler to calculate the cluster and system power states for the Tegra210 SoC. The power states returned by this handler are used by the PSCI library to decide cache maintenance operations - cluster v cpu. Change-Id: I93e4139d4cd8a086b51f328e9a76e91428ebcdab Signed-off-by: Varun Wadekar --- .../tegra/soc/t210/plat_psci_handlers.c | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c index 05028a1f6..91a13e8c3 100644 --- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c @@ -100,6 +100,39 @@ int32_t tegra_soc_validate_power_state(unsigned int power_state, return PSCI_E_SUCCESS; } +/******************************************************************************* + * Platform handler to calculate the proper target power level at the + * specified affinity level + ******************************************************************************/ +plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl, + const plat_local_state_t *states, + unsigned int ncpu) +{ + plat_local_state_t target = *states; + int cpu = plat_my_core_pos(); + int core_pos = read_mpidr() & MPIDR_CPU_MASK; + + /* get the power state at this level */ + if (lvl == MPIDR_AFFLVL1) + target = *(states + core_pos); + if (lvl == MPIDR_AFFLVL2) + target = *(states + cpu); + + /* Cluster idle/power-down */ + if ((lvl == MPIDR_AFFLVL1) && ((target == PSTATE_ID_CLUSTER_IDLE) || + (target == PSTATE_ID_CLUSTER_POWERDN))) { + return target; + } + + /* System Suspend */ + if (((lvl == MPIDR_AFFLVL2) || (lvl == MPIDR_AFFLVL1)) && + (target == PSTATE_ID_SOC_POWERDN)) + return PSTATE_ID_SOC_POWERDN; + + /* default state */ + return PSCI_LOCAL_STATE_RUN; +} + int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) { u_register_t mpidr = read_mpidr(); @@ -121,14 +154,14 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) } else if (stateid_afflvl1 == PSTATE_ID_CLUSTER_IDLE) { - assert(stateid_afflvl0 == PLAT_MAX_OFF_STATE); + assert(stateid_afflvl0 == PSTATE_ID_CLUSTER_IDLE); /* Prepare for cluster idle */ tegra_fc_cluster_idle(mpidr); } else if (stateid_afflvl1 == PSTATE_ID_CLUSTER_POWERDN) { - assert(stateid_afflvl0 == PLAT_MAX_OFF_STATE); + assert(stateid_afflvl0 == PSTATE_ID_CLUSTER_POWERDN); /* Prepare for cluster powerdn */ tegra_fc_cluster_powerdn(mpidr);