aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVarun Wadekar <vwadekar@nvidia.com>2020-03-12 14:32:44 -0700
committerVarun Wadekar <vwadekar@nvidia.com>2020-06-08 16:28:25 -0700
commit91535cdb88bc33845e5c0fae18cf88835dc8153c (patch)
tree07e231d96a7d4a518834be68fedf26e698a9e9b2
parent9e6f757f3df716b7a1a9ac05de130617e10316fb (diff)
downloadtf-a-tests-91535cdb88bc33845e5c0fae18cf88835dc8153c.tar.gz
plat: nvidia: introduce platform port for Tegra194
This patch contains the basic platform support for Tegra194 platforms to initialize the tftf framework and execute tests on the CPUs. The tests require support for a timer, non-volatile memory, UART and GIC. This port uses Tegra_TMR0 as the timer, TI UART 16550 as the console and DRAM as NVM. The GIC driver provided by ARM is used as is. Signed-off-by: Varun Wadekar <vwadekar@nvidia.com> Change-Id: I2da2121cb05445f47b7d3083cdd6ac6d52586797
-rw-r--r--plat/nvidia/drivers/spe/shared_console.S183
-rw-r--r--plat/nvidia/tegra194/helpers.S81
-rw-r--r--plat/nvidia/tegra194/include/platform_def.h150
-rw-r--r--plat/nvidia/tegra194/platform.mk28
-rw-r--r--plat/nvidia/tegra194/pwr_state.c77
-rw-r--r--plat/nvidia/tegra194/setup.c65
-rw-r--r--plat/nvidia/tegra194/tests.xml19
-rw-r--r--plat/nvidia/tegra194/tests_to_skip.txt6
-rw-r--r--plat/nvidia/tegra194/timers.c175
-rw-r--r--plat/nvidia/tegra194/topology.c60
10 files changed, 844 insertions, 0 deletions
diff --git a/plat/nvidia/drivers/spe/shared_console.S b/plat/nvidia/drivers/spe/shared_console.S
new file mode 100644
index 0000000..a8584ef
--- /dev/null
+++ b/plat/nvidia/drivers/spe/shared_console.S
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <drivers/console.h>
+
+#define CONSOLE_NUM_BYTES_SHIFT 24
+#define CONSOLE_FLUSH_DATA_TO_PORT (1 << 26)
+#define CONSOLE_RING_DOORBELL (1 << 31)
+#define CONSOLE_IS_BUSY (1 << 31)
+#define CONSOLE_TIMEOUT 0xC000 /* 50 ms */
+
+ /*
+ * This file contains a driver implementation to make use of the
+ * real console implementation provided by the SPE firmware running
+ * SoCs after Tegra186.
+ *
+ * This console is shared by multiple components and the SPE firmware
+ * finally displays everything on the UART port.
+ */
+
+ .globl console_init
+ .globl console_putc
+ .globl console_getc
+ .globl console_try_getc
+ .globl console_flush
+
+.macro check_if_console_is_ready base, tmp1, tmp2, label
+ /* wait until spe is ready or timeout expires */
+1: ldr \tmp1, [\base]
+ and \tmp1, \tmp1, #CONSOLE_IS_BUSY
+ cbnz \tmp1, 1b
+.endm
+
+ /*
+ * The console base is in the data section and not in .bss
+ * even though it is zero-init. In particular, this allows
+ * the console functions to start using this variable before
+ * the runtime memory is initialized for images which do not
+ * need to copy the .data section from ROM to RAM.
+ */
+ .section .data.console_base
+ .align 3
+console_base:
+ .quad 0x0
+
+ /* -----------------------------------------------
+ * int console_init(uintptr_t base_addr,
+ * unsigned int uart_clk,
+ * unsigned int baud_rate)
+ *
+ * Clobber list : x1 - x3
+ * -----------------------------------------------
+ */
+func console_init
+ /* Check the input base address */
+ cbz x0, register_fail
+
+ /* save base address */
+ adr x3, console_base
+ str x0, [x3]
+
+ /* Dont use clock or baud rate, so ok to overwrite them */
+ check_if_console_is_ready x0, x1, x2, register_fail
+
+register_fail:
+ mov w0, wzr
+ ret
+endfunc console_init
+
+ /* --------------------------------------------------------
+ * int console_spe_core_putc(int c, uintptr_t base_addr)
+ * Function to output a character over the console. It
+ * returns the character printed on success or -1 on error.
+ * In : w0 - character to be printed
+ * x1 - console base address
+ * Out : return -1 on error else return character.
+ * Clobber list : x2, x3
+ * --------------------------------------------------------
+ */
+func console_spe_core_putc
+ /* Check the input parameter */
+ cbz x1, putc_error
+
+ /* Prepend '\r' to '\n' */
+ cmp w0, #0xA
+ b.ne not_eol
+
+ check_if_console_is_ready x1, x2, x3, putc_error
+
+ /* spe is ready */
+ mov w2, #0xD /* '\r' */
+ and w2, w2, #0xFF
+ mov w3, #(CONSOLE_RING_DOORBELL | (1 << CONSOLE_NUM_BYTES_SHIFT))
+ orr w2, w2, w3
+ str w2, [x1]
+
+not_eol:
+ check_if_console_is_ready x1, x2, x3, putc_error
+
+ /* spe is ready */
+ mov w2, w0
+ and w2, w2, #0xFF
+ mov w3, #(CONSOLE_RING_DOORBELL | (1 << CONSOLE_NUM_BYTES_SHIFT))
+ orr w2, w2, w3
+ str w2, [x1]
+
+ ret
+putc_error:
+ mov w0, #-1
+ ret
+endfunc console_spe_core_putc
+
+ /* ---------------------------------------------
+ * int console_putc(int c)
+ *
+ * Clobber list : x1, x2
+ * ---------------------------------------------
+ */
+func console_putc
+ adr x1, console_base
+ ldr x1, [x1]
+ b console_spe_core_putc
+endfunc console_putc
+
+ /* ---------------------------------------------
+ * int console_getc(void)
+ *
+ * Clobber list : x0 - x3
+ * ---------------------------------------------
+ */
+func console_getc
+ mov w0, #-1
+ ret
+endfunc console_getc
+
+ /* ---------------------------------------------
+ * int console_try_getc(void)
+ *
+ * Clobber list : x0, x1
+ * ---------------------------------------------
+ */
+func console_try_getc
+ mov w0, #-1
+ ret
+endfunc console_try_getc
+
+ /* -------------------------------------------------
+ * int console_spe_core_flush(uintptr_t base_addr)
+ * Function to force a write of all buffered
+ * data that hasn't been output.
+ * In : x0 - console base address
+ * Out : return -1 on error else return 0.
+ * Clobber list : x0, x1
+ * -------------------------------------------------
+ */
+func console_spe_core_flush
+ cbz x0, flush_error
+
+ /* flush console */
+ mov w1, #(CONSOLE_RING_DOORBELL | CONSOLE_FLUSH_DATA_TO_PORT)
+ str w1, [x0]
+ mov w0, #0
+ ret
+flush_error:
+ mov w0, #-1
+ ret
+endfunc console_spe_core_flush
+
+ /* ---------------------------------------------
+ * int console_flush(void)
+ *
+ * Clobber list : x0, x1
+ * ---------------------------------------------
+ */
+func console_flush
+ adr x0, console_base
+ ldr x0, [x0]
+ b console_spe_core_flush
+endfunc console_flush
diff --git a/plat/nvidia/tegra194/helpers.S b/plat/nvidia/tegra194/helpers.S
new file mode 100644
index 0000000..1669131
--- /dev/null
+++ b/plat/nvidia/tegra194/helpers.S
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <platform_def.h>
+
+ .globl platform_get_core_pos
+ .globl plat_crash_console_init
+ .globl plat_crash_console_putc
+ .globl plat_crash_console_flush
+
+ /*
+ * Return 0 to 3 for the Cortex-A53 cores and 4 to 5 for the Cortex-A57
+ * cores.
+ */
+func platform_get_core_pos
+ 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_CORES_PER_CLUSTER */
+ mov x0, #-1
+ cmp x1, #(PLATFORM_CORES_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_CORES_PER_CLUSTER
+ mul x3, x3, x2
+ add x0, x1, x3
+
+1:
+ ret
+endfunc platform_get_core_pos
+
+ /* ---------------------------------------------
+ * int plat_crash_console_init(void)
+ * Function to initialize the crash console
+ * without a C Runtime to print crash report.
+ * Clobber list : x0 - x4
+ * ---------------------------------------------
+ */
+func plat_crash_console_init
+ mov_imm x0, TEGRA194_UARTC_BASE
+ mov_imm x1, TEGRA194_CONSOLE_CLKRATE
+ mov_imm x2, TEGRA194_CONSOLE_BAUDRATE
+ b console_init
+endfunc plat_crash_console_init
+
+ /* ---------------------------------------------
+ * int plat_crash_console_putc(int c)
+ * Function to print a character on the crash
+ * console without a C Runtime.
+ * Clobber list : x1, x2
+ * ---------------------------------------------
+ */
+func plat_crash_console_putc
+ mov_imm x1, TEGRA194_UARTC_BASE
+ b console_putc
+endfunc plat_crash_console_putc
+
+ /* ---------------------------------------------
+ * int plat_crash_console_flush()
+ * Function to force a write of all buffered
+ * data that hasn't been output.
+ * Out : return -1 on error else return 0.
+ * Clobber list : r0 - r1
+ * ---------------------------------------------
+ */
+func plat_crash_console_flush
+ mov_imm x1, TEGRA194_UARTC_BASE
+ b console_flush
+endfunc plat_crash_console_flush
diff --git a/plat/nvidia/tegra194/include/platform_def.h b/plat/nvidia/tegra194/include/platform_def.h
new file mode 100644
index 0000000..2ad63eb
--- /dev/null
+++ b/plat/nvidia/tegra194/include/platform_def.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <utils_def.h>
+
+/*******************************************************************************
+ * Platform definitions used by common code
+ ******************************************************************************/
+
+#ifndef __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+/*******************************************************************************
+ * Platform binary types for linking
+ ******************************************************************************/
+#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH aarch64
+
+/*******************************************************************************
+ * Tegra DRAM memory base address
+ ******************************************************************************/
+#define DRAM_BASE U(0x80000000)
+#define DRAM_END U(0xB0000000)
+#define DRAM_SIZE (DRAM_END - DRAM_BASE)
+
+/*******************************************************************************
+ * Run-time address of the TFTF image.
+ * It has to match the location where the Trusted Firmware-A loads the BL33
+ * image.
+ ******************************************************************************/
+#define TFTF_BASE 0x80080000
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+
+/* Translation table constants */
+#define MAX_XLAT_TABLES 20
+#define MAX_MMAP_REGIONS 20
+
+/* stack memory available to each CPU */
+#define PLATFORM_STACK_SIZE 0x1400
+#define PCPU_DV_MEM_STACK_SIZE 0x100
+
+/* total number of system nodes implemented by the platform */
+#define PLATFORM_SYSTEM_COUNT 1
+
+/* total number of clusters implemented by the platform */
+#define PLATFORM_CLUSTER_COUNT 4
+#define PLATFORM_CORES_PER_CLUSTER 2
+
+/* total number of CPUs implemented by the platform across all clusters */
+#define PLATFORM_CORE_COUNT (PLATFORM_CORES_PER_CLUSTER * \
+ PLATFORM_CLUSTER_COUNT)
+
+/* total number of nodes in the affinity hierarchy at all affinity levels */
+#define PLATFORM_NUM_AFFS (PLATFORM_SYSTEM_COUNT + \
+ PLATFORM_CLUSTER_COUNT + \
+ PLATFORM_CORE_COUNT)
+
+/*
+ * maximum number of affinity levels in the system that the platform
+ * implements
+ */
+#define PLATFORM_MAX_AFFLVL MPIDR_AFFLVL2
+#define PLAT_MAX_PWR_LEVEL PLATFORM_MAX_AFFLVL
+
+/*
+ * Defines the maximum number of power states at a power domain level for the
+ * platform.
+ */
+#define PLAT_MAX_PWR_STATES_PER_LVL 2
+
+/*
+ * Defines the offset of the last Shared Peripheral Interrupt supported by the
+ * TF-A Tests on this platform. SPI numbers are mapped onto GIC interrupt IDs,
+ * starting from interrupt ID 32. This offset ID corresponds to the last SPI
+ * number, to which 32 must be added to get the corresponding last GIC IRQ ID.
+ */
+#define PLAT_MAX_SPI_OFFSET_ID 415
+
+/* Local state bit width for each level in the state-ID field of power state */
+#define PLAT_LOCAL_PSTATE_WIDTH 4
+
+/*
+ * We want to run without support for non-volatile memory and hence using a
+ * portion of DRAM as workaround.
+ * The TFTF binary itself is loaded at 0xA0600000 so we have plenty of free
+ * memory at the beginning of the DRAM. Let's use 256MB from the start.
+ */
+#define TFTF_NVM_OFFSET 0x0FF80000
+#define TFTF_NVM_SIZE 0x10000000
+
+/*
+ * Times (in ms) used by test code for completion of different events.
+ * Suspend entry time for debug build is high due to the time taken
+ * by the VERBOSE/INFO prints. The value considers the worst case scenario
+ * where all CPUs are going and coming out of suspend continuously.
+ */
+#define PLAT_SUSPEND_ENTRY_TIME 500
+#define PLAT_SUSPEND_ENTRY_EXIT_TIME 1000
+
+/*******************************************************************************
+ * Non-Secure Software Generated Interupts IDs
+ ******************************************************************************/
+#define IRQ_NS_SGI_0 0
+#define IRQ_NS_SGI_1 1
+#define IRQ_NS_SGI_2 2
+#define IRQ_NS_SGI_3 3
+#define IRQ_NS_SGI_4 4
+#define IRQ_NS_SGI_5 5
+#define IRQ_NS_SGI_6 6
+#define IRQ_NS_SGI_7 7
+
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 40)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 40)
+
+/*******************************************************************************
+ * Used to align variables on the biggest cache line size in the platform.
+ * This is known only to the platform as it might have a combination of
+ * integrated and external caches.
+ ******************************************************************************/
+#define CACHE_WRITEBACK_SHIFT 6
+#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
+
+/*******************************************************************************
+ * Platform console related constants
+ ******************************************************************************/
+#define TEGRA194_CONSOLE_BAUDRATE U(115200)
+#define TEGRA194_CONSOLE_CLKRATE U(408000000)
+
+/*******************************************************************************
+ * Platform MMIO devices
+ ******************************************************************************/
+#define TEGRA194_GICD_BASE U(0x03881000)
+#define TEGRA194_GICC_BASE U(0x03882000)
+#define TEGRA194_SPE_BASE U(0x0C168000)
+#define TEGRA194_UARTC_BASE U(0x0C280000)
+#define TEGRA194_RTC_BASE U(0x0C2A0000)
+#define TEGRA194_TMRUS_BASE U(0x0C2E0000)
+#define SYS_CNT_BASE1 TEGRA194_TMRUS_BASE
+
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/nvidia/tegra194/platform.mk b/plat/nvidia/tegra194/platform.mk
new file mode 100644
index 0000000..494ed1e
--- /dev/null
+++ b/plat/nvidia/tegra194/platform.mk
@@ -0,0 +1,28 @@
+#
+# Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+PLAT_INCLUDES := -Iplat/nvidia/tegra194/include/
+
+PLAT_SOURCES := drivers/arm/gic/arm_gic_v2.c \
+ drivers/arm/gic/gic_common.c \
+ drivers/arm/gic/gic_v2.c \
+ drivers/arm/timer/private_timer.c \
+ drivers/ti/uart/aarch64/16550_console.S \
+ plat/nvidia/tegra194/helpers.S \
+ plat/nvidia/tegra194/pwr_state.c \
+ plat/nvidia/tegra194/topology.c \
+ plat/nvidia/tegra194/timers.c \
+ plat/nvidia/tegra194/setup.c
+
+PLAT_TESTS_SKIP_LIST := plat/nvidia/tegra194/tests_to_skip.txt
+
+TFTF_CFLAGS += -Wno-maybe-uninitialized
+
+ENABLE_ASSERTIONS := 1
+
+ifeq ($(USE_NVM),1)
+$(error "Tegra194 port of TFTF doesn't currently support USE_NVM=1")
+endif
diff --git a/plat/nvidia/tegra194/pwr_state.c b/plat/nvidia/tegra194/pwr_state.c
new file mode 100644
index 0000000..269b5d4
--- /dev/null
+++ b/plat/nvidia/tegra194/pwr_state.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <stddef.h>
+
+#include <platform.h>
+#include <psci.h>
+#include <utils_def.h>
+
+/*
+ * State IDs for local power states
+ */
+#define TEGRA194_RUN_STATE_ID U(0) /* Valid for CPUs and Clusters */
+#define TEGRA194_CORE_RETN_STATE_ID U(6) /* Valid for only CPUs */
+#define TEGRA194_CORE_OFF_STATE_ID U(7) /* Valid for CPUs and Clusters */
+#define TEGRA194_SOC_OFF_STATE_ID U(2) /* Valid for the System */
+
+/*
+ * Suspend depth definitions for each power state
+ */
+typedef enum {
+ TEGRA194_RUN_DEPTH = 0,
+ TEGRA194_CORE_RETENTION_DEPTH,
+ TEGRA194_CORE_OFF_DEPTH,
+ TEGRA194_SYSTEM_OFF_DEPTH,
+} suspend_depth_t;
+
+/* The state property array with details of idle state possible for the core */
+static const plat_state_prop_t core_state_prop[] = {
+ {TEGRA194_CORE_RETENTION_DEPTH, TEGRA194_CORE_RETN_STATE_ID, PSTATE_TYPE_STANDBY},
+ {0},
+};
+
+/*
+ * The state property array with details of idle state possible
+ * for the cluster
+ */
+static const plat_state_prop_t cluster_state_prop[] = {
+ {TEGRA194_CORE_OFF_DEPTH, TEGRA194_CORE_RETN_STATE_ID, PSTATE_TYPE_STANDBY},
+ {0},
+};
+
+/*
+ * The state property array with details of idle state possible
+ * for the system. Currently Tegra194 does not support CPU SUSPEND
+ * at system power level.
+ */
+static const plat_state_prop_t system_state_prop[] = {
+ {TEGRA194_SYSTEM_OFF_DEPTH, TEGRA194_SOC_OFF_STATE_ID, PSTATE_TYPE_POWERDOWN},
+ {0},
+};
+
+/*
+ * This functions returns the plat_state_prop_t array for all the valid low
+ * power states from platform for a specified affinity level and returns NULL
+ * for an invalid affinity level. The array is expected to be NULL-terminated.
+ * This function is expected to be used by tests that need to compose the power
+ * state parameter for use in PSCI_CPU_SUSPEND API or PSCI_STAT/RESIDENCY
+ * API.
+ */
+const plat_state_prop_t *plat_get_state_prop(unsigned int level)
+{
+ switch (level) {
+ case MPIDR_AFFLVL0:
+ return core_state_prop;
+ case MPIDR_AFFLVL1:
+ return cluster_state_prop;
+ case MPIDR_AFFLVL2:
+ return system_state_prop;
+ default:
+ return NULL;
+ }
+}
diff --git a/plat/nvidia/tegra194/setup.c b/plat/nvidia/tegra194/setup.c
new file mode 100644
index 0000000..818caa6
--- /dev/null
+++ b/plat/nvidia/tegra194/setup.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <drivers/console.h>
+#include <drivers/arm/gic_common.h>
+#include <drivers/arm/gic_v2.h>
+#include <platform.h>
+#include <platform_def.h>
+
+#include <xlat_tables_v2.h>
+
+/*
+ * The memory map currently provides the following apertures
+ *
+ * GIC Distributor : 4KB
+ * GIC CPU Interface : 4KB
+ * UARTC for the console : 128KB
+ * RTC : 4KB
+ * us Timer : 4KB
+ * DRAM aperture for NVM : 256MB
+ */
+static const mmap_region_t tegra194_mmap[] = {
+ MAP_REGION_FLAT(TEGRA194_GICD_BASE, 0x1000, /* 4KB */
+ MT_DEVICE | MT_RW | MT_NS),
+ MAP_REGION_FLAT(TEGRA194_GICC_BASE, 0x1000, /* 4KB */
+ MT_DEVICE | MT_RW | MT_NS),
+ MAP_REGION_FLAT(TEGRA194_UARTC_BASE, 0x20000U, /* 128KB */
+ MT_DEVICE | MT_RW | MT_NS),
+ MAP_REGION_FLAT(TEGRA194_RTC_BASE, 0x1000, /* 4KB */
+ MT_DEVICE | MT_RW | MT_NS),
+ MAP_REGION_FLAT(TEGRA194_TMRUS_BASE, 0x1000, /* 4KB */
+ MT_DEVICE | MT_RW | MT_NS),
+ MAP_REGION_FLAT(DRAM_BASE + TFTF_NVM_OFFSET, TFTF_NVM_SIZE,
+ MT_MEMORY | MT_RW | MT_NS),
+ {0}
+};
+
+const mmap_region_t *tftf_platform_get_mmap(void)
+{
+ return tegra194_mmap;
+}
+
+void tftf_plat_arch_setup(void)
+{
+ tftf_plat_configure_mmu();
+}
+
+void tftf_early_platform_setup(void)
+{
+ /* Tegra194 platforms use UARTC as the console */
+ console_init(TEGRA194_UARTC_BASE, TEGRA194_CONSOLE_CLKRATE,
+ TEGRA194_CONSOLE_BAUDRATE);
+}
+
+void tftf_platform_setup(void)
+{
+ gicv2_init(TEGRA194_GICC_BASE, TEGRA194_GICD_BASE);
+ gicv2_setup_distif();
+ gicv2_probe_gic_cpu_id();
+ gicv2_setup_cpuif();
+}
diff --git a/plat/nvidia/tegra194/tests.xml b/plat/nvidia/tegra194/tests.xml
new file mode 100644
index 0000000..03153f3
--- /dev/null
+++ b/plat/nvidia/tegra194/tests.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+
+ SPDX-License-Identifier: BSD-3-Clause
+-->
+
+
+<!-- External references to all individual tests files. -->
+<!DOCTYPE testsuites [
+ <!ENTITY tests-tftf-validation SYSTEM "../../../tftf/tests/tests-tftf-validation.xml">
+]>
+
+<testsuites>
+
+ &tests-tftf-validation;
+
+</testsuites>
diff --git a/plat/nvidia/tegra194/tests_to_skip.txt b/plat/nvidia/tegra194/tests_to_skip.txt
new file mode 100644
index 0000000..9636021
--- /dev/null
+++ b/plat/nvidia/tegra194/tests_to_skip.txt
@@ -0,0 +1,6 @@
+#
+# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
diff --git a/plat/nvidia/tegra194/timers.c b/plat/nvidia/tegra194/timers.c
new file mode 100644
index 0000000..98bd63b
--- /dev/null
+++ b/plat/nvidia/tegra194/timers.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stddef.h>
+
+#include <mmio.h>
+#include <platform.h>
+#include <timer.h>
+#include <tftf_lib.h>
+#include <utils_def.h>
+
+/* timer granularity in ms */
+#define TEGRA194_RTC_STEP_VALUE_MS U(2)
+
+/* IRQ value for Tegra194 Timer0 */
+#define TEGRA194_RTC_IRQ U(42)
+
+/* set to 1 = busy every eight 32kHz clocks during copy of sec+msec to AHB */
+#define TEGRA194_RTC_REG_BUSY U(0x004)
+#define TEGRA194_RTC_REG_SECONDS U(0x008)
+/* when msec is read, the seconds are buffered into shadow seconds. */
+#define TEGRA194_RTC_REG_SHADOW_SECONDS U(0x00c)
+#define TEGRA194_RTC_REG_MILLI_SECONDS U(0x010)
+#define TEGRA194_RTC_REG_SECONDS_ALARM0 U(0x014)
+#define TEGRA194_RTC_REG_SECONDS_ALARM1 U(0x018)
+#define TEGRA194_RTC_REG_MILLI_SECONDS_ALARM0 U(0x01c)
+#define TEGRA194_RTC_REG_MSEC_CDN_ALARM0 U(0x024)
+#define TEGRA194_RTC_REG_INTR_MASK U(0x028)
+/* write 1 bits to clear status bits */
+#define TEGRA194_RTC_REG_INTR_STATUS U(0x02c)
+
+/*
+ * bits in the TEGRA194_RTC_REG_BUSY register
+ * bit 0: 1 = busy, 0 = idle
+ */
+#define TEGRA194_RTC_REG_BUSY_BIT BIT_32(0)
+
+/* bits in INTR_MASK and INTR_STATUS */
+#define TEGRA194_RTC_INTR_MSEC_CDN_ALARM BIT_32(4)
+#define TEGRA194_RTC_INTR_SEC_CDN_ALARM BIT_32(3)
+#define TEGRA194_RTC_INTR_MSEC_ALARM BIT_32(2)
+#define TEGRA194_RTC_INTR_SEC_ALARM1 BIT_32(1)
+#define TEGRA194_RTC_INTR_SEC_ALARM0 BIT_32(0)
+
+static bool is_rtc_busy(void)
+{
+ uint32_t reg = mmio_read_32(TEGRA194_RTC_BASE + TEGRA194_RTC_REG_BUSY) &
+ TEGRA194_RTC_REG_BUSY_BIT;
+
+ /* 1 = busy, 0 = idle */
+ return (reg == 1);
+}
+
+/*
+ * Wait for hardware to be ready for writing.
+ * This function tries to maximize the amount of time before the next update.
+ * It does this by waiting for the RTC to become busy with its periodic update,
+ * then returning once the RTC first becomes not busy.
+ * This periodic update (where the seconds and milliseconds are copied to the
+ * AHB side) occurs every eight 32kHz clocks (~250uS).
+ * The behavior of this function allows us to make some assumptions without
+ * introducing a race, because 250uS is plenty of time to write a value.
+ */
+static void wait_until_idle(void)
+{
+ uint32_t retries = 500;
+
+ /* wait until idle */
+ while (is_rtc_busy() || (retries-- > 0)) {
+ waitus(1);
+ }
+}
+
+static void timer_idle_write_32(uint32_t offset, uint32_t val)
+{
+ /* wait until the RTC is idle first */
+ wait_until_idle();
+
+ /* actual write */
+ mmio_write_32(TEGRA194_RTC_BASE + offset, val);
+
+ /* wait until RTC has processed the write */
+ wait_until_idle();
+}
+
+static uint32_t timer_idle_read_32(uint32_t offset)
+{
+ /* wait until the RTC is idle first */
+ wait_until_idle();
+
+ /* actual read */
+ return mmio_read_32(TEGRA194_RTC_BASE + offset);
+}
+
+static int cancel_timer(void)
+{
+ /* read current values to clear them */
+ (void)timer_idle_read_32(TEGRA194_RTC_REG_MILLI_SECONDS);
+ (void)timer_idle_read_32(TEGRA194_RTC_REG_SHADOW_SECONDS);
+
+ /* clear the alarm */
+ timer_idle_write_32(TEGRA194_RTC_REG_MSEC_CDN_ALARM0, 0);
+ /* clear all status values */
+ timer_idle_write_32(TEGRA194_RTC_REG_INTR_STATUS, 0xffffffff);
+ /* disable all interrupts */
+ timer_idle_write_32(TEGRA194_RTC_REG_INTR_MASK, 0);
+
+ return 0;
+}
+
+static int program_timer(unsigned long time_out_ms)
+{
+ uint32_t reg;
+
+ /* set timer value */
+ reg = BIT_32(31) | (0x0fffffff & time_out_ms);
+ timer_idle_write_32(TEGRA194_RTC_REG_MSEC_CDN_ALARM0, reg);
+
+ /* enable timer interrupt */
+ timer_idle_write_32(TEGRA194_RTC_REG_INTR_MASK, TEGRA194_RTC_INTR_MSEC_ALARM);
+
+ /* program timeout value */
+ reg = timer_idle_read_32(TEGRA194_RTC_REG_MILLI_SECONDS);
+ timer_idle_write_32(TEGRA194_RTC_REG_MILLI_SECONDS_ALARM0, reg + time_out_ms);
+
+ return 0;
+}
+
+static int handler_timer(void)
+{
+ uint32_t __unused reg, status, mask;
+
+ /* disable timer interrupt */
+ reg = timer_idle_read_32(TEGRA194_RTC_REG_INTR_MASK);
+ reg &= ~TEGRA194_RTC_INTR_MSEC_CDN_ALARM;
+ timer_idle_write_32(TEGRA194_RTC_REG_INTR_MASK, reg);
+
+ /* read current values to clear them */
+ reg = timer_idle_read_32(TEGRA194_RTC_REG_MILLI_SECONDS);
+ reg = timer_idle_read_32(TEGRA194_RTC_REG_SHADOW_SECONDS);
+
+ /* clear interrupts */
+ status = timer_idle_read_32(TEGRA194_RTC_REG_INTR_STATUS);
+ mask = timer_idle_read_32(TEGRA194_RTC_REG_INTR_MASK);
+ mask &= ~status;
+ if (status) {
+ timer_idle_write_32(TEGRA194_RTC_REG_INTR_MASK, mask);
+ timer_idle_write_32(TEGRA194_RTC_REG_INTR_STATUS, status);
+ }
+
+ return 0;
+}
+
+static const plat_timer_t tegra194_timers = {
+ .program = program_timer,
+ .cancel = cancel_timer,
+ .handler = handler_timer,
+ .timer_step_value = TEGRA194_RTC_STEP_VALUE_MS,
+ .timer_irq = TEGRA194_RTC_IRQ
+};
+
+int plat_initialise_timer_ops(const plat_timer_t **timer_ops)
+{
+ assert(timer_ops != NULL);
+ *timer_ops = &tegra194_timers;
+
+ /* clear the timers */
+ cancel_timer();
+
+ return 0;
+}
diff --git a/plat/nvidia/tegra194/topology.c b/plat/nvidia/tegra194/topology.c
new file mode 100644
index 0000000..51ac263
--- /dev/null
+++ b/plat/nvidia/tegra194/topology.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <assert.h>
+#include <stddef.h>
+
+#include <plat_topology.h>
+#include <platform_def.h>
+#include <tftf_lib.h>
+
+static const struct {
+ unsigned cluster_id;
+ unsigned cpu_id;
+} tegra194_cores[] = {
+ { 0, 0 },
+ { 0, 1 },
+ { 1, 0 },
+ { 1, 1 },
+ { 2, 0 },
+ { 2, 1 },
+ { 3, 0 },
+ { 3, 1 }
+};
+
+/*
+ * The Tegra194 power domain tree descriptor. Tegra194 implements a system
+ * power domain at the level 2. The first entry in the power domain descriptor
+ * specifies the number of power domains at the highest power level.
+ */
+static const unsigned char tegra194_power_domain_tree_desc[] = {
+ /* Number of root nodes */
+ PLATFORM_SYSTEM_COUNT,
+ /* Number of children of root node */
+ PLATFORM_CLUSTER_COUNT,
+ /* Number of children for the first cluster */
+ PLATFORM_CORES_PER_CLUSTER,
+ /* Number of children for the second cluster */
+ PLATFORM_CORES_PER_CLUSTER,
+ /* Number of children for the third cluster */
+ PLATFORM_CORES_PER_CLUSTER,
+ /* Number of children for the fourth cluster */
+ PLATFORM_CORES_PER_CLUSTER
+};
+
+const unsigned char *tftf_plat_get_pwr_domain_tree_desc(void)
+{
+ return tegra194_power_domain_tree_desc;
+}
+
+uint64_t tftf_plat_get_mpidr(unsigned int core_pos)
+{
+ assert(core_pos < PLATFORM_CORE_COUNT);
+
+ return make_mpid(tegra194_cores[core_pos].cluster_id,
+ tegra194_cores[core_pos].cpu_id);
+}