Commit f097fb70 authored by Sandrine Bailleux's avatar Sandrine Bailleux Committed by TrustedFirmware Code Review
Browse files

Merge changes from topic "tegra-downstream-03122020" into integration

* changes:
  Tegra: assembly version of the 'plat_core_pos_by_mpidr' handler
  Tegra194: reset power state info for CPUs
  tlkd: remove system off/reset handlers
  Tegra186: system resume from TZSRAM memory
  Tegra186: disable PROGRAMMABLE_RESET_ADDRESS
  Tegra210: SE: switch SE clock source to CLK_M
  Tegra: increase platform assert logging level to VERBOSE
  spd: trusty: disable error messages seen during boot
  Tegra194: enable dual execution for EL2 and EL3
  Tegra: aarch64: calculate core position from one place
  Tegra194: Update t194_nvg.h to v6.7
parents c9796852 0ac1bf72
/* /*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -26,7 +27,6 @@ ...@@ -26,7 +27,6 @@
#define TLK_RESUME_FID TLK_TOS_YIELD_FID(0x100) #define TLK_RESUME_FID TLK_TOS_YIELD_FID(0x100)
#define TLK_SYSTEM_SUSPEND TLK_TOS_YIELD_FID(0xE001) #define TLK_SYSTEM_SUSPEND TLK_TOS_YIELD_FID(0xE001)
#define TLK_SYSTEM_RESUME TLK_TOS_YIELD_FID(0xE002) #define TLK_SYSTEM_RESUME TLK_TOS_YIELD_FID(0xE002)
#define TLK_SYSTEM_OFF TLK_TOS_YIELD_FID(0xE003)
#define TLK_IRQ_FIRED TLK_TOS_YIELD_FID(0xE004) #define TLK_IRQ_FIRED TLK_TOS_YIELD_FID(0xE004)
/* /*
...@@ -39,7 +39,6 @@ ...@@ -39,7 +39,6 @@
#define TLK_VA_TRANSLATE (0x32000004 | (ULL(1) << 31)) #define TLK_VA_TRANSLATE (0x32000004 | (ULL(1) << 31))
#define TLK_SUSPEND_DONE (0x32000005 | (ULL(1) << 31)) #define TLK_SUSPEND_DONE (0x32000005 | (ULL(1) << 31))
#define TLK_RESUME_DONE (0x32000006 | (ULL(1) << 31)) #define TLK_RESUME_DONE (0x32000006 | (ULL(1) << 31))
#define TLK_SYSTEM_OFF_DONE (0x32000007 | (ULL(1) << 31))
#define TLK_IRQ_DONE (0x32000008 | (ULL(1) << 31)) #define TLK_IRQ_DONE (0x32000008 | (ULL(1) << 31))
/* /*
......
...@@ -34,6 +34,11 @@ ...@@ -34,6 +34,11 @@
#define DENVER_CPU_PMSTATE_C7 U(0x7) #define DENVER_CPU_PMSTATE_C7 U(0x7)
#define DENVER_CPU_PMSTATE_MASK U(0xF) #define DENVER_CPU_PMSTATE_MASK U(0xF)
/* ACTRL_ELx bits to enable dual execution*/
#define DENVER_CPU_ENABLE_DUAL_EXEC_EL2 (ULL(1) << 9)
#define DENVER_CPU_ENABLE_DUAL_EXEC_EL3 (ULL(1) << 9)
#define DENVER_CPU_ENABLE_DUAL_EXEC_EL1 (U(1) << 4)
#ifndef __ASSEMBLER__ #ifndef __ASSEMBLER__
/* Disable Dynamic Code Optimisation */ /* Disable Dynamic Code Optimisation */
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
.globl plat_crash_console_init .globl plat_crash_console_init
.globl plat_crash_console_putc .globl plat_crash_console_putc
.globl plat_crash_console_flush .globl plat_crash_console_flush
.weak plat_core_pos_by_mpidr
.globl tegra_secure_entrypoint .globl tegra_secure_entrypoint
.globl plat_reset_handler .globl plat_reset_handler
...@@ -140,17 +141,14 @@ endfunc plat_is_my_cpu_primary ...@@ -140,17 +141,14 @@ endfunc plat_is_my_cpu_primary
* unsigned int plat_my_core_pos(void); * unsigned int plat_my_core_pos(void);
* *
* result: CorePos = CoreId + (ClusterId * cpus per cluster) * result: CorePos = CoreId + (ClusterId * cpus per cluster)
* Registers clobbered: x0, x8
* ---------------------------------------------------------- * ----------------------------------------------------------
*/ */
func plat_my_core_pos func plat_my_core_pos
mov x8, x30
mrs x0, mpidr_el1 mrs x0, mpidr_el1
and x1, x0, #MPIDR_CPU_MASK bl plat_core_pos_by_mpidr
and x0, x0, #MPIDR_CLUSTER_MASK ret x8
lsr x0, x0, #MPIDR_AFFINITY_BITS
mov x2, #PLATFORM_MAX_CPUS_PER_CLUSTER
mul x0, x0, x2
add x0, x1, x0
ret
endfunc plat_my_core_pos endfunc plat_my_core_pos
/* ----------------------------------------------------- /* -----------------------------------------------------
...@@ -273,6 +271,42 @@ _end: mov x0, x20 ...@@ -273,6 +271,42 @@ _end: mov x0, x20
ret ret
endfunc plat_reset_handler endfunc plat_reset_handler
/* ------------------------------------------------------
* int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
*
* This function implements a part of the critical
* interface between the psci generic layer and the
* platform that allows the former to query the platform
* to convert an MPIDR to a unique linear index. An error
* code (-1) is returned in case the MPIDR is invalid.
*
* Clobbers: x0-x3
* ------------------------------------------------------
*/
func plat_core_pos_by_mpidr
lsr x1, x0, #MPIDR_AFF0_SHIFT
and x1, x1, #MPIDR_AFFLVL_MASK /* core id */
lsr x2, x0, #MPIDR_AFF1_SHIFT
and x2, x2, #MPIDR_AFFLVL_MASK /* cluster id */
/* core_id >= PLATFORM_MAX_CPUS_PER_CLUSTER */
mov x0, #-1
cmp x1, #(PLATFORM_MAX_CPUS_PER_CLUSTER - 1)
b.gt 1f
/* cluster_id >= PLATFORM_CLUSTER_COUNT */
cmp x2, #(PLATFORM_CLUSTER_COUNT - 1)
b.gt 1f
/* CorePos = CoreId + (ClusterId * cpus per cluster) */
mov x3, #PLATFORM_MAX_CPUS_PER_CLUSTER
mul x3, x3, x2
add x0, x1, x3
1:
ret
endfunc plat_core_pos_by_mpidr
/* ---------------------------------------- /* ----------------------------------------
* Secure entrypoint function for CPU boot * Secure entrypoint function for CPU boot
* ---------------------------------------- * ----------------------------------------
......
...@@ -32,5 +32,4 @@ BL31_SOURCES += drivers/delay_timer/delay_timer.c \ ...@@ -32,5 +32,4 @@ BL31_SOURCES += drivers/delay_timer/delay_timer.c \
${COMMON_DIR}/tegra_io_storage.c \ ${COMMON_DIR}/tegra_io_storage.c \
${COMMON_DIR}/tegra_platform.c \ ${COMMON_DIR}/tegra_platform.c \
${COMMON_DIR}/tegra_pm.c \ ${COMMON_DIR}/tegra_pm.c \
${COMMON_DIR}/tegra_sip_calls.c \ ${COMMON_DIR}/tegra_sip_calls.c
${COMMON_DIR}/tegra_topology.c
/*
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <platform_def.h>
#include <arch.h>
#include <lib/psci/psci.h>
#include <plat/common/platform.h>
#pragma weak plat_core_pos_by_mpidr
/*******************************************************************************
* This function implements a part of the critical interface between the psci
* generic layer and the platform that allows the former to query the platform
* to convert an MPIDR to a unique linear index. An error code (-1) is returned
* in case the MPIDR is invalid.
******************************************************************************/
int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
{
u_register_t cluster_id, cpu_id;
int32_t result;
cluster_id = (mpidr >> (u_register_t)MPIDR_AFF1_SHIFT) &
(u_register_t)MPIDR_AFFLVL_MASK;
cpu_id = (mpidr >> (u_register_t)MPIDR_AFF0_SHIFT) &
(u_register_t)MPIDR_AFFLVL_MASK;
/* CorePos = CoreId + (ClusterId * cpus per cluster) */
result = (int32_t)cpu_id + ((int32_t)cluster_id *
PLATFORM_MAX_CPUS_PER_CLUSTER);
if (cluster_id >= (u_register_t)PLATFORM_CLUSTER_COUNT) {
result = PSCI_E_NOT_PRESENT;
}
/*
* Validate cpu_id by checking whether it represents a CPU in
* one of the two clusters present on the platform.
*/
if (cpu_id >= (u_register_t)PLATFORM_MAX_CPUS_PER_CLUSTER) {
result = PSCI_E_NOT_PRESENT;
}
return result;
}
...@@ -7,10 +7,6 @@ ...@@ -7,10 +7,6 @@
#ifndef TEGRA186_PRIVATE_H #ifndef TEGRA186_PRIVATE_H
#define TEGRA186_PRIVATE_H #define TEGRA186_PRIVATE_H
void tegra186_cpu_reset_handler(void); uint64_t tegra186_get_mc_ctx_size(void);
uint64_t tegra186_get_cpu_reset_handler_base(void);
uint64_t tegra186_get_cpu_reset_handler_size(void);
uint64_t tegra186_get_mc_ctx_offset(void);
void tegra186_set_system_suspend_entry(void);
#endif /* TEGRA186_PRIVATE_H */ #endif /* TEGRA186_PRIVATE_H */
...@@ -47,6 +47,8 @@ typedef struct plat_params_from_bl2 { ...@@ -47,6 +47,8 @@ typedef struct plat_params_from_bl2 {
uint64_t sc7entry_fw_size; uint64_t sc7entry_fw_size;
/* System Suspend Entry Firmware base address */ /* System Suspend Entry Firmware base address */
uint64_t sc7entry_fw_base; uint64_t sc7entry_fw_base;
/* Enable dual execution */
uint8_t enable_ccplex_lock_step;
} plat_params_from_bl2_t; } plat_params_from_bl2_t;
/******************************************************************************* /*******************************************************************************
......
...@@ -13,7 +13,7 @@ $(eval $(call add_define,CRASH_REPORTING)) ...@@ -13,7 +13,7 @@ $(eval $(call add_define,CRASH_REPORTING))
# enable assert() for release/debug builds # enable assert() for release/debug builds
ENABLE_ASSERTIONS := 1 ENABLE_ASSERTIONS := 1
PLAT_LOG_LEVEL_ASSERT := 40 PLAT_LOG_LEVEL_ASSERT := 50
$(eval $(call add_define,PLAT_LOG_LEVEL_ASSERT)) $(eval $(call add_define,PLAT_LOG_LEVEL_ASSERT))
# enable dynamic memory mapping # enable dynamic memory mapping
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include <bpmp_ipc.h> #include <bpmp_ipc.h>
#include <pmc.h> #include <pmc.h>
#include <security_engine.h> #include <security_engine.h>
#include <tegra186_private.h>
#include <tegra_private.h> #include <tegra_private.h>
#include "se_private.h" #include "se_private.h"
......
...@@ -10,8 +10,8 @@ ...@@ -10,8 +10,8 @@
#include <mce.h> #include <mce.h>
#include <memctrl_v2.h> #include <memctrl_v2.h>
#include <tegra_mc_def.h>
#include <tegra186_private.h> #include <tegra186_private.h>
#include <tegra_mc_def.h>
#include <tegra_platform.h> #include <tegra_platform.h>
#include <tegra_private.h> #include <tegra_private.h>
...@@ -711,13 +711,6 @@ tegra_mc_settings_t *tegra_get_mc_settings(void) ...@@ -711,13 +711,6 @@ tegra_mc_settings_t *tegra_get_mc_settings(void)
void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes) void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes)
{ {
uint32_t val; uint32_t val;
uint64_t src_base_tzdram;
const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
uint64_t src_len_in_bytes = BL31_END - BL31_START;
/* base address of BL3-1 source in TZDRAM */
src_base_tzdram = params_from_bl2->tzdram_base +
tegra186_get_cpu_reset_handler_size();
/* /*
* Setup the Memory controller to allow only secure accesses to * Setup the Memory controller to allow only secure accesses to
...@@ -746,15 +739,6 @@ void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes) ...@@ -746,15 +739,6 @@ void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes)
val = tegra_mc_read_32(MC_SECURITY_CFG3_0) & MC_SECURITY_BOM_HI_MASK; val = tegra_mc_read_32(MC_SECURITY_CFG3_0) & MC_SECURITY_BOM_HI_MASK;
mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_TZDRAM_ADDR_HI, val); mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_TZDRAM_ADDR_HI, val);
/*
* save tzdram_addr_lo and ATF-size, this would be used in SC7-RF to
* generate SHA256.
*/
mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV68_LO,
(uint32_t)src_base_tzdram);
mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV0_HI,
(uint32_t)src_len_in_bytes);
/* /*
* MCE propagates the security configuration values across the * MCE propagates the security configuration values across the
* CCPLEX. * CCPLEX.
......
...@@ -134,8 +134,7 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) ...@@ -134,8 +134,7 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_BOOTP_FCFG, val); mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_BOOTP_FCFG, val);
/* save MC context to TZDRAM */ /* save MC context to TZDRAM */
mc_ctx_base = params_from_bl2->tzdram_base + mc_ctx_base = params_from_bl2->tzdram_base;
tegra186_get_mc_ctx_offset();
tegra_mc_save_context((uintptr_t)mc_ctx_base); tegra_mc_save_context((uintptr_t)mc_ctx_base);
/* Prepare for system suspend */ /* Prepare for system suspend */
...@@ -158,9 +157,6 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) ...@@ -158,9 +157,6 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
(void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE, (void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE,
(uint64_t)TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0U); (uint64_t)TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0U);
/* set system suspend state for house-keeping */
tegra186_set_system_suspend_entry();
} else { } else {
; /* do nothing */ ; /* do nothing */
} }
...@@ -289,7 +285,7 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta ...@@ -289,7 +285,7 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta
if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) { if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
val = params_from_bl2->tzdram_base + val = params_from_bl2->tzdram_base +
tegra186_get_cpu_reset_handler_size(); tegra186_get_mc_ctx_size();
/* Initialise communication channel with BPMP */ /* Initialise communication channel with BPMP */
assert(tegra_bpmp_ipc_init() == 0); assert(tegra_bpmp_ipc_init() == 0);
...@@ -316,10 +312,19 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta ...@@ -316,10 +312,19 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta
* BL3-1 over to TZDRAM. * BL3-1 over to TZDRAM.
*/ */
val = params_from_bl2->tzdram_base + val = params_from_bl2->tzdram_base +
tegra186_get_cpu_reset_handler_size(); tegra186_get_mc_ctx_size();
memcpy16((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE, memcpy16((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE,
(uintptr_t)BL31_END - (uintptr_t)BL31_BASE); (uintptr_t)BL31_END - (uintptr_t)BL31_BASE);
/*
* Save code base and size; this would be used by SC7-RF to
* verify binary
*/
mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV68_LO,
(uint32_t)val);
mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV0_HI,
(uint32_t)src_len_in_bytes);
ret = tegra_bpmp_ipc_disable_clock(TEGRA186_CLK_SE); ret = tegra_bpmp_ipc_disable_clock(TEGRA186_CLK_SE);
if (ret != 0) { if (ret != 0) {
ERROR("Failed to disable clock\n"); ERROR("Failed to disable clock\n");
......
/* /*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -11,56 +12,30 @@ ...@@ -11,56 +12,30 @@
#include <lib/mmio.h> #include <lib/mmio.h>
#include <mce.h> #include <mce.h>
#include <tegra186_private.h>
#include <tegra_def.h> #include <tegra_def.h>
#include <tegra_private.h> #include <tegra_private.h>
#define MISCREG_AA64_RST_LOW 0x2004U
#define MISCREG_AA64_RST_HIGH 0x2008U
#define SCRATCH_SECURE_RSV1_SCRATCH_0 0x658U #define SCRATCH_SECURE_RSV1_SCRATCH_0 0x658U
#define SCRATCH_SECURE_RSV1_SCRATCH_1 0x65CU #define SCRATCH_SECURE_RSV1_SCRATCH_1 0x65CU
#define CPU_RESET_MODE_AA64 1U #define CPU_RESET_MODE_AA64 1U
extern void memcpy16(void *dest, const void *src, unsigned int length);
/******************************************************************************* /*******************************************************************************
* Setup secondary CPU vectors * Setup secondary CPU vectors
******************************************************************************/ ******************************************************************************/
void plat_secondary_setup(void) void plat_secondary_setup(void)
{ {
uint32_t addr_low, addr_high; uint32_t addr_low, addr_high;
const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
uint64_t cpu_reset_handler_base, cpu_reset_handler_size;
INFO("Setting up secondary CPU boot\n"); INFO("Setting up secondary CPU boot\n");
/*
* 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 = tegra186_get_cpu_reset_handler_base();
cpu_reset_handler_size = tegra186_get_cpu_reset_handler_size();
(void)memcpy16((void *)(uintptr_t)params_from_bl2->tzdram_base,
(const void *)(uintptr_t)cpu_reset_handler_base,
cpu_reset_handler_size);
/* TZDRAM base will be used as the "resume" address */ /* TZDRAM base will be used as the "resume" address */
addr_low = (uint32_t)params_from_bl2->tzdram_base | CPU_RESET_MODE_AA64; addr_low = (uintptr_t)&tegra_secure_entrypoint | CPU_RESET_MODE_AA64;
addr_high = (uint32_t)((params_from_bl2->tzdram_base >> 32U) & 0x7ffU); addr_high = (uintptr_t)(((uintptr_t)&tegra_secure_entrypoint >> 32U) & 0x7ffU);
/* write lower 32 bits first, then the upper 11 bits */
mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_LOW, addr_low);
mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_HIGH, addr_high);
/* save reset vector to be used during SYSTEM_SUSPEND exit */ /* save reset vector to be used during SYSTEM_SUSPEND exit */
mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_LO, mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_LO,
addr_low); addr_low);
mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_HI, mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_HI,
addr_high); addr_high);
/* update reset vector address to the CCPLEX */
(void)mce_update_reset_vector();
} }
...@@ -12,135 +12,30 @@ ...@@ -12,135 +12,30 @@
#include <plat/common/common_def.h> #include <plat/common/common_def.h>
#include <tegra_def.h> #include <tegra_def.h>
#define TEGRA186_STATE_SYSTEM_SUSPEND 0x5C7
#define TEGRA186_STATE_SYSTEM_RESUME 0x600D
#define TEGRA186_MC_CTX_SIZE 0x93 #define TEGRA186_MC_CTX_SIZE 0x93
.globl tegra186_cpu_reset_handler .globl tegra186_get_mc_ctx_size
/* CPU reset handler routine */
func tegra186_cpu_reset_handler _align=4
/* check if we are exiting system suspend state */
adr x0, __tegra186_system_suspend_state
ldr x1, [x0]
mov x2, #TEGRA186_STATE_SYSTEM_SUSPEND
lsl x2, x2, #16
add x2, x2, #TEGRA186_STATE_SYSTEM_SUSPEND
cmp x1, x2
bne boot_cpu
/* set system resume state */
mov x1, #TEGRA186_STATE_SYSTEM_RESUME
lsl x1, x1, #16
mov x2, #TEGRA186_STATE_SYSTEM_RESUME
add x1, x1, x2
str x1, [x0]
dsb sy
/* prepare to relocate to TZSRAM */
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) * Tegra186 reset data (offset 0x0 - 0x420)
* *
* 0x000: secure world's entrypoint * 0x000: MC context start
* 0x008: BL31 size (RO + RW) * 0x420: MC context end
* 0x00C: MC context start
* 0x42C: MC context end
*/ */
.align 4 .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
.globl __tegra186_system_suspend_state
__tegra186_system_suspend_state:
.quad 0
.align 4
.globl __tegra186_mc_context
__tegra186_mc_context: __tegra186_mc_context:
.rept TEGRA186_MC_CTX_SIZE .rept TEGRA186_MC_CTX_SIZE
.quad 0 .quad 0
.endr .endr
.size __tegra186_cpu_reset_handler_data, \
. - __tegra186_cpu_reset_handler_data
.align 4 .align 4
.globl __tegra186_cpu_reset_handler_end __tegra186_mc_context_end:
__tegra186_cpu_reset_handler_end:
.globl tegra186_get_cpu_reset_handler_size
.globl tegra186_get_cpu_reset_handler_base
.globl tegra186_get_mc_ctx_offset
.globl tegra186_set_system_suspend_entry
/* return size of the CPU reset handler */
func tegra186_get_cpu_reset_handler_size
adr x0, __tegra186_cpu_reset_handler_end
adr x1, tegra186_cpu_reset_handler
sub x0, x0, x1
ret
endfunc tegra186_get_cpu_reset_handler_size
/* return the start address of the CPU reset handler */
func tegra186_get_cpu_reset_handler_base
adr x0, tegra186_cpu_reset_handler
ret
endfunc tegra186_get_cpu_reset_handler_base
/* return the size of the MC context */ /* return the size of the MC context */
func tegra186_get_mc_ctx_offset func tegra186_get_mc_ctx_size
adr x0, __tegra186_mc_context adr x0, __tegra186_mc_context_end
adr x1, tegra186_cpu_reset_handler adr x1, __tegra186_mc_context
sub x0, x0, x1 sub x0, x0, x1
ret ret
endfunc tegra186_get_mc_ctx_offset endfunc tegra186_get_mc_ctx_size
/* set system suspend state before SC7 entry */
func tegra186_set_system_suspend_entry
mov x0, #TEGRA_MC_BASE
mov x3, #MC_SECURITY_CFG3_0
ldr w1, [x0, x3]
lsl x1, x1, #32
mov x3, #MC_SECURITY_CFG0_0
ldr w2, [x0, x3]
orr x3, x1, x2 /* TZDRAM base */
adr x0, __tegra186_system_suspend_state
adr x1, tegra186_cpu_reset_handler
sub x2, x0, x1 /* offset in TZDRAM */
mov x0, #TEGRA186_STATE_SYSTEM_SUSPEND
lsl x0, x0, #16
add x0, x0, #TEGRA186_STATE_SYSTEM_SUSPEND
str x0, [x3, x2] /* set value in TZDRAM */
dsb sy
ret
endfunc tegra186_set_system_suspend_entry
...@@ -14,7 +14,7 @@ $(eval $(call add_define,ENABLE_CHIP_VERIFICATION_HARNESS)) ...@@ -14,7 +14,7 @@ $(eval $(call add_define,ENABLE_CHIP_VERIFICATION_HARNESS))
RESET_TO_BL31 := 1 RESET_TO_BL31 := 1
PROGRAMMABLE_RESET_ADDRESS := 1 PROGRAMMABLE_RESET_ADDRESS := 0
COLD_BOOT_SINGLE_CPU := 1 COLD_BOOT_SINGLE_CPU := 1
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#ifndef T194_NVG_H #ifndef T194_NVG_H
#define T194_NVG_H #define T194_NVG_H
#include <lib/utils_def.h>
/** /**
* t194_nvg.h - Header for the NVIDIA Generic interface (NVG). * t194_nvg.h - Header for the NVIDIA Generic interface (NVG).
* Official documentation for this interface is included as part * Official documentation for this interface is included as part
...@@ -20,7 +22,7 @@ ...@@ -20,7 +22,7 @@
*/ */
enum { enum {
TEGRA_NVG_VERSION_MAJOR = U(6), TEGRA_NVG_VERSION_MAJOR = U(6),
TEGRA_NVG_VERSION_MINOR = U(6) TEGRA_NVG_VERSION_MINOR = U(7)
}; };
typedef enum { typedef enum {
...@@ -71,6 +73,9 @@ typedef enum { ...@@ -71,6 +73,9 @@ typedef enum {
TEGRA_NVG_CHANNEL_DDA_SNOC_GLOBAL_CTRL = U(77), TEGRA_NVG_CHANNEL_DDA_SNOC_GLOBAL_CTRL = U(77),
TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REQ_CTRL = U(78), TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REQ_CTRL = U(78),
TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REPLENTISH_CTRL = U(79), TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REPLENTISH_CTRL = U(79),
TEGRA_NVG_CHANNEL_RT_SAFE_MASK = U(80),
TEGRA_NVG_CHANNEL_RT_WINDOW_US = U(81),
TEGRA_NVG_CHANNEL_RT_FWD_PROGRESS_US = U(82),
TEGRA_NVG_CHANNEL_LAST_INDEX TEGRA_NVG_CHANNEL_LAST_INDEX
} tegra_nvg_channel_id_t; } tegra_nvg_channel_id_t;
...@@ -153,7 +158,7 @@ typedef union { ...@@ -153,7 +158,7 @@ typedef union {
typedef union { typedef union {
uint64_t flat; uint64_t flat;
struct nvg_power_perf_channel_t { struct {
uint32_t perf_per_watt : U(1); uint32_t perf_per_watt : U(1);
uint32_t reserved_31_1 : U(31); uint32_t reserved_31_1 : U(31);
uint32_t reserved_63_32 : U(32); uint32_t reserved_63_32 : U(32);
...@@ -162,7 +167,7 @@ typedef union { ...@@ -162,7 +167,7 @@ typedef union {
typedef union { typedef union {
uint64_t flat; uint64_t flat;
struct nvg_power_modes_channel_t { struct {
uint32_t low_battery : U(1); uint32_t low_battery : U(1);
uint32_t reserved_1_1 : U(1); uint32_t reserved_1_1 : U(1);
uint32_t battery_save : U(1); uint32_t battery_save : U(1);
...@@ -182,7 +187,7 @@ typedef union nvg_channel_1_data_u { ...@@ -182,7 +187,7 @@ typedef union nvg_channel_1_data_u {
typedef union { typedef union {
uint64_t flat; uint64_t flat;
struct nvg_ccplex_cache_control_channel_t { struct {
uint32_t gpu_ways : U(5); uint32_t gpu_ways : U(5);
uint32_t reserved_7_5 : U(3); uint32_t reserved_7_5 : U(3);
uint32_t gpu_only_ways : U(5); uint32_t gpu_only_ways : U(5);
...@@ -203,7 +208,7 @@ typedef union nvg_channel_2_data_u { ...@@ -203,7 +208,7 @@ typedef union nvg_channel_2_data_u {
typedef union { typedef union {
uint64_t flat; uint64_t flat;
struct nvg_wake_time_channel_t { struct {
uint32_t wake_time : U(32); uint32_t wake_time : U(32);
uint32_t reserved_63_32 : U(32); uint32_t reserved_63_32 : U(32);
} bits; } bits;
...@@ -211,7 +216,7 @@ typedef union { ...@@ -211,7 +216,7 @@ typedef union {
typedef union { typedef union {
uint64_t flat; uint64_t flat;
struct nvg_cstate_info_channel_t { struct {
uint32_t cluster_state : U(3); uint32_t cluster_state : U(3);
uint32_t reserved_6_3 : U(4); uint32_t reserved_6_3 : U(4);
uint32_t update_cluster : U(1); uint32_t update_cluster : U(1);
...@@ -242,7 +247,7 @@ typedef union { ...@@ -242,7 +247,7 @@ typedef union {
typedef union { typedef union {
uint64_t flat; uint64_t flat;
struct nvg_lower_bound_channel_t { struct {
uint32_t crossover_value : U(32); uint32_t crossover_value : U(32);
uint32_t reserved_63_32 : U(32); uint32_t reserved_63_32 : U(32);
} bits; } bits;
...@@ -250,7 +255,7 @@ typedef union { ...@@ -250,7 +255,7 @@ typedef union {
typedef union { typedef union {
uint64_t flat; uint64_t flat;
struct nvg_cstate_stat_query_channel_t { struct {
uint32_t unit_id : U(4); uint32_t unit_id : U(4);
uint32_t reserved_15_4 : U(12); uint32_t reserved_15_4 : U(12);
uint32_t stat_id : U(16); uint32_t stat_id : U(16);
...@@ -260,7 +265,7 @@ typedef union { ...@@ -260,7 +265,7 @@ typedef union {
typedef union { typedef union {
uint64_t flat; uint64_t flat;
struct nvg_num_cores_channel_t { struct {
uint32_t num_cores : U(4); uint32_t num_cores : U(4);
uint32_t reserved_31_4 : U(28); uint32_t reserved_31_4 : U(28);
uint32_t reserved_63_32 : U(32); uint32_t reserved_63_32 : U(32);
...@@ -269,7 +274,7 @@ typedef union { ...@@ -269,7 +274,7 @@ typedef union {
typedef union { typedef union {
uint64_t flat; uint64_t flat;
struct nvg_unique_logical_id_channel_t { struct {
uint32_t unique_core_id : U(3); uint32_t unique_core_id : U(3);
uint32_t reserved_31_3 : U(29); uint32_t reserved_31_3 : U(29);
uint32_t reserved_63_32 : U(32); uint32_t reserved_63_32 : U(32);
...@@ -278,7 +283,7 @@ typedef union { ...@@ -278,7 +283,7 @@ typedef union {
typedef union { typedef union {
uint64_t flat; uint64_t flat;
struct nvg_logical_to_physical_mappings_channel_t { struct {
uint32_t lcore0_pcore_id : U(4); uint32_t lcore0_pcore_id : U(4);
uint32_t lcore1_pcore_id : U(4); uint32_t lcore1_pcore_id : U(4);
uint32_t lcore2_pcore_id : U(4); uint32_t lcore2_pcore_id : U(4);
...@@ -306,7 +311,7 @@ typedef union { ...@@ -306,7 +311,7 @@ typedef union {
typedef union { typedef union {
uint64_t flat; uint64_t flat;
struct nvg_is_sc7_allowed_channel_t { struct {
uint32_t is_sc7_allowed : U(1); uint32_t is_sc7_allowed : U(1);
uint32_t reserved_31_1 : U(31); uint32_t reserved_31_1 : U(31);
uint32_t reserved_63_32 : U(32); uint32_t reserved_63_32 : U(32);
...@@ -315,7 +320,7 @@ typedef union { ...@@ -315,7 +320,7 @@ typedef union {
typedef union { typedef union {
uint64_t flat; uint64_t flat;
struct nvg_core_online_channel_t { struct {
uint32_t core_id : U(4); uint32_t core_id : U(4);
uint32_t reserved_31_4 : U(28); uint32_t reserved_31_4 : U(28);
uint32_t reserved_63_32 : U(32); uint32_t reserved_63_32 : U(32);
...@@ -324,7 +329,7 @@ typedef union { ...@@ -324,7 +329,7 @@ typedef union {
typedef union { typedef union {
uint64_t flat; uint64_t flat;
struct nvg_cc3_control_channel_t { struct {
uint32_t freq_req : U(9); uint32_t freq_req : U(9);
uint32_t reserved_30_9 : U(22); uint32_t reserved_30_9 : U(22);
uint32_t enable : U(1); uint32_t enable : U(1);
...@@ -374,7 +379,7 @@ typedef enum { ...@@ -374,7 +379,7 @@ typedef enum {
typedef union { typedef union {
uint64_t flat; uint64_t flat;
struct nvg_update_ccplex_gsc_channel_t { struct {
uint32_t gsc_enum : U(16); uint32_t gsc_enum : U(16);
uint32_t reserved_31_16 : U(16); uint32_t reserved_31_16 : U(16);
uint32_t reserved_63_32 : U(32); uint32_t reserved_63_32 : U(32);
...@@ -411,7 +416,7 @@ typedef union { ...@@ -411,7 +416,7 @@ typedef union {
typedef union { typedef union {
uint64_t flat; uint64_t flat;
struct nvg_hsm_error_ctrl_channel_t { struct {
uint32_t uncorr : U(1); uint32_t uncorr : U(1);
uint32_t corr : U(1); uint32_t corr : U(1);
uint32_t reserved_31_2 : U(30); uint32_t reserved_31_2 : U(30);
......
...@@ -368,7 +368,11 @@ int32_t tegra_soc_pwr_domain_on(u_register_t mpidr) ...@@ -368,7 +368,11 @@ int32_t tegra_soc_pwr_domain_on(u_register_t mpidr)
int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
{ {
const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
uint8_t enable_ccplex_lock_step = params_from_bl2->enable_ccplex_lock_step;
uint8_t stateid_afflvl2 = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]; uint8_t stateid_afflvl2 = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL];
cpu_context_t *ctx = cm_get_context(NON_SECURE);
uint64_t actlr_elx;
/* /*
* Reset power state info for CPUs when onlining, we set * Reset power state info for CPUs when onlining, we set
...@@ -377,6 +381,10 @@ int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) ...@@ -377,6 +381,10 @@ int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
* will re-init this info from non-secure software when the * will re-init this info from non-secure software when the
* core come online. * core come online.
*/ */
actlr_elx = read_ctx_reg((get_el1_sysregs_ctx(ctx)), (CTX_ACTLR_EL1));
actlr_elx &= ~DENVER_CPU_PMSTATE_MASK;
actlr_elx |= DENVER_CPU_PMSTATE_C1;
write_ctx_reg((get_el1_sysregs_ctx(ctx)), (CTX_ACTLR_EL1), (actlr_elx));
/* /*
* Check if we are exiting from deep sleep and restore SE * Check if we are exiting from deep sleep and restore SE
...@@ -446,13 +454,23 @@ int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) ...@@ -446,13 +454,23 @@ int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
mmio_write_32(TEGRA_XUSB_PADCTL_BASE + mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
XUSB_PADCTL_DEV_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_DEV); XUSB_PADCTL_DEV_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_DEV);
} }
}
/* /*
* Reset power state info for the last core doing SC7 * Enable dual execution optimized translations for all ELx.
* 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.
*/ */
if (enable_ccplex_lock_step != 0U) {
actlr_elx = read_actlr_el3();
actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL3;
write_actlr_el3(actlr_elx);
actlr_elx = read_actlr_el2();
actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL2;
write_actlr_el2(actlr_elx);
actlr_elx = read_actlr_el1();
actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL1;
write_actlr_el1(actlr_elx);
} }
return PSCI_E_SUCCESS; return PSCI_E_SUCCESS;
......
...@@ -201,6 +201,10 @@ void plat_enable_console(int32_t id) ...@@ -201,6 +201,10 @@ void plat_enable_console(int32_t id)
******************************************************************************/ ******************************************************************************/
void plat_early_platform_setup(void) void plat_early_platform_setup(void)
{ {
const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
uint8_t enable_ccplex_lock_step = params_from_bl2->enable_ccplex_lock_step;
uint64_t actlr_elx;
/* sanity check MCE firmware compatibility */ /* sanity check MCE firmware compatibility */
mce_verify_firmware_version(); mce_verify_firmware_version();
...@@ -250,6 +254,23 @@ void plat_early_platform_setup(void) ...@@ -250,6 +254,23 @@ void plat_early_platform_setup(void)
mmio_write_32(TEGRA_XUSB_PADCTL_BASE + mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
XUSB_PADCTL_DEV_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_DEV); XUSB_PADCTL_DEV_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_DEV);
} }
/*
* Enable dual execution optimized translations for all ELx.
*/
if (enable_ccplex_lock_step != 0U) {
actlr_elx = read_actlr_el3();
actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL3;
write_actlr_el3(actlr_elx);
actlr_elx = read_actlr_el2();
actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL2;
write_actlr_el2(actlr_elx);
actlr_elx = read_actlr_el1();
actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL1;
write_actlr_el1(actlr_elx);
}
} }
/* Secure IRQs for Tegra194 */ /* Secure IRQs for Tegra194 */
......
...@@ -927,17 +927,12 @@ static void tegra_se_enable_clocks(void) ...@@ -927,17 +927,12 @@ static void tegra_se_enable_clocks(void)
val &= ~ENTROPY_RESET_BIT; val &= ~ENTROPY_RESET_BIT;
mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEVICES_W, val); mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEVICES_W, val);
if (!tegra_chipid_is_t210_b01()) {
/* /*
* T210 SE clock source is turned off in kernel, to simplify * Switch SE clock source to CLK_M, to make sure SE clock
* SE clock source setting, we switch SE clock source to * is on when saving SE context
* CLK_M, SE_CLK_DIVISOR = 0. T210 B01 SE clock source is
* always on, so don't need this setting.
*/ */
mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_RST_CTL_CLK_SRC_SE, mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_RST_CTL_CLK_SRC_SE,
SE_CLK_SRC_CLK_M); SE_CLK_SRC_CLK_M);
}
/* Enable SE clock */ /* Enable SE clock */
val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_V); val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_V);
......
/* /*
* Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -429,7 +430,6 @@ static uintptr_t tlkd_smc_handler(uint32_t smc_fid, ...@@ -429,7 +430,6 @@ static uintptr_t tlkd_smc_handler(uint32_t smc_fid,
*/ */
case TLK_SUSPEND_DONE: case TLK_SUSPEND_DONE:
case TLK_RESUME_DONE: case TLK_RESUME_DONE:
case TLK_SYSTEM_OFF_DONE:
if (ns) if (ns)
SMC_RET1(handle, SMC_UNK); SMC_RET1(handle, SMC_UNK);
......
/* /*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -97,29 +98,6 @@ static void cpu_resume_handler(u_register_t suspend_level) ...@@ -97,29 +98,6 @@ static void cpu_resume_handler(u_register_t suspend_level)
panic(); panic();
} }
/*******************************************************************************
* System is about to be reset. Inform the SP to allow any book-keeping
******************************************************************************/
static void system_off_handler(void)
{
int cpu = read_mpidr() & MPIDR_CPU_MASK;
gp_regs_t *gp_regs;
/* TLK runs only on CPU0 */
if (cpu != 0)
return;
/* pass system off/reset events to TLK */
gp_regs = get_gpregs_ctx(&tlk_ctx.cpu_ctx);
write_ctx_reg(gp_regs, CTX_GPREG_X0, TLK_SYSTEM_OFF);
/*
* Enter the SP. We do not care about the return value because we
* must continue with the shutdown anyway.
*/
(void)tlkd_synchronous_sp_entry(&tlk_ctx);
}
/******************************************************************************* /*******************************************************************************
* Structure populated by the Dispatcher to be given a chance to perform any * Structure populated by the Dispatcher to be given a chance to perform any
* bookkeeping before PSCI executes a power mgmt. operation. * bookkeeping before PSCI executes a power mgmt. operation.
...@@ -128,6 +106,4 @@ const spd_pm_ops_t tlkd_pm_ops = { ...@@ -128,6 +106,4 @@ const spd_pm_ops_t tlkd_pm_ops = {
.svc_migrate_info = cpu_migrate_info, .svc_migrate_info = cpu_migrate_info,
.svc_suspend = cpu_suspend_handler, .svc_suspend = cpu_suspend_handler,
.svc_suspend_finish = cpu_resume_handler, .svc_suspend_finish = cpu_resume_handler,
.svc_system_off = system_off_handler,
.svc_system_reset = system_off_handler
}; };
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment