Merge pull request #1785 from vwadekar/tf2.0-tegra-downstream-rebase-1.25.19

Tf2.0 tegra downstream rebase 1.25.19
This commit is contained in:
Antonio Niño Díaz 2019-02-06 10:20:25 +00:00 committed by GitHub
commit 30490b15fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 1431 additions and 412 deletions

View File

@ -248,7 +248,6 @@ DTC_CPPFLAGS += -nostdinc -Iinclude -undef -x assembler-with-cpp
# Common sources and include directories
################################################################################
include lib/compiler-rt/compiler-rt.mk
include lib/libc/libc.mk
BL_COMMON_SOURCES += common/bl_common.c \
common/tf_log.c \
@ -392,6 +391,13 @@ endif
endif
################################################################################
# Include libc if not overridden
################################################################################
ifeq (${OVERRIDE_LIBC},0)
include lib/libc/libc.mk
endif
################################################################################
# Check incompatible options
################################################################################
@ -595,6 +601,7 @@ $(eval $(call assert_boolean,HANDLE_EA_EL3_FIRST))
$(eval $(call assert_boolean,HW_ASSISTED_COHERENCY))
$(eval $(call assert_boolean,MULTI_CONSOLE_API))
$(eval $(call assert_boolean,NS_TIMER_SWITCH))
$(eval $(call assert_boolean,OVERRIDE_LIBC))
$(eval $(call assert_boolean,PL011_GENERIC_UART))
$(eval $(call assert_boolean,PROGRAMMABLE_RESET_ADDRESS))
$(eval $(call assert_boolean,PSCI_EXTENDED_STATE_ID))

View File

@ -1,6 +1,23 @@
Tegra SoCs - Overview
=====================
- .. rubric:: T186
:name: t186
The NVIDIA® Parker (T186) series system-on-chip (SoC) delivers a heterogeneous
multi-processing (HMP) solution designed to optimize performance and
efficiency.
T186 has Dual NVIDIA Denver 2 ARM® CPU cores, plus Quad ARM Cortex®-A57 cores,
in a coherent multiprocessor configuration. The Denver 2 and Cortex-A57 cores
support ARMv8, executing both 64-bit Aarch64 code, and 32-bit Aarch32 code
including legacy ARMv7 applications. The Denver 2 processors each have 128 KB
Instruction and 64 KB Data Level 1 caches; and have a 2MB shared Level 2
unified cache. The Cortex-A57 processors each have 48 KB Instruction and 32 KB
Data Level 1 caches; and also have a 2 MB shared Level 2 unified cache. A
high speed coherency fabric connects these two processor complexes and allows
heterogeneous multi-processing with all six cores if required.
- .. rubric:: T210
:name: t210
@ -49,11 +66,21 @@ Directory structure
Trusted OS dispatcher
=====================
Tegra supports multiple Trusted OS', Trusted Little Kernel (TLK) being one of
them. In order to include the 'tlkd' dispatcher in the image, pass 'SPD=tlkd'
on the command line while preparing a bl31 image. This allows other Trusted OS
vendors to use the upstream code and include their dispatchers in the image
without changing any makefiles.
Tegra supports multiple Trusted OS'.
- Trusted Little Kernel (TLK): In order to include the 'tlkd' dispatcher in
the image, pass 'SPD=tlkd' on the command line while preparing a bl31 image.
- Trusty: In order to include the 'trusty' dispatcher in the image, pass
'SPD=trusty' on the command line while preparing a bl31 image.
This allows other Trusted OS vendors to use the upstream code and include
their dispatchers in the image without changing any makefiles.
These are the supported Trusted OS' by Tegra platforms.
Tegra132: TLK
Tegra210: TLK and Trusty
Tegra186: Trusty
Preparing the BL31 image to run on Tegra SoCs
=============================================
@ -61,7 +88,8 @@ Preparing the BL31 image to run on Tegra SoCs
.. code:: shell
CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf- make PLAT=tegra \
TARGET_SOC=<target-soc e.g. t210|t132> SPD=<dispatcher e.g. tlkd> bl31
TARGET_SOC=<target-soc e.g. t186|t210|t132> SPD=<dispatcher e.g. trusty|tlkd>
bl31
Platforms wanting to use different TZDRAM\_BASE, can add ``TZDRAM_BASE=<value>``
to the build command line.

View File

@ -575,6 +575,10 @@ Common build options
1 (do save and restore). 0 is the default. An SPD may set this to 1 if it
wants the timer registers to be saved and restored.
- ``OVERRIDE_LIBC``: This option allows platforms to override the default libc
for the BL image. It can be either 0 (include) or 1 (remove). The default
value is 0.
- ``PL011_GENERIC_UART``: Boolean option to indicate the PL011 driver that
the underlying hardware is not a full PL011 UART but a minimally compliant
generic UART, which is a subset of the PL011. The driver will not access

View File

@ -20,7 +20,9 @@
*/
#define TLK_REGISTER_LOGBUF TLK_TOS_YIELD_FID(0x1)
#define TLK_REGISTER_REQBUF TLK_TOS_YIELD_FID(0x2)
#define TLK_REGISTER_NS_DRAM TLK_TOS_YIELD_FID(0x4)
#define TLK_SS_REGISTER_HANDLER TLK_TOS_YIELD_FID(0x3)
#define TLK_REGISTER_NS_DRAM_RANGES TLK_TOS_YIELD_FID(0x4)
#define TLK_SET_ROOT_OF_TRUST TLK_TOS_YIELD_FID(0x5)
#define TLK_RESUME_FID TLK_TOS_YIELD_FID(0x100)
#define TLK_SYSTEM_SUSPEND TLK_TOS_YIELD_FID(0xE001)
#define TLK_SYSTEM_RESUME TLK_TOS_YIELD_FID(0xE002)

View File

@ -122,6 +122,9 @@ MULTI_CONSOLE_API := 0
# NS timer register save and restore
NS_TIMER_SWITCH := 0
# Include lib/libc in the final image
OVERRIDE_LIBC := 0
# Build PL011 UART driver in minimal generic UART mode
PL011_GENERIC_UART := 0

View File

@ -16,7 +16,7 @@
#include <string.h>
#include <tegra_def.h>
#define BPMP_TIMEOUT 2
#define BPMP_TIMEOUT 500 /* 500ms */
static uint32_t channel_base[NR_CHANNELS];
static uint32_t bpmp_init_state = BPMP_INIT_PENDING;
@ -115,58 +115,117 @@ int32_t tegra_bpmp_send_receive_atomic(int mrq, const void *ob_data, int ob_sz,
int tegra_bpmp_init(void)
{
uint32_t val, base;
uint32_t val, base, timeout = BPMP_TIMEOUT;
unsigned int ch;
int ret = 0;
if (bpmp_init_state != BPMP_INIT_COMPLETE) {
if (bpmp_init_state == BPMP_INIT_PENDING) {
/* check if the bpmp processor is alive. */
val = mmio_read_32(TEGRA_RES_SEMA_BASE + STA_OFFSET);
if (val != SIGN_OF_LIFE) {
ERROR("BPMP precessor not available\n");
return -ENOTSUP;
do {
val = mmio_read_32(TEGRA_RES_SEMA_BASE + STA_OFFSET);
if (val != SIGN_OF_LIFE) {
mdelay(1);
timeout--;
}
} while ((val != SIGN_OF_LIFE) && (timeout > 0U));
if (val == SIGN_OF_LIFE) {
/* check if clock for the atomics block is enabled */
val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_ENB_V);
if ((val & CAR_ENABLE_ATOMICS) == 0) {
ERROR("Clock to the atomics block is disabled\n");
}
/* check if the atomics block is out of reset */
val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_CLR_V);
if ((val & CAR_ENABLE_ATOMICS) == CAR_ENABLE_ATOMICS) {
ERROR("Reset to the atomics block is asserted\n");
}
/* base address to get the result from Atomics */
base = TEGRA_ATOMICS_BASE + RESULT0_REG_OFFSET;
/* channel area is setup by BPMP before signaling handshake */
for (ch = 0; ch < NR_CHANNELS; ch++) {
/* issue command to get the channel base address */
mmio_write_32(base, (ch << TRIGGER_ID_SHIFT) |
ATOMIC_CMD_GET);
/* get the base address for the channel */
channel_base[ch] = mmio_read_32(base);
/* increment result register offset */
base += 4U;
}
/* mark state as "initialized" */
bpmp_init_state = BPMP_INIT_COMPLETE;
/* the channel values have to be visible across all cpus */
flush_dcache_range((uint64_t)channel_base,
sizeof(channel_base));
flush_dcache_range((uint64_t)&bpmp_init_state,
sizeof(bpmp_init_state));
INFO("%s: done\n", __func__);
} else {
ERROR("BPMP not powered on\n");
/* bpmp is not present in the system */
bpmp_init_state = BPMP_NOT_PRESENT;
/* communication timed out */
ret = -ETIMEDOUT;
}
/* check if clock for the atomics block is enabled */
val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_ENB_V);
if ((val & CAR_ENABLE_ATOMICS) == 0) {
ERROR("Clock to the atomics block is disabled\n");
}
/* check if the atomics block is out of reset */
val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_CLR_V);
if ((val & CAR_ENABLE_ATOMICS) == CAR_ENABLE_ATOMICS) {
ERROR("Reset to the atomics block is asserted\n");
}
/* base address to get the result from Atomics */
base = TEGRA_ATOMICS_BASE + RESULT0_REG_OFFSET;
/* channel area is setup by BPMP before signaling handshake */
for (ch = 0; ch < NR_CHANNELS; ch++) {
/* issue command to get the channel base address */
mmio_write_32(base, (ch << TRIGGER_ID_SHIFT) |
ATOMIC_CMD_GET);
/* get the base address for the channel */
channel_base[ch] = mmio_read_32(base);
/* increment result register offset */
base += 4U;
}
/* mark state as "initialized" */
bpmp_init_state = BPMP_INIT_COMPLETE;
/* the channel values have to be visible across all cpus */
flush_dcache_range((uint64_t)channel_base, sizeof(channel_base));
flush_dcache_range((uint64_t)&bpmp_init_state,
sizeof(bpmp_init_state));
INFO("%s: done\n", __func__);
}
return ret;
}
void tegra_bpmp_suspend(void)
{
/* freeze the interface */
if (bpmp_init_state == BPMP_INIT_COMPLETE) {
bpmp_init_state = BPMP_SUSPEND_ENTRY;
flush_dcache_range((uint64_t)&bpmp_init_state,
sizeof(bpmp_init_state));
}
}
void tegra_bpmp_resume(void)
{
uint32_t val, timeout = 0;
if (bpmp_init_state == BPMP_SUSPEND_ENTRY) {
/* check if the bpmp processor is alive. */
do {
val = mmio_read_32(TEGRA_RES_SEMA_BASE + STA_OFFSET);
if (val != SIGN_OF_LIFE) {
mdelay(1);
timeout++;
}
} while ((val != SIGN_OF_LIFE) && (timeout < BPMP_TIMEOUT));
if (val == SIGN_OF_LIFE) {
INFO("%s: BPMP took %d ms to resume\n", __func__, timeout);
/* mark state as "initialized" */
bpmp_init_state = BPMP_INIT_COMPLETE;
/* state has to be visible across all cpus */
flush_dcache_range((uint64_t)&bpmp_init_state,
sizeof(bpmp_init_state));
} else {
ERROR("BPMP not powered on\n");
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -302,3 +302,49 @@ int32_t tegra_bpmp_ipc_reset_module(uint32_t rst_id)
return ret;
}
int tegra_bpmp_ipc_enable_clock(uint32_t clk_id)
{
int ret;
struct mrq_clk_request req;
/* only SE clocks are supported */
if (clk_id != TEGRA_CLK_SE) {
return -ENOTSUP;
}
/* prepare the MRQ_CLK command */
req.cmd_and_id = make_mrq_clk_cmd(CMD_CLK_ENABLE, clk_id);
ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, sizeof(req),
NULL, 0);
if (ret != 0) {
ERROR("%s: failed for module %d with error %d\n", __func__,
clk_id, ret);
}
return ret;
}
int tegra_bpmp_ipc_disable_clock(uint32_t clk_id)
{
int ret;
struct mrq_clk_request req;
/* only SE clocks are supported */
if (clk_id != TEGRA_CLK_SE) {
return -ENOTSUP;
}
/* prepare the MRQ_CLK command */
req.cmd_and_id = make_mrq_clk_cmd(CMD_CLK_DISABLE, clk_id);
ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, sizeof(req),
NULL, 0);
if (ret != 0) {
ERROR("%s: failed for module %d with error %d\n", __func__,
clk_id, ret);
}
return ret;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -11,10 +11,10 @@
* Flags used in IPC req
*/
#define FLAG_DO_ACK (U(1) << 0)
#define FLAG_RING_DOORBELL (U(1) << 1)
#define FLAG_RING_DOORBELL (U(1) << 1)
/* Bit 1 is designated for CCPlex in secure world */
#define HSP_MASTER_CCPLEX_BIT (U(1) << 1)
#define HSP_MASTER_CCPLEX_BIT (U(1) << 1)
/* Bit 19 is designated for BPMP in non-secure world */
#define HSP_MASTER_BPMP_BIT (U(1) << 19)
/* Timeout to receive response from BPMP is 1 sec */
@ -49,9 +49,10 @@ struct frame_data {
*/
/**
* MRQ code to issue a module reset command to BPMP
* MRQ command codes
*/
#define MRQ_RESET U(20)
#define MRQ_CLK U(22)
/**
* Reset sub-commands
@ -71,4 +72,56 @@ struct __attribute__((packed)) mrq_reset_request {
uint32_t reset_id;
};
/**
* MRQ_CLK sub-commands
*
*/
enum {
CMD_CLK_GET_RATE = 1,
CMD_CLK_SET_RATE = 2,
CMD_CLK_ROUND_RATE = 3,
CMD_CLK_GET_PARENT = 4,
CMD_CLK_SET_PARENT = 5,
CMD_CLK_IS_ENABLED = 6,
CMD_CLK_ENABLE = 7,
CMD_CLK_DISABLE = 8,
CMD_CLK_GET_ALL_INFO = 14,
CMD_CLK_GET_MAX_CLK_ID = 15,
CMD_CLK_MAX,
};
/**
* Used by the sender of an #MRQ_CLK message to control clocks. The
* clk_request is split into several sub-commands. Some sub-commands
* require no additional data. Others have a sub-command specific
* payload
*
* |sub-command |payload |
* |----------------------------|-----------------------|
* |CMD_CLK_GET_RATE |- |
* |CMD_CLK_SET_RATE |clk_set_rate |
* |CMD_CLK_ROUND_RATE |clk_round_rate |
* |CMD_CLK_GET_PARENT |- |
* |CMD_CLK_SET_PARENT |clk_set_parent |
* |CMD_CLK_IS_ENABLED |- |
* |CMD_CLK_ENABLE |- |
* |CMD_CLK_DISABLE |- |
* |CMD_CLK_GET_ALL_INFO |- |
* |CMD_CLK_GET_MAX_CLK_ID |- |
*
*/
struct mrq_clk_request {
/**
* sub-command and clock id concatenated to 32-bit word.
* - bits[31..24] is the sub-cmd.
* - bits[23..0] is the clock id
*/
uint32_t cmd_and_id;
};
/**
* Macro to prepare the MRQ_CLK sub-command
*/
#define make_mrq_clk_cmd(cmd, id) (((cmd) << 24) | (id & 0xFFFFFF))
#endif /* INTF_H */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -15,6 +15,7 @@
#include <flowctrl.h>
#include <pmc.h>
#include <tegra_def.h>
#include <utils_def.h>
#define CLK_RST_DEV_L_SET 0x300
#define CLK_RST_DEV_L_CLR 0x304
@ -75,6 +76,47 @@ static void tegra_fc_prepare_suspend(int cpu_id, uint32_t csr)
tegra_fc_cpu_csr(cpu_id, val | csr);
}
/*******************************************************************************
* After this, no core can wake from C7 until the action is reverted.
* If a wake up event is asserted, the FC state machine will stall until
* the action is reverted.
******************************************************************************/
void tegra_fc_ccplex_pgexit_lock(void)
{
unsigned int i, cpu = read_mpidr() & MPIDR_CPU_MASK;
uint32_t flags = tegra_fc_read_32(FLOWCTRL_FC_SEQ_INTERCEPT) & ~INTERCEPT_IRQ_PENDING;;
uint32_t icept_cpu_flags[] = {
INTERCEPT_EXIT_PG_CORE0,
INTERCEPT_EXIT_PG_CORE1,
INTERCEPT_EXIT_PG_CORE2,
INTERCEPT_EXIT_PG_CORE3
};
/* set the intercept flags */
for (i = 0; i < ARRAY_SIZE(icept_cpu_flags); i++) {
/* skip current CPU */
if (i == cpu)
continue;
/* enable power gate exit intercept locks */
flags |= icept_cpu_flags[i];
}
tegra_fc_write_32(FLOWCTRL_FC_SEQ_INTERCEPT, flags);
(void)tegra_fc_read_32(FLOWCTRL_FC_SEQ_INTERCEPT);
}
/*******************************************************************************
* Revert the ccplex powergate exit locks
******************************************************************************/
void tegra_fc_ccplex_pgexit_unlock(void)
{
/* clear lock bits, clear pending interrupts */
tegra_fc_write_32(FLOWCTRL_FC_SEQ_INTERCEPT, INTERCEPT_IRQ_PENDING);
(void)tegra_fc_read_32(FLOWCTRL_FC_SEQ_INTERCEPT);
}
/*******************************************************************************
* Powerdn the current CPU
******************************************************************************/
@ -128,6 +170,31 @@ void tegra_fc_cluster_powerdn(uint32_t mpidr)
tegra_fc_prepare_suspend(cpu, val);
}
/*******************************************************************************
* Check if cluster idle or power down state is allowed from this CPU
******************************************************************************/
bool tegra_fc_is_ccx_allowed(void)
{
unsigned int i, cpu = read_mpidr() & MPIDR_CPU_MASK;
uint32_t val;
bool ccx_allowed = true;
for (i = 0; i < ARRAY_SIZE(flowctrl_offset_cpu_csr); i++) {
/* skip current CPU */
if (i == cpu)
continue;
/* check if all other CPUs are already halted */
val = mmio_read_32(flowctrl_offset_cpu_csr[i]);
if ((val & FLOWCTRL_CSR_HALT_MASK) == 0U) {
ccx_allowed = false;
}
}
return ccx_allowed;
}
/*******************************************************************************
* Suspend the entire SoC
******************************************************************************/
@ -190,22 +257,19 @@ void tegra_fc_lock_active_cluster(void)
}
/*******************************************************************************
* Reset BPMP processor
* Power ON BPMP processor
******************************************************************************/
void tegra_fc_reset_bpmp(void)
void tegra_fc_bpmp_on(uint32_t entrypoint)
{
uint32_t val;
/* halt BPMP */
tegra_fc_write_32(FLOWCTRL_HALT_BPMP_EVENTS, FLOWCTRL_WAITEVENT);
/* Assert BPMP reset */
mmio_write_32(TEGRA_CAR_RESET_BASE + CLK_RST_DEV_L_SET, CLK_BPMP_RST);
/* Restore reset address (stored in PMC_SCRATCH39) */
val = tegra_pmc_read_32(PMC_SCRATCH39);
mmio_write_32(TEGRA_EVP_BASE + EVP_BPMP_RESET_VECTOR, val);
while (val != mmio_read_32(TEGRA_EVP_BASE + EVP_BPMP_RESET_VECTOR))
/* Set reset address (stored in PMC_SCRATCH39) */
mmio_write_32(TEGRA_EVP_BASE + EVP_BPMP_RESET_VECTOR, entrypoint);
while (entrypoint != mmio_read_32(TEGRA_EVP_BASE + EVP_BPMP_RESET_VECTOR))
; /* wait till value reaches EVP_BPMP_RESET_VECTOR */
/* Wait for 2us before de-asserting the reset signal. */
@ -217,3 +281,42 @@ void tegra_fc_reset_bpmp(void)
/* Un-halt BPMP */
tegra_fc_write_32(FLOWCTRL_HALT_BPMP_EVENTS, 0);
}
/*******************************************************************************
* Power OFF BPMP processor
******************************************************************************/
void tegra_fc_bpmp_off(void)
{
/* halt BPMP */
tegra_fc_write_32(FLOWCTRL_HALT_BPMP_EVENTS, FLOWCTRL_WAITEVENT);
/* Assert BPMP reset */
mmio_write_32(TEGRA_CAR_RESET_BASE + CLK_RST_DEV_L_SET, CLK_BPMP_RST);
/* Clear reset address */
mmio_write_32(TEGRA_EVP_BASE + EVP_BPMP_RESET_VECTOR, 0);
while (0 != mmio_read_32(TEGRA_EVP_BASE + EVP_BPMP_RESET_VECTOR))
; /* wait till value reaches EVP_BPMP_RESET_VECTOR */
}
/*******************************************************************************
* Route legacy FIQ to the GICD
******************************************************************************/
void tegra_fc_enable_fiq_to_ccplex_routing(void)
{
uint32_t val = tegra_fc_read_32(FLOW_CTLR_FLOW_DBG_QUAL);
/* set the bit to pass FIQs to the GICD */
tegra_fc_write_32(FLOW_CTLR_FLOW_DBG_QUAL, val | FLOWCTRL_FIQ2CCPLEX_ENABLE);
}
/*******************************************************************************
* Disable routing legacy FIQ to the GICD
******************************************************************************/
void tegra_fc_disable_fiq_to_ccplex_routing(void)
{
uint32_t val = tegra_fc_read_32(FLOW_CTLR_FLOW_DBG_QUAL);
/* clear the bit to pass FIQs to the GICD */
tegra_fc_write_32(FLOW_CTLR_FLOW_DBG_QUAL, val & ~FLOWCTRL_FIQ2CCPLEX_ENABLE);
}

View File

@ -17,7 +17,7 @@
/* Module IDs used during power ungate procedure */
static const uint32_t pmc_cpu_powergate_id[4] = {
0, /* CPU 0 */
14, /* CPU 0 */
9, /* CPU 1 */
10, /* CPU 2 */
11 /* CPU 3 */
@ -97,6 +97,45 @@ void tegra_pmc_lock_cpu_vectors(void)
tegra_pmc_write_32(PMC_SECURE_DISABLE3, val);
}
/*******************************************************************************
* Find out if this is the last standing CPU
******************************************************************************/
bool tegra_pmc_is_last_on_cpu(void)
{
int i, cpu = read_mpidr() & MPIDR_CPU_MASK;
uint32_t val = tegra_pmc_read_32(PMC_PWRGATE_STATUS);;
bool status = true;
/* check if this is the last standing CPU */
for (i = 0; i < PLATFORM_MAX_CPUS_PER_CLUSTER; i++) {
/* skip the current CPU */
if (i == cpu)
continue;
/* are other CPUs already power gated? */
if ((val & ((uint32_t)1 << pmc_cpu_powergate_id[i])) != 0U) {
status = false;
}
}
return status;
}
/*******************************************************************************
* Handler to be called on exiting System suspend. Right now only DPD registers
* are cleared.
******************************************************************************/
void tegra_pmc_resume(void)
{
/* Clear DPD sample */
mmio_write_32((TEGRA_PMC_BASE + PMC_IO_DPD_SAMPLE), 0x0);
/* Clear DPD Enable */
mmio_write_32((TEGRA_PMC_BASE + PMC_DPD_ENABLE_0), 0x0);
}
/*******************************************************************************
* Restart the system
******************************************************************************/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -63,11 +63,27 @@ func console_core_putc
/* Check the input parameter */
cbz x1, putc_error
/* Prepend '\r' to '\n' */
cmp w0, #0xA
b.ne 2f
/* wait until spe is ready */
1: ldr w2, [x1]
and w2, w2, #CONSOLE_IS_BUSY
cbnz w2, 1b
/* spe is ready */
mov w2, #0xD /* '\r' */
and w2, w2, #0xFF
mov w3, #(CONSOLE_WRITE | (1 << CONSOLE_NUM_BYTES_SHIFT))
orr w2, w2, w3
str w2, [x1]
/* wait until spe is ready */
2: ldr w2, [x1]
and w2, w2, #CONSOLE_IS_BUSY
cbnz w2, 2b
/* spe is ready */
mov w2, w0
and w2, w2, #0xFF

View File

