From f6e8ead4a12a0823f1f9c181552193a3ab95e960 Mon Sep 17 00:00:00 2001 From: Amith Date: Wed, 19 Aug 2015 20:13:12 -0700 Subject: [PATCH 01/12] spd: trusty: OEN_TAP_START aperture for standard calls This patch uses the OEN_TAP_START aperture for all the standard calls being passed to Trusty. Change-Id: Id78d01c7f48e4f54855600d7c789ffbfb898c541 Signed-off-by: Amith Signed-off-by: Varun Wadekar --- services/spd/trusty/trusty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/spd/trusty/trusty.c b/services/spd/trusty/trusty.c index 78a68ba0bc..b21ce715bc 100644 --- a/services/spd/trusty/trusty.c +++ b/services/spd/trusty/trusty.c @@ -395,7 +395,7 @@ DECLARE_RT_SVC( DECLARE_RT_SVC( trusty_std, - OEN_TOS_START, + OEN_TAP_START, SMC_ENTITY_SECURE_MONITOR, SMC_TYPE_STD, NULL, From d288ab2446aebfd1f4cf7f30a5b5b7212bce10d7 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 9 Dec 2015 18:18:53 -0800 Subject: [PATCH 02/12] Tegra: handlers for common and SoC-specific SiP calls This patch implements a handler for common SiP calls. A weak implementation for the SoC-specific handler has been provided which can be overridden by SoCs to implement any custom SiP calls. Change-Id: I45122892a84ea35d7b44be0f35dc15f6bb95193e Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/tegra_common.mk | 1 + .../tegra_sip_calls.c} | 30 ++++++-- plat/nvidia/tegra/soc/t132/plat_sip_calls.c | 75 +++---------------- plat/nvidia/tegra/soc/t210/platform_t210.mk | 1 - 4 files changed, 38 insertions(+), 69 deletions(-) rename plat/nvidia/tegra/{soc/t210/plat_sip_calls.c => common/tegra_sip_calls.c} (83%) diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk index 82da7fd046..c9e92557c8 100644 --- a/plat/nvidia/tegra/common/tegra_common.mk +++ b/plat/nvidia/tegra/common/tegra_common.mk @@ -59,4 +59,5 @@ BL31_SOURCES += drivers/arm/gic/gic_v2.c \ ${COMMON_DIR}/tegra_delay_timer.c \ ${COMMON_DIR}/tegra_gic.c \ ${COMMON_DIR}/tegra_pm.c \ + ${COMMON_DIR}/tegra_sip_calls.c \ ${COMMON_DIR}/tegra_topology.c diff --git a/plat/nvidia/tegra/soc/t210/plat_sip_calls.c b/plat/nvidia/tegra/common/tegra_sip_calls.c similarity index 83% rename from plat/nvidia/tegra/soc/t210/plat_sip_calls.c rename to plat/nvidia/tegra/common/tegra_sip_calls.c index 7d9838a35a..3bcd4418f0 100644 --- a/plat/nvidia/tegra/soc/t210/plat_sip_calls.c +++ b/plat/nvidia/tegra/common/tegra_sip_calls.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -40,14 +39,30 @@ #include /******************************************************************************* - * Tegra210 SiP SMCs + * Common Tegra SiP SMCs ******************************************************************************/ #define TEGRA_SIP_NEW_VIDEOMEM_REGION 0x82000003 +/******************************************************************************* + * SoC specific SiP handler + ******************************************************************************/ +#pragma weak plat_sip_handler +int plat_sip_handler(uint32_t smc_fid, + uint64_t x1, + uint64_t x2, + uint64_t x3, + uint64_t x4, + void *cookie, + void *handle, + uint64_t flags) +{ + return -ENOTSUP; +} + /******************************************************************************* * This function is responsible for handling all SiP calls from the NS world ******************************************************************************/ -uint64_t tegra210_sip_handler(uint32_t smc_fid, +uint64_t tegra_sip_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, @@ -64,6 +79,11 @@ uint64_t tegra210_sip_handler(uint32_t smc_fid, if (!ns) SMC_RET1(handle, SMC_UNK); + /* Check if this is a SoC specific SiP */ + err = plat_sip_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags); + if (err == 0) + SMC_RET1(handle, err); + switch (smc_fid) { case TEGRA_SIP_NEW_VIDEOMEM_REGION: @@ -104,11 +124,11 @@ uint64_t tegra210_sip_handler(uint32_t smc_fid, /* Define a runtime service descriptor for fast SMC calls */ DECLARE_RT_SVC( - tegra210_sip_fast, + tegra_sip_fast, OEN_SIP_START, OEN_SIP_END, SMC_TYPE_FAST, NULL, - tegra210_sip_handler + tegra_sip_handler ); diff --git a/plat/nvidia/tegra/soc/t132/plat_sip_calls.c b/plat/nvidia/tegra/soc/t132/plat_sip_calls.c index 450e1dd3b9..6c89944e9f 100644 --- a/plat/nvidia/tegra/soc/t132/plat_sip_calls.c +++ b/plat/nvidia/tegra/soc/t132/plat_sip_calls.c @@ -35,8 +35,6 @@ #include #include #include -#include -#include #include #define NS_SWITCH_AARCH32 1 @@ -45,7 +43,6 @@ /******************************************************************************* * Tegra132 SiP SMCs ******************************************************************************/ -#define TEGRA_SIP_NEW_VIDEOMEM_REGION 0x82000003 #define TEGRA_SIP_AARCH_SWITCH 0x82000004 /******************************************************************************* @@ -56,55 +53,19 @@ #define SPSR64 SPSR_64(MODE_EL2, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS) /******************************************************************************* - * This function is responsible for handling all SiP calls from the NS world + * This function is responsible for handling all T132 SiP calls ******************************************************************************/ -uint64_t tegra132_sip_handler(uint32_t smc_fid, - uint64_t x1, - uint64_t x2, - uint64_t x3, - uint64_t x4, - void *cookie, - void *handle, - uint64_t flags) +int plat_sip_handler(uint32_t smc_fid, + uint64_t x1, + uint64_t x2, + uint64_t x3, + uint64_t x4, + void *cookie, + void *handle, + uint64_t flags) { - uint32_t ns; - int err; - - /* Determine which security state this SMC originated from */ - ns = is_caller_non_secure(flags); - if (!ns) - SMC_RET1(handle, SMC_UNK); - switch (smc_fid) { - case TEGRA_SIP_NEW_VIDEOMEM_REGION: - - /* clean up the high bits */ - x1 = (uint32_t)x1; - x2 = (uint32_t)x2; - - /* - * Check if Video Memory overlaps TZDRAM (contains bl31/bl32) - * or falls outside of the valid DRAM range - */ - err = bl31_check_ns_address(x1, x2); - if (err) - SMC_RET1(handle, err); - - /* - * Check if Video Memory is aligned to 1MB. - */ - if ((x1 & 0xFFFFF) || (x2 & 0xFFFFF)) { - ERROR("Unaligned Video Memory base address!\n"); - SMC_RET1(handle, -ENOTSUP); - } - - /* new video memory carveout settings */ - tegra_memctrl_videomem_setup(x1, x2); - - SMC_RET1(handle, 0); - break; - case TEGRA_SIP_AARCH_SWITCH: /* clean up the high bits */ @@ -113,7 +74,7 @@ uint64_t tegra132_sip_handler(uint32_t smc_fid, if (!x1 || x2 > NS_SWITCH_AARCH32) { ERROR("%s: invalid parameters\n", __func__); - SMC_RET1(handle, SMC_UNK); + return -EINVAL; } /* x1 = ns entry point */ @@ -125,24 +86,12 @@ uint64_t tegra132_sip_handler(uint32_t smc_fid, INFO("CPU switched to AARCH%s mode\n", (x2 == NS_SWITCH_AARCH32) ? "32" : "64"); - SMC_RET1(handle, 0); - break; + return 0; default: ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid); break; } - SMC_RET1(handle, SMC_UNK); + return -ENOTSUP; } - -/* Define a runtime service descriptor for fast SMC calls */ -DECLARE_RT_SVC( - tegra132_sip_fast, - - OEN_SIP_START, - OEN_SIP_END, - SMC_TYPE_FAST, - NULL, - tegra132_sip_handler -); diff --git a/plat/nvidia/tegra/soc/t210/platform_t210.mk b/plat/nvidia/tegra/soc/t210/platform_t210.mk index d83c54db0d..2c908f9da2 100644 --- a/plat/nvidia/tegra/soc/t210/platform_t210.mk +++ b/plat/nvidia/tegra/soc/t210/platform_t210.mk @@ -51,7 +51,6 @@ BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ ${COMMON_DIR}/drivers/flowctrl/flowctrl.c \ ${COMMON_DIR}/drivers/memctrl/memctrl_v1.c \ ${SOC_DIR}/plat_psci_handlers.c \ - ${SOC_DIR}/plat_sip_calls.c \ ${SOC_DIR}/plat_setup.c \ ${SOC_DIR}/plat_secondary.c From 31a4957cd3c1674000c0cd66931878310701edb9 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 7 Jan 2016 14:04:21 -0800 Subject: [PATCH 03/12] Tegra: PM: soc-specific system off handler This patch introduces a power down handler which can be overriden by SoCs to customise the power down process. The current SoCs do not have a way of powering down the entire system as external PMIC chips are involved in the process. But future SoCs will have a way to power off the entire system without talking to an external PMIC. Change-Id: Ie7750714141a29cb0a1a616fafc531c4f11d0985 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/tegra_pm.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c index 8b7a059030..42ab5f2531 100644 --- a/plat/nvidia/tegra/common/tegra_pm.c +++ b/plat/nvidia/tegra/common/tegra_pm.c @@ -55,6 +55,7 @@ extern uint64_t tegra_sec_entry_point; #pragma weak tegra_soc_pwr_domain_off #pragma weak tegra_soc_pwr_domain_on_finish #pragma weak tegra_soc_prepare_system_reset +#pragma weak tegra_soc_prepare_system_off int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) { @@ -81,6 +82,12 @@ int tegra_soc_prepare_system_reset(void) return PSCI_E_SUCCESS; } +__dead2 void tegra_soc_prepare_system_off(void) +{ + ERROR("Tegra System Off: operation not handled.\n"); + panic(); +} + /******************************************************************************* * This handler is called by the PSCI implementation during the `SYSTEM_SUSPEND` * call to get the `power_state` parameter. This allows the platform to encode @@ -199,8 +206,9 @@ void tegra_pwr_domain_suspend_finish(const psci_power_state_t *target_state) ******************************************************************************/ __dead2 void tegra_system_off(void) { - ERROR("Tegra System Off: operation not handled.\n"); - panic(); + INFO("Powering down system...\n"); + + tegra_soc_prepare_system_off(); } /******************************************************************************* @@ -208,6 +216,8 @@ __dead2 void tegra_system_off(void) ******************************************************************************/ __dead2 void tegra_system_reset(void) { + INFO("Restarting system...\n"); + /* per-SoC system reset handler */ tegra_soc_prepare_system_reset(); From 25caa16d6ea3aeeb30e21af6b5fc3cdffb583788 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Fri, 8 Jan 2016 17:48:42 -0800 Subject: [PATCH 04/12] Tegra: enable runtime console This patch enables the runtime console for all Tegra platforms before exiting BL31. This would enable debug/error prints to be always displayed on the UART console. Change-Id: Ic48d61d05b0ab07973d6fc2dc6b68733a42a3f63 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/tegra_bl31_setup.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c index 3a9514bda9..b1e55730eb 100644 --- a/plat/nvidia/tegra/common/tegra_bl31_setup.c +++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-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: @@ -193,6 +193,16 @@ void bl31_platform_setup(void) INFO("BL3-1: Tegra platform setup complete\n"); } +/******************************************************************************* + * Perform any BL3-1 platform runtime setup prior to BL3-1 cold boot exit + ******************************************************************************/ +void bl31_plat_runtime_setup(void) +{ + /* Initialize the runtime console */ + console_init(tegra_console_base, TEGRA_BOOT_UART_CLK_IN_HZ, + TEGRA_CONSOLE_BAUDRATE); +} + /******************************************************************************* * Perform the very early platform specific architectural setup here. At the * moment this only intializes the mmu in a quick and dirty way. From 06b19d58ce5fd91751256ef011ef81ff49c0adec Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 30 Dec 2015 15:06:41 -0800 Subject: [PATCH 05/12] Tegra: drivers: memctrl: introduce function to secure on-chip TZRAM This patch introduces a function to secure the on-chip TZRAM memory. The Tegra132 and Tegra210 chips do not have a compelling use case to lock the TZRAM. The trusted OS owns the TZRAM aperture on these chips and so it can take care of locking the aperture. This might not be true for future chips and this patch makes the TZRAM programming flexible. Change-Id: I3ac9f1de1b792ccd23d4ded274784bbab2ea224a Signed-off-by: Varun Wadekar --- .../tegra/common/drivers/memctrl/memctrl_v1.c | 14 ++++++++++++++ plat/nvidia/tegra/common/tegra_bl31_setup.c | 7 +++++++ plat/nvidia/tegra/include/drivers/memctrl.h | 3 ++- plat/nvidia/tegra/include/drivers/memctrl_v1.h | 2 +- plat/nvidia/tegra/include/t132/tegra_def.h | 8 +++++++- plat/nvidia/tegra/include/t210/tegra_def.h | 8 +++++++- 6 files changed, 38 insertions(+), 4 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c index ac7d1415a2..0003446f9c 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c @@ -107,6 +107,20 @@ void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes) tegra_mc_write_32(MC_SECURITY_CFG1_0, size_in_bytes >> 20); } +/* + * Secure the BL31 TZRAM aperture. + * + * phys_base = physical base of TZRAM aperture + * size_in_bytes = size of aperture in bytes + */ +void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes) +{ + /* + * The v1 hardware controller does not have any registers + * for setting up the on-chip TZRAM. + */ +} + static void tegra_clear_videomem(uintptr_t non_overlap_area_start, unsigned long long non_overlap_area_size) { diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c index b1e55730eb..ba599cbec7 100644 --- a/plat/nvidia/tegra/common/tegra_bl31_setup.c +++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c @@ -44,6 +44,7 @@ #include #include #include +#include #include /******************************************************************************* @@ -183,6 +184,12 @@ void bl31_platform_setup(void) tegra_memctrl_tzdram_setup(plat_bl31_params_from_bl2.tzdram_base, plat_bl31_params_from_bl2.tzdram_size); + /* + * Set up the TZRAM memory aperture to allow only secure world + * access + */ + tegra_memctrl_tzram_setup(TEGRA_TZRAM_BASE, TEGRA_TZRAM_SIZE); + /* Set the next EL to be AArch64 */ tmp_reg = SCR_RES1_BITS | SCR_RW_BIT; write_scr(tmp_reg); diff --git a/plat/nvidia/tegra/include/drivers/memctrl.h b/plat/nvidia/tegra/include/drivers/memctrl.h index b06b4de789..db98fc074a 100644 --- a/plat/nvidia/tegra/include/drivers/memctrl.h +++ b/plat/nvidia/tegra/include/drivers/memctrl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-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: @@ -33,6 +33,7 @@ void tegra_memctrl_setup(void); void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes); +void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes); void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes); #endif /* __MEMCTRL_H__ */ diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v1.h b/plat/nvidia/tegra/include/drivers/memctrl_v1.h index e2e05277b1..e44a9ea924 100644 --- a/plat/nvidia/tegra/include/drivers/memctrl_v1.h +++ b/plat/nvidia/tegra/include/drivers/memctrl_v1.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-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: diff --git a/plat/nvidia/tegra/include/t132/tegra_def.h b/plat/nvidia/tegra/include/t132/tegra_def.h index 09d9b74290..e288067fc7 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, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-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: @@ -89,4 +89,10 @@ ******************************************************************************/ #define TEGRA_MC_BASE 0x70019000 +/******************************************************************************* + * Tegra TZRAM constants + ******************************************************************************/ +#define TEGRA_TZRAM_BASE 0x7C010000 +#define TEGRA_TZRAM_SIZE 0x10000 + #endif /* __TEGRA_DEF_H__ */ diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h index 8be39bb32b..2c73408777 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, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-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: @@ -114,4 +114,10 @@ ******************************************************************************/ #define TEGRA_MC_BASE 0x70019000 +/******************************************************************************* + * Tegra TZRAM constants + ******************************************************************************/ +#define TEGRA_TZRAM_BASE 0x7C010000 +#define TEGRA_TZRAM_SIZE 0x10000 + #endif /* __TEGRA_DEF_H__ */ From 9f9bafa34661e5e3506d9278fc07a0e6d24ea765 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Tue, 19 Jan 2016 13:55:19 -0800 Subject: [PATCH 06/12] Tegra: define platform power states The platform power states, PLAT_MAX_RET_STATE and PLAT_MAX_OFF_STATE, can change on Tegra SoCs and so should be defined per-soc. This patch moves these macro definitions to individual SoC's tegra_def.h files. Change-Id: Ib9b2752bc4d79cef6f79bee49882d340f71977a2 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/include/platform_def.h | 6 ------ plat/nvidia/tegra/include/t132/tegra_def.h | 9 +++++++++ plat/nvidia/tegra/include/t210/tegra_def.h | 9 +++++++++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/plat/nvidia/tegra/include/platform_def.h b/plat/nvidia/tegra/include/platform_def.h index 92c4c554ba..08e851c171 100644 --- a/plat/nvidia/tegra/include/platform_def.h +++ b/plat/nvidia/tegra/include/platform_def.h @@ -52,12 +52,6 @@ #define PLAT_NUM_PWR_DOMAINS (PLATFORM_CORE_COUNT + \ PLATFORM_CLUSTER_COUNT + 1) -/******************************************************************************* - * Platform power states - ******************************************************************************/ -#define PLAT_MAX_RET_STATE 1 -#define PLAT_MAX_OFF_STATE (PSTATE_ID_SOC_POWERDN + 1) - /******************************************************************************* * Platform console related constants ******************************************************************************/ diff --git a/plat/nvidia/tegra/include/t132/tegra_def.h b/plat/nvidia/tegra/include/t132/tegra_def.h index e288067fc7..318f4def15 100644 --- a/plat/nvidia/tegra/include/t132/tegra_def.h +++ b/plat/nvidia/tegra/include/t132/tegra_def.h @@ -39,6 +39,15 @@ ******************************************************************************/ #define PSTATE_ID_SOC_POWERDN 0xD +/******************************************************************************* + * Platform power states (used by PSCI framework) + * + * - PLAT_MAX_RET_STATE should be less than lowest PSTATE_ID + * - PLAT_MAX_OFF_STATE should be greater than the highest PSTATE_ID + ******************************************************************************/ +#define PLAT_MAX_RET_STATE 1 +#define PLAT_MAX_OFF_STATE (PSTATE_ID_SOC_POWERDN + 1) + /******************************************************************************* * GIC memory map ******************************************************************************/ diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h index 2c73408777..ce85427e43 100644 --- a/plat/nvidia/tegra/include/t210/tegra_def.h +++ b/plat/nvidia/tegra/include/t210/tegra_def.h @@ -47,6 +47,15 @@ ******************************************************************************/ #define PLAT_SYS_SUSPEND_STATE_ID PSTATE_ID_SOC_POWERDN +/******************************************************************************* + * Platform power states (used by PSCI framework) + * + * - PLAT_MAX_RET_STATE should be less than lowest PSTATE_ID + * - PLAT_MAX_OFF_STATE should be greater than the highest PSTATE_ID + ******************************************************************************/ +#define PLAT_MAX_RET_STATE 1 +#define PLAT_MAX_OFF_STATE (PSTATE_ID_SOC_POWERDN + 1) + /******************************************************************************* * GIC memory map ******************************************************************************/ From 990c1e0113bdcbd17bab2954d2c216001503c509 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 27 Jan 2016 11:31:06 -0800 Subject: [PATCH 07/12] Tegra: enable PSCI extended state ID processing This patch enables the PSCI_EXTENDED_STATE_ID macro. Tegra platforms have moved on to using the extended state ID for CPU_SUSPEND, where the NS world passes the state ID and wakeup time as part of the state ID field. Change-Id: Ie8b0fec285d8b2330bc26ff239a4f628425c9fcf Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/tegra_pm.c | 7 +--- plat/nvidia/tegra/platform.mk | 5 ++- .../tegra/soc/t132/plat_psci_handlers.c | 25 +------------ .../tegra/soc/t210/plat_psci_handlers.c | 37 +------------------ 4 files changed, 8 insertions(+), 66 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c index 42ab5f2531..683af2814e 100644 --- a/plat/nvidia/tegra/common/tegra_pm.c +++ b/plat/nvidia/tegra/common/tegra_pm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-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: @@ -233,13 +233,8 @@ __dead2 void tegra_system_reset(void) int32_t tegra_validate_power_state(unsigned int power_state, psci_power_state_t *req_state) { - int pwr_lvl = psci_get_pstate_pwrlvl(power_state); - assert(req_state); - if (pwr_lvl > PLAT_MAX_PWR_LVL) - return PSCI_E_INVALID_PARAMS; - return tegra_soc_validate_power_state(power_state, req_state); } diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk index cec7caff36..756899cb75 100644 --- a/plat/nvidia/tegra/platform.mk +++ b/plat/nvidia/tegra/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2015-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: @@ -30,6 +30,9 @@ SOC_DIR := plat/nvidia/tegra/soc/${TARGET_SOC} +# Enable PSCI v1.0 extended state ID format +PSCI_EXTENDED_STATE_ID := 1 + # Disable the PSCI platform compatibility layer ENABLE_PLAT_COMPAT := 0 diff --git a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c index 48a2fbaa37..bc7a7cced9 100644 --- a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-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: @@ -59,36 +59,15 @@ static int cpu_powergate_mask[PLATFORM_MAX_CPUS_PER_CLUSTER]; int32_t tegra_soc_validate_power_state(unsigned int power_state, psci_power_state_t *req_state) { - int pwr_lvl = psci_get_pstate_pwrlvl(power_state); int state_id = psci_get_pstate_id(power_state); int cpu = read_mpidr() & MPIDR_CPU_MASK; - if (pwr_lvl > PLAT_MAX_PWR_LVL) - return PSCI_E_INVALID_PARAMS; - - /* Sanity check the requested afflvl */ - if (psci_get_pstate_type(power_state) == PSTATE_TYPE_STANDBY) { - /* - * It's possible to enter standby only on affinity level 0 i.e. - * a cpu on Tegra. Ignore any other affinity level. - */ - if (pwr_lvl != MPIDR_AFFLVL0) - return PSCI_E_INVALID_PARAMS; - - /* power domain in standby state */ - req_state->pwr_domain_state[pwr_lvl] = PLAT_MAX_RET_STATE; - - return PSCI_E_SUCCESS; - } - /* * Sanity check the requested state id, power level and CPU number. * Currently T132 only supports SYSTEM_SUSPEND on last standing CPU * i.e. CPU 0 */ - if ((pwr_lvl != PLAT_MAX_PWR_LVL) || - (state_id != PSTATE_ID_SOC_POWERDN) || - (cpu != 0)) { + if ((state_id != PSTATE_ID_SOC_POWERDN) || (cpu != 0)) { ERROR("unsupported state id @ power level\n"); return PSCI_E_INVALID_PARAMS; } diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c index b184063d8f..332de2567a 100644 --- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-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: @@ -58,39 +58,14 @@ static int cpu_powergate_mask[PLATFORM_MAX_CPUS_PER_CLUSTER]; int32_t tegra_soc_validate_power_state(unsigned int power_state, psci_power_state_t *req_state) { - int pwr_lvl = psci_get_pstate_pwrlvl(power_state); int state_id = psci_get_pstate_id(power_state); - if (pwr_lvl > PLAT_MAX_PWR_LVL) { - ERROR("%s: unsupported power_state (0x%x)\n", __func__, - power_state); - return PSCI_E_INVALID_PARAMS; - } - - /* Sanity check the requested afflvl */ - if (psci_get_pstate_type(power_state) == PSTATE_TYPE_STANDBY) { - /* - * It's possible to enter standby only on affinity level 0 i.e. - * a cpu on Tegra. Ignore any other affinity level. - */ - if (pwr_lvl != MPIDR_AFFLVL0) - return PSCI_E_INVALID_PARAMS; - - /* power domain in standby state */ - req_state->pwr_domain_state[pwr_lvl] = PLAT_MAX_RET_STATE; - - return PSCI_E_SUCCESS; - } - /* Sanity check the requested state id */ switch (state_id) { case PSTATE_ID_CORE_POWERDN: /* * Core powerdown request only for afflvl 0 */ - if (pwr_lvl != MPIDR_AFFLVL0) - goto error; - req_state->pwr_domain_state[MPIDR_AFFLVL0] = state_id & 0xff; break; @@ -100,9 +75,6 @@ int32_t tegra_soc_validate_power_state(unsigned int power_state, /* * Cluster powerdown/idle request only for afflvl 1 */ - if (pwr_lvl != MPIDR_AFFLVL1) - goto error; - req_state->pwr_domain_state[MPIDR_AFFLVL1] = state_id; req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_OFF_STATE; @@ -112,9 +84,6 @@ int32_t tegra_soc_validate_power_state(unsigned int power_state, /* * System powerdown request only for afflvl 2 */ - if (pwr_lvl != PLAT_MAX_PWR_LVL) - goto error; - for (int i = MPIDR_AFFLVL0; i < PLAT_MAX_PWR_LVL; i++) req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE; @@ -129,10 +98,6 @@ int32_t tegra_soc_validate_power_state(unsigned int power_state, } return PSCI_E_SUCCESS; - -error: - ERROR("%s: unsupported state id (%d)\n", __func__, state_id); - return PSCI_E_INVALID_PARAMS; } int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) From 9f1c5dd19b7596db74db84e2ac58c31794fb20b5 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Mon, 22 Feb 2016 11:09:41 -0800 Subject: [PATCH 08/12] cpus: denver: disable DCO operations from platform code This patch moves the code to disable DCO operations out from common CPU files. This allows the platform code to call thsi API as and when required. There are certain CPU power down states which require the DCO to be kept ON and platforms can decide selectively now. Change-Id: Icb946fe2545a7d8c5903c420d1ee169c4921a2d1 Signed-off-by: Varun Wadekar --- include/lib/cpus/aarch64/denver.h | 9 ++++++++- lib/cpus/aarch64/denver.S | 20 +++---------------- .../tegra/soc/t132/plat_psci_handlers.c | 12 ++++++++++- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/include/lib/cpus/aarch64/denver.h b/include/lib/cpus/aarch64/denver.h index 0de094a4c9..e083533740 100644 --- a/include/lib/cpus/aarch64/denver.h +++ b/include/lib/cpus/aarch64/denver.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-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: @@ -44,4 +44,11 @@ /* CPU state ids - implementation defined */ #define DENVER_CPU_STATE_POWER_DOWN 0x3 +#ifndef __ASSEMBLY__ + +/* Disable Dynamic Code Optimisation */ +void denver_disable_dco(void); + +#endif + #endif /* __DENVER_H__ */ diff --git a/lib/cpus/aarch64/denver.S b/lib/cpus/aarch64/denver.S index c38515562f..3e238a1c19 100644 --- a/lib/cpus/aarch64/denver.S +++ b/lib/cpus/aarch64/denver.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-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: @@ -35,6 +35,8 @@ #include #include + .global denver_disable_dco + /* --------------------------------------------- * Disable debug interfaces * --------------------------------------------- @@ -111,22 +113,6 @@ func denver_core_pwr_dwn mov x19, x30 - /* ---------------------------------------------------- - * We enter the 'core power gated with ARM state not - * retained' power state during CPU power down. We let - * DCO know that we expect to enter this power state - * by writing to the ACTLR_EL1 register. - * ---------------------------------------------------- - */ - mov x0, #DENVER_CPU_STATE_POWER_DOWN - msr actlr_el1, x0 - - /* --------------------------------------------- - * Force DCO to be quiescent - * --------------------------------------------- - */ - bl denver_disable_dco - /* --------------------------------------------- * Force the debug interfaces to be quiescent * --------------------------------------------- diff --git a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c index bc7a7cced9..2abb2929fd 100644 --- a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c @@ -110,6 +110,13 @@ int tegra_soc_pwr_domain_on(u_register_t mpidr) int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state) { tegra_fc_cpu_off(read_mpidr() & MPIDR_CPU_MASK); + + /* Disable DCO operations */ + denver_disable_dco(); + + /* Power down the CPU */ + write_actlr_el1(DENVER_CPU_STATE_POWER_DOWN); + return PSCI_E_SUCCESS; } @@ -128,7 +135,10 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) /* Program FC to enter suspend state */ tegra_fc_cpu_powerdn(read_mpidr()); - /* Suspend DCO operations */ + /* Disable DCO operations */ + denver_disable_dco(); + + /* Program the suspend state ID */ write_actlr_el1(target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]); return PSCI_E_SUCCESS; From 102e4087935c454e0168cec7e9925b1e03be8325 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 3 Mar 2016 13:28:10 -0800 Subject: [PATCH 09/12] Tegra: allow individual SoCs to restore their settings This patch uses the Memory controller driver's handler to restore its settings and moves the other chip specific code to their own 'pwr_domain_on_finish' handlers. Change-Id: I3c9d23bdab9e2e3c05034ff6812cf941ccd7a75e Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c | 8 ++++++++ plat/nvidia/tegra/common/tegra_pm.c | 10 +++------- plat/nvidia/tegra/include/drivers/memctrl.h | 1 + plat/nvidia/tegra/soc/t132/plat_psci_handlers.c | 10 ++++++++++ plat/nvidia/tegra/soc/t210/plat_psci_handlers.c | 5 +++++ 5 files changed, 27 insertions(+), 7 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c index 0003446f9c..c4170504c4 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c @@ -89,6 +89,14 @@ void tegra_memctrl_setup(void) tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size); } +/* + * Restore Memory Controller settings after "System Suspend" + */ +void tegra_memctrl_restore_settings(void) +{ + tegra_memctrl_setup(); +} + /* * Secure the BL31 DRAM aperture. * diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c index 683af2814e..64405fb3a0 100644 --- a/plat/nvidia/tegra/common/tegra_pm.c +++ b/plat/nvidia/tegra/common/tegra_pm.c @@ -168,14 +168,10 @@ void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state) PSTATE_ID_SOC_POWERDN) { /* - * Lock scratch registers which hold the CPU vectors. + * Restore Memory Controller settings as it loses state + * during system suspend. */ - tegra_pmc_lock_cpu_vectors(); - - /* - * SMMU configuration. - */ - tegra_memctrl_setup(); + tegra_memctrl_restore_settings(); /* * Security configuration to allow DRAM/device access. diff --git a/plat/nvidia/tegra/include/drivers/memctrl.h b/plat/nvidia/tegra/include/drivers/memctrl.h index db98fc074a..a3f08755ac 100644 --- a/plat/nvidia/tegra/include/drivers/memctrl.h +++ b/plat/nvidia/tegra/include/drivers/memctrl.h @@ -32,6 +32,7 @@ #define __MEMCTRL_H__ void tegra_memctrl_setup(void); +void tegra_memctrl_restore_settings(void); void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes); void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes); void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes); diff --git a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c index 2abb2929fd..f05f3d0e9f 100644 --- a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c @@ -107,6 +107,16 @@ int tegra_soc_pwr_domain_on(u_register_t mpidr) return PSCI_E_SUCCESS; } +int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) +{ + /* + * Lock scratch registers which hold the CPU vectors + */ + tegra_pmc_lock_cpu_vectors(); + + return PSCI_E_SUCCESS; +} + int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state) { tegra_fc_cpu_off(read_mpidr() & MPIDR_CPU_MASK); diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c index 332de2567a..95fb93fe00 100644 --- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c @@ -154,6 +154,11 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] == PLAT_SYS_SUSPEND_STATE_ID) { + /* + * Lock scratch registers which hold the CPU vectors + */ + tegra_pmc_lock_cpu_vectors(); + /* * Enable WRAP to INCR burst type conversions for * incoming requests on the AXI slave ports. From 49622c8d4962ab14d30119f9cc02ec6cd2c3c9df Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 3 Mar 2016 18:27:28 -0800 Subject: [PATCH 10/12] Tegra: increase BL31 image size to 256KB This patch increases the BL31 image size for all Tegra platforms to 256KB, so that we can relocate BL31 to TZSRAM on supported chips. Change-Id: I467063c68632b53b5d4ef8ff1f76f5988096bd9c Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/include/platform_def.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/nvidia/tegra/include/platform_def.h b/plat/nvidia/tegra/include/platform_def.h index 08e851c171..ad245e2f89 100644 --- a/plat/nvidia/tegra/include/platform_def.h +++ b/plat/nvidia/tegra/include/platform_def.h @@ -68,7 +68,7 @@ /******************************************************************************* * BL31 specific defines. ******************************************************************************/ -#define BL31_SIZE 0x20000 +#define BL31_SIZE 0x40000 #define BL31_BASE TZDRAM_BASE #define BL31_LIMIT (TZDRAM_BASE + BL31_SIZE - 1) #define BL32_BASE (TZDRAM_BASE + BL31_SIZE) From 260ae46f271a2552371847c3dc2da20d0287756e Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Fri, 18 Mar 2016 13:01:12 -0700 Subject: [PATCH 11/12] Tegra: memmap BL31's TZDRAM carveout This patch maps the TZDRAM carveout used by the BL31. In the near future BL31 would be running from the TZRAM for security and performance reasons. The only downside to this solution is that the TZRAM loses its state in System Suspend. So, we map the TZDRAM carveout that the BL31 would use to save its state before entering System Suspend. Change-Id: Id5bda7e9864afd270cf86418c703fa61c2cb095f Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/tegra_bl31_setup.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c index ba599cbec7..72da4b3c0a 100644 --- a/plat/nvidia/tegra/common/tegra_bl31_setup.c +++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c @@ -225,6 +225,7 @@ void bl31_plat_arch_setup(void) #if USE_COHERENT_MEM unsigned long coh_start, coh_size; #endif + plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); /* add memory regions */ mmap_add_region(total_base, total_base, @@ -234,6 +235,14 @@ void bl31_plat_arch_setup(void) ro_size, MT_MEMORY | MT_RO | MT_SECURE); + /* map TZDRAM used by BL31 as coherent memory */ + if (TEGRA_TZRAM_BASE == tegra_bl31_phys_base) { + mmap_add_region(params_from_bl2->tzdram_base, + params_from_bl2->tzdram_base, + BL31_SIZE, + MT_DEVICE | MT_RW | MT_SECURE); + } + #if USE_COHERENT_MEM coh_start = total_base + (BL_COHERENT_RAM_BASE - BL31_RO_BASE); coh_size = BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE; From 26c0d9b2ed406d4e39a4e92a365c285f5845d696 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Fri, 18 Mar 2016 14:35:28 -0700 Subject: [PATCH 12/12] Tegra: implement pwr_domain_pwr_down_wfi() handler This patch adds the pwr_domain_power_down_wfi() handler for Tegra platforms which in turn executes the soc specific `power_down_wfi` handler. Change-Id: I5deecc09959db3c3d73f928f5c871966331cfd95 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/tegra_pm.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c index 64405fb3a0..f5ef3e764b 100644 --- a/plat/nvidia/tegra/common/tegra_pm.c +++ b/plat/nvidia/tegra/common/tegra_pm.c @@ -54,6 +54,7 @@ extern uint64_t tegra_sec_entry_point; #pragma weak tegra_soc_pwr_domain_on #pragma weak tegra_soc_pwr_domain_off #pragma weak tegra_soc_pwr_domain_on_finish +#pragma weak tegra_soc_pwr_domain_power_down_wfi #pragma weak tegra_soc_prepare_system_reset #pragma weak tegra_soc_prepare_system_off @@ -77,6 +78,11 @@ int tegra_soc_pwr_domain_on_finish(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) +{ + return PSCI_E_SUCCESS; +} + int tegra_soc_prepare_system_reset(void) { return PSCI_E_SUCCESS; @@ -136,7 +142,7 @@ void tegra_pwr_domain_off(const psci_power_state_t *target_state) } /******************************************************************************* - * Handler called when called when a power domain is about to be suspended. The + * Handler called when a power domain is about to be suspended. The * target_state encodes the power state that each level should transition to. ******************************************************************************/ void tegra_pwr_domain_suspend(const psci_power_state_t *target_state) @@ -147,6 +153,24 @@ void tegra_pwr_domain_suspend(const psci_power_state_t *target_state) tegra_gic_cpuif_deactivate(); } +/******************************************************************************* + * Handler called at the end of the power domain suspend sequence. The + * target_state encodes the power state that each level should transition to. + ******************************************************************************/ +__dead2 void tegra_pwr_domain_power_down_wfi(const psci_power_state_t + *target_state) +{ + /* call the chip's power down handler */ + tegra_soc_pwr_domain_power_down_wfi(target_state); + + /* enter power down state */ + wfi(); + + /* we can never reach here */ + ERROR("%s: operation not handled.\n", __func__); + panic(); +} + /******************************************************************************* * Handler called when a power domain has just been powered on after * being turned off earlier. The target_state encodes the low power state that @@ -259,6 +283,7 @@ static const plat_psci_ops_t tegra_plat_psci_ops = { .pwr_domain_suspend = tegra_pwr_domain_suspend, .pwr_domain_on_finish = tegra_pwr_domain_on_finish, .pwr_domain_suspend_finish = tegra_pwr_domain_suspend_finish, + .pwr_domain_pwr_down_wfi = tegra_pwr_domain_power_down_wfi, .system_off = tegra_system_off, .system_reset = tegra_system_reset, .validate_power_state = tegra_validate_power_state,