@ -162,13 +162,15 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
}
/*
* Parse platform specific parameters - TZDRAM aperture base and size
* Parse platform specific parameters
*/
assert(plat_params != NULL);
plat_bl31_params_from_bl2.tzdram_base = plat_params->tzdram_base;
plat_bl31_params_from_bl2.tzdram_size = plat_params->tzdram_size;
plat_bl31_params_from_bl2.uart_id = plat_params->uart_id;
plat_bl31_params_from_bl2.l2_ecc_parity_prot_dis = plat_params->l2_ecc_parity_prot_dis;
plat_bl31_params_from_bl2.sc7entry_fw_size = plat_params->sc7entry_fw_size;
plat_bl31_params_from_bl2.sc7entry_fw_base = plat_params->sc7entry_fw_base;
/*
* It is very important that we run either from TZDRAM or TZSRAM base.
@ -404,6 +406,14 @@ void bl31_plat_arch_setup(void)
*/
boot_profiler_add_record("[TF] arch setup entry");
/* add MMIO space */
plat_mmio_map = plat_get_mmio_map();
if (plat_mmio_map != NULL) {
mmap_add(plat_mmio_map);
} else {
WARN("MMIO map not available\n");
}
/* add memory regions */
mmap_add_region(rw_start, rw_start,
rw_size,
@ -415,14 +425,6 @@ void bl31_plat_arch_setup(void)
code_size,
MT_CODE | 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;
@ -432,18 +434,12 @@ void bl31_plat_arch_setup(void)
(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE);
#endif
/* map on-chip free running uS timer */
mmap_add_region(page_align(TEGRA_TMRUS_BASE, 0),
page_align(TEGRA_TMRUS_BASE, 0),
TEGRA_TMRUS_SIZE,
(uint8_t)MT_DEVICE | (uint8_t)MT_RO | (uint8_t)MT_SECURE);
/* add MMIO space */
plat_mmio_map = plat_get_mmio_map();
if (plat_mmio_map != NULL) {
mmap_add(plat_mmio_map);
} else {
WARN("MMIO map not available\n");
/* 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);
}
/* set up translation tables */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -16,9 +16,15 @@
#include <lib/el3_runtime/context_mgmt.h>
#include <plat/common/platform.h>
#if ENABLE_WDT_LEGACY_FIQ_HANDLING
#include <flowctrl.h>
#endif
#include <tegra_def.h>
#include <tegra_private.h>
/* Legacy FIQ used by earlier Tegra platforms */
#define LEGACY_FIQ_PPI_WDT 28U
static DEFINE_BAKERY_LOCK(tegra_fiq_lock);
/*******************************************************************************
@ -46,33 +52,58 @@ static uint64_t tegra_fiq_interrupt_handler(uint32_t id,
(void)handle;
(void)cookie;
/*
* Read the pending interrupt ID
*/
irq = plat_ic_get_pending_interrupt_id();
bakery_lock_get(&tegra_fiq_lock);
/*
* The FIQ was generated when the execution was in the non-secure
* world. Save the context registers to start with.
* Jump to NS world only if the NS world's FIQ handler has
* been registered
*/
cm_el1_sysregs_context_save(NON_SECURE);
if (ns_fiq_handler_addr != 0U) {
/*
* Save elr_el3 and spsr_el3 from the saved context, and overwrite
* the context with the NS fiq_handler_addr and SPSR value.
*/
fiq_state[cpu].elr_el3 = read_ctx_reg((el3state_ctx), (uint32_t)(CTX_ELR_EL3));
fiq_state[cpu].spsr_el3 = read_ctx_reg((el3state_ctx), (uint32_t)(CTX_SPSR_EL3));
/*
* The FIQ was generated when the execution was in the non-secure
* world. Save the context registers to start with.
*/
cm_el1_sysregs_context_save(NON_SECURE);
/*
* Save elr_el3 and spsr_el3 from the saved context, and overwrite
* the context with the NS fiq_handler_addr and SPSR value.
*/
fiq_state[cpu].elr_el3 = read_ctx_reg((el3state_ctx), (uint32_t)(CTX_ELR_EL3));
fiq_state[cpu].spsr_el3 = read_ctx_reg((el3state_ctx), (uint32_t)(CTX_SPSR_EL3));
/*
* Set the new ELR to continue execution in the NS world using the
* FIQ handler registered earlier.
*/
cm_set_elr_el3(NON_SECURE, ns_fiq_handler_addr);
}
#if ENABLE_WDT_LEGACY_FIQ_HANDLING
/*
* Set the new ELR to continue execution in the NS world using the
* FIQ handler registered earlier.
* Tegra platforms that use LEGACY_FIQ as the watchdog timer FIQ
* need to issue an IPI to other CPUs, to allow them to handle
* the "system hung" scenario. This interrupt is passed to the GICD
* via the Flow Controller. So, once we receive this interrupt,
* disable the routing so that we can mark it as "complete" in the
* GIC later.
*/
assert(ns_fiq_handler_addr != 0ULL);
write_ctx_reg((el3state_ctx), (uint32_t)(CTX_ELR_EL3), (ns_fiq_handler_addr));
if (irq == LEGACY_FIQ_PPI_WDT) {
tegra_fc_disable_fiq_to_ccplex_routing();
}
#endif
/*
* Mark this interrupt as complete to avoid a FIQ storm.
*/
irq = plat_ic_acknowledge_interrupt();
if (irq < 1022U) {
(void)plat_ic_acknowledge_interrupt();
plat_ic_end_of_interrupt(irq);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -41,6 +41,7 @@ uint8_t tegra_fake_system_suspend;
* provide typical implementations that will be overridden by a SoC.
*/
#pragma weak tegra_soc_pwr_domain_suspend_pwrdown_early
#pragma weak tegra_soc_cpu_standby
#pragma weak tegra_soc_pwr_domain_suspend
#pragma weak tegra_soc_pwr_domain_on
#pragma weak tegra_soc_pwr_domain_off
@ -55,6 +56,12 @@ int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *tar
return PSCI_E_NOT_SUPPORTED;
}
int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state)
{
(void)cpu_state;
return PSCI_E_SUCCESS;
}
int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
{
(void)target_state;
@ -139,14 +146,37 @@ void tegra_get_sys_suspend_power_state(psci_power_state_t *req_state)
******************************************************************************/
void tegra_cpu_standby(plat_local_state_t cpu_state)
{
u_register_t saved_scr_el3;
(void)cpu_state;
/* Tegra SoC specific handler */
if (tegra_soc_cpu_standby(cpu_state) != PSCI_E_SUCCESS)
ERROR("%s failed\n", __func__);
saved_scr_el3 = read_scr_el3();
/*
* As per ARM ARM D1.17.2, any physical IRQ interrupt received by the
* PE will be treated as a wake-up event, if SCR_EL3.IRQ is set to '1',
* irrespective of the value of the PSTATE.I bit value.
*/
write_scr_el3(saved_scr_el3 | SCR_IRQ_BIT);
/*
* Enter standby state
* dsb is good practice before using wfi to enter low power states
*
* dsb & isb is good practice before using wfi to enter low power states
*/
dsb();
isb();
wfi();
/*
* Restore saved scr_el3 that has IRQ bit cleared as we don't want EL3
* handling any further interrupts
*/
write_scr_el3(saved_scr_el3);
}
/*******************************************************************************
@ -244,7 +274,7 @@ void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state)
/*
* Initialize the GIC cpu and distributor interfaces
*/
plat_gic_setup();
tegra_gic_init();
/*
* Check if we are exiting from deep sleep.

View File

@ -116,6 +116,16 @@ uintptr_t tegra_sip_handler(uint32_t smc_fid,
/* new video memory carveout settings */
tegra_memctrl_videomem_setup(x1, local_x2_32);
/*
* Ensure again that GPU is still in reset after VPR resize
*/
regval = mmio_read_32(TEGRA_CAR_RESET_BASE +
TEGRA_GPU_RESET_REG_OFFSET);
if ((regval & GPU_RESET_BIT) == 0U) {
mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_GPU_RESET_GPU_SET_OFFSET,
GPU_SET_BIT);
}
SMC_RET1(handle, 0);
/*

View File

@ -27,8 +27,10 @@
#define SIGN_OF_LIFE 0xAAAAAAAAU
/* flags to indicate bpmp driver's state */
#define BPMP_NOT_PRESENT 0xF00DBEEFU
#define BPMP_INIT_COMPLETE 0xBEEFF00DU
#define BPMP_INIT_PENDING 0xDEADBEEFU
#define BPMP_SUSPEND_ENTRY 0xF00DCAFEU
/* requests serviced by the bpmp */
#define MRQ_PING 0
@ -106,6 +108,16 @@ typedef struct mb_data {
*/
int tegra_bpmp_init(void);
/**
* Function to suspend the interface with the bpmp
*/
void tegra_bpmp_suspend(void);
/**
* Function to resume the interface with the bpmp
*/
void tegra_bpmp_resume(void);
/**
* Handler to send a MRQ_* command to the bpmp
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -17,6 +17,11 @@
#define TEGRA_RESET_ID_XUSB_PADCTL U(114)
#define TEGRA_RESET_ID_GPCDMA U(70)
/**
* Clock identifier for the SE device
*/
#define TEGRA_CLK_SE U(124)
/**
* Function to initialise the IPC with the bpmp
*/
@ -27,4 +32,16 @@ int32_t tegra_bpmp_ipc_init(void);
*/
int32_t tegra_bpmp_ipc_reset_module(uint32_t rst_id);
/**
* Handler to enable clock to a module. Only SE device is
* supported for now.
*/
int tegra_bpmp_ipc_enable_clock(uint32_t clk_id);
/**
* Handler to disable clock to a module. Only SE device is
* supported for now.
*/
int tegra_bpmp_ipc_disable_clock(uint32_t clk_id);
#endif /* __BPMP_IPC_H__ */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -11,7 +11,7 @@
#include <tegra_def.h>
#define FLOWCTRL_HALT_CPU0_EVENTS 0x0U
#define FLOWCTRL_HALT_CPU0_EVENTS (0x0U)
#define FLOWCTRL_WAITEVENT (2U << 29)
#define FLOWCTRL_WAIT_FOR_INTERRUPT (4U << 29)
#define FLOWCTRL_JTAG_RESUME (1U << 28)
@ -20,19 +20,46 @@
#define FLOWCTRL_HALT_LIC_FIQ (1U << 10)
#define FLOWCTRL_HALT_GIC_IRQ (1U << 9)
#define FLOWCTRL_HALT_GIC_FIQ (1U << 8)
#define FLOWCTRL_HALT_BPMP_EVENTS 0x4U
#define FLOWCTRL_CPU0_CSR 0x8U
#define FLOW_CTRL_CSR_PWR_OFF_STS (1U << 16)
#define FLOWCTRL_HALT_BPMP_EVENTS (0x4U)
#define FLOWCTRL_CPU0_CSR (0x8U)
#define FLOWCTRL_CSR_HALT_MASK (1U << 22)
#define FLOWCTRL_CSR_PWR_OFF_STS (1U << 16)
#define FLOWCTRL_CSR_INTR_FLAG (1U << 15)
#define FLOWCTRL_CSR_EVENT_FLAG (1U << 14)
#define FLOWCTRL_CSR_IMMEDIATE_WAKE (1U << 3)
#define FLOWCTRL_CSR_ENABLE (1U << 0)
#define FLOWCTRL_HALT_CPU1_EVENTS 0x14U
#define FLOWCTRL_CPU1_CSR 0x18U
#define FLOWCTRL_CC4_CORE0_CTRL 0x6cU
#define FLOWCTRL_WAIT_WFI_BITMAP 0x100U
#define FLOWCTRL_L2_FLUSH_CONTROL 0x94U
#define FLOWCTRL_BPMP_CLUSTER_CONTROL 0x98U
#define FLOWCTRL_HALT_CPU1_EVENTS (0x14U)
#define FLOWCTRL_CPU1_CSR (0x18U)
#define FLOW_CTLR_FLOW_DBG_QUAL (0x50U)
#define FLOWCTRL_FIQ2CCPLEX_ENABLE (1U << 28)
#define FLOWCTRL_FC_SEQ_INTERCEPT (0x5cU)
#define INTERCEPT_IRQ_PENDING (0xffU)
#define INTERCEPT_HVC (U(1) << 21)
#define INTERCEPT_ENTRY_CC4 (U(1) << 20)
#define INTERCEPT_ENTRY_PG_NONCPU (U(1) << 19)
#define INTERCEPT_EXIT_PG_NONCPU (U(1) << 18)
#define INTERCEPT_ENTRY_RG_CPU (U(1) << 17)
#define INTERCEPT_EXIT_RG_CPU (U(1) << 16)
#define INTERCEPT_ENTRY_PG_CORE0 (U(1) << 15)
#define INTERCEPT_EXIT_PG_CORE0 (U(1) << 14)
#define INTERCEPT_ENTRY_PG_CORE1 (U(1) << 13)
#define INTERCEPT_EXIT_PG_CORE1 (U(1) << 12)
#define INTERCEPT_ENTRY_PG_CORE2 (U(1) << 11)
#define INTERCEPT_EXIT_PG_CORE2 (U(1) << 10)
#define INTERCEPT_ENTRY_PG_CORE3 (U(1) << 9)
#define INTERCEPT_EXIT_PG_CORE3 (U(1) << 8)
#define INTERRUPT_PENDING_NONCPU (U(1) << 7)
#define INTERRUPT_PENDING_CRAIL (U(1) << 6)
#define INTERRUPT_PENDING_CORE0 (U(1) << 5)
#define INTERRUPT_PENDING_CORE1 (U(1) << 4)
#define INTERRUPT_PENDING_CORE2 (U(1) << 3)
#define INTERRUPT_PENDING_CORE3 (U(1) << 2)
#define CC4_INTERRUPT_PENDING (U(1) << 1)
#define HVC_INTERRUPT_PENDING (U(1) << 0)
#define FLOWCTRL_CC4_CORE0_CTRL (0x6cU)
#define FLOWCTRL_WAIT_WFI_BITMAP (0x100U)
#define FLOWCTRL_L2_FLUSH_CONTROL (0x94U)
#define FLOWCTRL_BPMP_CLUSTER_CONTROL (0x98U)
#define FLOWCTRL_BPMP_CLUSTER_PWRON_LOCK (1U << 2)
#define FLOWCTRL_ENABLE_EXT 12U
@ -50,13 +77,19 @@ static inline void tegra_fc_write_32(uint32_t off, uint32_t val)
mmio_write_32(TEGRA_FLOWCTRL_BASE + off, val);
}
void tegra_fc_bpmp_on(uint32_t entrypoint);
void tegra_fc_bpmp_off(void);
void tegra_fc_ccplex_pgexit_lock(void);
void tegra_fc_ccplex_pgexit_unlock(void);
void tegra_fc_cluster_idle(uint32_t midr);
void tegra_fc_cpu_powerdn(uint32_t mpidr);
void tegra_fc_cluster_powerdn(uint32_t midr);
void tegra_fc_soc_powerdn(uint32_t midr);
void tegra_fc_cpu_on(int cpu);
void tegra_fc_cpu_off(int cpu);
void tegra_fc_disable_fiq_to_ccplex_routing(void);
void tegra_fc_enable_fiq_to_ccplex_routing(void);
bool tegra_fc_is_ccx_allowed(void);
void tegra_fc_lock_active_cluster(void);
void tegra_fc_reset_bpmp(void);
void tegra_fc_soc_powerdn(uint32_t midr);
#endif /* FLOWCTRL_H */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -9,22 +9,37 @@
#include <lib/mmio.h>
#include <lib/utils_def.h>
#include <stdbool.h>
#include <tegra_def.h>
#define PMC_CONFIG U(0x0)
#define PMC_IO_DPD_SAMPLE U(0x20)
#define PMC_DPD_ENABLE_0 U(0x24)
#define PMC_PWRGATE_STATUS U(0x38)
#define PMC_PWRGATE_TOGGLE U(0x30)
#define PMC_SECURE_SCRATCH0 U(0xb0)
#define PMC_SECURE_SCRATCH5 U(0xc4)
#define PMC_CRYPTO_OP_0 U(0xf4)
#define PMC_TOGGLE_START U(0x100)
#define PMC_SCRATCH39 U(0x138)
#define PMC_SCRATCH41 U(0x140)
#define PMC_SECURE_SCRATCH6 U(0x224)
#define PMC_SECURE_SCRATCH7 U(0x228)
#define PMC_SECURE_DISABLE2 U(0x2c4)
#define PMC_SECURE_DISABLE2_WRITE22_ON (U(1) << 28)
#define PMC_SECURE_SCRATCH8 U(0x300)
#define PMC_SECURE_SCRATCH79 U(0x41c)
#define PMC_FUSE_CONTROL_0 U(0x450)
#define PMC_SECURE_SCRATCH22 U(0x338)
#define PMC_SECURE_DISABLE3 U(0x2d8)
#define PMC_SECURE_DISABLE3_WRITE34_ON (U(1) << 20)
#define PMC_SECURE_DISABLE3_WRITE35_ON (U(1) << 22)
#define PMC_SECURE_SCRATCH34 U(0x368)
#define PMC_SECURE_SCRATCH35 U(0x36c)
#define PMC_SECURE_SCRATCH80 U(0xa98)
#define PMC_SECURE_SCRATCH119 U(0xb34)
#define PMC_SCRATCH201 U(0x844)
static inline uint32_t tegra_pmc_read_32(uint32_t off)
{
@ -36,9 +51,11 @@ static inline void tegra_pmc_write_32(uint32_t off, uint32_t val)
mmio_write_32(TEGRA_PMC_BASE + off, val);
}
void tegra_pmc_cpu_setup(uint64_t reset_addr);
void tegra_pmc_lock_cpu_vectors(void);
void tegra_pmc_cpu_on(int32_t cpu);
void tegra_pmc_cpu_setup(uint64_t reset_addr);
bool tegra_pmc_is_last_on_cpu(void);
void tegra_pmc_lock_cpu_vectors(void);
void tegra_pmc_resume(void);
__dead2 void tegra_pmc_system_reset(void);
#endif /* PMC_H */

View File

@ -618,9 +618,9 @@ typedef struct smmu_regs {
.val = 0x00000000U, \
}
#define smmu_make_gnsr0_sec_cfg(name) \
#define smmu_make_gnsr0_sec_cfg(base_addr, name) \
{ \
.reg = TEGRA_SMMU0_BASE + SMMU_GNSR0_ ## name, \
.reg = base_addr + SMMU_GNSR0_ ## name, \
.val = 0x00000000U, \
}
@ -628,60 +628,199 @@ typedef struct smmu_regs {
* On ARM-SMMU, conditional offset to access secure aliases of non-secure registers
* is 0x400. So, add it to register address
*/
#define smmu_make_gnsr0_nsec_cfg(name) \
#define smmu_make_gnsr0_nsec_cfg(base_addr, name) \
{ \
.reg = TEGRA_SMMU0_BASE + 0x400U + SMMU_GNSR0_ ## name, \
.reg = base_addr + 0x400U + SMMU_GNSR0_ ## name, \
.val = 0x00000000U, \
}
#define smmu_make_gnsr0_smr_cfg(n) \
#define smmu_make_gnsr0_smr_cfg(base_addr, n) \
{ \
.reg = TEGRA_SMMU0_BASE + SMMU_GNSR0_SMR ## n, \
.reg = base_addr + SMMU_GNSR0_SMR ## n, \
.val = 0x00000000U, \
}
#define smmu_make_gnsr0_s2cr_cfg(n) \
#define smmu_make_gnsr0_s2cr_cfg(base_addr, n) \
{ \
.reg = TEGRA_SMMU0_BASE + SMMU_GNSR0_S2CR ## n, \
.reg = base_addr + SMMU_GNSR0_S2CR ## n, \
.val = 0x00000000U, \
}
#define smmu_make_gnsr1_cbar_cfg(n) \
#define smmu_make_gnsr1_cbar_cfg(base_addr, n) \
{ \
.reg = TEGRA_SMMU0_BASE + (1U << PGSHIFT) + SMMU_GNSR1_CBAR ## n, \
.reg = base_addr + (1U << PGSHIFT) + SMMU_GNSR1_CBAR ## n, \
.val = 0x00000000U, \
}
#define smmu_make_gnsr1_cba2r_cfg(n) \
#define smmu_make_gnsr1_cba2r_cfg(base_addr, n) \
{ \
.reg = TEGRA_SMMU0_BASE + (1U << PGSHIFT) + SMMU_GNSR1_CBA2R ## n, \
.reg = base_addr + (1U << PGSHIFT) + SMMU_GNSR1_CBA2R ## n, \
.val = 0x00000000U, \
}
#define make_smmu_cb_cfg(name, n) \
#define smmu_make_cb_cfg(base_addr, name, n) \
{ \
.reg = TEGRA_SMMU0_BASE + (CB_SIZE >> 1) + (n * (1 << PGSHIFT)) \
.reg = base_addr + (CB_SIZE >> 1) + (n * (1 << PGSHIFT)) \
+ SMMU_CBn_ ## name, \
.val = 0x00000000U, \
}
#define smmu_make_smrg_group(n) \
smmu_make_gnsr0_smr_cfg(n), \
smmu_make_gnsr0_s2cr_cfg(n), \
smmu_make_gnsr1_cbar_cfg(n), \
smmu_make_gnsr1_cba2r_cfg(n) /* don't put "," here. */
#define smmu_make_smrg_group(base_addr, n) \
smmu_make_gnsr0_smr_cfg(base_addr, n), \
smmu_make_gnsr0_s2cr_cfg(base_addr, n), \
smmu_make_gnsr1_cbar_cfg(base_addr, n), \
smmu_make_gnsr1_cba2r_cfg(base_addr, n) /* don't put "," here. */
#define smmu_make_cb_group(n) \
make_smmu_cb_cfg(SCTLR, n), \
make_smmu_cb_cfg(TCR2, n), \
make_smmu_cb_cfg(TTBR0_LO, n), \
make_smmu_cb_cfg(TTBR0_HI, n), \
make_smmu_cb_cfg(TCR, n), \
make_smmu_cb_cfg(PRRR_MAIR0, n),\
make_smmu_cb_cfg(FSR, n), \
make_smmu_cb_cfg(FAR_LO, n), \
make_smmu_cb_cfg(FAR_HI, n), \
make_smmu_cb_cfg(FSYNR0, n) /* don't put "," here. */
#define smmu_make_cb_group(base_addr, n) \
smmu_make_cb_cfg(base_addr, SCTLR, n), \
smmu_make_cb_cfg(base_addr, TCR2, n), \
smmu_make_cb_cfg(base_addr, TTBR0_LO, n), \
smmu_make_cb_cfg(base_addr, TTBR0_HI, n), \
smmu_make_cb_cfg(base_addr, TCR, n), \
smmu_make_cb_cfg(base_addr, PRRR_MAIR0, n),\
smmu_make_cb_cfg(base_addr, FSR, n), \
smmu_make_cb_cfg(base_addr, FAR_LO, n), \
smmu_make_cb_cfg(base_addr, FAR_HI, n), \
smmu_make_cb_cfg(base_addr, FSYNR0, n) /* don't put "," here. */
#define smmu_make_cfg(base_addr) \
smmu_make_gnsr0_nsec_cfg(base_addr, CR0), \
smmu_make_gnsr0_sec_cfg(base_addr, IDR0), \
smmu_make_gnsr0_sec_cfg(base_addr, IDR1), \
smmu_make_gnsr0_sec_cfg(base_addr, IDR2), \
smmu_make_gnsr0_nsec_cfg(base_addr, GFSR), \
smmu_make_gnsr0_nsec_cfg(base_addr, GFSYNR0), \
smmu_make_gnsr0_nsec_cfg(base_addr, GFSYNR1), \
smmu_make_gnsr0_nsec_cfg(base_addr, TLBGSTATUS),\
smmu_make_gnsr0_nsec_cfg(base_addr, PIDR2), \
smmu_make_smrg_group(base_addr, 0), \
smmu_make_smrg_group(base_addr, 1), \
smmu_make_smrg_group(base_addr, 2), \
smmu_make_smrg_group(base_addr, 3), \
smmu_make_smrg_group(base_addr, 4), \
smmu_make_smrg_group(base_addr, 5), \
smmu_make_smrg_group(base_addr, 6), \
smmu_make_smrg_group(base_addr, 7), \
smmu_make_smrg_group(base_addr, 8), \
smmu_make_smrg_group(base_addr, 9), \
smmu_make_smrg_group(base_addr, 10), \
smmu_make_smrg_group(base_addr, 11), \
smmu_make_smrg_group(base_addr, 12), \
smmu_make_smrg_group(base_addr, 13), \
smmu_make_smrg_group(base_addr, 14), \
smmu_make_smrg_group(base_addr, 15), \
smmu_make_smrg_group(base_addr, 16), \
smmu_make_smrg_group(base_addr, 17), \
smmu_make_smrg_group(base_addr, 18), \
smmu_make_smrg_group(base_addr, 19), \
smmu_make_smrg_group(base_addr, 20), \
smmu_make_smrg_group(base_addr, 21), \
smmu_make_smrg_group(base_addr, 22), \
smmu_make_smrg_group(base_addr, 23), \
smmu_make_smrg_group(base_addr, 24), \
smmu_make_smrg_group(base_addr, 25), \
smmu_make_smrg_group(base_addr, 26), \
smmu_make_smrg_group(base_addr, 27), \
smmu_make_smrg_group(base_addr, 28), \
smmu_make_smrg_group(base_addr, 29), \
smmu_make_smrg_group(base_addr, 30), \
smmu_make_smrg_group(base_addr, 31), \
smmu_make_smrg_group(base_addr, 32), \
smmu_make_smrg_group(base_addr, 33), \
smmu_make_smrg_group(base_addr, 34), \
smmu_make_smrg_group(base_addr, 35), \
smmu_make_smrg_group(base_addr, 36), \
smmu_make_smrg_group(base_addr, 37), \
smmu_make_smrg_group(base_addr, 38), \
smmu_make_smrg_group(base_addr, 39), \
smmu_make_smrg_group(base_addr, 40), \
smmu_make_smrg_group(base_addr, 41), \
smmu_make_smrg_group(base_addr, 42), \
smmu_make_smrg_group(base_addr, 43), \
smmu_make_smrg_group(base_addr, 44), \
smmu_make_smrg_group(base_addr, 45), \
smmu_make_smrg_group(base_addr, 46), \
smmu_make_smrg_group(base_addr, 47), \
smmu_make_smrg_group(base_addr, 48), \
smmu_make_smrg_group(base_addr, 49), \
smmu_make_smrg_group(base_addr, 50), \
smmu_make_smrg_group(base_addr, 51), \
smmu_make_smrg_group(base_addr, 52), \
smmu_make_smrg_group(base_addr, 53), \
smmu_make_smrg_group(base_addr, 54), \
smmu_make_smrg_group(base_addr, 55), \
smmu_make_smrg_group(base_addr, 56), \
smmu_make_smrg_group(base_addr, 57), \
smmu_make_smrg_group(base_addr, 58), \
smmu_make_smrg_group(base_addr, 59), \
smmu_make_smrg_group(base_addr, 60), \
smmu_make_smrg_group(base_addr, 61), \
smmu_make_smrg_group(base_addr, 62), \
smmu_make_smrg_group(base_addr, 63), \
smmu_make_cb_group(base_addr, 0), \
smmu_make_cb_group(base_addr, 1), \
smmu_make_cb_group(base_addr, 2), \
smmu_make_cb_group(base_addr, 3), \
smmu_make_cb_group(base_addr, 4), \
smmu_make_cb_group(base_addr, 5), \
smmu_make_cb_group(base_addr, 6), \
smmu_make_cb_group(base_addr, 7), \
smmu_make_cb_group(base_addr, 8), \
smmu_make_cb_group(base_addr, 9), \
smmu_make_cb_group(base_addr, 10), \
smmu_make_cb_group(base_addr, 11), \
smmu_make_cb_group(base_addr, 12), \
smmu_make_cb_group(base_addr, 13), \
smmu_make_cb_group(base_addr, 14), \
smmu_make_cb_group(base_addr, 15), \
smmu_make_cb_group(base_addr, 16), \
smmu_make_cb_group(base_addr, 17), \
smmu_make_cb_group(base_addr, 18), \
smmu_make_cb_group(base_addr, 19), \
smmu_make_cb_group(base_addr, 20), \
smmu_make_cb_group(base_addr, 21), \
smmu_make_cb_group(base_addr, 22), \
smmu_make_cb_group(base_addr, 23), \
smmu_make_cb_group(base_addr, 24), \
smmu_make_cb_group(base_addr, 25), \
smmu_make_cb_group(base_addr, 26), \
smmu_make_cb_group(base_addr, 27), \
smmu_make_cb_group(base_addr, 28), \
smmu_make_cb_group(base_addr, 29), \
smmu_make_cb_group(base_addr, 30), \
smmu_make_cb_group(base_addr, 31), \
smmu_make_cb_group(base_addr, 32), \
smmu_make_cb_group(base_addr, 33), \
smmu_make_cb_group(base_addr, 34), \
smmu_make_cb_group(base_addr, 35), \
smmu_make_cb_group(base_addr, 36), \
smmu_make_cb_group(base_addr, 37), \
smmu_make_cb_group(base_addr, 38), \
smmu_make_cb_group(base_addr, 39), \
smmu_make_cb_group(base_addr, 40), \
smmu_make_cb_group(base_addr, 41), \
smmu_make_cb_group(base_addr, 42), \
smmu_make_cb_group(base_addr, 43), \
smmu_make_cb_group(base_addr, 44), \
smmu_make_cb_group(base_addr, 45), \
smmu_make_cb_group(base_addr, 46), \
smmu_make_cb_group(base_addr, 47), \
smmu_make_cb_group(base_addr, 48), \
smmu_make_cb_group(base_addr, 49), \
smmu_make_cb_group(base_addr, 50), \
smmu_make_cb_group(base_addr, 51), \
smmu_make_cb_group(base_addr, 52), \
smmu_make_cb_group(base_addr, 53), \
smmu_make_cb_group(base_addr, 54), \
smmu_make_cb_group(base_addr, 55), \
smmu_make_cb_group(base_addr, 56), \
smmu_make_cb_group(base_addr, 57), \
smmu_make_cb_group(base_addr, 58), \
smmu_make_cb_group(base_addr, 59), \
smmu_make_cb_group(base_addr, 60), \
smmu_make_cb_group(base_addr, 61), \
smmu_make_cb_group(base_addr, 62), \
smmu_make_cb_group(base_addr, 63) /* don't put "," here. */
#define smmu_bypass_cfg \
{ \

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -50,7 +50,7 @@ spacer:
bl asm_print_hex
adr x4, spacer
bl asm_print_str
ldr x4, [x7], #8
ldr w4, [x7], #4
bl asm_print_hex
adr x4, newline
bl asm_print_str

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -53,12 +53,6 @@
#define BL32_BASE (TZDRAM_BASE + BL31_SIZE)
#define BL32_LIMIT TZDRAM_END
/*******************************************************************************
* Platform specific page table and MMU setup constants
******************************************************************************/
#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 35)
#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 35)
/*******************************************************************************
* Some data must be aligned on the biggest cache line size in the platform.
* This is known only to the platform as it might have a combination of

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -24,6 +24,12 @@
#define PLAT_MAX_RET_STATE U(1)
#define PLAT_MAX_OFF_STATE (PSTATE_ID_SOC_POWERDN + U(1))
/*******************************************************************************
* Chip specific page table and MMU setup constants
******************************************************************************/
#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 35)
#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 35)
/*******************************************************************************
* GIC memory map
******************************************************************************/
@ -41,7 +47,9 @@
******************************************************************************/
#define TEGRA_CAR_RESET_BASE U(0x60006000)
#define TEGRA_GPU_RESET_REG_OFFSET U(0x28C)
#define TEGRA_GPU_RESET_GPU_SET_OFFSET U(0x290)
#define GPU_RESET_BIT (U(1) << 24)
#define GPU_SET_BIT (U(1) << 24)
/*******************************************************************************
* Tegra Flow Controller constants

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -57,6 +57,12 @@
#define PLAT_MAX_RET_STATE U(1)
#define PLAT_MAX_OFF_STATE U(8)
/*******************************************************************************
* Chip specific page table and MMU setup constants
******************************************************************************/
#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 35)
#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 35)
/*******************************************************************************
* Secure IRQ definitions
******************************************************************************/
@ -210,7 +216,9 @@
******************************************************************************/
#define TEGRA_CAR_RESET_BASE U(0x05000000)
#define TEGRA_GPU_RESET_REG_OFFSET U(0x30)
#define TEGRA_GPU_RESET_GPU_SET_OFFSET U(0x34)
#define GPU_RESET_BIT (U(1) << 0)
#define GPU_SET_BIT (U(1) << 0)
#define TEGRA_GPCDMA_RST_SET_REG_OFFSET U(0x6A0004)
#define TEGRA_GPCDMA_RST_CLR_REG_OFFSET U(0x6A0008)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -14,7 +14,6 @@
******************************************************************************/
#define PSTATE_ID_CORE_POWERDN U(7)
#define PSTATE_ID_CLUSTER_IDLE U(16)
#define PSTATE_ID_CLUSTER_POWERDN U(17)
#define PSTATE_ID_SOC_POWERDN U(27)
/*******************************************************************************
@ -32,10 +31,23 @@
#define PLAT_MAX_RET_STATE U(1)
#define PLAT_MAX_OFF_STATE (PSTATE_ID_SOC_POWERDN + U(1))
/*******************************************************************************
* Chip specific page table and MMU setup constants
******************************************************************************/
#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 35)
#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 35)
/*******************************************************************************
* SC7 entry firmware's header size
******************************************************************************/
#define SC7ENTRY_FW_HEADER_SIZE_BYTES U(0x400)
/*******************************************************************************
* iRAM memory constants
******************************************************************************/
#define TEGRA_IRAM_BASE 0x40000000
#define TEGRA_IRAM_BASE U(0x40000000)
#define TEGRA_IRAM_A_SIZE U(0x10000) /* 64KB */
#define TEGRA_IRAM_SIZE U(40000) /* 256KB */
/*******************************************************************************
* GIC memory map
@ -43,6 +55,11 @@
#define TEGRA_GICD_BASE U(0x50041000)
#define TEGRA_GICC_BASE U(0x50042000)
/*******************************************************************************
* Secure IRQ definitions
******************************************************************************/
#define TEGRA210_WDT_CPU_LEGACY_FIQ U(28)
/*******************************************************************************
* Tegra Memory Select Switch Controller constants
******************************************************************************/
@ -84,21 +101,55 @@
* Tegra Clock and Reset Controller constants
******************************************************************************/
#define TEGRA_CAR_RESET_BASE U(0x60006000)
#define TEGRA_BOND_OUT_H U(0x74)
#define APB_DMA_LOCK_BIT (U(1) << 2)
#define AHB_DMA_LOCK_BIT (U(1) << 1)
#define TEGRA_BOND_OUT_U U(0x78)
#define IRAM_D_LOCK_BIT (U(1) << 23)
#define IRAM_C_LOCK_BIT (U(1) << 22)
#define IRAM_B_LOCK_BIT (U(1) << 21)
#define TEGRA_GPU_RESET_REG_OFFSET U(0x28C)
#define TEGRA_GPU_RESET_GPU_SET_OFFSET U(0x290)
#define GPU_RESET_BIT (U(1) << 24)
#define GPU_SET_BIT (U(1) << 24)
#define TEGRA_RST_DEV_SET_Y U(0x2a8)
#define NVENC_RESET_BIT (U(1) << 27)
#define TSECB_RESET_BIT (U(1) << 14)
#define APE_RESET_BIT (U(1) << 6)
#define NVJPG_RESET_BIT (U(1) << 3)
#define NVDEC_RESET_BIT (U(1) << 2)
#define TEGRA_RST_DEV_SET_L U(0x300)
#define HOST1X_RESET_BIT (U(1) << 28)
#define ISP_RESET_BIT (U(1) << 23)
#define USBD_RESET_BIT (U(1) << 22)
#define VI_RESET_BIT (U(1) << 20)
#define SDMMC4_RESET_BIT (U(1) << 15)
#define SDMMC1_RESET_BIT (U(1) << 14)
#define SDMMC2_RESET_BIT (U(1) << 9)
#define TEGRA_RST_DEV_SET_H U(0x308)
#define USB2_RESET_BIT (U(1) << 26)
#define APBDMA_RESET_BIT (U(1) << 2)
#define AHBDMA_RESET_BIT (U(1) << 1)
#define TEGRA_RST_DEV_SET_U U(0x310)
#define XUSB_DEV_RESET_BIT (U(1) << 31)
#define XUSB_HOST_RESET_BIT (U(1) << 25)
#define TSEC_RESET_BIT (U(1) << 19)
#define PCIE_RESET_BIT (U(1) << 6)
#define SDMMC3_RESET_BIT (U(1) << 5)
#define TEGRA_RST_DEVICES_V U(0x358)
#define TEGRA_RST_DEVICES_W U(0x35C)
#define ENTROPY_CLK_ENB_BIT (U(1) << 21)
#define TEGRA_CLK_OUT_ENB_V U(0x360)
#define SE_CLK_ENB_BIT (U(1) << 31)
#define TEGRA_CLK_OUT_ENB_W U(0x364)
#define ENTROPY_RESET_BIT (U(1) << 21)
#define TEGRA_RST_DEV_SET_V U(0x430)
#define SE_RESET_BIT (U(1) << 31)
#define HDA_RESET_BIT (U(1) << 29)
#define SATA_RESET_BIT (U(1) << 28)
#define TEGRA_RST_DEV_CLR_V U(0x434)
#define TEGRA_CLK_ENB_V U(0x440)
/* SE Clock Offsets */
#define TEGRA_RST_DEVICES_V 0x358UL
#define SE_RESET_BIT (0x1UL << 31)
#define TEGRA_RST_DEVICES_W 0x35CUL
#define ENTROPY_CLK_ENB_BIT (0x1UL << 21)
#define TEGRA_CLK_OUT_ENB_V 0x360UL
#define SE_CLK_ENB_BIT (0x1UL << 31)
#define TEGRA_CLK_OUT_ENB_W 0x364UL
#define ENTROPY_RESET_BIT (0x1UL << 21)
/*******************************************************************************
* Tegra Flow Controller constants
******************************************************************************/
@ -124,6 +175,10 @@
******************************************************************************/
#define TEGRA_MISC_BASE U(0x70000000)
#define HARDWARE_REVISION_OFFSET U(0x804)
#define APB_SLAVE_SECURITY_ENABLE U(0xC00)
#define PMC_SECURITY_EN_BIT (U(1) << 13)
#define PINMUX_AUX_DVFS_PWM U(0x3184)
#define PINMUX_PWM_TRISTATE (U(1) << 4)
/*******************************************************************************
* Tegra UART controller base addresses
@ -148,6 +203,7 @@
* Tegra Power Mgmt Controller constants
******************************************************************************/
#define TEGRA_PMC_BASE U(0x7000E400)
#define TEGRA_PMC_SIZE U(0xC00) /* 3k */
/*******************************************************************************
* Tegra Atomics constants
@ -180,6 +236,17 @@
#define MC_SMMU_PPCS_ASID_0 0x270U
#define PPCS_SMMU_ENABLE (0x1U << 31)
/*******************************************************************************
* Tegra CLDVFS constants
******************************************************************************/
#define TEGRA_CL_DVFS_BASE U(0x70110000)
#define DVFS_DFLL_CTRL U(0x00)
#define ENABLE_OPEN_LOOP U(1)
#define ENABLE_CLOSED_LOOP U(2)
#define DVFS_DFLL_OUTPUT_CFG U(0x20)
#define DFLL_OUTPUT_CFG_I2C_EN_BIT (U(1) << 30)
#define DFLL_OUTPUT_CFG_CLK_EN_BIT (U(1) << 6)
/*******************************************************************************
* Tegra SE constants
******************************************************************************/

View File

@ -46,6 +46,10 @@ typedef struct plat_params_from_bl2 {
int32_t l2_ecc_parity_prot_dis;
/* SHMEM base address for storing the boot logs */
uint64_t boot_profiler_shmem_base;
/* System Suspend Entry Firmware size */
uint64_t sc7entry_fw_size;
/* System Suspend Entry Firmware base address */
uint64_t sc7entry_fw_base;
} plat_params_from_bl2_t;
/*******************************************************************************
@ -97,6 +101,7 @@ extern uint8_t tegra_fake_system_suspend;
void tegra_pm_system_suspend_entry(void);
void tegra_pm_system_suspend_exit(void);
int32_t tegra_system_suspended(void);
int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state);
int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state);
int32_t tegra_soc_pwr_domain_on(u_register_t mpidr);
int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state);

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@ -34,6 +34,9 @@ ENABLE_SVE_FOR_NS := 0
# enable D-cache early during CPU warmboot
WARMBOOT_ENABLE_DCACHE_EARLY := 1
# remove the standard libc
OVERRIDE_LIBC := 1
include plat/nvidia/tegra/common/tegra_common.mk
include ${SOC_DIR}/platform_${TARGET_SOC}.mk
@ -42,3 +45,17 @@ BUILD_PLAT := ${BUILD_BASE}/${PLAT}/${TARGET_SOC}/${BUILD_TYPE}
# platform cflags (enable signed comparisons, disable stdlib)
TF_CFLAGS += -Wsign-compare -nostdlib
# override with necessary libc files for the Tegra platform
override LIBC_SRCS := $(addprefix lib/libc/, \
assert.c \
memcpy.c \
memmove.c \
memset.c \
printf.c \
putchar.c \
strlen.c \
snprintf.c)
INCLUDES += -Iinclude/lib/libc \
-Iinclude/lib/libc/$(ARCH) \

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -101,4 +101,5 @@ uint32_t plat_get_console_from_id(int id)
void plat_gic_setup(void)
{
tegra_gic_setup(NULL, 0);
tegra_gic_init();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -94,7 +94,7 @@ const static uint32_t tegra186_streamid_override_regs[] = {
* Array to hold the security configs for stream IDs
******************************************************************************/
const static mc_streamid_security_cfg_t tegra186_streamid_sec_cfgs[] = {
mc_make_sec_cfg(SCEW, NON_SECURE, NO_OVERRIDE, ENABLE),
mc_make_sec_cfg(SCEW, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(AFIR, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(AFIW, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(NVDISPLAYR1, NON_SECURE, OVERRIDE, ENABLE),
@ -109,17 +109,17 @@ const static mc_streamid_security_cfg_t tegra186_streamid_sec_cfgs[] = {
mc_make_sec_cfg(SATAW, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(UFSHCW, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(SDMMCR, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(SCEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
mc_make_sec_cfg(SCEDMAW, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(UFSHCR, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(SDMMCWAA, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(SESWR, NON_SECURE, NO_OVERRIDE, ENABLE),
mc_make_sec_cfg(MPCORER, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(PTCR, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(BPMPW, NON_SECURE, NO_OVERRIDE, ENABLE),
mc_make_sec_cfg(BPMPW, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(ETRW, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(GPUSRD, SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(VICSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
mc_make_sec_cfg(SCEDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
mc_make_sec_cfg(SCEDMAR, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(HDAW, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(ISPWA, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(EQOSW, NON_SECURE, OVERRIDE, ENABLE),
@ -129,20 +129,20 @@ const static mc_streamid_security_cfg_t tegra186_streamid_sec_cfgs[] = {
mc_make_sec_cfg(VIW, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(AXISR, SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(SDMMCW, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(BPMPDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
mc_make_sec_cfg(BPMPDMAW, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(ISPRA, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(NVDECSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
mc_make_sec_cfg(XUSB_DEVW, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(NVDECSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
mc_make_sec_cfg(NVDECSRD, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(MPCOREW, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(NVDISPLAYR, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(BPMPDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
mc_make_sec_cfg(BPMPDMAR, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(NVJPGSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
mc_make_sec_cfg(NVDECSRD1, NON_SECURE, NO_OVERRIDE, ENABLE),
mc_make_sec_cfg(NVDECSRD1, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(TSECSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
mc_make_sec_cfg(NVJPGSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
mc_make_sec_cfg(SDMMCWA, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(SCER, NON_SECURE, NO_OVERRIDE, ENABLE),
mc_make_sec_cfg(SCER, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(XUSB_HOSTR, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(VICSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
mc_make_sec_cfg(AONDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
@ -151,7 +151,7 @@ const static mc_streamid_security_cfg_t tegra186_streamid_sec_cfgs[] = {
mc_make_sec_cfg(HOST1XDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
mc_make_sec_cfg(EQOSR, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(SATAR, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(BPMPR, NON_SECURE, NO_OVERRIDE, ENABLE),
mc_make_sec_cfg(BPMPR, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(HDAR, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(SDMMCRAB, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(ETRR, NON_SECURE, OVERRIDE, ENABLE),
@ -162,10 +162,10 @@ const static mc_streamid_security_cfg_t tegra186_streamid_sec_cfgs[] = {
mc_make_sec_cfg(TSECSWRB, NON_SECURE, NO_OVERRIDE, ENABLE),
mc_make_sec_cfg(ISPWB, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(GPUSRD2, SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(APEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
mc_make_sec_cfg(APER, NON_SECURE, NO_OVERRIDE, ENABLE),
mc_make_sec_cfg(APEW, NON_SECURE, NO_OVERRIDE, ENABLE),
mc_make_sec_cfg(APEDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
mc_make_sec_cfg(APEDMAW, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(APER, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(APEW, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(APEDMAR, NON_SECURE, NO_OVERRIDE, DISABLE),
};
/*******************************************************************************
@ -219,9 +219,7 @@ static void tegra186_memctrl_reconfig_mss_clients(void)
assert(val == MC_CLIENT_HOTRESET_CTRL0_RESET_VAL);
wdata_0 = MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB |
#if ENABLE_AFI_DEVICE
MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB |
#endif
MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB |
MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB |
MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB;
@ -271,9 +269,7 @@ static void tegra186_memctrl_reconfig_mss_clients(void)
* MC clients with default SO_DEV override still enabled at TSA:
* AONW, BPMPW, SCEW, APEW
*/
#if ENABLE_AFI_DEVICE
mc_set_tsa_passthrough(AFIW);
#endif
mc_set_tsa_passthrough(HDAW);
mc_set_tsa_passthrough(SATAW);
mc_set_tsa_passthrough(XUSB_HOSTW);
@ -413,9 +409,7 @@ static void tegra186_memctrl_reconfig_mss_clients(void)
* boot and strongly ordered MSS clients
*/
val = MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL &
#if ENABLE_AFI_DEVICE
mc_set_pcfifo_unordered_boot_so_mss(1, AFIW) &
#endif
mc_set_pcfifo_unordered_boot_so_mss(1, HDAW) &
mc_set_pcfifo_unordered_boot_so_mss(1, SATAW);
tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG1, val);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -91,6 +91,8 @@ static const mmap_region_t tegra_mmap[] = {
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(TEGRA_PMC_BASE, 0x40000U, /* 256KB */
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(TEGRA_TMRUS_BASE, 0x1000U, /* 4KB */
MT_DEVICE | MT_RO | MT_SECURE),
MAP_REGION_FLAT(TEGRA_SCRATCH_BASE, 0x10000U, /* 64KB */
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(TEGRA_MMCRAB_BASE, 0x60000U, /* 384KB */
@ -194,14 +196,13 @@ static const interrupt_prop_t tegra186_interrupt_props[] = {
void plat_gic_setup(void)
{
tegra_gic_setup(tegra186_interrupt_props, ARRAY_SIZE(tegra186_interrupt_props));
tegra_gic_init();
/*
* Initialize the FIQ handler only if the platform supports any
* FIQ interrupt sources.
*/
if (sizeof(tegra186_interrupt_props) > 0U) {
tegra_fiq_handler_setup();
}
tegra_fiq_handler_setup();
}
/*******************************************************************************

View File

@ -161,143 +161,7 @@ static __attribute__((aligned(16))) smmu_regs_t tegra186_smmu_context[] = {
mc_make_sid_override_cfg(UFSHCR),
mc_make_sid_override_cfg(NVENCSWR),
mc_make_sid_override_cfg(AFIW),
smmu_make_gnsr0_nsec_cfg(CR0),
smmu_make_gnsr0_sec_cfg(IDR0),
smmu_make_gnsr0_sec_cfg(IDR1),
smmu_make_gnsr0_sec_cfg(IDR2),
smmu_make_gnsr0_nsec_cfg(GFSR),
smmu_make_gnsr0_nsec_cfg(GFSYNR0),
smmu_make_gnsr0_nsec_cfg(GFSYNR1),
smmu_make_gnsr0_nsec_cfg(TLBGSTATUS),
smmu_make_gnsr0_nsec_cfg(PIDR2),
smmu_make_smrg_group(0),
smmu_make_smrg_group(1),
smmu_make_smrg_group(2),
smmu_make_smrg_group(3),
smmu_make_smrg_group(4),
smmu_make_smrg_group(5),
smmu_make_smrg_group(6),
smmu_make_smrg_group(7),
smmu_make_smrg_group(8),
smmu_make_smrg_group(9),
smmu_make_smrg_group(10),
smmu_make_smrg_group(11),
smmu_make_smrg_group(12),
smmu_make_smrg_group(13),
smmu_make_smrg_group(14),
smmu_make_smrg_group(15),
smmu_make_smrg_group(16),
smmu_make_smrg_group(17),
smmu_make_smrg_group(18),
smmu_make_smrg_group(19),
smmu_make_smrg_group(20),
smmu_make_smrg_group(21),
smmu_make_smrg_group(22),
smmu_make_smrg_group(23),
smmu_make_smrg_group(24),
smmu_make_smrg_group(25),
smmu_make_smrg_group(26),
smmu_make_smrg_group(27),
smmu_make_smrg_group(28),
smmu_make_smrg_group(29),
smmu_make_smrg_group(30),
smmu_make_smrg_group(31),
smmu_make_smrg_group(32),
smmu_make_smrg_group(33),
smmu_make_smrg_group(34),
smmu_make_smrg_group(35),
smmu_make_smrg_group(36),
smmu_make_smrg_group(37),
smmu_make_smrg_group(38),
smmu_make_smrg_group(39),
smmu_make_smrg_group(40),
smmu_make_smrg_group(41),
smmu_make_smrg_group(42),
smmu_make_smrg_group(43),
smmu_make_smrg_group(44),
smmu_make_smrg_group(45),
smmu_make_smrg_group(46),
smmu_make_smrg_group(47),
smmu_make_smrg_group(48),
smmu_make_smrg_group(49),
smmu_make_smrg_group(50),
smmu_make_smrg_group(51),
smmu_make_smrg_group(52),
smmu_make_smrg_group(53),
smmu_make_smrg_group(54),
smmu_make_smrg_group(55),
smmu_make_smrg_group(56),
smmu_make_smrg_group(57),
smmu_make_smrg_group(58),
smmu_make_smrg_group(59),
smmu_make_smrg_group(60),
smmu_make_smrg_group(61),
smmu_make_smrg_group(62),
smmu_make_smrg_group(63),
smmu_make_cb_group(0),
smmu_make_cb_group(1),
smmu_make_cb_group(2),
smmu_make_cb_group(3),
smmu_make_cb_group(4),
smmu_make_cb_group(5),
smmu_make_cb_group(6),
smmu_make_cb_group(7),
smmu_make_cb_group(8),
smmu_make_cb_group(9),
smmu_make_cb_group(10),
smmu_make_cb_group(11),
smmu_make_cb_group(12),
smmu_make_cb_group(13),
smmu_make_cb_group(14),
smmu_make_cb_group(15),
smmu_make_cb_group(16),
smmu_make_cb_group(17),
smmu_make_cb_group(18),
smmu_make_cb_group(19),
smmu_make_cb_group(20),
smmu_make_cb_group(21),
smmu_make_cb_group(22),
smmu_make_cb_group(23),
smmu_make_cb_group(24),
smmu_make_cb_group(25),
smmu_make_cb_group(26),
smmu_make_cb_group(27),
smmu_make_cb_group(28),
smmu_make_cb_group(29),
smmu_make_cb_group(30),
smmu_make_cb_group(31),
smmu_make_cb_group(32),
smmu_make_cb_group(33),
smmu_make_cb_group(34),
smmu_make_cb_group(35),
smmu_make_cb_group(36),
smmu_make_cb_group(37),
smmu_make_cb_group(38),
smmu_make_cb_group(39),
smmu_make_cb_group(40),
smmu_make_cb_group(41),
smmu_make_cb_group(42),
smmu_make_cb_group(43),
smmu_make_cb_group(44),
smmu_make_cb_group(45),
smmu_make_cb_group(46),
smmu_make_cb_group(47),
smmu_make_cb_group(48),
smmu_make_cb_group(49),
smmu_make_cb_group(50),
smmu_make_cb_group(51),
smmu_make_cb_group(52),
smmu_make_cb_group(53),
smmu_make_cb_group(54),
smmu_make_cb_group(55),
smmu_make_cb_group(56),
smmu_make_cb_group(57),
smmu_make_cb_group(58),
smmu_make_cb_group(59),
smmu_make_cb_group(60),
smmu_make_cb_group(61),
smmu_make_cb_group(62),
smmu_make_cb_group(63),
smmu_make_cfg(TEGRA_SMMU0_BASE),
smmu_bypass_cfg, /* TBU settings */
_END_OF_TABLE_,
};

View File

@ -1,13 +1,10 @@
#
# Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
# platform configs
ENABLE_AFI_DEVICE := 1
$(eval $(call add_define,ENABLE_AFI_DEVICE))
ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS := 1
$(eval $(call add_define,ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS))
@ -33,7 +30,7 @@ $(eval $(call add_define,PLATFORM_MAX_CPUS_PER_CLUSTER))
MAX_XLAT_TABLES := 24
$(eval $(call add_define,MAX_XLAT_TABLES))
MAX_MMAP_REGIONS := 24
MAX_MMAP_REGIONS := 25
$(eval $(call add_define,MAX_MMAP_REGIONS))
# platform files

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -15,12 +15,14 @@
#include <bpmp.h>
#include <flowctrl.h>
#include <memctrl.h>
#include <pmc.h>
#include <platform_def.h>
#include <security_engine.h>
#include <tegra_def.h>
#include <tegra_private.h>
#include <tegra_platform.h>
#include <utils.h>
/*
* Register used to clear CPU reset signals. Each CPU has two reset
@ -35,11 +37,13 @@
#define SCLK_BURST_POLICY_DEFAULT 0x10000000
static int cpu_powergate_mask[PLATFORM_MAX_CPUS_PER_CLUSTER];
static bool tegra_bpmp_available = true;
int32_t tegra_soc_validate_power_state(unsigned int power_state,
psci_power_state_t *req_state)
{
int state_id = psci_get_pstate_id(power_state);
const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
/* Sanity check the requested state id */
switch (state_id) {
@ -52,16 +56,24 @@ int32_t tegra_soc_validate_power_state(unsigned int power_state,
break;
case PSTATE_ID_CLUSTER_IDLE:
case PSTATE_ID_CLUSTER_POWERDN:
/*
* Cluster powerdown/idle request only for afflvl 1
*/
req_state->pwr_domain_state[MPIDR_AFFLVL1] = state_id;
req_state->pwr_domain_state[MPIDR_AFFLVL0] = PSTATE_ID_CORE_POWERDN;
/*
* Cluster idle request for afflvl 0
*/
req_state->pwr_domain_state[MPIDR_AFFLVL0] = PSTATE_ID_CORE_POWERDN;
req_state->pwr_domain_state[MPIDR_AFFLVL1] = state_id;
break;
case PSTATE_ID_SOC_POWERDN:
/*
* sc7entry-fw must be present in the system when the bpmp
* firmware is not present, for a successful System Suspend
* entry.
*/
if (!tegra_bpmp_init() && !plat_params->sc7entry_fw_base)
return PSCI_E_NOT_SUPPORTED;
/*
* System powerdown request only for afflvl 2
*/
@ -83,7 +95,7 @@ int32_t tegra_soc_validate_power_state(unsigned int power_state,
/*******************************************************************************
* Platform handler to calculate the proper target power level at the
* specified affinity level
* specified affinity level.
******************************************************************************/
plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl,
const plat_local_state_t *states,
@ -92,7 +104,7 @@ plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl,
plat_local_state_t target = PSCI_LOCAL_STATE_RUN;
int cpu = plat_my_core_pos();
int core_pos = read_mpidr() & MPIDR_CPU_MASK;
uint32_t bpmp_reply, data[3];
uint32_t bpmp_reply, data[3], val;
int ret;
/* get the power state at this level */
@ -107,40 +119,44 @@ plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl,
ret = tegra_bpmp_init();
if (ret != 0U) {
/*
* flag to indicate that BPMP firmware is not
* available and the CPU has to handle entry/exit
* for all power states
*/
tegra_bpmp_available = false;
/* Cluster idle not allowed */
target = PSCI_LOCAL_STATE_RUN;
} else {
/* Cluster idle */
data[0] = (uint32_t)cpu;
data[1] = TEGRA_PM_CC6;
data[2] = TEGRA_PM_SC1;
ret = tegra_bpmp_send_receive_atomic(MRQ_DO_IDLE,
(void *)&data, (int)sizeof(data),
(void *)&bpmp_reply,
(int)sizeof(bpmp_reply));
/*******************************************
* BPMP is not present, so handle CC6 entry
* from the CPU
******************************************/
/* check if cluster idle entry is allowed */
if ((ret != 0L) || (bpmp_reply != BPMP_CCx_ALLOWED)) {
/* check if cluster idle state has been enabled */
val = mmio_read_32(TEGRA_CL_DVFS_BASE + DVFS_DFLL_CTRL);
if (val == ENABLE_CLOSED_LOOP) {
/*
* Acquire the cluster idle lock to stop
* other CPUs from powering up.
*/
tegra_fc_ccplex_pgexit_lock();
/* Cluster idle not allowed */
target = PSCI_LOCAL_STATE_RUN;
/* Cluster idle only from the last standing CPU */
if (tegra_pmc_is_last_on_cpu() && tegra_fc_is_ccx_allowed()) {
/* Cluster idle allowed */
target = PSTATE_ID_CLUSTER_IDLE;
} else {
/* release cluster idle lock */
tegra_fc_ccplex_pgexit_unlock();
}
}
}
} else if ((lvl == MPIDR_AFFLVL1) && (target == PSTATE_ID_CLUSTER_POWERDN)) {
/* initialize the bpmp interface */
ret = tegra_bpmp_init();
if (ret != 0U) {
/* Cluster power down not allowed */
target = PSCI_LOCAL_STATE_RUN;
} else {
/* Cluster power-down */
data[0] = (uint32_t)cpu;
data[1] = TEGRA_PM_CC7;
data[1] = TEGRA_PM_CC6;
data[2] = TEGRA_PM_SC1;
ret = tegra_bpmp_send_receive_atomic(MRQ_DO_IDLE,
(void *)&data, (int)sizeof(data),
@ -176,7 +192,9 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
unsigned int stateid_afflvl2 = pwr_domain_state[MPIDR_AFFLVL2];
unsigned int stateid_afflvl1 = pwr_domain_state[MPIDR_AFFLVL1];
unsigned int stateid_afflvl0 = pwr_domain_state[MPIDR_AFFLVL0];
uint32_t cfg;
int ret = PSCI_E_SUCCESS;
uint32_t val;
if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
@ -197,16 +215,43 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
assert(stateid_afflvl0 == PSTATE_ID_CORE_POWERDN);
if (!tegra_bpmp_available) {
/*
* When disabled, DFLL loses its state. Enable
* open loop state for the DFLL as we dont want
* garbage values being written to the pmic
* when we enter cluster idle state.
*/
mmio_write_32(TEGRA_CL_DVFS_BASE + DVFS_DFLL_CTRL,
ENABLE_OPEN_LOOP);
/* Find if the platform uses OVR2/MAX77621 PMIC */
cfg = mmio_read_32(TEGRA_CL_DVFS_BASE + DVFS_DFLL_OUTPUT_CFG);
if (cfg & DFLL_OUTPUT_CFG_CLK_EN_BIT) {
/* OVR2 */
/* PWM tristate */
val = mmio_read_32(TEGRA_MISC_BASE + PINMUX_AUX_DVFS_PWM);
val |= PINMUX_PWM_TRISTATE;
mmio_write_32(TEGRA_MISC_BASE + PINMUX_AUX_DVFS_PWM, val);
/*
* SCRATCH201[1] is being used to identify CPU
* PMIC in warmboot code.
* 0 : OVR2
* 1 : MAX77621
*/
tegra_pmc_write_32(PMC_SCRATCH201, 0x0);
} else {
/* MAX77621 */
tegra_pmc_write_32(PMC_SCRATCH201, 0x2);
}
}
/* Prepare for cluster idle */
tegra_fc_cluster_idle(mpidr);
} else if (stateid_afflvl1 == PSTATE_ID_CLUSTER_POWERDN) {
assert(stateid_afflvl0 == PSTATE_ID_CORE_POWERDN);
/* Prepare for cluster powerdn */
tegra_fc_cluster_powerdn(mpidr);
} else if (stateid_afflvl0 == PSTATE_ID_CORE_POWERDN) {
/* Prepare for cpu powerdn */
@ -221,12 +266,82 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
return ret;
}
static void tegra_reset_all_dma_masters(void)
{
uint32_t val, mask;
/*
* Reset all possible DMA masters in the system.
*/
val = GPU_RESET_BIT;
mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_GPU_RESET_REG_OFFSET, val);
val = NVENC_RESET_BIT | TSECB_RESET_BIT | APE_RESET_BIT |
NVJPG_RESET_BIT | NVDEC_RESET_BIT;
mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_Y, val);
val = HOST1X_RESET_BIT | ISP_RESET_BIT | USBD_RESET_BIT |
VI_RESET_BIT | SDMMC4_RESET_BIT | SDMMC1_RESET_BIT |
SDMMC2_RESET_BIT;
mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_L, val);
val = USB2_RESET_BIT | APBDMA_RESET_BIT | AHBDMA_RESET_BIT;
mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_H, val);
val = XUSB_DEV_RESET_BIT | XUSB_HOST_RESET_BIT | TSEC_RESET_BIT |
PCIE_RESET_BIT | SDMMC3_RESET_BIT;
mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_U, val);
val = SE_RESET_BIT | HDA_RESET_BIT | SATA_RESET_BIT;
mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_V, val);
/*
* If any of the DMA masters are still alive, assume
* that the system has been compromised and reboot.
*/
val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_GPU_RESET_REG_OFFSET);
mask = GPU_RESET_BIT;
if ((val & mask) != mask)
tegra_pmc_system_reset();
mask = NVENC_RESET_BIT | TSECB_RESET_BIT | APE_RESET_BIT |
NVJPG_RESET_BIT | NVDEC_RESET_BIT;
val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_Y);
if ((val & mask) != mask)
tegra_pmc_system_reset();
mask = HOST1X_RESET_BIT | ISP_RESET_BIT | USBD_RESET_BIT |
VI_RESET_BIT | SDMMC4_RESET_BIT | SDMMC1_RESET_BIT |
SDMMC2_RESET_BIT;
val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_L);
if ((val & mask) != mask)
tegra_pmc_system_reset();
mask = USB2_RESET_BIT | APBDMA_RESET_BIT | AHBDMA_RESET_BIT;
val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_H);
if ((val & mask) != mask)
tegra_pmc_system_reset();
mask = XUSB_DEV_RESET_BIT | XUSB_HOST_RESET_BIT | TSEC_RESET_BIT |
PCIE_RESET_BIT | SDMMC3_RESET_BIT;
val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_U);
if ((val & mask) != mask)
tegra_pmc_system_reset();
val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_V);
mask = SE_RESET_BIT | HDA_RESET_BIT | SATA_RESET_BIT;
if ((val & mask) != mask)
tegra_pmc_system_reset();
}
int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
{
u_register_t mpidr = read_mpidr();
const plat_local_state_t *pwr_domain_state =
target_state->pwr_domain_state;
unsigned int stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL];
const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
uint32_t val;
if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
@ -235,6 +350,61 @@ int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
tegra_se_save_tzram();
}
/* de-init the interface */
tegra_bpmp_suspend();
/*
* The CPU needs to load the System suspend entry firmware
* if nothing is running on the BPMP.
*/
if (!tegra_bpmp_available) {
/*
* BPMP firmware is not running on the co-processor, so
* we need to explicitly load the firmware to enable
* entry/exit to/from System Suspend and set the BPMP
* on its way.
*/
/* Power off BPMP before we proceed */
tegra_fc_bpmp_off();
/* bond out IRAM banks B, C and D */
mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_BOND_OUT_U,
IRAM_B_LOCK_BIT | IRAM_C_LOCK_BIT |
IRAM_D_LOCK_BIT);
/* bond out APB/AHB DMAs */
mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_BOND_OUT_H,
APB_DMA_LOCK_BIT | AHB_DMA_LOCK_BIT);
/* Power off BPMP before we proceed */
tegra_fc_bpmp_off();
/*
* Reset all the hardware blocks that can act as DMA
* masters on the bus.
*/
tegra_reset_all_dma_masters();
/* clean up IRAM of any cruft */
zeromem((void *)(uintptr_t)TEGRA_IRAM_BASE,
TEGRA_IRAM_A_SIZE);
/* Copy the firmware to BPMP's internal RAM */
(void)memcpy((void *)(uintptr_t)TEGRA_IRAM_BASE,
(const void *)(plat_params->sc7entry_fw_base + SC7ENTRY_FW_HEADER_SIZE_BYTES),
plat_params->sc7entry_fw_size - SC7ENTRY_FW_HEADER_SIZE_BYTES);
/* Power on the BPMP and execute from IRAM base */
tegra_fc_bpmp_on(TEGRA_IRAM_BASE);
/* Wait until BPMP powers up */
do {
val = mmio_read_32(TEGRA_RES_SEMA_BASE + STA_OFFSET);
} while (val != SIGN_OF_LIFE);
}
/* enter system suspend */
tegra_fc_soc_powerdn(mpidr);
}
@ -245,7 +415,9 @@ int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
uint32_t val;
uint32_t cfg;
uint32_t val, entrypoint = 0;
uint64_t offset;
/* platform parameter passed by the previous bootloader */
if (plat_params->l2_ecc_parity_prot_dis != 1) {
@ -284,9 +456,61 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
/*
* Restore Boot and Power Management Processor (BPMP) reset
* address and reset it.
* address and reset it, if it is supported by the platform.
*/
tegra_fc_reset_bpmp();
if (!tegra_bpmp_available) {
tegra_fc_bpmp_off();
} else {
entrypoint = tegra_pmc_read_32(PMC_SCRATCH39);
tegra_fc_bpmp_on(entrypoint);
/* initialise the interface */
tegra_bpmp_resume();
}
/* sc7entry-fw is part of TZDRAM area */
if (plat_params->sc7entry_fw_base != 0U) {
offset = plat_params->tzdram_base - plat_params->sc7entry_fw_base;
tegra_memctrl_tzdram_setup(plat_params->sc7entry_fw_base,
plat_params->tzdram_size + offset);
/* restrict PMC access to secure world */
val = mmio_read_32(TEGRA_MISC_BASE + APB_SLAVE_SECURITY_ENABLE);
val |= PMC_SECURITY_EN_BIT;
mmio_write_32(TEGRA_MISC_BASE + APB_SLAVE_SECURITY_ENABLE, val);
}
}
/*
* Check if we are exiting cluster idle state
*/
if (target_state->pwr_domain_state[MPIDR_AFFLVL1] ==
PSTATE_ID_CLUSTER_IDLE) {
if (!tegra_bpmp_available) {
/* PWM un-tristate */
cfg = mmio_read_32(TEGRA_CL_DVFS_BASE + DVFS_DFLL_OUTPUT_CFG);
if (cfg & DFLL_OUTPUT_CFG_CLK_EN_BIT) {
val = mmio_read_32(TEGRA_MISC_BASE + PINMUX_AUX_DVFS_PWM);
val &= ~PINMUX_PWM_TRISTATE;
mmio_write_32(TEGRA_MISC_BASE + PINMUX_AUX_DVFS_PWM, val);
/* make sure the setting took effect */
val = mmio_read_32(TEGRA_MISC_BASE + PINMUX_AUX_DVFS_PWM);
assert((val & PINMUX_PWM_TRISTATE) == 0U);
}
/*
* Restore operation mode for the DFLL ring
* oscillator
*/
mmio_write_32(TEGRA_CL_DVFS_BASE + DVFS_DFLL_CTRL,
ENABLE_CLOSED_LOOP);
/* release cluster idle lock */
tegra_fc_ccplex_pgexit_unlock();
}
}
/*
@ -296,6 +520,12 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
*/
tegra_fc_lock_active_cluster();
/*
* Resume PMC hardware block for Tegra210 platforms supporting sc7entry-fw
*/
if (!tegra_chipid_is_t210_b01() && (plat_params->sc7entry_fw_base != 0U))
tegra_pmc_resume();
return PSCI_E_SUCCESS;
}

View File

@ -1,15 +1,24 @@
/*
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <bpmp.h>
#include <assert.h>
#include <cortex_a57.h>
#include <common/bl_common.h>
#include <common/debug.h>
#include <common/interrupt_props.h>
#include <drivers/console.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <drivers/arm/gic_common.h>
#include <drivers/arm/gicv2.h>
#include <bl31/interrupt_mgmt.h>
#include <bpmp.h>
#include <flowctrl.h>
#include <memctrl.h>
#include <platform.h>
#include <security_engine.h>
#include <tegra_def.h>
@ -137,10 +146,76 @@ void plat_early_platform_setup(void)
}
}
/* Secure IRQs for Tegra186 */
static const interrupt_prop_t tegra210_interrupt_props[] = {
INTR_PROP_DESC(TEGRA210_WDT_CPU_LEGACY_FIQ, GIC_HIGHEST_SEC_PRIORITY,
GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
};
void plat_late_platform_setup(void)
{
const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
uint64_t sc7entry_end, offset;
int ret;
uint32_t val;
/* memmap TZDRAM area containing the SC7 Entry Firmware */
if (plat_params->sc7entry_fw_base && plat_params->sc7entry_fw_size) {
assert(plat_params->sc7entry_fw_size <= TEGRA_IRAM_A_SIZE);
/*
* Verify that the SC7 entry firmware resides inside the TZDRAM
* aperture, _before_ the BL31 code and the start address is
* exactly 1MB from BL31 base.
*/
/* sc7entry-fw must be _before_ BL31 base */
assert(plat_params->tzdram_base > plat_params->sc7entry_fw_base);
sc7entry_end = plat_params->sc7entry_fw_base +
plat_params->sc7entry_fw_size;
assert(sc7entry_end < plat_params->tzdram_base);
/* sc7entry-fw start must be exactly 1MB behind BL31 base */
offset = plat_params->tzdram_base - plat_params->sc7entry_fw_base;
assert(offset == 0x100000);
/* secure TZDRAM area */
tegra_memctrl_tzdram_setup(plat_params->sc7entry_fw_base,
plat_params->tzdram_size + offset);
/* power off BPMP processor until SC7 entry */
tegra_fc_bpmp_off();
/* memmap SC7 entry firmware code */
ret = mmap_add_dynamic_region(plat_params->sc7entry_fw_base,
plat_params->sc7entry_fw_base,
plat_params->sc7entry_fw_size,
MT_SECURE | MT_RO_DATA);
assert(ret == 0);
/* restrict PMC access to secure world */
val = mmio_read_32(TEGRA_MISC_BASE + APB_SLAVE_SECURITY_ENABLE);
val |= PMC_SECURITY_EN_BIT;
mmio_write_32(TEGRA_MISC_BASE + APB_SLAVE_SECURITY_ENABLE, val);
}
}
/*******************************************************************************
* Initialize the GIC and SGIs
******************************************************************************/
void plat_gic_setup(void)
{
tegra_gic_setup(NULL, 0);
tegra_gic_setup(tegra210_interrupt_props, ARRAY_SIZE(tegra210_interrupt_props));
tegra_gic_init();
/* Enable handling for FIQs */
tegra_fiq_handler_setup();
/*
* Enable routing watchdog FIQs from the flow controller to
* the GICD.
*/
tegra_fc_enable_fiq_to_ccplex_routing();
}

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <arch_helpers.h>
#include <assert.h>
#include <common/bl_common.h>
#include <common/debug.h>
#include <common/runtime_svc.h>
#include <errno.h>
#include <mmio.h>
#include <utils_def.h>
#include <memctrl.h>
#include <pmc.h>
#include <tegra_private.h>
#include <tegra_platform.h>
#include <tegra_def.h>
/*******************************************************************************
* PMC parameters
******************************************************************************/
#define PMC_READ U(0xaa)
#define PMC_WRITE U(0xbb)
/*******************************************************************************
* Tegra210 SiP SMCs
******************************************************************************/
#define TEGRA_SIP_PMC_COMMANDS U(0xC2FFFE00)
/*******************************************************************************
* This function is responsible for handling all T210 SiP calls
******************************************************************************/
int plat_sip_handler(uint32_t smc_fid,
uint64_t x1,
uint64_t x2,
uint64_t x3,
uint64_t x4,
const void *cookie,
void *handle,
uint64_t flags)
{
uint32_t val, ns;
/* 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_PMC_COMMANDS:
/* check the address is within PMC range and is 4byte aligned */
if ((x2 >= TEGRA_PMC_SIZE) || (x2 & 0x3))
return -EINVAL;
/* pmc_secure_scratch registers are not accessible */
if (((x2 >= PMC_SECURE_SCRATCH0) && (x2 <= PMC_SECURE_SCRATCH5)) ||
((x2 >= PMC_SECURE_SCRATCH6) && (x2 <= PMC_SECURE_SCRATCH7)) ||
((x2 >= PMC_SECURE_SCRATCH8) && (x2 <= PMC_SECURE_SCRATCH79)) ||
((x2 >= PMC_SECURE_SCRATCH80) && (x2 <= PMC_SECURE_SCRATCH119)))
return -EFAULT;
/* PMC secure-only registers are not accessible */
if ((x2 == PMC_DPD_ENABLE_0) || (x2 == PMC_FUSE_CONTROL_0) ||
(x2 == PMC_CRYPTO_OP_0))
return -EFAULT;
/* Perform PMC read/write */
if (x1 == PMC_READ) {
val = mmio_read_32((uint32_t)(TEGRA_PMC_BASE + x2));
write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X1, val);
} else if (x1 == PMC_WRITE) {
mmio_write_32((uint32_t)(TEGRA_PMC_BASE + x2), (uint32_t)x3);
} else {
return -EINVAL;
}
break;
default:
ERROR("%s: unsupported function ID\n", __func__);
return -ENOTSUP;
}
return 0;
}

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@ -19,9 +19,12 @@ $(eval $(call add_define,PLATFORM_MAX_CPUS_PER_CLUSTER))
MAX_XLAT_TABLES := 10
$(eval $(call add_define,MAX_XLAT_TABLES))
MAX_MMAP_REGIONS := 15
MAX_MMAP_REGIONS := 16
$(eval $(call add_define,MAX_MMAP_REGIONS))
ENABLE_WDT_LEGACY_FIQ_HANDLING := 1
$(eval $(call add_define,ENABLE_WDT_LEGACY_FIQ_HANDLING))
PLAT_INCLUDES += -I${SOC_DIR}/drivers/se
BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \
@ -33,7 +36,8 @@ BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \
${SOC_DIR}/plat_psci_handlers.c \
${SOC_DIR}/plat_setup.c \
${SOC_DIR}/drivers/se/security_engine.c \
${SOC_DIR}/plat_secondary.c
${SOC_DIR}/plat_secondary.c \
${SOC_DIR}/plat_sip_calls.c
# Enable workarounds for selected Cortex-A57 erratas.
A57_DISABLE_NON_TEMPORAL_HINT := 1
@ -48,3 +52,6 @@ A53_DISABLE_NON_TEMPORAL_HINT := 1
ERRATA_A53_826319 := 1
ERRATA_A53_836870 := 1
ERRATA_A53_855873 := 1
# Skip L1 $ flush when powering down Cortex-A57 CPUs
SKIP_A57_L1_FLUSH_PWR_DWN := 1

View File

@ -126,7 +126,6 @@ uint64_t tlkd_synchronous_sp_entry(tlk_context_t *tlk_ctx)
/* Passing a NULL context is a critical programming error */
assert(tlk_ctx);
assert(tlk_ctx->c_rt_ctx == 0);
/* Apply the Secure EL1 system register context and switch to it */
assert(cm_get_context(SECURE) == &tlk_ctx->cpu_ctx);

View File

@ -195,14 +195,18 @@ static uintptr_t tlkd_smc_handler(uint32_t smc_fid,
* b. register shared memory with the SP for passing args
* required for maintaining sessions with the Trusted
* Applications.
* c. register non-secure world's memory map with the OS
* d. open/close sessions
* e. issue commands to the Trusted Apps
* f. resume the preempted yielding SMC call.
* c. register shared persistent buffers for secure storage
* d. register NS DRAM ranges passed by Cboot
* e. register Root of Trust parameters from Cboot for Verified Boot
* f. open/close sessions
* g. issue commands to the Trusted Apps
* h. resume the preempted yielding SMC call.
*/
case TLK_REGISTER_LOGBUF:
case TLK_REGISTER_REQBUF:
case TLK_REGISTER_NS_DRAM:
case TLK_SS_REGISTER_HANDLER:
case TLK_REGISTER_NS_DRAM_RANGES:
case TLK_SET_ROOT_OF_TRUST:
case TLK_OPEN_TA_SESSION:
case TLK_CLOSE_TA_SESSION:
case TLK_TA_LAUNCH_OP:
@ -400,6 +404,7 @@ static uintptr_t tlkd_smc_handler(uint32_t smc_fid,
SMC_RET2(handle, TLK_VERSION_MAJOR, TLK_VERSION_MINOR);
default:
WARN("%s: Unhandled SMC: 0x%x\n", __func__, smc_fid);
break;
}

View File

@ -7,6 +7,7 @@
#include <assert.h>
#include <stdbool.h>
#include <string.h>
#include <xlat_tables_v2.h>
#include <arch_helpers.h>
#include <bl31/bl31.h>
@ -352,32 +353,32 @@ static void trusty_cpu_resume(uint32_t on)
}
}
static int32_t trusty_cpu_off_handler(u_register_t unused)
static int32_t trusty_cpu_off_handler(u_register_t max_off_lvl)
{
trusty_cpu_suspend(1);
trusty_cpu_suspend(max_off_lvl);
return 0;
}
static void trusty_cpu_on_finish_handler(u_register_t unused)
static void trusty_cpu_on_finish_handler(u_register_t max_off_lvl)
{
struct trusty_cpu_ctx *ctx = get_trusty_ctx();
if (ctx->saved_sp == NULL) {
(void)trusty_init();
} else {
trusty_cpu_resume(1);
trusty_cpu_resume(max_off_lvl);
}
}
static void trusty_cpu_suspend_handler(u_register_t unused)
static void trusty_cpu_suspend_handler(u_register_t max_off_lvl)
{
trusty_cpu_suspend(0);
trusty_cpu_suspend(max_off_lvl);
}
static void trusty_cpu_suspend_finish_handler(u_register_t unused)
static void trusty_cpu_suspend_finish_handler(u_register_t max_off_lvl)
{
trusty_cpu_resume(0);
trusty_cpu_resume(max_off_lvl);
}
static const spd_pm_ops_t trusty_pm = {
@ -412,6 +413,14 @@ static int32_t trusty_setup(void)
return -1;
}
/* memmap first page of trusty's code memory before peeking */
ret = mmap_add_dynamic_region(ep_info->pc, /* PA */
ep_info->pc, /* VA */
PAGE_SIZE, /* size */
MT_SECURE | MT_RW_DATA); /* attrs */
assert(ret == 0);
/* peek into trusty's code to see if we have a 32-bit or 64-bit image */
instr = *(uint32_t *)ep_info->pc;
if (instr >> 24 == 0xeaU) {
@ -424,6 +433,9 @@ static int32_t trusty_setup(void)
return -1;
}
/* unmap trusty's memory page */
(void)mmap_remove_dynamic_region(ep_info->pc, PAGE_SIZE);
SET_PARAM_HEAD(ep_info, PARAM_EP, VERSION_1, SECURE | EP_ST_ENABLE);
if (!aarch32)
ep_info->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX,