Merge pull request #1733 from vwadekar/tf2.0-tegra-downstream-rebase-1.3.19
Tegra downstream rebase 1.3.19
diff --git a/docs/plat/nvidia-tegra.rst b/docs/plat/nvidia-tegra.rst
index 56dfacf..e244c1c 100644
--- a/docs/plat/nvidia-tegra.rst
+++ b/docs/plat/nvidia-tegra.rst
@@ -80,6 +80,8 @@
uint64\_t tzdram\_base;
/* UART port ID \*/
int uart\_id;
+/* L2 ECC parity protection disable flag \*/
+int l2\_ecc\_parity\_prot\_dis;
} plat\_params\_from\_bl2\_t;
Power Management
diff --git a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
index 0476ba8..2bf9a22 100644
--- a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
+++ b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
@@ -11,6 +11,7 @@
#include <cortex_a57.h>
#include <platform_def.h>
#include <tegra_def.h>
+#include <tegra_platform.h>
#define MIDR_PN_CORTEX_A57 0xD07
@@ -45,7 +46,6 @@
.globl ns_image_entrypoint
.globl tegra_bl31_phys_base
.globl tegra_console_base
- .globl tegra_enable_l2_ecc_parity_prot
/* ---------------------
* Common CPU init code
@@ -92,20 +92,6 @@
msr actlr_el2, x0
isb
- /* -------------------------------------------------------
- * Enable L2 ECC and Parity Protection
- * -------------------------------------------------------
- */
- adr x0, tegra_enable_l2_ecc_parity_prot
- ldr x0, [x0]
- cbz x0, 1f
- mrs x0, CORTEX_A57_L2CTLR_EL1
- and x1, x0, #CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT
- cbnz x1, 1f
- orr x0, x0, #CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT
- msr CORTEX_A57_L2CTLR_EL1, x0
- isb
-
/* --------------------------------
* Enable the cycle count register
* --------------------------------
@@ -326,6 +312,23 @@
#if ERRATA_TEGRA_INVALIDATE_BTB_AT_BOOT
+ /* --------------------------------------------------------
+ * Skip the invalidate BTB workaround for Tegra210B01 SKUs.
+ * --------------------------------------------------------
+ */
+ mov x0, #TEGRA_MISC_BASE
+ add x0, x0, #HARDWARE_REVISION_OFFSET
+ ldr w1, [x0]
+ lsr w1, w1, #CHIP_ID_SHIFT
+ and w1, w1, #CHIP_ID_MASK
+ cmp w1, #TEGRA_CHIPID_TEGRA21 /* T210? */
+ b.ne 2f
+ ldr w1, [x0]
+ lsr w1, w1, #MAJOR_VERSION_SHIFT
+ and w1, w1, #MAJOR_VERSION_MASK
+ cmp w1, #0x02 /* T210 B01? */
+ b.eq 2f
+
/* -------------------------------------------------------
* Invalidate BTB along with I$ to remove any stale
* entries from the branch predictor array.
@@ -382,7 +385,7 @@
.rept 65
nop
.endr
-
+2:
/* --------------------------------------------------
* Do not insert instructions here
* --------------------------------------------------
@@ -460,10 +463,3 @@
*/
tegra_console_base:
.quad 0
-
- /* --------------------------------------------------
- * Enable L2 ECC and Parity Protection
- * --------------------------------------------------
- */
-tegra_enable_l2_ecc_parity_prot:
- .quad 0
diff --git a/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c b/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c
new file mode 100644
index 0000000..96e3667
--- /dev/null
+++ b/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bpmp.h>
+#include <common/debug.h>
+#include <delay_timer.h>
+#include <errno.h>
+#include <mmio.h>
+#include <platform.h>
+#include <stdbool.h>
+#include <string.h>
+#include <tegra_def.h>
+
+#define BPMP_TIMEOUT_10US 10
+
+static uint32_t channel_base[NR_CHANNELS];
+static uint32_t bpmp_init_state = BPMP_INIT_PENDING;
+
+static uint32_t channel_field(unsigned int ch)
+{
+ return mmio_read_32(TEGRA_RES_SEMA_BASE + STA_OFFSET) & CH_MASK(ch);
+}
+
+static bool master_free(unsigned int ch)
+{
+ return channel_field(ch) == MA_FREE(ch);
+}
+
+static bool master_acked(unsigned int ch)
+{
+ return channel_field(ch) == MA_ACKD(ch);
+}
+
+static void signal_slave(unsigned int ch)
+{
+ mmio_write_32(TEGRA_RES_SEMA_BASE + CLR_OFFSET, CH_MASK(ch));
+}
+
+static void free_master(unsigned int ch)
+{
+ mmio_write_32(TEGRA_RES_SEMA_BASE + CLR_OFFSET,
+ MA_ACKD(ch) ^ MA_FREE(ch));
+}
+
+/* should be called with local irqs disabled */
+int32_t tegra_bpmp_send_receive_atomic(int mrq, const void *ob_data, int ob_sz,
+ void *ib_data, int ib_sz)
+{
+ unsigned int ch = (unsigned int)plat_my_core_pos();
+ mb_data_t *p = (mb_data_t *)(uintptr_t)channel_base[ch];
+ int32_t ret = -ETIMEDOUT, timeout = 0;
+
+ if (bpmp_init_state == BPMP_INIT_COMPLETE) {
+
+ /* loop until BPMP is free */
+ for (timeout = 0; timeout < BPMP_TIMEOUT_10US; timeout++) {
+ if (master_free(ch) == true) {
+ break;
+ }
+
+ udelay(1);
+ }
+
+ if (timeout != BPMP_TIMEOUT_10US) {
+
+ /* generate the command struct */
+ p->code = mrq;
+ p->flags = DO_ACK;
+ (void)memcpy((void *)p->data, ob_data, (size_t)ob_sz);
+
+ /* signal command ready to the BPMP */
+ signal_slave(ch);
+ mmio_write_32(TEGRA_PRI_ICTLR_BASE + CPU_IEP_FIR_SET,
+ (1UL << INT_SHR_SEM_OUTBOX_FULL));
+
+ /* loop until the command is executed */
+ for (timeout = 0; timeout < BPMP_TIMEOUT_10US; timeout++) {
+ if (master_acked(ch) == true) {
+ break;
+ }
+
+ udelay(1);
+ }
+
+ if (timeout != BPMP_TIMEOUT_10US) {
+
+ /* get the command response */
+ (void)memcpy(ib_data, (const void *)p->data,
+ (size_t)ib_sz);
+
+ /* return error code */
+ ret = p->code;
+
+ /* free this channel */
+ free_master(ch);
+ }
+ }
+
+ } else {
+ /* return error code */
+ ret = -EINVAL;
+ }
+
+ if (timeout == BPMP_TIMEOUT_10US) {
+ ERROR("Timed out waiting for bpmp's response");
+ }
+
+ return ret;
+}
+
+int tegra_bpmp_init(void)
+{
+ uint32_t val, base;
+ unsigned int ch;
+ int ret = 0;
+
+ if (bpmp_init_state != BPMP_INIT_COMPLETE) {
+
+ /* 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");
+ ret = -ENOTSUP;
+ }
+
+ /* 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 += 4UL;
+ }
+
+ /* mark state as "initialized" */
+ if (ret == 0)
+ 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;
+}
diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
index 55b9152..de431b7 100644
--- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
+++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
@@ -87,6 +87,9 @@
* strongly ordered MSS clients. ROC needs to be single point
* of control on overriding the memory type. So, remove TSA's
* memtype override.
+ *
+ * MC clients with default SO_DEV override still enabled at TSA:
+ * AONW, BPMPW, SCEW, APEW
*/
#if ENABLE_AFI_DEVICE
mc_set_tsa_passthrough(AFIW);
@@ -106,63 +109,121 @@
mc_set_tsa_passthrough(AONDMAW);
mc_set_tsa_passthrough(SCEDMAW);
- /*
- * Change COH_PATH_OVERRIDE_SO_DEV from NO_OVERRIDE -> FORCE_COHERENT
- * for boot and strongly ordered MSS clients. This steers all sodev
- * transactions to ROC.
+ /* Parker has no IO Coherency support and need the following:
+ * Ordered MC Clients on Parker are AFI, EQOS, SATA, XUSB.
+ * ISO clients(DISP, VI, EQOS) should never snoop caches and
+ * don't need ROC/PCFIFO ordering.
+ * ISO clients(EQOS) that need ordering should use PCFIFO ordering
+ * and bypass ROC ordering by using FORCE_NON_COHERENT path.
+ * FORCE_NON_COHERENT/FORCE_COHERENT config take precedence
+ * over SMMU attributes.
+ * Force all Normal memory transactions from ISO and non-ISO to be
+ * non-coherent(bypass ROC, avoid cache snoop to avoid perf hit).
+ * Force the SO_DEV transactions from ordered ISO clients(EQOS) to
+ * non-coherent path and enable MC PCFIFO interlock for ordering.
+ * Force the SO_DEV transactions from ordered non-ISO clients (PCIe,
+ * XUSB, SATA) to coherent so that the transactions are
+ * ordered by ROC.
+ * PCFIFO ensure write ordering.
+ * Read after Write ordering is maintained/enforced by MC clients.
+ * Clients that need PCIe type write ordering must
+ * go through ROC ordering.
+ * Ordering enable for Read clients is not necessary.
+ * R5's and A9 would get necessary ordering from AXI and
+ * don't need ROC ordering enable:
+ * - MMIO ordering is through dev mapping and MMIO
+ * accesses bypass SMMU.
+ * - Normal memory is accessed through SMMU and ordering is
+ * ensured by client and AXI.
+ * - Ack point for Normal memory is WCAM in MC.
+ * - MMIO's can be early acked and AXI ensures dev memory ordering,
+ * Client ensures read/write direction change ordering.
+ * - See Bug 200312466 for more details.
*
- * Change AXID_OVERRIDE/AXID_OVERRIDE_SO_DEV only for some clients
- * whose AXI IDs we know and trust.
+ * CGID_TAG_ADR is only present from T186 A02. As this code is common
+ * between A01 and A02, tegra_memctrl_set_overrides() programs
+ * CGID_TAG_ADR for the necessary clients on A02.
*/
-
-#if ENABLE_AFI_DEVICE
- /* Match AFIW */
- mc_set_forced_coherent_so_dev_cfg(AFIR);
-#endif
-
+ mc_set_txn_override(HDAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(BPMPW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(PTCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVDISPLAYR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(EQOSW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVJPGSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(ISPRA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SDMMCWAA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(VICSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(MPCOREW, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+ mc_set_txn_override(GPUSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(AXISR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SCEDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SDMMCW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(EQOSR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ /* See bug 200131110 comment #35*/
+ mc_set_txn_override(APEDMAR, CGID_TAG_CLIENT_AXI_ID, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVENCSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SDMMCRAB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(VICSRD1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(BPMPDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(VIW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SDMMCRAA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(AXISW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(XUSB_DEVR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(UFSHCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(TSECSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(GPUSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SATAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(XUSB_HOSTW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT);
+ mc_set_txn_override(TSECSWRB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(GPUSRD2, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SCEDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(GPUSWR2, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(AONDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ /* See bug 200131110 comment #35*/
+ mc_set_txn_override(APEDMAW, CGID_TAG_CLIENT_AXI_ID, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(AONW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(HOST1XDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(ETRR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SESWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVJPGSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVDECSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(TSECSRDB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(BPMPDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(APER, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVDECSRD1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(XUSB_HOSTR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(ISPWA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SESRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SCER, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(AONR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(MPCORER, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+ mc_set_txn_override(SDMMCWA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(HDAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVDECSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(UFSHCW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(AONDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SATAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT);
+ mc_set_txn_override(ETRW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(VICSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVENCSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ /* See bug 200131110 comment #35 */
+ mc_set_txn_override(AFIR, CGID_TAG_DEFAULT, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SDMMCWAB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SDMMCRA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVDISPLAYR1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(ISPWB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(BPMPR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(APEW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SDMMCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(XUSB_DEVW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT);
+ mc_set_txn_override(TSECSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
/*
* See bug 200131110 comment #35 - there are no normal requests
* and AWID for SO/DEV requests is hardcoded in RTL for a
* particular PCIE controller
*/
-#if ENABLE_AFI_DEVICE
- mc_set_forced_coherent_so_dev_cfg(AFIW);
-#endif
- mc_set_forced_coherent_cfg(HDAR);
- mc_set_forced_coherent_cfg(HDAW);
- mc_set_forced_coherent_cfg(SATAR);
- mc_set_forced_coherent_cfg(SATAW);
- mc_set_forced_coherent_cfg(XUSB_HOSTR);
- mc_set_forced_coherent_cfg(XUSB_HOSTW);
- mc_set_forced_coherent_cfg(XUSB_DEVR);
- mc_set_forced_coherent_cfg(XUSB_DEVW);
- mc_set_forced_coherent_cfg(SDMMCRAB);
- mc_set_forced_coherent_cfg(SDMMCWAB);
-
- /* Match APEDMAW */
- mc_set_forced_coherent_axid_so_dev_cfg(APEDMAR);
-
- /*
- * See bug 200131110 comment #35 - AWID for normal requests
- * is 0x80 and AWID for SO/DEV requests is 0x01
- */
- mc_set_forced_coherent_axid_so_dev_cfg(APEDMAW);
- mc_set_forced_coherent_cfg(SESRD);
- mc_set_forced_coherent_cfg(SESWR);
- mc_set_forced_coherent_cfg(ETRR);
- mc_set_forced_coherent_cfg(ETRW);
- mc_set_forced_coherent_cfg(AXISR);
- mc_set_forced_coherent_cfg(AXISW);
- mc_set_forced_coherent_cfg(EQOSR);
- mc_set_forced_coherent_cfg(EQOSW);
- mc_set_forced_coherent_cfg(UFSHCR);
- mc_set_forced_coherent_cfg(UFSHCW);
- mc_set_forced_coherent_cfg(BPMPDMAR);
- mc_set_forced_coherent_cfg(BPMPDMAW);
- mc_set_forced_coherent_cfg(AONDMAR);
- mc_set_forced_coherent_cfg(AONDMAW);
- mc_set_forced_coherent_cfg(SCEDMAR);
- mc_set_forced_coherent_cfg(SCEDMAW);
+ mc_set_txn_override(AFIW, CGID_TAG_DEFAULT, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_COHERENT);
+ mc_set_txn_override(SCEW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
/*
* At this point, ordering can occur at ROC. So, remove PCFIFO's
@@ -192,11 +253,12 @@
mc_set_pcfifo_unordered_boot_so_mss(4, SESWR) &
mc_set_pcfifo_unordered_boot_so_mss(4, ETRW) &
mc_set_pcfifo_unordered_boot_so_mss(4, AXISW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, EQOSW) &
mc_set_pcfifo_unordered_boot_so_mss(4, UFSHCW) &
mc_set_pcfifo_unordered_boot_so_mss(4, BPMPDMAW) &
mc_set_pcfifo_unordered_boot_so_mss(4, AONDMAW) &
mc_set_pcfifo_unordered_boot_so_mss(4, SCEDMAW);
+ /* EQOSW is the only client that has PCFIFO order enabled. */
+ val |= mc_set_pcfifo_ordered_boot_so_mss(4, EQOSW);
tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG4, val);
val = MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL &
@@ -204,45 +266,6 @@
tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG5, val);
/*
- * At this point, ordering can occur at ROC. SMMU need not
- * reorder any requests.
- *
- * Change SMMU_*_ORDERED_CLIENT from ORDERED -> UNORDERED
- * for boot and strongly ordered MSS clients
- */
- val = MC_SMMU_CLIENT_CONFIG1_RESET_VAL &
-#if ENABLE_AFI_DEVICE
- mc_set_smmu_unordered_boot_so_mss(1, AFIW) &
-#endif
- mc_set_smmu_unordered_boot_so_mss(1, HDAW) &
- mc_set_smmu_unordered_boot_so_mss(1, SATAW);
- tegra_mc_write_32(MC_SMMU_CLIENT_CONFIG1, val);
-
- val = MC_SMMU_CLIENT_CONFIG2_RESET_VAL &
- mc_set_smmu_unordered_boot_so_mss(2, XUSB_HOSTW) &
- mc_set_smmu_unordered_boot_so_mss(2, XUSB_DEVW);
- tegra_mc_write_32(MC_SMMU_CLIENT_CONFIG2, val);
-
- val = MC_SMMU_CLIENT_CONFIG3_RESET_VAL &
- mc_set_smmu_unordered_boot_so_mss(3, SDMMCWAB);
- tegra_mc_write_32(MC_SMMU_CLIENT_CONFIG3, val);
-
- val = MC_SMMU_CLIENT_CONFIG4_RESET_VAL &
- mc_set_smmu_unordered_boot_so_mss(4, SESWR) &
- mc_set_smmu_unordered_boot_so_mss(4, ETRW) &
- mc_set_smmu_unordered_boot_so_mss(4, AXISW) &
- mc_set_smmu_unordered_boot_so_mss(4, EQOSW) &
- mc_set_smmu_unordered_boot_so_mss(4, UFSHCW) &
- mc_set_smmu_unordered_boot_so_mss(4, BPMPDMAW) &
- mc_set_smmu_unordered_boot_so_mss(4, AONDMAW) &
- mc_set_smmu_unordered_boot_so_mss(4, SCEDMAW);
- tegra_mc_write_32(MC_SMMU_CLIENT_CONFIG4, val);
-
- val = MC_SMMU_CLIENT_CONFIG5_RESET_VAL &
- mc_set_smmu_unordered_boot_so_mss(5, APEDMAW);
- tegra_mc_write_32(MC_SMMU_CLIENT_CONFIG5, val);
-
- /*
* Deassert HOTRESET FLUSH_ENABLE for boot and strongly ordered MSS
* clients to allow memory traffic from all clients to start passing
* through ROC
diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c
index b496650..0806307 100644
--- a/plat/nvidia/tegra/common/tegra_bl31_setup.c
+++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c
@@ -27,6 +27,7 @@
#include <memctrl.h>
#include <tegra_def.h>
+#include <tegra_platform.h>
#include <tegra_private.h>
/* length of Trusty's input parameters (in bytes) */
@@ -122,6 +123,7 @@
plat_params_from_bl2_t *plat_params = (plat_params_from_bl2_t *)arg1;
image_info_t bl32_img_info = { {0} };
uint64_t tzdram_start, tzdram_end, bl32_start, bl32_end;
+ uint32_t console_clock;
/*
* For RESET_TO_BL31 systems, BL31 is the first bootloader to run so
@@ -155,6 +157,7 @@
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;
/*
* It is very important that we run either from TZDRAM or TZSRAM base.
@@ -165,6 +168,15 @@
panic();
/*
+ * Reference clock used by the FPGAs is a lot slower.
+ */
+ if (tegra_platform_is_fpga() == 1U) {
+ console_clock = TEGRA_BOOT_UART_CLK_13_MHZ;
+ } else {
+ console_clock = TEGRA_BOOT_UART_CLK_408_MHZ;
+ }
+
+ /*
* Get the base address of the UART controller to be used for the
* console
*/
@@ -174,8 +186,8 @@
/*
* Configure the UART port to be used as the console
*/
- console_init(tegra_console_base, TEGRA_BOOT_UART_CLK_IN_HZ,
- TEGRA_CONSOLE_BAUDRATE);
+ console_init(tegra_console_base, console_clock,
+ TEGRA_CONSOLE_BAUDRATE);
}
/*
@@ -239,6 +251,11 @@
args->arg0 = bl32_mem_size;
args->arg1 = bl32_boot_params;
args->arg2 = TRUSTY_PARAMS_LEN_BYTES;
+
+ /* update EKS size */
+ if (args->arg4 != 0U) {
+ args->arg2 = args->arg4;
+ }
}
#endif
diff --git a/plat/nvidia/tegra/common/tegra_fiq_glue.c b/plat/nvidia/tegra/common/tegra_fiq_glue.c
index 0b663ce..9a43f76 100644
--- a/plat/nvidia/tegra/common/tegra_fiq_glue.c
+++ b/plat/nvidia/tegra/common/tegra_fiq_glue.c
@@ -41,6 +41,11 @@
uint32_t cpu = plat_my_core_pos();
uint32_t irq;
+ (void)id;
+ (void)flags;
+ (void)handle;
+ (void)cookie;
+
bakery_lock_get(&tegra_fiq_lock);
/*
diff --git a/plat/nvidia/tegra/common/tegra_platform.c b/plat/nvidia/tegra/common/tegra_platform.c
index 10edf92..72da126 100644
--- a/plat/nvidia/tegra/common/tegra_platform.c
+++ b/plat/nvidia/tegra/common/tegra_platform.c
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
+#include <assert.h>
#include <lib/mmio.h>
-
#include <tegra_def.h>
#include <tegra_platform.h>
#include <tegra_private.h>
@@ -19,35 +19,33 @@
TEGRA_PLATFORM_QT,
TEGRA_PLATFORM_FPGA,
TEGRA_PLATFORM_EMULATION,
+ TEGRA_PLATFORM_LINSIM,
+ TEGRA_PLATFORM_UNIT_FPGA,
+ TEGRA_PLATFORM_VIRT_DEV_KIT,
TEGRA_PLATFORM_MAX,
} tegra_platform_t;
/*******************************************************************************
* Tegra macros defining all the SoC minor versions
******************************************************************************/
-#define TEGRA_MINOR_QT 0
-#define TEGRA_MINOR_FPGA 1
-#define TEGRA_MINOR_EMULATION_MIN 2
-#define TEGRA_MINOR_EMULATION_MAX 10
-
-/*******************************************************************************
- * Tegra major, minor version helper macros
- ******************************************************************************/
-#define MAJOR_VERSION_SHIFT 0x4
-#define MAJOR_VERSION_MASK 0xF
-#define MINOR_VERSION_SHIFT 0x10
-#define MINOR_VERSION_MASK 0xF
-#define CHIP_ID_SHIFT 8
-#define CHIP_ID_MASK 0xFF
+#define TEGRA_MINOR_QT U(0)
+#define TEGRA_MINOR_FPGA U(1)
+#define TEGRA_MINOR_ASIM_QT U(2)
+#define TEGRA_MINOR_ASIM_LINSIM U(3)
+#define TEGRA_MINOR_DSIM_ASIM_LINSIM U(4)
+#define TEGRA_MINOR_UNIT_FPGA U(5)
+#define TEGRA_MINOR_VIRT_DEV_KIT U(6)
/*******************************************************************************
- * Tegra chip ID values
+ * Tegra macros defining all the SoC pre_si_platform
******************************************************************************/
-typedef enum tegra_chipid {
- TEGRA_CHIPID_TEGRA13 = 0x13,
- TEGRA_CHIPID_TEGRA21 = 0x21,
- TEGRA_CHIPID_TEGRA18 = 0x18,
-} tegra_chipid_t;
+#define TEGRA_PRE_SI_QT U(1)
+#define TEGRA_PRE_SI_FPGA U(2)
+#define TEGRA_PRE_SI_UNIT_FPGA U(3)
+#define TEGRA_PRE_SI_ASIM_QT U(4)
+#define TEGRA_PRE_SI_ASIM_LINSIM U(5)
+#define TEGRA_PRE_SI_DSIM_ASIM_LINSIM U(6)
+#define TEGRA_PRE_SI_VDK U(8)
/*
* Read the chip ID value
@@ -73,80 +71,191 @@
return (tegra_get_chipid() >> MINOR_VERSION_SHIFT) & MINOR_VERSION_MASK;
}
-uint8_t tegra_chipid_is_t132(void)
+/*
+ * Read the chip's pre_si_platform valus from the chip ID value
+ */
+static uint32_t tegra_get_chipid_pre_si_platform(void)
{
- uint32_t chip_id = (tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK;
+ return (tegra_get_chipid() >> PRE_SI_PLATFORM_SHIFT) & PRE_SI_PLATFORM_MASK;
+}
- return (chip_id == TEGRA_CHIPID_TEGRA13);
+bool tegra_chipid_is_t132(void)
+{
+ uint32_t chip_id = ((tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK);
+
+ return (chip_id == (uint32_t)TEGRA_CHIPID_TEGRA13);
}
-uint8_t tegra_chipid_is_t210(void)
+bool tegra_chipid_is_t186(void)
{
uint32_t chip_id = (tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK;
- return (chip_id == TEGRA_CHIPID_TEGRA21);
+ return (chip_id == TEGRA_CHIPID_TEGRA18);
}
-uint8_t tegra_chipid_is_t186(void)
+bool tegra_chipid_is_t210(void)
{
uint32_t chip_id = (tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK;
- return (chip_id == TEGRA_CHIPID_TEGRA18);
+ return (chip_id == (uint32_t)TEGRA_CHIPID_TEGRA21);
}
+bool tegra_chipid_is_t210_b01(void)
+{
+ return (tegra_chipid_is_t210() && (tegra_get_chipid_major() == 0x2UL));
+}
+
/*
* Read the chip ID value and derive the platform
*/
static tegra_platform_t tegra_get_platform(void)
{
- uint32_t major = tegra_get_chipid_major();
- uint32_t minor = tegra_get_chipid_minor();
+ uint32_t major, minor, pre_si_platform;
+ tegra_platform_t ret;
- /* Actual silicon platforms have a non-zero major version */
- if (major > 0)
- return TEGRA_PLATFORM_SILICON;
+ /* get the major/minor chip ID values */
+ major = tegra_get_chipid_major();
+ minor = tegra_get_chipid_minor();
+ pre_si_platform = tegra_get_chipid_pre_si_platform();
- /*
- * The minor version number is used by simulation platforms
- */
+ if (major == 0U) {
+ /*
+ * The minor version number is used by simulation platforms
+ */
+ switch (minor) {
+ /*
+ * Cadence's QuickTurn emulation system is a Solaris-based
+ * chip emulation system
+ */
+ case TEGRA_MINOR_QT:
+ case TEGRA_MINOR_ASIM_QT:
+ ret = TEGRA_PLATFORM_QT;
+ break;
- /*
- * Cadence's QuickTurn emulation system is a Solaris-based
- * chip emulation system
- */
- if (minor == TEGRA_MINOR_QT)
- return TEGRA_PLATFORM_QT;
+ /*
+ * FPGAs are used during early software/hardware development
+ */
+ case TEGRA_MINOR_FPGA:
+ ret = TEGRA_PLATFORM_FPGA;
+ break;
+ /*
+ * Linsim is a reconfigurable, clock-driven, mixed RTL/cmodel
+ * simulation framework.
+ */
+ case TEGRA_MINOR_ASIM_LINSIM:
+ case TEGRA_MINOR_DSIM_ASIM_LINSIM:
+ ret = TEGRA_PLATFORM_LINSIM;
+ break;
- /*
- * FPGAs are used during early software/hardware development
- */
- if (minor == TEGRA_MINOR_FPGA)
- return TEGRA_PLATFORM_FPGA;
+ /*
+ * Unit FPGAs run the actual hardware block IP on the FPGA with
+ * the other parts of the system using Linsim.
+ */
+ case TEGRA_MINOR_UNIT_FPGA:
+ ret = TEGRA_PLATFORM_UNIT_FPGA;
+ break;
+ /*
+ * The Virtualizer Development Kit (VDK) is the standard chip
+ * development from Synopsis.
+ */
+ case TEGRA_MINOR_VIRT_DEV_KIT:
+ ret = TEGRA_PLATFORM_VIRT_DEV_KIT;
+ break;
- /* Minor version reserved for other emulation platforms */
- if ((minor > TEGRA_MINOR_FPGA) && (minor <= TEGRA_MINOR_EMULATION_MAX))
- return TEGRA_PLATFORM_EMULATION;
+ default:
+ ret = TEGRA_PLATFORM_MAX;
+ break;
+ }
- /* unsupported platform */
- return TEGRA_PLATFORM_MAX;
+ } else if (pre_si_platform > 0U) {
+
+ switch (pre_si_platform) {
+ /*
+ * Cadence's QuickTurn emulation system is a Solaris-based
+ * chip emulation system
+ */
+ case TEGRA_PRE_SI_QT:
+ case TEGRA_PRE_SI_ASIM_QT:
+ ret = TEGRA_PLATFORM_QT;
+ break;
+
+ /*
+ * FPGAs are used during early software/hardware development
+ */
+ case TEGRA_PRE_SI_FPGA:
+ ret = TEGRA_PLATFORM_FPGA;
+ break;
+ /*
+ * Linsim is a reconfigurable, clock-driven, mixed RTL/cmodel
+ * simulation framework.
+ */
+ case TEGRA_PRE_SI_ASIM_LINSIM:
+ case TEGRA_PRE_SI_DSIM_ASIM_LINSIM:
+ ret = TEGRA_PLATFORM_LINSIM;
+ break;
+
+ /*
+ * Unit FPGAs run the actual hardware block IP on the FPGA with
+ * the other parts of the system using Linsim.
+ */
+ case TEGRA_PRE_SI_UNIT_FPGA:
+ ret = TEGRA_PLATFORM_UNIT_FPGA;
+ break;
+ /*
+ * The Virtualizer Development Kit (VDK) is the standard chip
+ * development from Synopsis.
+ */
+ case TEGRA_PRE_SI_VDK:
+ ret = TEGRA_PLATFORM_VIRT_DEV_KIT;
+ break;
+
+ default:
+ ret = TEGRA_PLATFORM_MAX;
+ break;
+ }
+
+ } else {
+ /* Actual silicon platforms have a non-zero major version */
+ ret = TEGRA_PLATFORM_SILICON;
+ }
+
+ return ret;
}
-uint8_t tegra_platform_is_silicon(void)
+bool tegra_platform_is_silicon(void)
{
- return (tegra_get_platform() == TEGRA_PLATFORM_SILICON);
+ return ((tegra_get_platform() == TEGRA_PLATFORM_SILICON) ? true : false);
}
-uint8_t tegra_platform_is_qt(void)
+bool tegra_platform_is_qt(void)
{
- return (tegra_get_platform() == TEGRA_PLATFORM_QT);
+ return ((tegra_get_platform() == TEGRA_PLATFORM_QT) ? true : false);
}
-uint8_t tegra_platform_is_fpga(void)
+bool tegra_platform_is_linsim(void)
{
- return (tegra_get_platform() == TEGRA_PLATFORM_FPGA);
+ tegra_platform_t plat = tegra_get_platform();
+
+ return (((plat == TEGRA_PLATFORM_LINSIM) ||
+ (plat == TEGRA_PLATFORM_UNIT_FPGA)) ? true : false);
}
-uint8_t tegra_platform_is_emulation(void)
+bool tegra_platform_is_fpga(void)
+{
+ return ((tegra_get_platform() == TEGRA_PLATFORM_FPGA) ? true : false);
+}
+
+bool tegra_platform_is_emulation(void)
{
return (tegra_get_platform() == TEGRA_PLATFORM_EMULATION);
}
+
+bool tegra_platform_is_unit_fpga(void)
+{
+ return ((tegra_get_platform() == TEGRA_PLATFORM_UNIT_FPGA) ? true : false);
+}
+
+bool tegra_platform_is_virt_dev_kit(void)
+{
+ return ((tegra_get_platform() == TEGRA_PLATFORM_VIRT_DEV_KIT) ? true : false);
+}
diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c
index 8361ddd..ce44983 100644
--- a/plat/nvidia/tegra/common/tegra_pm.c
+++ b/plat/nvidia/tegra/common/tegra_pm.c
@@ -21,6 +21,7 @@
#include <memctrl.h>
#include <pmc.h>
#include <tegra_def.h>
+#include <tegra_platform.h>
#include <tegra_private.h>
extern uint64_t tegra_bl31_phys_base;
@@ -222,6 +223,7 @@
void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
plat_params_from_bl2_t *plat_params;
+ uint32_t console_clock;
/*
* Initialize the GIC cpu and distributor interfaces
@@ -234,10 +236,19 @@
if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] ==
PSTATE_ID_SOC_POWERDN) {
+ /*
+ * Reference clock used by the FPGAs is a lot slower.
+ */
+ if (tegra_platform_is_fpga() == 1U) {
+ console_clock = TEGRA_BOOT_UART_CLK_13_MHZ;
+ } else {
+ console_clock = TEGRA_BOOT_UART_CLK_408_MHZ;
+ }
+
/* Initialize the runtime console */
if (tegra_console_base != (uint64_t)0) {
- console_init(tegra_console_base, TEGRA_BOOT_UART_CLK_IN_HZ,
- TEGRA_CONSOLE_BAUDRATE);
+ console_init(tegra_console_base, console_clock,
+ TEGRA_CONSOLE_BAUDRATE);
}
/*
diff --git a/plat/nvidia/tegra/common/tegra_sip_calls.c b/plat/nvidia/tegra/common/tegra_sip_calls.c
index e50d12f..e7acece 100644
--- a/plat/nvidia/tegra/common/tegra_sip_calls.c
+++ b/plat/nvidia/tegra/common/tegra_sip_calls.c
@@ -31,20 +31,29 @@
******************************************************************************/
extern uint8_t tegra_fake_system_suspend;
-
/*******************************************************************************
* SoC specific SiP handler
******************************************************************************/
#pragma weak plat_sip_handler
-int plat_sip_handler(uint32_t smc_fid,
+int32_t plat_sip_handler(uint32_t smc_fid,
uint64_t x1,
uint64_t x2,
uint64_t x3,
uint64_t x4,
- void *cookie,
+ const void *cookie,
void *handle,
uint64_t flags)
{
+ /* unused parameters */
+ (void)smc_fid;
+ (void)x1;
+ (void)x2;
+ (void)x3;
+ (void)x4;
+ (void)cookie;
+ (void)handle;
+ (void)flags;
+
return -ENOTSUP;
}
@@ -61,112 +70,115 @@
u_register_t flags)
{
uint32_t regval;
- int err;
+ int32_t err;
/* Check if this is a SoC specific SiP */
err = plat_sip_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags);
- if (err == 0)
- SMC_RET1(handle, (uint64_t)err);
+ if (err == 0) {
- switch (smc_fid) {
+ SMC_RET1(handle, (uint64_t)err);
- case TEGRA_SIP_NEW_VIDEOMEM_REGION:
+ } else {
- /* clean up the high bits */
- x2 = (uint32_t)x2;
+ switch (smc_fid) {
- /*
- * Check if Video Memory overlaps TZDRAM (contains bl31/bl32)
- * or falls outside of the valid DRAM range
- */
- err = bl31_check_ns_address(x1, x2);
- if (err)
- SMC_RET1(handle, err);
+ case TEGRA_SIP_NEW_VIDEOMEM_REGION:
- /*
- * Check if Video Memory is aligned to 1MB.
- */
- if ((x1 & 0xFFFFF) || (x2 & 0xFFFFF)) {
- ERROR("Unaligned Video Memory base address!\n");
- SMC_RET1(handle, -ENOTSUP);
- }
+ /* clean up the high bits */
+ x2 = (uint32_t)x2;
- /*
- * The GPU is the user of the Video Memory region. In order to
- * transition to the new memory region smoothly, we program the
- * new base/size ONLY if the GPU is in reset mode.
- */
- regval = mmio_read_32(TEGRA_CAR_RESET_BASE +
- TEGRA_GPU_RESET_REG_OFFSET);
- if ((regval & GPU_RESET_BIT) == 0U) {
- ERROR("GPU not in reset! Video Memory setup failed\n");
- SMC_RET1(handle, -ENOTSUP);
- }
+ /*
+ * Check if Video Memory overlaps TZDRAM (contains bl31/bl32)
+ * or falls outside of the valid DRAM range
+ */
+ err = bl31_check_ns_address(x1, x2);
+ if (err != 0) {
+ SMC_RET1(handle, (uint64_t)err);
+ }
- /* new video memory carveout settings */
- tegra_memctrl_videomem_setup(x1, x2);
+ /*
+ * Check if Video Memory is aligned to 1MB.
+ */
+ if (((x1 & 0xFFFFFU) != 0U) || ((x2 & 0xFFFFFU) != 0U)) {
+ ERROR("Unaligned Video Memory base address!\n");
+ SMC_RET1(handle, -ENOTSUP);
+ }
- SMC_RET1(handle, 0);
- break;
+ /*
+ * The GPU is the user of the Video Memory region. In order to
+ * transition to the new memory region smoothly, we program the
+ * new base/size ONLY if the GPU is in reset mode.
+ */
+ regval = mmio_read_32(TEGRA_CAR_RESET_BASE +
+ TEGRA_GPU_RESET_REG_OFFSET);
+ if ((regval & GPU_RESET_BIT) == 0UL) {
+ ERROR("GPU not in reset! Video Memory setup failed\n");
+ SMC_RET1(handle, -ENOTSUP);
+ }
- /*
- * The NS world registers the address of its handler to be
- * used for processing the FIQ. This is normally used by the
- * NS FIQ debugger driver to detect system hangs by programming
- * a watchdog timer to fire a FIQ interrupt.
- */
- case TEGRA_SIP_FIQ_NS_ENTRYPOINT:
+ /* new video memory carveout settings */
+ tegra_memctrl_videomem_setup(x1, (uint32_t)x2);
- if (!x1)
- SMC_RET1(handle, SMC_UNK);
+ SMC_RET1(handle, 0);
/*
- * TODO: Check if x1 contains a valid DRAM address
+ * The NS world registers the address of its handler to be
+ * used for processing the FIQ. This is normally used by the
+ * NS FIQ debugger driver to detect system hangs by programming
+ * a watchdog timer to fire a FIQ interrupt.
*/
+ case TEGRA_SIP_FIQ_NS_ENTRYPOINT:
- /* store the NS world's entrypoint */
- tegra_fiq_set_ns_entrypoint(x1);
+ if (x1 == 0U) {
+ SMC_RET1(handle, SMC_UNK);
+ }
- SMC_RET1(handle, 0);
- break;
+ /*
+ * TODO: Check if x1 contains a valid DRAM address
+ */
- /*
- * The NS world's FIQ handler issues this SMC to get the NS EL1/EL0
- * CPU context when the FIQ interrupt was triggered. This allows the
- * NS world to understand the CPU state when the watchdog interrupt
- * triggered.
- */
- case TEGRA_SIP_FIQ_NS_GET_CONTEXT:
+ /* store the NS world's entrypoint */
+ tegra_fiq_set_ns_entrypoint(x1);
- /* retrieve context registers when FIQ triggered */
- tegra_fiq_get_intr_context();
-
- SMC_RET0(handle);
- break;
+ SMC_RET1(handle, 0);
- case TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND:
/*
- * System suspend fake mode is set if we are on VDK and we make
- * a debug SIP call. This mode ensures that we excercise debug
- * path instead of the regular code path to suit the pre-silicon
- * platform needs. These include replacing the call to WFI by
- * a warm reset request.
+ * The NS world's FIQ handler issues this SMC to get the NS EL1/EL0
+ * CPU context when the FIQ interrupt was triggered. This allows the
+ * NS world to understand the CPU state when the watchdog interrupt
+ * triggered.
*/
- if (tegra_platform_is_emulation() != 0U) {
+ case TEGRA_SIP_FIQ_NS_GET_CONTEXT:
- tegra_fake_system_suspend = 1;
- SMC_RET1(handle, 0);
- }
+ /* retrieve context registers when FIQ triggered */
+ (void)tegra_fiq_get_intr_context();
- /*
- * We return to the external world as if this SIP is not
- * implemented in case, we are not running on VDK.
- */
- break;
+ SMC_RET0(handle);
+
+ case TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND:
+ /*
+ * System suspend fake mode is set if we are on VDK and we make
+ * a debug SIP call. This mode ensures that we excercise debug
+ * path instead of the regular code path to suit the pre-silicon
+ * platform needs. These include replacing the call to WFI by
+ * a warm reset request.
+ */
+ if (tegra_platform_is_virt_dev_kit() != false) {
- default:
- ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
- break;
+ tegra_fake_system_suspend = 1;
+ SMC_RET1(handle, 0);
+ }
+
+ /*
+ * We return to the external world as if this SIP is not
+ * implemented in case, we are not running on VDK.
+ */
+ break;
+
+ default:
+ ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
+ break;
+ }
}
SMC_RET1(handle, SMC_UNK);
@@ -176,9 +188,9 @@
DECLARE_RT_SVC(
tegra_sip_fast,
- OEN_SIP_START,
- OEN_SIP_END,
- SMC_TYPE_FAST,
- NULL,
- tegra_sip_handler
+ (OEN_SIP_START),
+ (OEN_SIP_END),
+ (SMC_TYPE_FAST),
+ (NULL),
+ (tegra_sip_handler)
);
diff --git a/plat/nvidia/tegra/common/tegra_topology.c b/plat/nvidia/tegra/common/tegra_topology.c
index 893f28f..4f6cf93 100644
--- a/plat/nvidia/tegra/common/tegra_topology.c
+++ b/plat/nvidia/tegra/common/tegra_topology.c
@@ -7,41 +7,38 @@
#include <platform_def.h>
#include <arch.h>
+#include <platform.h>
#include <lib/psci/psci.h>
-extern const unsigned char tegra_power_domain_tree_desc[];
#pragma weak plat_core_pos_by_mpidr
/*******************************************************************************
- * This function returns the Tegra default topology tree information.
- ******************************************************************************/
-const unsigned char *plat_get_power_domain_tree_desc(void)
-{
- return tegra_power_domain_tree_desc;
-}
-
-/*******************************************************************************
* This function implements a part of the critical interface between the psci
* generic layer and the platform that allows the former to query the platform
* to convert an MPIDR to a unique linear index. An error code (-1) is returned
* in case the MPIDR is invalid.
******************************************************************************/
-int plat_core_pos_by_mpidr(u_register_t mpidr)
+int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
{
- unsigned int cluster_id, cpu_id;
+ u_register_t cluster_id, cpu_id;
+ int32_t result;
- cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
- cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+ cluster_id = (mpidr >> (u_register_t)MPIDR_AFF1_SHIFT) & (u_register_t)MPIDR_AFFLVL_MASK;
+ cpu_id = (mpidr >> (u_register_t)MPIDR_AFF0_SHIFT) & (u_register_t)MPIDR_AFFLVL_MASK;
- if (cluster_id >= PLATFORM_CLUSTER_COUNT)
- return PSCI_E_NOT_PRESENT;
+ result = (int32_t)cpu_id + ((int32_t)cluster_id * 4);
+
+ if (cluster_id >= (u_register_t)PLATFORM_CLUSTER_COUNT) {
+ result = PSCI_E_NOT_PRESENT;
+ }
/*
* Validate cpu_id by checking whether it represents a CPU in
* one of the two clusters present on the platform.
*/
- if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER)
- return PSCI_E_NOT_PRESENT;
+ if (cpu_id >= (u_register_t)PLATFORM_MAX_CPUS_PER_CLUSTER) {
+ result = PSCI_E_NOT_PRESENT;
+ }
- return (cpu_id + (cluster_id * 4));
+ return result;
}
diff --git a/plat/nvidia/tegra/include/drivers/bpmp.h b/plat/nvidia/tegra/include/drivers/bpmp.h
new file mode 100644
index 0000000..27f57df
--- /dev/null
+++ b/plat/nvidia/tegra/include/drivers/bpmp.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BPMP_H
+#define BPMP_H
+
+#include <stdint.h>
+
+/* macro to enable clock to the Atomics block */
+#define CAR_ENABLE_ATOMICS (1UL << 16)
+
+/* command to get the channel base addresses from bpmp */
+#define ATOMIC_CMD_GET 4UL
+
+/* Hardware IRQ # used to signal bpmp of an incoming command */
+#define INT_SHR_SEM_OUTBOX_FULL 6UL
+
+/* macros to decode the bpmp's state */
+#define CH_MASK(ch) (0x3UL << ((ch) * 2UL))
+#define MA_FREE(ch) (0x2UL << ((ch) * 2UL))
+#define MA_ACKD(ch) (0x3UL << ((ch) * 2UL))
+
+/* response from bpmp to indicate it has powered up */
+#define SIGN_OF_LIFE 0xAAAAAAAAUL
+
+/* flags to indicate bpmp driver's state */
+#define BPMP_INIT_COMPLETE 0xBEEFF00DUL
+#define BPMP_INIT_PENDING 0xDEADBEEFUL
+
+/* requests serviced by the bpmp */
+#define MRQ_PING 0
+#define MRQ_QUERY_TAG 1
+#define MRQ_DO_IDLE 2
+#define MRQ_TOLERATE_IDLE 3
+#define MRQ_MODULE_LOAD 4
+#define MRQ_MODULE_UNLOAD 5
+#define MRQ_SWITCH_CLUSTER 6
+#define MRQ_TRACE_MODIFY 7
+#define MRQ_WRITE_TRACE 8
+#define MRQ_THREADED_PING 9
+#define MRQ_CPUIDLE_USAGE 10
+#define MRQ_MODULE_MAIL 11
+#define MRQ_SCX_ENABLE 12
+#define MRQ_BPMPIDLE_USAGE 14
+#define MRQ_HEAP_USAGE 15
+#define MRQ_SCLK_SKIP_SET_RATE 16
+#define MRQ_ENABLE_SUSPEND 17
+#define MRQ_PASR_MASK 18
+#define MRQ_DEBUGFS 19
+#define MRQ_THERMAL 27
+
+/* Tegra PM states as known to BPMP */
+#define TEGRA_PM_CC1 9
+#define TEGRA_PM_CC4 12
+#define TEGRA_PM_CC6 14
+#define TEGRA_PM_CC7 15
+#define TEGRA_PM_SC1 17
+#define TEGRA_PM_SC2 18
+#define TEGRA_PM_SC3 19
+#define TEGRA_PM_SC4 20
+#define TEGRA_PM_SC7 23
+
+/* flag to indicate if entry into a CCx power state is allowed */
+#define BPMP_CCx_ALLOWED 0UL
+
+/* number of communication channels to interact with the bpmp */
+#define NR_CHANNELS 4U
+
+/* flag to ask bpmp to acknowledge command packet */
+#define NO_ACK (0UL << 0UL)
+#define DO_ACK (1UL << 0UL)
+
+/* size of the command/response data */
+#define MSG_DATA_MAX_SZ 120U
+
+/**
+ * command/response packet to/from the bpmp
+ *
+ * command
+ * -------
+ * code: MRQ_* command
+ * flags: DO_ACK or NO_ACK
+ * data:
+ * [0] = cpu #
+ * [1] = cluster power state (TEGRA_PM_CCx)
+ * [2] = system power state (TEGRA_PM_SCx)
+ *
+ * response
+ * ---------
+ * code: error code
+ * flags: not used
+ * data:
+ * [0-3] = response value
+ */
+typedef struct mb_data {
+ int32_t code;
+ uint32_t flags;
+ uint8_t data[MSG_DATA_MAX_SZ];
+} mb_data_t;
+
+/**
+ * Function to initialise the interface with the bpmp
+ */
+int tegra_bpmp_init(void);
+
+/**
+ * Handler to send a MRQ_* command to the bpmp
+ */
+int32_t tegra_bpmp_send_receive_atomic(int mrq, const void *ob_data, int ob_sz,
+ void *ib_data, int ib_sz);
+
+#endif /* BPMP_H */
diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v2.h b/plat/nvidia/tegra/include/drivers/memctrl_v2.h
index 957ff54..ffe5269 100644
--- a/plat/nvidia/tegra/include/drivers/memctrl_v2.h
+++ b/plat/nvidia/tegra/include/drivers/memctrl_v2.h
@@ -100,6 +100,19 @@
******************************************************************************/
#define MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(addr) (addr + sizeof(uint32_t))
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_SO_DEV (0UL << 4)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_SO_DEV (1UL << 4)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SO_DEV (2UL << 4)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_SO_DEV (3UL << 4)
+
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_NORMAL (0UL << 8)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_NORMAL (1UL << 8)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_NORMAL (2UL << 8)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_NORMAL (3UL << 8)
+
+#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_ZERO (0UL << 12)
+#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_CLIENT_AXI_ID (1UL << 12)
+
/*******************************************************************************
* Memory Controller transaction override config registers
******************************************************************************/
@@ -312,98 +325,51 @@
/*******************************************************************************
* Memory Controller's PCFIFO client configuration registers
******************************************************************************/
-#define MC_PCFIFO_CLIENT_CONFIG1 0xdd4
-#define MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL 0x20000
-#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_UNORDERED (0 << 17)
-#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_MASK (1 << 17)
-#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_UNORDERED (0 << 21)
-#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_MASK (1 << 21)
-#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_UNORDERED (0 << 29)
-#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_MASK (1 << 29)
-
-#define MC_PCFIFO_CLIENT_CONFIG2 0xdd8
-#define MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL 0x20000
-#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_UNORDERED (0 << 11)
-#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_MASK (1 << 11)
-#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_UNORDERED (0 << 13)
-#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_MASK (1 << 13)
-
-#define MC_PCFIFO_CLIENT_CONFIG3 0xddc
-#define MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL 0
-#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_UNORDERED (0 << 7)
-#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_MASK (1 << 7)
-
-#define MC_PCFIFO_CLIENT_CONFIG4 0xde0
-#define MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL 0
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_UNORDERED (0 << 1)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_MASK (1 << 1)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_UNORDERED (0 << 5)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_MASK (1 << 5)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_UNORDERED (0 << 13)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_MASK (1 << 13)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_UNORDERED (0 << 15)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_MASK (1 << 15)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_UNORDERED (0 << 17)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_MASK (1 << 17)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_UNORDERED (0 << 22)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_MASK (1 << 22)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_UNORDERED (0 << 26)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_MASK (1 << 26)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_UNORDERED (0 << 30)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_MASK (1 << 30)
-
-#define MC_PCFIFO_CLIENT_CONFIG5 0xbf4
-#define MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL 0
-#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_UNORDERED (0 << 0)
-#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_MASK (1 << 0)
-
-/*******************************************************************************
- * Memory Controller's SMMU client configuration registers
- ******************************************************************************/
-#define MC_SMMU_CLIENT_CONFIG1 0x44
-#define MC_SMMU_CLIENT_CONFIG1_RESET_VAL 0x20000
-#define MC_SMMU_CLIENT_CONFIG1_AFIW_UNORDERED (0 << 17)
-#define MC_SMMU_CLIENT_CONFIG1_AFIW_MASK (1 << 17)
-#define MC_SMMU_CLIENT_CONFIG1_HDAW_UNORDERED (0 << 21)
-#define MC_SMMU_CLIENT_CONFIG1_HDAW_MASK (1 << 21)
-#define MC_SMMU_CLIENT_CONFIG1_SATAW_UNORDERED (0 << 29)
-#define MC_SMMU_CLIENT_CONFIG1_SATAW_MASK (1 << 29)
+#define MC_PCFIFO_CLIENT_CONFIG1 0xdd4UL
+#define MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL 0x20000UL
+#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_UNORDERED (0UL << 17)
+#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_MASK (1UL << 17)
+#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_UNORDERED (0UL << 21)
+#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_MASK (1UL << 21)
+#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_UNORDERED (0UL << 29)
+#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_MASK (1UL << 29)
-#define MC_SMMU_CLIENT_CONFIG2 0x48
-#define MC_SMMU_CLIENT_CONFIG2_RESET_VAL 0x20000
-#define MC_SMMU_CLIENT_CONFIG2_XUSB_HOSTW_UNORDERED (0 << 11)
-#define MC_SMMU_CLIENT_CONFIG2_XUSB_HOSTW_MASK (1 << 11)
-#define MC_SMMU_CLIENT_CONFIG2_XUSB_DEVW_UNORDERED (0 << 13)
-#define MC_SMMU_CLIENT_CONFIG2_XUSB_DEVW_MASK (1 << 13)
+#define MC_PCFIFO_CLIENT_CONFIG2 0xdd8UL
+#define MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL 0x20000UL
+#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_UNORDERED (0UL << 11)
+#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_MASK (1UL << 11)
+#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_UNORDERED (0UL << 13)
+#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_MASK (1UL << 13)
-#define MC_SMMU_CLIENT_CONFIG3 0x4c
-#define MC_SMMU_CLIENT_CONFIG3_RESET_VAL 0
-#define MC_SMMU_CLIENT_CONFIG3_SDMMCWAB_UNORDERED (0 << 7)
-#define MC_SMMU_CLIENT_CONFIG3_SDMMCWAB_MASK (1 << 7)
+#define MC_PCFIFO_CLIENT_CONFIG3 0xddcUL
+#define MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL 0UL
+#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_UNORDERED (0UL << 7)
+#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_MASK (1UL << 7)
-#define MC_SMMU_CLIENT_CONFIG4 0xb9c
-#define MC_SMMU_CLIENT_CONFIG4_RESET_VAL 0
-#define MC_SMMU_CLIENT_CONFIG4_SESWR_UNORDERED (0 << 1)
-#define MC_SMMU_CLIENT_CONFIG4_SESWR_MASK (1 << 1)
-#define MC_SMMU_CLIENT_CONFIG4_ETRW_UNORDERED (0 << 5)
-#define MC_SMMU_CLIENT_CONFIG4_ETRW_MASK (1 << 5)
-#define MC_SMMU_CLIENT_CONFIG4_AXISW_UNORDERED (0 << 13)
-#define MC_SMMU_CLIENT_CONFIG4_AXISW_MASK (1 << 13)
-#define MC_SMMU_CLIENT_CONFIG4_EQOSW_UNORDERED (0 << 15)
-#define MC_SMMU_CLIENT_CONFIG4_EQOSW_MASK (1 << 15)
-#define MC_SMMU_CLIENT_CONFIG4_UFSHCW_UNORDERED (0 << 17)
-#define MC_SMMU_CLIENT_CONFIG4_UFSHCW_MASK (1 << 17)
-#define MC_SMMU_CLIENT_CONFIG4_BPMPDMAW_UNORDERED (0 << 22)
-#define MC_SMMU_CLIENT_CONFIG4_BPMPDMAW_MASK (1 << 22)
-#define MC_SMMU_CLIENT_CONFIG4_AONDMAW_UNORDERED (0 << 26)
-#define MC_SMMU_CLIENT_CONFIG4_AONDMAW_MASK (1 << 26)
-#define MC_SMMU_CLIENT_CONFIG4_SCEDMAW_UNORDERED (0 << 30)
-#define MC_SMMU_CLIENT_CONFIG4_SCEDMAW_MASK (1 << 30)
+#define MC_PCFIFO_CLIENT_CONFIG4 0xde0UL
+#define MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL 0UL
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_UNORDERED (0UL << 1)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_MASK (1UL << 1)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_UNORDERED (0UL << 5)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_MASK (1UL << 5)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_UNORDERED (0UL << 13)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_MASK (1UL << 13)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_UNORDERED (0UL << 15)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_ORDERED (1UL << 15)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_MASK (1UL << 15)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_UNORDERED (0UL << 17)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_MASK (1UL << 17)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_UNORDERED (0UL << 22)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_MASK (1UL << 22)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_UNORDERED (0UL << 26)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_MASK (1UL << 26)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_UNORDERED (0UL << 30)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_MASK (1UL << 30)
-#define MC_SMMU_CLIENT_CONFIG5 0xbac
-#define MC_SMMU_CLIENT_CONFIG5_RESET_VAL 0
-#define MC_SMMU_CLIENT_CONFIG5_APEDMAW_UNORDERED (0 << 0)
-#define MC_SMMU_CLIENT_CONFIG5_APEDMAW_MASK (1 << 0)
+#define MC_PCFIFO_CLIENT_CONFIG5 0xbf4UL
+#define MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL 0UL
+#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_UNORDERED (0UL << 0)
+#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_MASK (1UL << 0)
#ifndef __ASSEMBLY__
@@ -433,9 +399,8 @@
(~MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_MASK | \
MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_UNORDERED)
-#define mc_set_smmu_unordered_boot_so_mss(id, client) \
- (~MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_MASK | \
- MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_UNORDERED)
+#define mc_set_pcfifo_ordered_boot_so_mss(id, client) \
+ MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_ORDERED
#define mc_set_tsa_passthrough(client) \
{ \
@@ -445,25 +410,13 @@
TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
}
-#define mc_set_forced_coherent_cfg(client) \
- { \
- tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_##client, \
- MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV); \
- }
-
-#define mc_set_forced_coherent_so_dev_cfg(client) \
- { \
- tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_##client, \
- MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV | \
- MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_CLIENT); \
- }
-
-#define mc_set_forced_coherent_axid_so_dev_cfg(client) \
+#define mc_set_txn_override(client, normal_axi_id, so_dev_axi_id, normal_override, so_dev_override) \
{ \
tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_##client, \
- MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV | \
- MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_CGID | \
- MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_CLIENT); \
+ MC_TXN_OVERRIDE_##normal_axi_id | \
+ MC_TXN_OVERRIDE_CONFIG_COH_PATH_##so_dev_override##_SO_DEV | \
+ MC_TXN_OVERRIDE_CONFIG_COH_PATH_##normal_override##_NORMAL | \
+ MC_TXN_OVERRIDE_CONFIG_CGID_##so_dev_axi_id); \
}
/*******************************************************************************
diff --git a/plat/nvidia/tegra/include/drivers/security_engine.h b/plat/nvidia/tegra/include/drivers/security_engine.h
new file mode 100644
index 0000000..abfb217
--- /dev/null
+++ b/plat/nvidia/tegra/include/drivers/security_engine.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SECURITY_ENGINE_H
+#define SECURITY_ENGINE_H
+
+/*******************************************************************************
+ * Structure definition
+ ******************************************************************************/
+
+/* Security Engine Linked List */
+struct tegra_se_ll {
+ /* DMA buffer address */
+ uint32_t addr;
+ /* Data length in DMA buffer */
+ uint32_t data_len;
+};
+
+#define SE_LL_MAX_BUFFER_NUM 4
+typedef struct tegra_se_io_lst {
+ volatile uint32_t last_buff_num;
+ volatile struct tegra_se_ll buffer[SE_LL_MAX_BUFFER_NUM];
+} tegra_se_io_lst_t __attribute__((aligned(4)));
+
+/* SE device structure */
+typedef struct tegra_se_dev {
+ /* Security Engine ID */
+ const int se_num;
+ /* SE base address */
+ const uint64_t se_base;
+ /* SE context size in AES blocks */
+ const uint32_t ctx_size_blks;
+ /* pointer to source linked list buffer */
+ tegra_se_io_lst_t *src_ll_buf;
+ /* pointer to destination linked list buffer */
+ tegra_se_io_lst_t *dst_ll_buf;
+} tegra_se_dev_t;
+
+/*******************************************************************************
+ * Public interface
+ ******************************************************************************/
+void tegra_se_init(void);
+int tegra_se_suspend(void);
+void tegra_se_resume(void);
+int tegra_se_save_tzram(void);
+
+#endif /* SECURITY_ENGINE_H */
diff --git a/plat/nvidia/tegra/include/platform_def.h b/plat/nvidia/tegra/include/platform_def.h
index d10dc26..0a0126b 100644
--- a/plat/nvidia/tegra/include/platform_def.h
+++ b/plat/nvidia/tegra/include/platform_def.h
@@ -34,7 +34,8 @@
* Platform console related constants
******************************************************************************/
#define TEGRA_CONSOLE_BAUDRATE U(115200)
-#define TEGRA_BOOT_UART_CLK_IN_HZ U(408000000)
+#define TEGRA_BOOT_UART_CLK_13_MHZ U(13000000)
+#define TEGRA_BOOT_UART_CLK_408_MHZ U(408000000)
/*******************************************************************************
* Platform memory map related constants
diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h
index 14cdfd5..8d71cae 100644
--- a/plat/nvidia/tegra/include/t210/tegra_def.h
+++ b/plat/nvidia/tegra/include/t210/tegra_def.h
@@ -33,6 +33,11 @@
#define PLAT_MAX_OFF_STATE (PSTATE_ID_SOC_POWERDN + U(1))
/*******************************************************************************
+ * iRAM memory constants
+ ******************************************************************************/
+#define TEGRA_IRAM_BASE 0x40000000
+
+/*******************************************************************************
* GIC memory map
******************************************************************************/
#define TEGRA_GICD_BASE U(0x50041000)
@@ -56,6 +61,20 @@
ENABLE_WRAP_INCR_MASTER0_BIT)
/*******************************************************************************
+ * Tegra Resource Semaphore constants
+ ******************************************************************************/
+#define TEGRA_RES_SEMA_BASE 0x60001000UL
+#define STA_OFFSET 0UL
+#define SET_OFFSET 4UL
+#define CLR_OFFSET 8UL
+
+/*******************************************************************************
+ * Tegra Primary Interrupt Controller constants
+ ******************************************************************************/
+#define TEGRA_PRI_ICTLR_BASE 0x60004000UL
+#define CPU_IEP_FIR_SET 0x18UL
+
+/*******************************************************************************
* Tegra micro-seconds timer constants
******************************************************************************/
#define TEGRA_TMRUS_BASE U(0x60005010)
@@ -67,6 +86,8 @@
#define TEGRA_CAR_RESET_BASE U(0x60006000)
#define TEGRA_GPU_RESET_REG_OFFSET U(0x28C)
#define GPU_RESET_BIT (U(1) << 24)
+#define TEGRA_RST_DEV_CLR_V U(0x434)
+#define TEGRA_CLK_ENB_V U(0x440)
/*******************************************************************************
* Tegra Flow Controller constants
@@ -74,6 +95,11 @@
#define TEGRA_FLOWCTRL_BASE U(0x60007000)
/*******************************************************************************
+ * Tegra AHB arbitration controller
+ ******************************************************************************/
+#define TEGRA_AHB_ARB_BASE 0x6000C000UL
+
+/*******************************************************************************
* Tegra Secure Boot Controller constants
******************************************************************************/
#define TEGRA_SB_BASE U(0x6000C200)
@@ -104,6 +130,15 @@
#define TEGRA_PMC_BASE U(0x7000E400)
/*******************************************************************************
+ * Tegra Atomics constants
+ ******************************************************************************/
+#define TEGRA_ATOMICS_BASE 0x70016000UL
+#define TRIGGER0_REG_OFFSET 0UL
+#define TRIGGER_WIDTH_SHIFT 4UL
+#define TRIGGER_ID_SHIFT 16UL
+#define RESULT0_REG_OFFSET 0xC00UL
+
+/*******************************************************************************
* Tegra Memory Controller constants
******************************************************************************/
#define TEGRA_MC_BASE U(0x70019000)
@@ -119,6 +154,15 @@
#define MC_VIDEO_PROTECT_SIZE_MB U(0x64c)
/*******************************************************************************
+ * Tegra SE constants
+ ******************************************************************************/
+#define TEGRA_SE1_BASE U(0x70012000)
+#define TEGRA_SE2_BASE U(0x70412000)
+#define TEGRA_PKA1_BASE U(0x70420000)
+#define TEGRA_SE2_RANGE_SIZE U(0x2000)
+#define SE_TZRAM_SECURITY U(0x4)
+
+/*******************************************************************************
* Tegra TZRAM constants
******************************************************************************/
#define TEGRA_TZRAM_BASE U(0x7C010000)
diff --git a/plat/nvidia/tegra/include/tegra_platform.h b/plat/nvidia/tegra/include/tegra_platform.h
index 63a0e01..1e7ba16 100644
--- a/plat/nvidia/tegra/include/tegra_platform.h
+++ b/plat/nvidia/tegra/include/tegra_platform.h
@@ -8,27 +8,56 @@
#define TEGRA_PLATFORM_H
#include <cdefs.h>
+#include <stdbool.h>
+#include <utils_def.h>
+
+/*******************************************************************************
+ * Tegra major, minor version helper macros
+ ******************************************************************************/
+#define MAJOR_VERSION_SHIFT U(0x4)
+#define MAJOR_VERSION_MASK U(0xF)
+#define MINOR_VERSION_SHIFT U(0x10)
+#define MINOR_VERSION_MASK U(0xF)
+#define CHIP_ID_SHIFT U(8)
+#define CHIP_ID_MASK U(0xFF)
+#define PRE_SI_PLATFORM_SHIFT U(0x14)
+#define PRE_SI_PLATFORM_MASK U(0xF)
+
+/*******************************************************************************
+ * Tegra chip ID values
+ ******************************************************************************/
+#define TEGRA_CHIPID_TEGRA13 U(0x13)
+#define TEGRA_CHIPID_TEGRA21 U(0x21)
+#define TEGRA_CHIPID_TEGRA18 U(0x18)
+
+#ifndef __ASSEMBLY__
/*
- * Tegra chip major/minor version
+ * Tegra chip ID major/minor identifiers
*/
uint32_t tegra_get_chipid_major(void);
uint32_t tegra_get_chipid_minor(void);
/*
- * Tegra chip identifiers
+ * Tegra chip ID identifiers
*/
-uint8_t tegra_chipid_is_t132(void);
-uint8_t tegra_chipid_is_t210(void);
-uint8_t tegra_chipid_is_t186(void);
+bool tegra_chipid_is_t132(void);
+bool tegra_chipid_is_t186(void);
+bool tegra_chipid_is_t210(void);
+bool tegra_chipid_is_t210_b01(void);
/*
* Tegra platform identifiers
*/
-uint8_t tegra_platform_is_silicon(void);
-uint8_t tegra_platform_is_qt(void);
-uint8_t tegra_platform_is_emulation(void);
-uint8_t tegra_platform_is_fpga(void);
+bool tegra_platform_is_silicon(void);
+bool tegra_platform_is_qt(void);
+bool tegra_platform_is_emulation(void);
+bool tegra_platform_is_linsim(void);
+bool tegra_platform_is_fpga(void);
+bool tegra_platform_is_unit_fpga(void);
+bool tegra_platform_is_virt_dev_kit(void);
+
+#endif /* __ASSEMBLY__ */
#endif /* TEGRA_PLATFORM_H */
diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h
index 93223cc..1682927 100644
--- a/plat/nvidia/tegra/include/tegra_private.h
+++ b/plat/nvidia/tegra/include/tegra_private.h
@@ -32,9 +32,16 @@
uint64_t tzdram_base;
/* UART port ID */
int uart_id;
+ /* L2 ECC parity protection disable flag */
+ int l2_ecc_parity_prot_dis;
} plat_params_from_bl2_t;
/*******************************************************************************
+ * Helper function to access l2ctlr_el1 register on Cortex-A57 CPUs
+ ******************************************************************************/
+DEFINE_RENAME_SYSREG_RW_FUNCS(l2ctlr_el1, CORTEX_A57_L2CTLR_EL1)
+
+/*******************************************************************************
* Struct describing parameters passed to bl31
******************************************************************************/
struct tegra_bl31_params {
@@ -47,19 +54,19 @@
};
/* Declarations for plat_psci_handlers.c */
-int32_t tegra_soc_validate_power_state(unsigned int power_state,
+int32_t tegra_soc_validate_power_state(uint32_t power_state,
psci_power_state_t *req_state);
/* Declarations for plat_setup.c */
const mmap_region_t *plat_get_mmio_map(void);
-uint32_t plat_get_console_from_id(int id);
+uint32_t plat_get_console_from_id(int32_t id);
void plat_gic_setup(void);
struct tegra_bl31_params *plat_get_bl31_params(void);
plat_params_from_bl2_t *plat_get_bl31_plat_params(void);
/* Declarations for plat_secondary.c */
void plat_secondary_setup(void);
-int plat_lock_cpu_vectors(void);
+int32_t plat_lock_cpu_vectors(void);
/* Declarations for tegra_fiq_glue.c */
void tegra_fiq_handler_setup(void);
@@ -92,4 +99,22 @@
void tegra_secure_entrypoint(void);
void tegra186_cpu_reset_handler(void);
+/* Declarations for tegra_sip_calls.c */
+uintptr_t tegra_sip_handler(uint32_t smc_fid,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4,
+ void *cookie,
+ void *handle,
+ u_register_t flags);
+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);
+
#endif /* TEGRA_PRIVATE_H */
diff --git a/plat/nvidia/tegra/soc/t132/plat_setup.c b/plat/nvidia/tegra/soc/t132/plat_setup.c
index f72b73e..3f9cda9 100644
--- a/plat/nvidia/tegra/soc/t132/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t132/plat_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,25 +7,10 @@
#include <arch_helpers.h>
#include <common/bl_common.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
-
+#include <platform.h>
#include <tegra_def.h>
#include <tegra_private.h>
-/*******************************************************************************
- * The Tegra power domain tree has a single system level power domain i.e. a
- * single root node. The first entry in the power domain descriptor specifies
- * the number of power domains at the highest power level.
- *******************************************************************************
- */
-const unsigned char tegra_power_domain_tree_desc[] = {
- /* No of root nodes */
- 1,
- /* No of clusters */
- PLATFORM_CLUSTER_COUNT,
- /* No of CPU cores */
- PLATFORM_CORE_COUNT,
-};
-
/* sets of MMIO ranges setup */
#define MMIO_RANGE_0_ADDR 0x50000000
#define MMIO_RANGE_1_ADDR 0x60000000
@@ -54,6 +39,29 @@
return tegra_mmap;
}
+/*******************************************************************************
+ * The Tegra power domain tree has a single system level power domain i.e. a
+ * single root node. The first entry in the power domain descriptor specifies
+ * the number of power domains at the highest power level.
+ *******************************************************************************
+ */
+const unsigned char tegra_power_domain_tree_desc[] = {
+ /* No of root nodes */
+ 1,
+ /* No of clusters */
+ PLATFORM_CLUSTER_COUNT,
+ /* No of CPU cores */
+ PLATFORM_CORE_COUNT,
+};
+
+/*******************************************************************************
+ * This function returns the Tegra default topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ return tegra_power_domain_tree_desc;
+}
+
unsigned int plat_get_syscnt_freq2(void)
{
return 12000000;
diff --git a/plat/nvidia/tegra/soc/t132/plat_sip_calls.c b/plat/nvidia/tegra/soc/t132/plat_sip_calls.c
index 02dd1cd..90c6bb2 100644
--- a/plat/nvidia/tegra/soc/t132/plat_sip_calls.c
+++ b/plat/nvidia/tegra/soc/t132/plat_sip_calls.c
@@ -38,7 +38,7 @@
uint64_t x2,
uint64_t x3,
uint64_t x4,
- void *cookie,
+ const void *cookie,
void *handle,
uint64_t flags)
{
diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
index 1429a61..599e46e 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
@@ -99,9 +99,9 @@
ret = 0;
} else {
/* For shutdown/reboot commands, we dont have to check for timeouts */
- if ((req == (uint32_t)TEGRA_ARI_MISC_CCPLEX) &&
- ((lo == (uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF) ||
- (lo == (uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT))) {
+ if ((req == TEGRA_ARI_MISC_CCPLEX) &&
+ ((lo == TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF) ||
+ (lo == TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT))) {
ret = 0;
} else {
/*
@@ -161,38 +161,38 @@
uint32_t system, uint8_t sys_state_force, uint32_t wake_mask,
uint8_t update_wake_mask)
{
- uint32_t val = 0U;
+ uint64_t val = 0U;
/* clean the previous response state */
ari_clobber_response(ari_base);
/* update CLUSTER_CSTATE? */
if (cluster != 0U) {
- val |= (cluster & (uint32_t)CLUSTER_CSTATE_MASK) |
- (uint32_t)CLUSTER_CSTATE_UPDATE_BIT;
+ val |= (cluster & CLUSTER_CSTATE_MASK) |
+ CLUSTER_CSTATE_UPDATE_BIT;
}
/* update CCPLEX_CSTATE? */
if (ccplex != 0U) {
- val |= ((ccplex & (uint32_t)CCPLEX_CSTATE_MASK) << (uint32_t)CCPLEX_CSTATE_SHIFT) |
- (uint32_t)CCPLEX_CSTATE_UPDATE_BIT;
+ val |= ((ccplex & CCPLEX_CSTATE_MASK) << CCPLEX_CSTATE_SHIFT) |
+ CCPLEX_CSTATE_UPDATE_BIT;
}
/* update SYSTEM_CSTATE? */
if (system != 0U) {
- val |= ((system & (uint32_t)SYSTEM_CSTATE_MASK) << (uint32_t)SYSTEM_CSTATE_SHIFT) |
- (((uint32_t)sys_state_force << SYSTEM_CSTATE_FORCE_UPDATE_SHIFT) |
- (uint32_t)SYSTEM_CSTATE_UPDATE_BIT);
+ val |= ((system & SYSTEM_CSTATE_MASK) << SYSTEM_CSTATE_SHIFT) |
+ (((uint64_t)sys_state_force << SYSTEM_CSTATE_FORCE_UPDATE_SHIFT) |
+ SYSTEM_CSTATE_UPDATE_BIT);
}
/* update wake mask value? */
if (update_wake_mask != 0U) {
- val |= (uint32_t)CSTATE_WAKE_MASK_UPDATE_BIT;
+ val |= CSTATE_WAKE_MASK_UPDATE_BIT;
}
/* set the updated cstate info */
- return ari_request_wait(ari_base, 0U, TEGRA_ARI_UPDATE_CSTATE_INFO, val,
- wake_mask);
+ return ari_request_wait(ari_base, 0U, TEGRA_ARI_UPDATE_CSTATE_INFO,
+ (uint32_t)val, wake_mask);
}
int32_t ari_update_crossover_time(uint32_t ari_base, uint32_t type, uint32_t time)
@@ -299,10 +299,8 @@
int32_t ret, result;
/* check for allowed power state */
- if ((state != TEGRA_ARI_CORE_C0) &&
- (state != TEGRA_ARI_CORE_C1) &&
- (state != TEGRA_ARI_CORE_C6) &&
- (state != TEGRA_ARI_CORE_C7)) {
+ if ((state != TEGRA_ARI_CORE_C0) && (state != TEGRA_ARI_CORE_C1) &&
+ (state != TEGRA_ARI_CORE_C6) && (state != TEGRA_ARI_CORE_C7)) {
ERROR("%s: unknown cstate (%d)\n", __func__, state);
result = EINVAL;
} else {
@@ -325,10 +323,10 @@
int32_t ari_online_core(uint32_t ari_base, uint32_t core)
{
- uint64_t cpu = read_mpidr() & (uint64_t)(MPIDR_CPU_MASK);
- uint64_t cluster = (read_mpidr() & (uint64_t)(MPIDR_CLUSTER_MASK)) >>
- (uint64_t)(MPIDR_AFFINITY_BITS);
- uint64_t impl = (read_midr() >> (uint64_t)MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK;
+ uint64_t cpu = read_mpidr() & (MPIDR_CPU_MASK);
+ uint64_t cluster = (read_mpidr() & (MPIDR_CLUSTER_MASK)) >>
+ (MPIDR_AFFINITY_BITS);
+ uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
int32_t ret;
/* construct the current CPU # */
@@ -342,8 +340,7 @@
/*
* The Denver cluster has 2 CPUs only - 0, 1.
*/
- if ((impl == (uint32_t)DENVER_IMPL) &&
- ((core == 2U) || (core == 3U))) {
+ if ((impl == DENVER_IMPL) && ((core == 2U) || (core == 3U))) {
ERROR("%s: unknown core id (%d)\n", __func__, core);
ret = EINVAL;
} else {
@@ -465,7 +462,7 @@
{
int32_t ret = 0;
/* sanity check GSC ID */
- if (gsc_idx > (uint32_t)TEGRA_ARI_GSC_VPR_IDX) {
+ if (gsc_idx > TEGRA_ARI_GSC_VPR_IDX) {
ret = EINVAL;
} else {
/* clean the previous response state */
@@ -497,8 +494,8 @@
uint64_t *data)
{
int32_t ret, result;
- uint32_t val;
- uint8_t req_cmd, req_status;
+ uint32_t val, req_status;
+ uint8_t req_cmd;
req_cmd = (uint8_t)(req >> UNCORE_PERFMON_CMD_SHIFT);
@@ -523,7 +520,7 @@
result = ret;
} else {
/* read the command status value */
- req_status = (uint8_t)ari_get_response_high(ari_base) &
+ req_status = ari_get_response_high(ari_base) &
UNCORE_PERFMON_RESP_STATUS_MASK;
/*
diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
index 828ad3c..e948e99 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
@@ -111,8 +111,8 @@
static uint32_t mce_get_curr_cpu_ari_base(void)
{
uint64_t mpidr = read_mpidr();
- uint64_t cpuid = mpidr & (uint64_t)MPIDR_CPU_MASK;
- uint64_t impl = (read_midr() >> (uint64_t)MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK;
+ uint64_t cpuid = mpidr & MPIDR_CPU_MASK;
+ uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
/*
* T186 has 2 CPU clusters, one with Denver CPUs and the other with
@@ -131,9 +131,9 @@
static arch_mce_ops_t *mce_get_curr_cpu_ops(void)
{
uint64_t mpidr = read_mpidr();
- uint64_t cpuid = mpidr & (uint64_t)MPIDR_CPU_MASK;
- uint64_t impl = (read_midr() >> (uint64_t)MIDR_IMPL_SHIFT) &
- (uint64_t)MIDR_IMPL_MASK;
+ uint64_t cpuid = mpidr & MPIDR_CPU_MASK;
+ uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) &
+ MIDR_IMPL_MASK;
/*
* T186 has 2 CPU clusters, one with Denver CPUs and the other with
@@ -172,9 +172,6 @@
switch (cmd) {
case MCE_CMD_ENTER_CSTATE:
ret = ops->enter_cstate(cpu_ari_base, arg0, arg1);
- if (ret < 0) {
- ERROR("%s: enter_cstate failed(%d)\n", __func__, ret);
- }
break;
@@ -183,30 +180,22 @@
* get the parameters required for the update cstate info
* command
*/
- arg3 = read_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X4));
- arg4 = read_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X5));
- arg5 = read_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X6));
+ arg3 = read_ctx_reg(gp_regs, CTX_GPREG_X4);
+ arg4 = read_ctx_reg(gp_regs, CTX_GPREG_X5);
+ arg5 = read_ctx_reg(gp_regs, CTX_GPREG_X6);
ret = ops->update_cstate_info(cpu_ari_base, (uint32_t)arg0,
(uint32_t)arg1, (uint32_t)arg2, (uint8_t)arg3,
(uint32_t)arg4, (uint8_t)arg5);
- if (ret < 0) {
- ERROR("%s: update_cstate_info failed(%d)\n",
- __func__, ret);
- }
- write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X4), (0));
- write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X5), (0));
- write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X6), (0));
+ write_ctx_reg(gp_regs, CTX_GPREG_X4, (0ULL));
+ write_ctx_reg(gp_regs, CTX_GPREG_X5, (0ULL));
+ write_ctx_reg(gp_regs, CTX_GPREG_X6, (0ULL));
break;
case MCE_CMD_UPDATE_CROSSOVER_TIME:
ret = ops->update_crossover_time(cpu_ari_base, arg0, arg1);
- if (ret < 0) {
- ERROR("%s: update_crossover_time failed(%d)\n",
- __func__, ret);
- }
break;
@@ -214,61 +203,40 @@
ret64 = ops->read_cstate_stats(cpu_ari_base, arg0);
/* update context to return cstate stats value */
- write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1), (ret64));
- write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X2), (ret64));
+ write_ctx_reg(gp_regs, CTX_GPREG_X1, (ret64));
+ write_ctx_reg(gp_regs, CTX_GPREG_X2, (ret64));
break;
case MCE_CMD_WRITE_CSTATE_STATS:
ret = ops->write_cstate_stats(cpu_ari_base, arg0, arg1);
- if (ret < 0) {
- ERROR("%s: write_cstate_stats failed(%d)\n",
- __func__, ret);
- }
break;
case MCE_CMD_IS_CCX_ALLOWED:
ret = ops->is_ccx_allowed(cpu_ari_base, arg0, arg1);
- if (ret < 0) {
- ERROR("%s: is_ccx_allowed failed(%d)\n", __func__, ret);
- break;
- }
/* update context to return CCx status value */
- write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1),
- (uint64_t)(ret));
+ write_ctx_reg(gp_regs, CTX_GPREG_X1, (uint64_t)(ret));
break;
case MCE_CMD_IS_SC7_ALLOWED:
ret = ops->is_sc7_allowed(cpu_ari_base, arg0, arg1);
- if (ret < 0) {
- ERROR("%s: is_sc7_allowed failed(%d)\n", __func__, ret);
- break;
- }
/* update context to return SC7 status value */
- write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1),
- (uint64_t)(ret));
- write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X3),
- (uint64_t)(ret));
+ write_ctx_reg(gp_regs, CTX_GPREG_X1, (uint64_t)(ret));
+ write_ctx_reg(gp_regs, CTX_GPREG_X3, (uint64_t)(ret));
break;
case MCE_CMD_ONLINE_CORE:
ret = ops->online_core(cpu_ari_base, arg0);
- if (ret < 0) {
- ERROR("%s: online_core failed(%d)\n", __func__, ret);
- }
break;
case MCE_CMD_CC3_CTRL:
ret = ops->cc3_ctrl(cpu_ari_base, arg0, arg1, arg2);
- if (ret < 0) {
- ERROR("%s: cc3_ctrl failed(%d)\n", __func__, ret);
- }
break;
@@ -277,10 +245,10 @@
arg0);
/* update context to return if echo'd data matched source */
- write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1),
- ((ret64 == arg0) ? 1ULL : 0ULL));
- write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X2),
- ((ret64 == arg0) ? 1ULL : 0ULL));
+ write_ctx_reg(gp_regs, CTX_GPREG_X1, ((ret64 == arg0) ?
+ 1ULL : 0ULL));
+ write_ctx_reg(gp_regs, CTX_GPREG_X2, ((ret64 == arg0) ?
+ 1ULL : 0ULL));
break;
@@ -292,10 +260,8 @@
* version = minor(63:32) | major(31:0). Update context
* to return major and minor version number.
*/
- write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1),
- (ret64));
- write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X2),
- (ret64 >> 32ULL));
+ write_ctx_reg(gp_regs, CTX_GPREG_X1, (ret64));
+ write_ctx_reg(gp_regs, CTX_GPREG_X2, (ret64 >> 32ULL));
break;
@@ -304,32 +270,22 @@
TEGRA_ARI_MISC_FEATURE_LEAF_0, arg0);
/* update context to return features value */
- write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1), (ret64));
+ write_ctx_reg(gp_regs, CTX_GPREG_X1, (ret64));
break;
case MCE_CMD_ROC_FLUSH_CACHE_TRBITS:
ret = ops->roc_flush_cache_trbits(cpu_ari_base);
- if (ret < 0) {
- ERROR("%s: flush cache_trbits failed(%d)\n", __func__,
- ret);
- }
break;
case MCE_CMD_ROC_FLUSH_CACHE:
ret = ops->roc_flush_cache(cpu_ari_base);
- if (ret < 0) {
- ERROR("%s: flush cache failed(%d)\n", __func__, ret);
- }
break;
case MCE_CMD_ROC_CLEAN_CACHE:
ret = ops->roc_clean_cache(cpu_ari_base);
- if (ret < 0) {
- ERROR("%s: clean cache failed(%d)\n", __func__, ret);
- }
break;
@@ -337,9 +293,9 @@
ret64 = ops->read_write_mca(cpu_ari_base, arg0, &arg1);
/* update context to return MCA data/error */
- write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1), (ret64));
- write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X2), (arg1));
- write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X3), (ret64));
+ write_ctx_reg(gp_regs, CTX_GPREG_X1, (ret64));
+ write_ctx_reg(gp_regs, CTX_GPREG_X2, (arg1));
+ write_ctx_reg(gp_regs, CTX_GPREG_X3, (ret64));
break;
@@ -347,8 +303,8 @@
ret64 = ops->read_write_mca(cpu_ari_base, arg0, &arg1);
/* update context to return MCA error */
- write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1), (ret64));
- write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X3), (ret64));
+ write_ctx_reg(gp_regs, CTX_GPREG_X1, (ret64));
+ write_ctx_reg(gp_regs, CTX_GPREG_X3, (ret64));
break;
@@ -375,7 +331,7 @@
ret = ops->read_write_uncore_perfmon(cpu_ari_base, arg0, &arg1);
/* update context to return data */
- write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1), (arg1));
+ write_ctx_reg(gp_regs, CTX_GPREG_X1, (arg1));
break;
case MCE_CMD_MISC_CCPLEX:
diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c b/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c
index 1ac3710..44ee8fb 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c
@@ -200,15 +200,14 @@
int32_t nvg_online_core(uint32_t ari_base, uint32_t core)
{
- uint64_t cpu = read_mpidr() & (uint64_t)MPIDR_CPU_MASK;
- uint64_t impl = (read_midr() >> (uint64_t)MIDR_IMPL_SHIFT) &
- (uint64_t)MIDR_IMPL_MASK;
+ uint64_t cpu = read_mpidr() & MPIDR_CPU_MASK;
+ uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
int32_t ret = 0;
(void)ari_base;
/* sanity check code id */
- if ((core >= (uint32_t)MCE_CORE_ID_MAX) || (cpu == core)) {
+ if ((core >= MCE_CORE_ID_MAX) || (cpu == core)) {
ERROR("%s: unsupported core id (%d)\n", __func__, core);
ret = EINVAL;
} else {
diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
index fb94bce..7a9ce28 100644
--- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
@@ -12,6 +12,7 @@
#include <common/bl_common.h>
#include <common/debug.h>
#include <context.h>
+#include <cortex_a57.h>
#include <denver.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/psci/psci.h>
@@ -29,32 +30,33 @@
extern uint32_t __tegra186_cpu_reset_handler_end,
__tegra186_smmu_context;
+/* TZDRAM offset for saving SMMU context */
+#define TEGRA186_SMMU_CTX_OFFSET 16UL
+
/* state id mask */
-#define TEGRA186_STATE_ID_MASK 0xF
+#define TEGRA186_STATE_ID_MASK 0xFU
/* constants to get power state's wake time */
-#define TEGRA186_WAKE_TIME_MASK 0x0FFFFFF0
-#define TEGRA186_WAKE_TIME_SHIFT 4
+#define TEGRA186_WAKE_TIME_MASK 0x0FFFFFF0U
+#define TEGRA186_WAKE_TIME_SHIFT 4U
/* default core wake mask for CPU_SUSPEND */
-#define TEGRA186_CORE_WAKE_MASK 0x180c
+#define TEGRA186_CORE_WAKE_MASK 0x180cU
/* context size to save during system suspend */
-#define TEGRA186_SE_CONTEXT_SIZE 3
+#define TEGRA186_SE_CONTEXT_SIZE 3U
static uint32_t se_regs[TEGRA186_SE_CONTEXT_SIZE];
-static struct t18x_psci_percpu_data {
- unsigned int wake_time;
-} __aligned(CACHE_WRITEBACK_GRANULE) percpu_data[PLATFORM_CORE_COUNT];
+static struct tegra_psci_percpu_data {
+ uint32_t wake_time;
+} __aligned(CACHE_WRITEBACK_GRANULE) tegra_percpu_data[PLATFORM_CORE_COUNT];
-/* System power down state */
-uint32_t tegra186_system_powerdn_state = TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF;
-
-int32_t tegra_soc_validate_power_state(unsigned int power_state,
+int32_t tegra_soc_validate_power_state(uint32_t power_state,
psci_power_state_t *req_state)
{
- int state_id = psci_get_pstate_id(power_state) & TEGRA186_STATE_ID_MASK;
- int cpu = plat_my_core_pos();
+ uint8_t state_id = (uint8_t)psci_get_pstate_id(power_state) & TEGRA186_STATE_ID_MASK;
+ uint32_t cpu = plat_my_core_pos();
+ int32_t ret = PSCI_E_SUCCESS;
/* save the core wake time (in TSC ticks)*/
- percpu_data[cpu].wake_time = (power_state & TEGRA186_WAKE_TIME_MASK)
+ tegra_percpu_data[cpu].wake_time = (power_state & TEGRA186_WAKE_TIME_MASK)
<< TEGRA186_WAKE_TIME_SHIFT;
/*
@@ -64,8 +66,8 @@
* from DRAM in that function, because the L2 cache is not flushed
* unless the cluster is entering CC6/CC7.
*/
- clean_dcache_range((uint64_t)&percpu_data[cpu],
- sizeof(percpu_data[cpu]));
+ clean_dcache_range((uint64_t)&tegra_percpu_data[cpu],
+ sizeof(tegra_percpu_data[cpu]));
/* Sanity check the requested state id */
switch (state_id) {
@@ -80,18 +82,19 @@
default:
ERROR("%s: unsupported state id (%d)\n", __func__, state_id);
- return PSCI_E_INVALID_PARAMS;
+ ret = PSCI_E_INVALID_PARAMS;
+ break;
}
- return PSCI_E_SUCCESS;
+ return ret;
}
-int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
+int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
{
const plat_local_state_t *pwr_domain_state;
- unsigned int stateid_afflvl0, stateid_afflvl2;
- int cpu = plat_my_core_pos();
- plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+ uint8_t stateid_afflvl0, stateid_afflvl2;
+ uint32_t cpu = plat_my_core_pos();
+ const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
mce_cstate_info_t cstate_info = { 0 };
uint64_t smmu_ctx_base;
uint32_t val;
@@ -109,8 +112,8 @@
/* Enter CPU idle/powerdown */
val = (stateid_afflvl0 == PSTATE_ID_CORE_IDLE) ?
TEGRA_ARI_CORE_C6 : TEGRA_ARI_CORE_C7;
- (void)mce_command_handler(MCE_CMD_ENTER_CSTATE, val,
- percpu_data[cpu].wake_time, 0);
+ (void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE, (uint64_t)val,
+ tegra_percpu_data[cpu].wake_time, 0U);
} else if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
@@ -138,18 +141,20 @@
cstate_info.system_state_force = 1;
cstate_info.update_wake_mask = 1;
mce_update_cstate_info(&cstate_info);
-
/* Loop until system suspend is allowed */
do {
- val = mce_command_handler(MCE_CMD_IS_SC7_ALLOWED,
+ val = (uint32_t)mce_command_handler(
+ (uint64_t)MCE_CMD_IS_SC7_ALLOWED,
TEGRA_ARI_CORE_C7,
MCE_CORE_SLEEP_TIME_INFINITE,
- 0);
- } while (val == 0);
+ 0U);
+ } while (val == 0U);
/* Instruct the MCE to enter system suspend state */
- (void)mce_command_handler(MCE_CMD_ENTER_CSTATE,
- TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0);
+ (void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE,
+ TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0U);
+ } else {
+ ; /* do nothing */
}
return PSCI_E_SUCCESS;
@@ -159,23 +164,28 @@
* Platform handler to calculate the proper target power level at the
* specified affinity level
******************************************************************************/
-plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl,
+plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl,
const plat_local_state_t *states,
- unsigned int ncpu)
+ uint32_t ncpu)
{
plat_local_state_t target = *states;
- int cpu = plat_my_core_pos(), ret, cluster_powerdn = 1;
- int core_pos = read_mpidr() & MPIDR_CPU_MASK;
+ uint32_t pos = 0;
+ plat_local_state_t result = PSCI_LOCAL_STATE_RUN;
+ uint32_t cpu = plat_my_core_pos(), num_cpu = ncpu;
+ int32_t ret, cluster_powerdn = 1;
+ uint64_t core_pos = read_mpidr() & (uint64_t)MPIDR_CPU_MASK;
mce_cstate_info_t cstate_info = { 0 };
/* get the power state at this level */
- if (lvl == MPIDR_AFFLVL1)
- target = *(states + core_pos);
- if (lvl == MPIDR_AFFLVL2)
- target = *(states + cpu);
+ if (lvl == (uint32_t)MPIDR_AFFLVL1) {
+ target = states[core_pos];
+ }
+ if (lvl == (uint32_t)MPIDR_AFFLVL2) {
+ target = states[cpu];
+ }
/* CPU suspend */
- if (lvl == MPIDR_AFFLVL1 && target == PSTATE_ID_CORE_POWERDN) {
+ if ((lvl == (uint32_t)MPIDR_AFFLVL1) && (target == PSTATE_ID_CORE_POWERDN)) {
/* Program default wake mask */
cstate_info.wake_mask = TEGRA186_CORE_WAKE_MASK;
@@ -183,25 +193,29 @@
mce_update_cstate_info(&cstate_info);
/* Check if CCx state is allowed. */
- ret = mce_command_handler(MCE_CMD_IS_CCX_ALLOWED,
- TEGRA_ARI_CORE_C7, percpu_data[cpu].wake_time,
- 0);
- if (ret)
- return PSTATE_ID_CORE_POWERDN;
+ ret = mce_command_handler((uint64_t)MCE_CMD_IS_CCX_ALLOWED,
+ TEGRA_ARI_CORE_C7, tegra_percpu_data[cpu].wake_time,
+ 0U);
+ if (ret != 0) {
+ result = PSTATE_ID_CORE_POWERDN;
+ }
}
/* CPU off */
- if (lvl == MPIDR_AFFLVL1 && target == PLAT_MAX_OFF_STATE) {
+ if ((lvl == (uint32_t)MPIDR_AFFLVL1) && (target == PLAT_MAX_OFF_STATE)) {
/* find out the number of ON cpus in the cluster */
do {
- target = *states++;
- if (target != PLAT_MAX_OFF_STATE)
+ target = states[pos];
+ if (target != PLAT_MAX_OFF_STATE) {
cluster_powerdn = 0;
- } while (--ncpu);
+ }
+ --num_cpu;
+ pos++;
+ } while (num_cpu != 0U);
/* Enable cluster powerdn from last CPU in the cluster */
- if (cluster_powerdn) {
+ if (cluster_powerdn != 0) {
/* Enable CC7 state and turn off wake mask */
cstate_info.cluster = TEGRA_ARI_CLUSTER_CC7;
@@ -209,12 +223,13 @@
mce_update_cstate_info(&cstate_info);
/* Check if CCx state is allowed. */
- ret = mce_command_handler(MCE_CMD_IS_CCX_ALLOWED,
+ ret = mce_command_handler((uint64_t)MCE_CMD_IS_CCX_ALLOWED,
TEGRA_ARI_CORE_C7,
MCE_CORE_SLEEP_TIME_INFINITE,
- 0);
- if (ret)
- return PSTATE_ID_CORE_POWERDN;
+ 0U);
+ if (ret != 0) {
+ result = PSTATE_ID_CORE_POWERDN;
+ }
} else {
@@ -225,20 +240,21 @@
}
/* System Suspend */
- if (((lvl == MPIDR_AFFLVL2) || (lvl == MPIDR_AFFLVL1)) &&
- (target == PSTATE_ID_SOC_POWERDN))
- return PSTATE_ID_SOC_POWERDN;
+ if (((lvl == (uint32_t)MPIDR_AFFLVL2) || (lvl == (uint32_t)MPIDR_AFFLVL1)) &&
+ (target == PSTATE_ID_SOC_POWERDN)) {
+ result = PSTATE_ID_SOC_POWERDN;
+ }
/* default state */
- return PSCI_LOCAL_STATE_RUN;
+ return result;
}
-int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
+int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
{
const plat_local_state_t *pwr_domain_state =
target_state->pwr_domain_state;
- plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
- unsigned int stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] &
+ const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+ uint8_t stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] &
TEGRA186_STATE_ID_MASK;
uint64_t val;
@@ -250,7 +266,7 @@
*/
val = params_from_bl2->tzdram_base +
((uintptr_t)&__tegra186_cpu_reset_handler_end -
- (uintptr_t)tegra186_cpu_reset_handler);
+ (uintptr_t)&tegra186_cpu_reset_handler);
memcpy16((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE,
(uintptr_t)&__BL31_END__ - (uintptr_t)BL31_BASE);
}
@@ -258,32 +274,51 @@
return PSCI_E_SUCCESS;
}
-int tegra_soc_pwr_domain_on(u_register_t mpidr)
+int32_t tegra_soc_pwr_domain_on(u_register_t mpidr)
{
- uint32_t target_cpu = mpidr & MPIDR_CPU_MASK;
+ uint32_t target_cpu = mpidr & (uint64_t)MPIDR_CPU_MASK;
uint32_t target_cluster = (mpidr & MPIDR_CLUSTER_MASK) >>
- MPIDR_AFFINITY_BITS;
+ (uint64_t)MPIDR_AFFINITY_BITS;
+ int32_t ret = PSCI_E_SUCCESS;
- if (target_cluster > MPIDR_AFFLVL1) {
+ if (target_cluster > (uint64_t)MPIDR_AFFLVL1) {
+
ERROR("%s: unsupported CPU (0x%lx)\n", __func__, mpidr);
- return PSCI_E_NOT_PRESENT;
- }
+ ret = PSCI_E_NOT_PRESENT;
- /* construct the target CPU # */
- target_cpu |= (target_cluster << 2);
+ } else {
+ /* construct the target CPU # */
+ target_cpu |= (target_cluster << 2);
- mce_command_handler(MCE_CMD_ONLINE_CORE, target_cpu, 0, 0);
+ (void)mce_command_handler((uint64_t)MCE_CMD_ONLINE_CORE, target_cpu, 0U, 0U);
+ }
- return PSCI_E_SUCCESS;
+ return ret;
}
-int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
+int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
- int stateid_afflvl2 = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL];
- int stateid_afflvl0 = target_state->pwr_domain_state[MPIDR_AFFLVL0];
+ uint8_t stateid_afflvl2 = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL];
+ uint8_t stateid_afflvl0 = target_state->pwr_domain_state[MPIDR_AFFLVL0];
mce_cstate_info_t cstate_info = { 0 };
+ uint64_t impl, val;
+ const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
+
+ impl = (read_midr() >> MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK;
/*
+ * Enable ECC and Parity Protection for Cortex-A57 CPUs (Tegra186
+ * A02p and beyond).
+ */
+ if ((plat_params->l2_ecc_parity_prot_dis != 1) &&
+ (impl != (uint64_t)DENVER_IMPL)) {
+
+ val = read_l2ctlr_el1();
+ val |= CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT;
+ write_l2ctlr_el1(val);
+ }
+
+ /*
* Reset power state info for CPUs when onlining, we set
* deepest power when offlining a core but that may not be
* requested by non-secure sw which controls idle states. It
@@ -328,65 +363,28 @@
return PSCI_E_SUCCESS;
}
-int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
+int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
{
- int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
+ uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK;
+
+ (void)target_state;
/* Disable Denver's DCO operations */
- if (impl == DENVER_IMPL)
+ if (impl == DENVER_IMPL) {
denver_disable_dco();
+ }
/* Turn off CPU */
- (void)mce_command_handler(MCE_CMD_ENTER_CSTATE, TEGRA_ARI_CORE_C7,
- MCE_CORE_SLEEP_TIME_INFINITE, 0);
+ (void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE, TEGRA_ARI_CORE_C7,
+ MCE_CORE_SLEEP_TIME_INFINITE, 0U);
return PSCI_E_SUCCESS;
}
__dead2 void tegra_soc_prepare_system_off(void)
{
- mce_cstate_info_t cstate_info = { 0 };
- uint32_t val;
-
- if (tegra186_system_powerdn_state == TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF) {
-
- /* power off the entire system */
- mce_enter_ccplex_state(tegra186_system_powerdn_state);
-
- } else if (tegra186_system_powerdn_state == TEGRA_ARI_SYSTEM_SC8) {
-
- /* Prepare for quasi power down */
- cstate_info.cluster = TEGRA_ARI_CLUSTER_CC7;
- cstate_info.system = TEGRA_ARI_SYSTEM_SC8;
- cstate_info.system_state_force = 1;
- cstate_info.update_wake_mask = 1;
- mce_update_cstate_info(&cstate_info);
-
- /* loop until other CPUs power down */
- do {
- val = mce_command_handler(MCE_CMD_IS_SC7_ALLOWED,
- TEGRA_ARI_CORE_C7,
- MCE_CORE_SLEEP_TIME_INFINITE,
- 0);
- } while (val == 0);
-
- /* Enter quasi power down state */
- (void)mce_command_handler(MCE_CMD_ENTER_CSTATE,
- TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0);
-
- /* disable GICC */
- tegra_gic_cpuif_deactivate();
-
- /* power down core */
- prepare_cpu_pwr_dwn();
-
- /* flush L1/L2 data caches */
- dcsw_op_all(DCCISW);
-
- } else {
- ERROR("%s: unsupported power down state (%d)\n", __func__,
- tegra186_system_powerdn_state);
- }
+ /* power off the entire system */
+ mce_enter_ccplex_state(TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF);
wfi();
@@ -396,7 +394,7 @@
}
}
-int tegra_soc_prepare_system_reset(void)
+int32_t tegra_soc_prepare_system_reset(void)
{
mce_enter_ccplex_state(TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT);
diff --git a/plat/nvidia/tegra/soc/t186/plat_secondary.c b/plat/nvidia/tegra/soc/t186/plat_secondary.c
index 4485e27..35a403b 100644
--- a/plat/nvidia/tegra/soc/t186/plat_secondary.c
+++ b/plat/nvidia/tegra/soc/t186/plat_secondary.c
@@ -14,14 +14,13 @@
#include <tegra_def.h>
#include <tegra_private.h>
-#define MISCREG_CPU_RESET_VECTOR 0x2000
-#define MISCREG_AA64_RST_LOW 0x2004
-#define MISCREG_AA64_RST_HIGH 0x2008
+#define MISCREG_AA64_RST_LOW 0x2004U
+#define MISCREG_AA64_RST_HIGH 0x2008U
-#define SCRATCH_SECURE_RSV1_SCRATCH_0 0x658
-#define SCRATCH_SECURE_RSV1_SCRATCH_1 0x65C
+#define SCRATCH_SECURE_RSV1_SCRATCH_0 0x658U
+#define SCRATCH_SECURE_RSV1_SCRATCH_1 0x65CU
-#define CPU_RESET_MODE_AA64 1
+#define CPU_RESET_MODE_AA64 1U
extern void memcpy16(void *dest, const void *src, unsigned int length);
@@ -34,7 +33,7 @@
void plat_secondary_setup(void)
{
uint32_t addr_low, addr_high;
- plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+ const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
uint64_t cpu_reset_handler_base;
INFO("Setting up secondary CPU boot\n");
@@ -58,7 +57,7 @@
}
addr_low = (uint32_t)cpu_reset_handler_base | CPU_RESET_MODE_AA64;
- addr_high = (uint32_t)((cpu_reset_handler_base >> 32) & 0x7ff);
+ addr_high = (uint32_t)((cpu_reset_handler_base >> 32U) & 0x7ffU);
/* write lower 32 bits first, then the upper 11 bits */
mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_LOW, addr_low);
@@ -71,5 +70,5 @@
addr_high);
/* update reset vector address to the CCPLEX */
- mce_update_reset_vector();
+ (void)mce_update_reset_vector();
}
diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c
index 15dbd16..bbd19c1 100644
--- a/plat/nvidia/tegra/soc/t186/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t186/plat_setup.c
@@ -27,15 +27,12 @@
#include <tegra_platform.h>
#include <tegra_private.h>
-DEFINE_RENAME_SYSREG_RW_FUNCS(l2ctlr_el1, CORTEX_A57_L2CTLR_EL1)
-extern uint64_t tegra_enable_l2_ecc_parity_prot;
-
/*******************************************************************************
* Tegra186 CPU numbers in cluster #0
*******************************************************************************
*/
-#define TEGRA186_CLUSTER0_CORE2 2
-#define TEGRA186_CLUSTER0_CORE3 3
+#define TEGRA186_CLUSTER0_CORE2 2U
+#define TEGRA186_CLUSTER0_CORE3 3U
/*******************************************************************************
* The Tegra power domain tree has a single system level power domain i.e. a
@@ -43,7 +40,7 @@
* the number of power domains at the highest power level.
*******************************************************************************
*/
-const unsigned char tegra_power_domain_tree_desc[] = {
+const uint8_t tegra_power_domain_tree_desc[] = {
/* No of root nodes */
1,
/* No of clusters */
@@ -54,45 +51,53 @@
PLATFORM_MAX_CPUS_PER_CLUSTER
};
+/*******************************************************************************
+ * This function returns the Tegra default topology tree information.
+ ******************************************************************************/
+const uint8_t *plat_get_power_domain_tree_desc(void)
+{
+ return tegra_power_domain_tree_desc;
+}
+
/*
* Table of regions to map using the MMU.
*/
static const mmap_region_t tegra_mmap[] = {
- MAP_REGION_FLAT(TEGRA_MISC_BASE, 0x10000, /* 64KB */
+ MAP_REGION_FLAT(TEGRA_MISC_BASE, 0x10000U, /* 64KB */
MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(TEGRA_TSA_BASE, 0x20000, /* 128KB */
+ MAP_REGION_FLAT(TEGRA_TSA_BASE, 0x20000U, /* 128KB */
MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(TEGRA_MC_STREAMID_BASE, 0x10000, /* 64KB */
+ MAP_REGION_FLAT(TEGRA_MC_STREAMID_BASE, 0x10000U, /* 64KB */
MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(TEGRA_MC_BASE, 0x10000, /* 64KB */
+ MAP_REGION_FLAT(TEGRA_MC_BASE, 0x10000U, /* 64KB */
MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(TEGRA_UARTA_BASE, 0x20000, /* 128KB - UART A, B*/
+ MAP_REGION_FLAT(TEGRA_UARTA_BASE, 0x20000U, /* 128KB - UART A, B*/
MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(TEGRA_UARTC_BASE, 0x20000, /* 128KB - UART C, G */
+ MAP_REGION_FLAT(TEGRA_UARTC_BASE, 0x20000U, /* 128KB - UART C, G */
MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(TEGRA_UARTD_BASE, 0x30000, /* 192KB - UART D, E, F */
+ MAP_REGION_FLAT(TEGRA_UARTD_BASE, 0x30000U, /* 192KB - UART D, E, F */
MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(TEGRA_FUSE_BASE, 0x10000, /* 64KB */
+ MAP_REGION_FLAT(TEGRA_FUSE_BASE, 0x10000U, /* 64KB */
MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(TEGRA_GICD_BASE, 0x20000, /* 128KB */
+ MAP_REGION_FLAT(TEGRA_GICD_BASE, 0x20000U, /* 128KB */
MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(TEGRA_SE0_BASE, 0x10000, /* 64KB */
+ MAP_REGION_FLAT(TEGRA_SE0_BASE, 0x10000U, /* 64KB */
MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(TEGRA_PKA1_BASE, 0x10000, /* 64KB */
+ MAP_REGION_FLAT(TEGRA_PKA1_BASE, 0x10000U, /* 64KB */
MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(TEGRA_RNG1_BASE, 0x10000, /* 64KB */
+ MAP_REGION_FLAT(TEGRA_RNG1_BASE, 0x10000U, /* 64KB */
MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(TEGRA_CAR_RESET_BASE, 0x10000, /* 64KB */
+ MAP_REGION_FLAT(TEGRA_CAR_RESET_BASE, 0x10000U, /* 64KB */
MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(TEGRA_PMC_BASE, 0x40000, /* 256KB */
+ MAP_REGION_FLAT(TEGRA_PMC_BASE, 0x40000U, /* 256KB */
MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(TEGRA_SCRATCH_BASE, 0x10000, /* 64KB */
+ MAP_REGION_FLAT(TEGRA_SCRATCH_BASE, 0x10000U, /* 64KB */
MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(TEGRA_MMCRAB_BASE, 0x60000, /* 384KB */
+ MAP_REGION_FLAT(TEGRA_MMCRAB_BASE, 0x60000U, /* 384KB */
MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(TEGRA_ARM_ACTMON_CTR_BASE, 0x20000, /* 128KB - ARM/Denver */
+ MAP_REGION_FLAT(TEGRA_ARM_ACTMON_CTR_BASE, 0x20000U, /* 128KB - ARM/Denver */
MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(TEGRA_SMMU0_BASE, 0x1000000, /* 64KB */
+ MAP_REGION_FLAT(TEGRA_SMMU0_BASE, 0x1000000U, /* 64KB */
MT_DEVICE | MT_RW | MT_SECURE),
{0}
};
@@ -109,7 +114,7 @@
/*******************************************************************************
* Handler to get the System Counter Frequency
******************************************************************************/
-unsigned int plat_get_syscnt_freq2(void)
+uint32_t plat_get_syscnt_freq2(void)
{
return 31250000;
}
@@ -136,56 +141,42 @@
/*******************************************************************************
* Retrieve the UART controller base to be used as the console
******************************************************************************/
-uint32_t plat_get_console_from_id(int id)
+uint32_t plat_get_console_from_id(int32_t id)
{
- if (id > TEGRA186_MAX_UART_PORTS)
- return 0;
+ uint32_t ret;
- return tegra186_uart_addresses[id];
-}
+ if (id > TEGRA186_MAX_UART_PORTS) {
+ ret = 0;
+ } else {
+ ret = tegra186_uart_addresses[id];
+ }
-/* represent chip-version as concatenation of major (15:12), minor (11:8) and subrev (7:0) */
-#define TEGRA186_VER_A02P 0x1201
+ return ret;
+}
/*******************************************************************************
* Handler for early platform setup
******************************************************************************/
void plat_early_platform_setup(void)
{
- int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
- uint32_t chip_subrev, val;
+ uint64_t impl, val;
+ const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
/* sanity check MCE firmware compatibility */
mce_verify_firmware_version();
+ impl = (read_midr() >> MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK;
+
/*
- * Enable ECC and Parity Protection for Cortex-A57 CPUs
- * for Tegra A02p SKUs
+ * Enable ECC and Parity Protection for Cortex-A57 CPUs (Tegra186
+ * A02p and beyond).
*/
- if (impl != DENVER_IMPL) {
-
- /* get the major, minor and sub-version values */
- chip_subrev = mmio_read_32(TEGRA_FUSE_BASE + OPT_SUBREVISION) &
- SUBREVISION_MASK;
+ if ((plat_params->l2_ecc_parity_prot_dis != 1) &&
+ (impl != (uint64_t)DENVER_IMPL)) {
- /* prepare chip version number */
- val = (tegra_get_chipid_major() << 12) |
- (tegra_get_chipid_minor() << 8) |
- chip_subrev;
-
- /* enable L2 ECC for Tegra186 A02P and beyond */
- if (val >= TEGRA186_VER_A02P) {
-
- val = read_l2ctlr_el1();
- val |= CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT;
- write_l2ctlr_el1(val);
-
- /*
- * Set the flag to enable ECC/Parity Protection
- * when we exit System Suspend or Cluster Powerdn
- */
- tegra_enable_l2_ecc_parity_prot = 1;
- }
+ val = read_l2ctlr_el1();
+ val |= CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT;
+ write_l2ctlr_el1(val);
}
}
@@ -208,8 +199,9 @@
* Initialize the FIQ handler only if the platform supports any
* FIQ interrupt sources.
*/
- if (sizeof(tegra186_interrupt_props) > 0)
+ if (sizeof(tegra186_interrupt_props) > 0U) {
tegra_fiq_handler_setup();
+ }
}
/*******************************************************************************
@@ -242,33 +234,34 @@
* to convert an MPIDR to a unique linear index. An error code (-1) is returned
* in case the MPIDR is invalid.
******************************************************************************/
-int plat_core_pos_by_mpidr(u_register_t mpidr)
+int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
{
- unsigned int cluster_id, cpu_id, pos;
+ u_register_t cluster_id, cpu_id, pos;
+ int32_t ret;
- cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
- cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+ cluster_id = (mpidr >> (u_register_t)MPIDR_AFF1_SHIFT) & (u_register_t)MPIDR_AFFLVL_MASK;
+ cpu_id = (mpidr >> (u_register_t)MPIDR_AFF0_SHIFT) & (u_register_t)MPIDR_AFFLVL_MASK;
/*
* Validate cluster_id by checking whether it represents
* one of the two clusters present on the platform.
- */
- if (cluster_id >= PLATFORM_CLUSTER_COUNT)
- return PSCI_E_NOT_PRESENT;
-
- /*
* Validate cpu_id by checking whether it represents a CPU in
* one of the two clusters present on the platform.
*/
- if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER)
- return PSCI_E_NOT_PRESENT;
+ if ((cluster_id >= (u_register_t)PLATFORM_CLUSTER_COUNT) ||
+ (cpu_id >= (u_register_t)PLATFORM_MAX_CPUS_PER_CLUSTER)) {
+ ret = PSCI_E_NOT_PRESENT;
+ } else {
+ /* calculate the core position */
+ pos = cpu_id + (cluster_id << 2U);
- /* calculate the core position */
- pos = cpu_id + (cluster_id << 2);
-
- /* check for non-existent CPUs */
- if (pos == TEGRA186_CLUSTER0_CORE2 || pos == TEGRA186_CLUSTER0_CORE3)
- return PSCI_E_NOT_PRESENT;
+ /* check for non-existent CPUs */
+ if ((pos == TEGRA186_CLUSTER0_CORE2) || (pos == TEGRA186_CLUSTER0_CORE3)) {
+ ret = PSCI_E_NOT_PRESENT;
+ } else {
+ ret = (int32_t)pos;
+ }
+ }
- return pos;
+ return ret;
}
diff --git a/plat/nvidia/tegra/soc/t186/plat_sip_calls.c b/plat/nvidia/tegra/soc/t186/plat_sip_calls.c
index bf98fcf..955029e 100644
--- a/plat/nvidia/tegra/soc/t186/plat_sip_calls.c
+++ b/plat/nvidia/tegra/soc/t186/plat_sip_calls.c
@@ -20,8 +20,6 @@
#include <t18x_ari.h>
#include <tegra_private.h>
-extern uint32_t tegra186_system_powerdn_state;
-
/*******************************************************************************
* Offset to read the ref_clk counter value
******************************************************************************/
@@ -30,7 +28,6 @@
/*******************************************************************************
* Tegra186 SiP SMCs
******************************************************************************/
-#define TEGRA_SIP_SYSTEM_SHUTDOWN_STATE 0xC2FFFE01
#define TEGRA_SIP_GET_ACTMON_CLK_COUNTERS 0xC2FFFE02
#define TEGRA_SIP_MCE_CMD_ENTER_CSTATE 0xC2FFFF00
#define TEGRA_SIP_MCE_CMD_UPDATE_CSTATE_INFO 0xC2FFFF01
@@ -60,7 +57,7 @@
uint64_t x2,
uint64_t x3,
uint64_t x4,
- void *cookie,
+ const void *cookie,
void *handle,
uint64_t flags)
{
@@ -115,33 +112,6 @@
return 0;
- case TEGRA_SIP_SYSTEM_SHUTDOWN_STATE:
-
- /* clean up the high bits */
- x1 = (uint32_t)x1;
-
- /*
- * SC8 is a special Tegra186 system state where the CPUs and
- * DRAM are powered down but the other subsystem is still
- * alive.
- */
- if ((x1 == TEGRA_ARI_SYSTEM_SC8) ||
- (x1 == TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF)) {
-
- tegra186_system_powerdn_state = x1;
- flush_dcache_range(
- (uintptr_t)&tegra186_system_powerdn_state,
- sizeof(tegra186_system_powerdn_state));
-
- } else {
-
- ERROR("%s: unhandled powerdn state (%d)\n", __func__,
- (uint32_t)x1);
- return -ENOTSUP;
- }
-
- return 0;
-
/*
* This function ID reads the Activity monitor's core/ref clock
* counter values for a core/cluster.
diff --git a/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h b/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h
new file mode 100644
index 0000000..0157747
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SE_PRIVATE_H
+#define SE_PRIVATE_H
+
+#include <stdbool.h>
+#include <security_engine.h>
+
+/*
+ * PMC registers
+ */
+
+/* Secure scratch registers */
+#define PMC_SECURE_SCRATCH4_OFFSET 0xC0U
+#define PMC_SECURE_SCRATCH5_OFFSET 0xC4U
+#define PMC_SECURE_SCRATCH6_OFFSET 0x224U
+#define PMC_SECURE_SCRATCH7_OFFSET 0x228U
+#define PMC_SECURE_SCRATCH120_OFFSET 0xB38U
+#define PMC_SECURE_SCRATCH121_OFFSET 0xB3CU
+#define PMC_SECURE_SCRATCH122_OFFSET 0xB40U
+#define PMC_SECURE_SCRATCH123_OFFSET 0xB44U
+
+/*
+ * AHB arbitration memory write queue
+ */
+#define ARAHB_MEM_WRQUE_MST_ID_OFFSET 0xFCU
+#define ARAHB_MST_ID_SE2_MASK (0x1U << 13)
+#define ARAHB_MST_ID_SE_MASK (0x1U << 14)
+
+/* SE Status register */
+#define SE_STATUS_OFFSET 0x800U
+#define SE_STATUS_SHIFT 0
+#define SE_STATUS_IDLE \
+ ((0U) << SE_STATUS_SHIFT)
+#define SE_STATUS_BUSY \
+ ((1U) << SE_STATUS_SHIFT)
+#define SE_STATUS(x) \
+ ((x) & ((0x3U) << SE_STATUS_SHIFT))
+
+/* SE config register */
+#define SE_CONFIG_REG_OFFSET 0x14U
+#define SE_CONFIG_ENC_ALG_SHIFT 12
+#define SE_CONFIG_ENC_ALG_AES_ENC \
+ ((1U) << SE_CONFIG_ENC_ALG_SHIFT)
+#define SE_CONFIG_ENC_ALG_RNG \
+ ((2U) << SE_CONFIG_ENC_ALG_SHIFT)
+#define SE_CONFIG_ENC_ALG_SHA \
+ ((3U) << SE_CONFIG_ENC_ALG_SHIFT)
+#define SE_CONFIG_ENC_ALG_RSA \
+ ((4U) << SE_CONFIG_ENC_ALG_SHIFT)
+#define SE_CONFIG_ENC_ALG_NOP \
+ ((0U) << SE_CONFIG_ENC_ALG_SHIFT)
+#define SE_CONFIG_ENC_ALG(x) \
+ ((x) & ((0xFU) << SE_CONFIG_ENC_ALG_SHIFT))
+
+#define SE_CONFIG_DEC_ALG_SHIFT 8
+#define SE_CONFIG_DEC_ALG_AES \
+ ((1U) << SE_CONFIG_DEC_ALG_SHIFT)
+#define SE_CONFIG_DEC_ALG_NOP \
+ ((0U) << SE_CONFIG_DEC_ALG_SHIFT)
+#define SE_CONFIG_DEC_ALG(x) \
+ ((x) & ((0xFU) << SE_CONFIG_DEC_ALG_SHIFT))
+
+#define SE_CONFIG_DST_SHIFT 2
+#define SE_CONFIG_DST_MEMORY \
+ ((0U) << SE_CONFIG_DST_SHIFT)
+#define SE_CONFIG_DST_HASHREG \
+ ((1U) << SE_CONFIG_DST_SHIFT)
+#define SE_CONFIG_DST_KEYTAB \
+ ((2U) << SE_CONFIG_DST_SHIFT)
+#define SE_CONFIG_DST_SRK \
+ ((3U) << SE_CONFIG_DST_SHIFT)
+#define SE_CONFIG_DST_RSAREG \
+ ((4U) << SE_CONFIG_DST_SHIFT)
+#define SE_CONFIG_DST(x) \
+ ((x) & ((0x7U) << SE_CONFIG_DST_SHIFT))
+
+/* DRBG random number generator config */
+#define SE_RNG_CONFIG_REG_OFFSET 0x340
+
+#define DRBG_MODE_SHIFT 0
+#define DRBG_MODE_NORMAL \
+ ((0UL) << DRBG_MODE_SHIFT)
+#define DRBG_MODE_FORCE_INSTANTION \
+ ((1UL) << DRBG_MODE_SHIFT)
+#define DRBG_MODE_FORCE_RESEED \
+ ((2UL) << DRBG_MODE_SHIFT)
+#define SE_RNG_CONFIG_MODE(x) \
+ ((x) & ((0x3UL) << DRBG_MODE_SHIFT))
+
+#define DRBG_SRC_SHIFT 2
+#define DRBG_SRC_NONE \
+ ((0UL) << DRBG_SRC_SHIFT)
+#define DRBG_SRC_ENTROPY \
+ ((1UL) << DRBG_SRC_SHIFT)
+#define DRBG_SRC_LFSR \
+ ((2UL) << DRBG_SRC_SHIFT)
+#define SE_RNG_SRC_CONFIG_MODE(x) \
+ ((x) & ((0x3UL) << DRBG_SRC_SHIFT))
+
+/* DRBG random number generator entropy config */
+#define SE_RNG_SRC_CONFIG_REG_OFFSET 0x344U
+
+#define DRBG_RO_ENT_SRC_SHIFT 1
+#define DRBG_RO_ENT_SRC_ENABLE \
+ ((1U) << DRBG_RO_ENT_SRC_SHIFT)
+#define DRBG_RO_ENT_SRC_DISABLE \
+ ((0U) << DRBG_RO_ENT_SRC_SHIFT)
+#define SE_RNG_SRC_CONFIG_RO_ENT_SRC(x) \
+ ((x) & ((0x1U) << DRBG_RO_ENT_SRC_SHIFT))
+
+#define DRBG_RO_ENT_SRC_LOCK_SHIFT 0
+#define DRBG_RO_ENT_SRC_LOCK_ENABLE \
+ ((1U) << DRBG_RO_ENT_SRC_LOCK_SHIFT)
+#define DRBG_RO_ENT_SRC_LOCK_DISABLE \
+ ((0U) << DRBG_RO_ENT_SRC_LOCK_SHIFT)
+#define SE_RNG_SRC_CONFIG_RO_ENT_SRC_LOCK(x) \
+ ((x) & ((0x1U) << DRBG_RO_ENT_SRC_LOCK_SHIFT))
+
+#define DRBG_RO_ENT_IGNORE_MEM_SHIFT 12
+#define DRBG_RO_ENT_IGNORE_MEM_ENABLE \
+ ((1U) << DRBG_RO_ENT_IGNORE_MEM_SHIFT)
+#define DRBG_RO_ENT_IGNORE_MEM_DISABLE \
+ ((0U) << DRBG_RO_ENT_IGNORE_MEM_SHIFT)
+#define SE_RNG_SRC_CONFIG_RO_ENT_IGNORE_MEM(x) \
+ ((x) & ((0x1U) << DRBG_RO_ENT_IGNORE_MEM_SHIFT))
+
+/* SE OPERATION */
+#define SE_OPERATION_REG_OFFSET 0x8U
+#define SE_OPERATION_SHIFT 0
+#define SE_OP_ABORT \
+ ((0x0U) << SE_OPERATION_SHIFT)
+#define SE_OP_START \
+ ((0x1U) << SE_OPERATION_SHIFT)
+#define SE_OP_RESTART \
+ ((0x2U) << SE_OPERATION_SHIFT)
+#define SE_OP_CTX_SAVE \
+ ((0x3U) << SE_OPERATION_SHIFT)
+#define SE_OP_RESTART_IN \
+ ((0x4U) << SE_OPERATION_SHIFT)
+#define SE_OPERATION(x) \
+ ((x) & ((0x7U) << SE_OPERATION_SHIFT))
+
+/* SE_CTX_SAVE_AUTO */
+#define SE_CTX_SAVE_AUTO_REG_OFFSET 0x74U
+
+/* Enable */
+#define SE_CTX_SAVE_AUTO_ENABLE_SHIFT 0
+#define SE_CTX_SAVE_AUTO_DIS \
+ ((0U) << SE_CTX_SAVE_AUTO_ENABLE_SHIFT)
+#define SE_CTX_SAVE_AUTO_EN \
+ ((1U) << SE_CTX_SAVE_AUTO_ENABLE_SHIFT)
+#define SE_CTX_SAVE_AUTO_ENABLE(x) \
+ ((x) & ((0x1U) << SE_CTX_SAVE_AUTO_ENABLE_SHIFT))
+
+/* Lock */
+#define SE_CTX_SAVE_AUTO_LOCK_SHIFT 8
+#define SE_CTX_SAVE_AUTO_LOCK_EN \
+ ((1U) << SE_CTX_SAVE_AUTO_LOCK_SHIFT)
+#define SE_CTX_SAVE_AUTO_LOCK_DIS \
+ ((0U) << SE_CTX_SAVE_AUTO_LOCK_SHIFT)
+#define SE_CTX_SAVE_AUTO_LOCK(x) \
+ ((x) & ((0x1U) << SE_CTX_SAVE_AUTO_LOCK_SHIFT))
+
+/* Current context save number of blocks */
+#define SE_CTX_SAVE_AUTO_CURR_CNT_SHIFT 16
+#define SE_CTX_SAVE_AUTO_CURR_CNT_MASK 0x3FFU
+#define SE_CTX_SAVE_GET_BLK_COUNT(x) \
+ (((x) >> SE_CTX_SAVE_AUTO_CURR_CNT_SHIFT) & \
+ SE_CTX_SAVE_AUTO_CURR_CNT_MASK)
+
+#define SE_CTX_SAVE_SIZE_BLOCKS_SE1 133
+#define SE_CTX_SAVE_SIZE_BLOCKS_SE2 646
+
+/* SE TZRAM OPERATION - only for SE1 */
+#define SE_TZRAM_OPERATION 0x540U
+
+#define SE_TZRAM_OP_MODE_SHIFT 1
+#define SE_TZRAM_OP_MODE_SAVE \
+ ((0U) << SE_TZRAM_OP_MODE_SHIFT)
+#define SE_TZRAM_OP_MODE_RESTORE \
+ ((1U) << SE_TZRAM_OP_MODE_SHIFT)
+#define SE_TZRAM_OP_MODE(x) \
+ ((x) & ((0x1U) << SE_TZRAM_OP_MODE_SHIFT))
+
+#define SE_TZRAM_OP_BUSY_SHIFT 2
+#define SE_TZRAM_OP_BUSY_OFF \
+ ((0U) << SE_TZRAM_OP_BUSY_SHIFT)
+#define SE_TZRAM_OP_BUSY_ON \
+ ((1U) << SE_TZRAM_OP_BUSY_SHIFT)
+#define SE_TZRAM_OP_BUSY(x) \
+ ((x) & ((0x1U) << SE_TZRAM_OP_BUSY_SHIFT))
+
+#define SE_TZRAM_OP_REQ_SHIFT 0
+#define SE_TZRAM_OP_REQ_IDLE \
+ ((0U) << SE_TZRAM_OP_REQ_SHIFT)
+#define SE_TZRAM_OP_REQ_INIT \
+ ((1U) << SE_TZRAM_OP_REQ_SHIFT)
+#define SE_TZRAM_OP_REQ(x) \
+ ((x) & ((0x1U) << SE_TZRAM_OP_REQ_SHIFT))
+
+/* SE Interrupt */
+#define SE_INT_STATUS_REG_OFFSET 0x10U
+#define SE_INT_OP_DONE_SHIFT 4
+#define SE_INT_OP_DONE_CLEAR \
+ ((0U) << SE_INT_OP_DONE_SHIFT)
+#define SE_INT_OP_DONE_ACTIVE \
+ ((1U) << SE_INT_OP_DONE_SHIFT)
+#define SE_INT_OP_DONE(x) \
+ ((x) & ((0x1U) << SE_INT_OP_DONE_SHIFT))
+
+/* SE error status */
+#define SE_ERR_STATUS_REG_OFFSET 0x804U
+
+/* SE linked list (LL) register */
+#define SE_IN_LL_ADDR_REG_OFFSET 0x18U
+#define SE_OUT_LL_ADDR_REG_OFFSET 0x24U
+#define SE_BLOCK_COUNT_REG_OFFSET 0x318U
+
+/* AES data sizes */
+#define TEGRA_SE_AES_BLOCK_SIZE 16
+#define TEGRA_SE_AES_MIN_KEY_SIZE 16
+#define TEGRA_SE_AES_MAX_KEY_SIZE 32
+#define TEGRA_SE_AES_IV_SIZE 16
+
+/*******************************************************************************
+ * Inline functions definition
+ ******************************************************************************/
+
+static inline uint32_t tegra_se_read_32(const tegra_se_dev_t *dev, uint32_t offset)
+{
+ return mmio_read_32(dev->se_base + offset);
+}
+
+static inline void tegra_se_write_32(const tegra_se_dev_t *dev, uint32_t offset, uint32_t val)
+{
+ mmio_write_32(dev->se_base + offset, val);
+}
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+#endif /* SE_PRIVATE_H */
diff --git a/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c b/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c
new file mode 100644
index 0000000..fa99db6
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c
@@ -0,0 +1,503 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <common/debug.h>
+#include <delay_timer.h>
+#include <errno.h>
+#include <mmio.h>
+#include <psci.h>
+#include <se_private.h>
+#include <security_engine.h>
+#include <tegra_platform.h>
+
+/*******************************************************************************
+ * Constants and Macros
+ ******************************************************************************/
+
+#define TIMEOUT_100MS 100UL // Timeout in 100ms
+
+/*******************************************************************************
+ * Data structure and global variables
+ ******************************************************************************/
+
+/* The security engine contexts are formatted as follows:
+ *
+ * SE1 CONTEXT:
+ * #--------------------------------#
+ * | Random Data 1 Block |
+ * #--------------------------------#
+ * | Sticky Bits 2 Blocks |
+ * #--------------------------------#
+ * | Key Table 64 Blocks |
+ * | For each Key (x16): |
+ * | Key: 2 Blocks |
+ * | Original-IV: 1 Block |
+ * | Updated-IV: 1 Block |
+ * #--------------------------------#
+ * | RSA Keys 64 Blocks |
+ * #--------------------------------#
+ * | Known Pattern 1 Block |
+ * #--------------------------------#
+ *
+ * SE2/PKA1 CONTEXT:
+ * #--------------------------------#
+ * | Random Data 1 Block |
+ * #--------------------------------#
+ * | Sticky Bits 2 Blocks |
+ * #--------------------------------#
+ * | Key Table 64 Blocks |
+ * | For each Key (x16): |
+ * | Key: 2 Blocks |
+ * | Original-IV: 1 Block |
+ * | Updated-IV: 1 Block |
+ * #--------------------------------#
+ * | RSA Keys 64 Blocks |
+ * #--------------------------------#
+ * | PKA sticky bits 1 Block |
+ * #--------------------------------#
+ * | PKA keys 512 Blocks |
+ * #--------------------------------#
+ * | Known Pattern 1 Block |
+ * #--------------------------------#
+ */
+
+/* SE input and output linked list buffers */
+static tegra_se_io_lst_t se1_src_ll_buf;
+static tegra_se_io_lst_t se1_dst_ll_buf;
+
+/* SE2 input and output linked list buffers */
+static tegra_se_io_lst_t se2_src_ll_buf;
+static tegra_se_io_lst_t se2_dst_ll_buf;
+
+/* SE1 security engine device handle */
+static tegra_se_dev_t se_dev_1 = {
+ .se_num = 1,
+ /* setup base address for se */
+ .se_base = TEGRA_SE1_BASE,
+ /* Setup context size in AES blocks */
+ .ctx_size_blks = SE_CTX_SAVE_SIZE_BLOCKS_SE1,
+ /* Setup SRC buffers for SE operations */
+ .src_ll_buf = &se1_src_ll_buf,
+ /* Setup DST buffers for SE operations */
+ .dst_ll_buf = &se1_dst_ll_buf,
+};
+
+/* SE2 security engine device handle */
+static tegra_se_dev_t se_dev_2 = {
+ .se_num = 2,
+ /* setup base address for se */
+ .se_base = TEGRA_SE2_BASE,
+ /* Setup context size in AES blocks */
+ .ctx_size_blks = SE_CTX_SAVE_SIZE_BLOCKS_SE2,
+ /* Setup SRC buffers for SE operations */
+ .src_ll_buf = &se2_src_ll_buf,
+ /* Setup DST buffers for SE operations */
+ .dst_ll_buf = &se2_dst_ll_buf,
+};
+
+/*******************************************************************************
+ * Functions Definition
+ ******************************************************************************/
+
+static void tegra_se_make_data_coherent(const tegra_se_dev_t *se_dev)
+{
+ flush_dcache_range(((uint64_t)(se_dev->src_ll_buf)),
+ sizeof(tegra_se_io_lst_t));
+ flush_dcache_range(((uint64_t)(se_dev->dst_ll_buf)),
+ sizeof(tegra_se_io_lst_t));
+}
+
+/*
+ * Check that SE operation has completed after kickoff
+ * This function is invoked after an SE operation has been started,
+ * and it checks the following conditions:
+ * 1. SE_INT_STATUS = SE_OP_DONE
+ * 2. SE_STATUS = IDLE
+ * 3. AHB bus data transfer complete.
+ * 4. SE_ERR_STATUS is clean.
+ */
+static int32_t tegra_se_operation_complete(const tegra_se_dev_t *se_dev)
+{
+ uint32_t val = 0;
+ int32_t ret = 0;
+ uint32_t timeout;
+
+ /* Poll the SE interrupt register to ensure H/W operation complete */
+ val = tegra_se_read_32(se_dev, SE_INT_STATUS_REG_OFFSET);
+ for (timeout = 0; (SE_INT_OP_DONE(val) == SE_INT_OP_DONE_CLEAR) &&
+ (timeout < TIMEOUT_100MS); timeout++) {
+ mdelay(1);
+ val = tegra_se_read_32(se_dev, SE_INT_STATUS_REG_OFFSET);
+ }
+
+ if (timeout == TIMEOUT_100MS) {
+ ERROR("%s: ERR: Atomic context save operation timeout!\n",
+ __func__);
+ ret = -ETIMEDOUT;
+ }
+
+ /* Poll the SE status idle to ensure H/W operation complete */
+ if (ret == 0) {
+ val = tegra_se_read_32(se_dev, SE_STATUS_OFFSET);
+ for (timeout = 0; (val != 0U) && (timeout < TIMEOUT_100MS);
+ timeout++) {
+ mdelay(1);
+ val = tegra_se_read_32(se_dev, SE_STATUS_OFFSET);
+ }
+
+ if (timeout == TIMEOUT_100MS) {
+ ERROR("%s: ERR: MEM_INTERFACE and SE state "
+ "idle state timeout.\n", __func__);
+ ret = -ETIMEDOUT;
+ }
+ }
+
+ /* Check AHB bus transfer complete */
+ if (ret == 0) {
+ val = mmio_read_32(TEGRA_AHB_ARB_BASE + ARAHB_MEM_WRQUE_MST_ID_OFFSET);
+ for (timeout = 0; ((val & (ARAHB_MST_ID_SE_MASK | ARAHB_MST_ID_SE2_MASK)) != 0U) &&
+ (timeout < TIMEOUT_100MS); timeout++) {
+ mdelay(1);
+ val = mmio_read_32(TEGRA_AHB_ARB_BASE + ARAHB_MEM_WRQUE_MST_ID_OFFSET);
+ }
+
+ if (timeout == TIMEOUT_100MS) {
+ ERROR("%s: SE write over AHB timeout.\n", __func__);
+ ret = -ETIMEDOUT;
+ }
+ }
+
+ /* Ensure that no errors are thrown during operation */
+ if (ret == 0) {
+ val = tegra_se_read_32(se_dev, SE_ERR_STATUS_REG_OFFSET);
+ if (val != 0U) {
+ ERROR("%s: error during SE operation! 0x%x", __func__, val);
+ ret = -ENOTSUP;
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * Verify the SE context save auto has been enabled.
+ * SE_CTX_SAVE_AUTO.ENABLE == ENABLE
+ * If the SE context save auto is not enabled, then set
+ * the context save auto enable and lock the setting.
+ * If the SE context save auto is not enabled and the
+ * enable setting is locked, then return an error.
+ */
+static inline int32_t tegra_se_ctx_save_auto_enable(const tegra_se_dev_t *se_dev)
+{
+ uint32_t val;
+ int32_t ret = 0;
+
+ val = tegra_se_read_32(se_dev, SE_CTX_SAVE_AUTO_REG_OFFSET);
+ if (SE_CTX_SAVE_AUTO_ENABLE(val) == SE_CTX_SAVE_AUTO_DIS) {
+ if (SE_CTX_SAVE_AUTO_LOCK(val) == SE_CTX_SAVE_AUTO_LOCK_EN) {
+ ERROR("%s: ERR: Cannot enable atomic. Write locked!\n",
+ __func__);
+ ret = -EACCES;
+ }
+
+ /* Program SE_CTX_SAVE_AUTO */
+ if (ret == 0) {
+ tegra_se_write_32(se_dev, SE_CTX_SAVE_AUTO_REG_OFFSET,
+ SE_CTX_SAVE_AUTO_LOCK_EN |
+ SE_CTX_SAVE_AUTO_EN);
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * Wait for SE engine to be idle and clear pending interrupts before
+ * starting the next SE operation.
+ */
+static int32_t tegra_se_operation_prepare(const tegra_se_dev_t *se_dev)
+{
+ int32_t ret = 0;
+ uint32_t val = 0;
+ uint32_t timeout;
+
+ /* Wait for previous operation to finish */
+ val = tegra_se_read_32(se_dev, SE_STATUS_OFFSET);
+ for (timeout = 0; (val != 0U) && (timeout < TIMEOUT_100MS); timeout++) {
+ mdelay(1);
+ val = tegra_se_read_32(se_dev, SE_STATUS_OFFSET);
+ }
+
+ if (timeout == TIMEOUT_100MS) {
+ ERROR("%s: ERR: SE status is not idle!\n", __func__);
+ ret = -ETIMEDOUT;
+ }
+
+ /* Clear any pending interrupts from previous operation */
+ val = tegra_se_read_32(se_dev, SE_INT_STATUS_REG_OFFSET);
+ tegra_se_write_32(se_dev, SE_INT_STATUS_REG_OFFSET, val);
+ return ret;
+}
+
+/*
+ * SE atomic context save. At SC7 entry, SE driver triggers the
+ * hardware automatically performs the context save operation.
+ */
+static int32_t tegra_se_context_save_atomic(const tegra_se_dev_t *se_dev)
+{
+ int32_t ret = 0;
+ uint32_t val = 0;
+ uint32_t blk_count_limit = 0;
+ uint32_t block_count;
+
+ /* Check that previous operation is finalized */
+ ret = tegra_se_operation_prepare(se_dev);
+
+ /* Ensure HW atomic context save has been enabled
+ * This should have been done at boot time.
+ * SE_CTX_SAVE_AUTO.ENABLE == ENABLE
+ */
+ if (ret == 0) {
+ ret = tegra_se_ctx_save_auto_enable(se_dev);
+ }
+
+ /* Read the context save progress counter: block_count
+ * Ensure no previous context save has been triggered
+ * SE_CTX_SAVE_AUTO.CURR_CNT == 0
+ */
+ if (ret == 0) {
+ val = tegra_se_read_32(se_dev, SE_CTX_SAVE_AUTO_REG_OFFSET);
+ block_count = SE_CTX_SAVE_GET_BLK_COUNT(val);
+ if (block_count != 0U) {
+ ERROR("%s: ctx_save triggered multiple times\n",
+ __func__);
+ ret = -EALREADY;
+ }
+ }
+
+ /* Set the destination block count when the context save complete */
+ if (ret == 0) {
+ blk_count_limit = block_count + se_dev->ctx_size_blks;
+ }
+
+ /* Program SE_CONFIG register as for RNG operation
+ * SE_CONFIG.ENC_ALG = RNG
+ * SE_CONFIG.DEC_ALG = NOP
+ * SE_CONFIG.ENC_MODE is ignored
+ * SE_CONFIG.DEC_MODE is ignored
+ * SE_CONFIG.DST = MEMORY
+ */
+ if (ret == 0) {
+ val = (SE_CONFIG_ENC_ALG_RNG |
+ SE_CONFIG_DEC_ALG_NOP |
+ SE_CONFIG_DST_MEMORY);
+ tegra_se_write_32(se_dev, SE_CONFIG_REG_OFFSET, val);
+
+ tegra_se_make_data_coherent(se_dev);
+
+ /* SE_CTX_SAVE operation */
+ tegra_se_write_32(se_dev, SE_OPERATION_REG_OFFSET,
+ SE_OP_CTX_SAVE);
+
+ ret = tegra_se_operation_complete(se_dev);
+ }
+
+ /* Check that context has written the correct number of blocks */
+ if (ret == 0) {
+ val = tegra_se_read_32(se_dev, SE_CTX_SAVE_AUTO_REG_OFFSET);
+ if (SE_CTX_SAVE_GET_BLK_COUNT(val) != blk_count_limit) {
+ ERROR("%s: expected %d blocks but %d were written\n",
+ __func__, blk_count_limit, val);
+ ret = -ECANCELED;
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * Security engine primitive operations, including normal operation
+ * and the context save operation.
+ */
+static int tegra_se_perform_operation(const tegra_se_dev_t *se_dev, uint32_t nbytes)
+{
+ uint32_t nblocks = nbytes / TEGRA_SE_AES_BLOCK_SIZE;
+ int ret = 0;
+
+ assert(se_dev);
+
+ /* Use device buffers for in and out */
+ tegra_se_write_32(se_dev, SE_OUT_LL_ADDR_REG_OFFSET, ((uint64_t)(se_dev->dst_ll_buf)));
+ tegra_se_write_32(se_dev, SE_IN_LL_ADDR_REG_OFFSET, ((uint64_t)(se_dev->src_ll_buf)));
+
+ /* Check that previous operation is finalized */
+ ret = tegra_se_operation_prepare(se_dev);
+ if (ret != 0) {
+ goto op_error;
+ }
+
+ /* Program SE operation size */
+ if (nblocks) {
+ tegra_se_write_32(se_dev, SE_BLOCK_COUNT_REG_OFFSET, nblocks - 1);
+ }
+
+ /* Make SE LL data coherent before the SE operation */
+ tegra_se_make_data_coherent(se_dev);
+
+ /* Start hardware operation */
+ tegra_se_write_32(se_dev, SE_OPERATION_REG_OFFSET, SE_OP_START);
+
+ /* Wait for operation to finish */
+ ret = tegra_se_operation_complete(se_dev);
+
+op_error:
+ return ret;
+}
+
+/*
+ * Security Engine sequence to generat SRK
+ * SE and SE2 will generate different SRK by different
+ * entropy seeds.
+ */
+static int tegra_se_generate_srk(const tegra_se_dev_t *se_dev)
+{
+ int ret = PSCI_E_INTERN_FAIL;
+ uint32_t val;
+
+ /* Confgure the following hardware register settings:
+ * SE_CONFIG.DEC_ALG = NOP
+ * SE_CONFIG.ENC_ALG = RNG
+ * SE_CONFIG.DST = SRK
+ * SE_OPERATION.OP = START
+ * SE_CRYPTO_LAST_BLOCK = 0
+ */
+ se_dev->src_ll_buf->last_buff_num = 0;
+ se_dev->dst_ll_buf->last_buff_num = 0;
+
+ /* Configure random number generator */
+ val = (DRBG_MODE_FORCE_RESEED | DRBG_SRC_ENTROPY);
+ tegra_se_write_32(se_dev, SE_RNG_CONFIG_REG_OFFSET, val);
+
+ /* Configure output destination = SRK */
+ val = (SE_CONFIG_ENC_ALG_RNG |
+ SE_CONFIG_DEC_ALG_NOP |
+ SE_CONFIG_DST_SRK);
+ tegra_se_write_32(se_dev, SE_CONFIG_REG_OFFSET, val);
+
+ /* Perform hardware operation */
+ ret = tegra_se_perform_operation(se_dev, 0);
+
+ return ret;
+}
+
+/*
+ * Initialize the SE engine handle
+ */
+void tegra_se_init(void)
+{
+ INFO("%s: start SE init\n", __func__);
+
+ /* Generate random SRK to initialize DRBG */
+ tegra_se_generate_srk(&se_dev_1);
+ tegra_se_generate_srk(&se_dev_2);
+
+ INFO("%s: SE init done\n", __func__);
+}
+
+/*
+ * Security engine power suspend entry point.
+ * This function is invoked from PSCI power domain suspend handler.
+ */
+int32_t tegra_se_suspend(void)
+{
+ int32_t ret = 0;
+
+ /* Atomic context save se2 and pka1 */
+ INFO("%s: SE2/PKA1 atomic context save\n", __func__);
+ ret = tegra_se_context_save_atomic(&se_dev_2);
+
+ /* Atomic context save se */
+ if (ret == 0) {
+ INFO("%s: SE1 atomic context save\n", __func__);
+ ret = tegra_se_context_save_atomic(&se_dev_1);
+ }
+
+ if (ret == 0) {
+ INFO("%s: SE atomic context save done\n", __func__);
+ }
+
+ return ret;
+}
+
+/*
+ * Save TZRAM to shadow TZRAM in AON
+ */
+int32_t tegra_se_save_tzram(void)
+{
+ uint32_t val = 0;
+ int32_t ret = 0;
+ uint32_t timeout;
+
+ INFO("%s: SE TZRAM save start\n", __func__);
+
+ val = (SE_TZRAM_OP_REQ_INIT | SE_TZRAM_OP_MODE_SAVE);
+ tegra_se_write_32(&se_dev_1, SE_TZRAM_OPERATION, val);
+
+ val = tegra_se_read_32(&se_dev_1, SE_TZRAM_OPERATION);
+ for (timeout = 0; (SE_TZRAM_OP_BUSY(val) == SE_TZRAM_OP_BUSY_ON) &&
+ (timeout < TIMEOUT_100MS); timeout++) {
+ mdelay(1);
+ val = tegra_se_read_32(&se_dev_1, SE_TZRAM_OPERATION);
+ }
+
+ if (timeout == TIMEOUT_100MS) {
+ ERROR("%s: ERR: TZRAM save timeout!\n", __func__);
+ ret = -ETIMEDOUT;
+ }
+
+ if (ret == 0) {
+ INFO("%s: SE TZRAM save done!\n", __func__);
+ }
+
+ return ret;
+}
+
+/*
+ * The function is invoked by SE resume
+ */
+static void tegra_se_warm_boot_resume(const tegra_se_dev_t *se_dev)
+{
+ uint32_t val;
+
+ assert(se_dev);
+
+ /* Lock RNG source to ENTROPY on resume */
+ val = DRBG_RO_ENT_IGNORE_MEM_ENABLE |
+ DRBG_RO_ENT_SRC_LOCK_ENABLE |
+ DRBG_RO_ENT_SRC_ENABLE;
+ tegra_se_write_32(se_dev, SE_RNG_SRC_CONFIG_REG_OFFSET, val);
+
+ /* Enable and lock the SE atomic context save setting */
+ if (tegra_se_ctx_save_auto_enable(se_dev) != 0) {
+ ERROR("%s: ERR: enable SE%d context save auto failed!\n",
+ __func__, se_dev->se_num);
+ }
+
+ /* Set a random value to SRK to initialize DRBG */
+ tegra_se_generate_srk(se_dev);
+}
+
+/*
+ * The function is invoked on SC7 resume
+ */
+void tegra_se_resume(void)
+{
+ tegra_se_warm_boot_resume(&se_dev_1);
+ tegra_se_warm_boot_resume(&se_dev_2);
+}
diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
index 27786d3..ed30ff4 100644
--- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
@@ -1,13 +1,11 @@
/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
-
-#include <platform_def.h>
-
+#include <cortex_a57.h>
#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/delay_timer.h>
@@ -15,10 +13,14 @@
#include <lib/psci/psci.h>
#include <plat/common/platform.h>
+#include <bpmp.h>
#include <flowctrl.h>
#include <pmc.h>
+#include <platform_def.h>
+#include <security_engine.h>
#include <tegra_def.h>
#include <tegra_private.h>
+#include <tegra_platform.h>
/*
* Register used to clear CPU reset signals. Each CPU has two reset
@@ -55,7 +57,7 @@
* Cluster powerdown/idle request only for afflvl 1
*/
req_state->pwr_domain_state[MPIDR_AFFLVL1] = state_id;
- req_state->pwr_domain_state[MPIDR_AFFLVL0] = state_id;
+ req_state->pwr_domain_state[MPIDR_AFFLVL0] = PSTATE_ID_CORE_POWERDN;
break;
@@ -87,9 +89,11 @@
const plat_local_state_t *states,
unsigned int ncpu)
{
- plat_local_state_t target = *states;
+ 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];
+ int ret;
/* get the power state at this level */
if (lvl == MPIDR_AFFLVL1)
@@ -97,19 +101,57 @@
if (lvl == MPIDR_AFFLVL2)
target = *(states + cpu);
- /* Cluster idle/power-down */
- if ((lvl == MPIDR_AFFLVL1) && ((target == PSTATE_ID_CLUSTER_IDLE) ||
- (target == PSTATE_ID_CLUSTER_POWERDN))) {
- return target;
- }
+ if ((lvl == MPIDR_AFFLVL1) && (target == PSTATE_ID_CLUSTER_IDLE)) {
+
+ /* initialize the bpmp interface */
+ (void)tegra_bpmp_init();
+
+ /* 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));
- /* System Suspend */
- if (((lvl == MPIDR_AFFLVL2) || (lvl == MPIDR_AFFLVL1)) &&
- (target == PSTATE_ID_SOC_POWERDN))
- return PSTATE_ID_SOC_POWERDN;
+ /* check if cluster idle entry is allowed */
+ if ((ret != 0L) || (bpmp_reply != BPMP_CCx_ALLOWED)) {
- /* default state */
- return PSCI_LOCAL_STATE_RUN;
+ /* Cluster idle not allowed */
+ target = PSCI_LOCAL_STATE_RUN;
+ }
+
+ } else if ((lvl == MPIDR_AFFLVL1) && (target == PSTATE_ID_CLUSTER_POWERDN)) {
+
+ /* initialize the bpmp interface */
+ (void)tegra_bpmp_init();
+
+ /* Cluster power-down */
+ data[0] = (uint32_t)cpu;
+ data[1] = TEGRA_PM_CC7;
+ 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));
+
+ /* check if cluster power down is allowed */
+ if ((ret != 0L) || (bpmp_reply != BPMP_CCx_ALLOWED)) {
+
+ /* Cluster power down not allowed */
+ target = PSCI_LOCAL_STATE_RUN;
+ }
+
+ } else if (((lvl == MPIDR_AFFLVL2) || (lvl == MPIDR_AFFLVL1)) &&
+ (target == PSTATE_ID_SOC_POWERDN)) {
+
+ /* System Suspend */
+ target = PSTATE_ID_SOC_POWERDN;
+
+ } else {
+ ; /* do nothing */
+ }
+
+ return target;
}
int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
@@ -120,27 +162,43 @@
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];
+ int ret = PSCI_E_SUCCESS;
if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
assert((stateid_afflvl0 == PLAT_MAX_OFF_STATE) ||
- (stateid_afflvl0 == PSTATE_ID_SOC_POWERDN));
+ (stateid_afflvl0 == PSTATE_ID_SOC_POWERDN));
assert((stateid_afflvl1 == PLAT_MAX_OFF_STATE) ||
- (stateid_afflvl1 == PSTATE_ID_SOC_POWERDN));
+ (stateid_afflvl1 == PSTATE_ID_SOC_POWERDN));
- /* suspend the entire soc */
- tegra_fc_soc_powerdn(mpidr);
+ if (tegra_chipid_is_t210_b01()) {
+
+ /* Suspend se/se2 and pka1 */
+ if (tegra_se_suspend() != 0) {
+ ret = PSCI_E_INTERN_FAIL;
+ }
+
+ /* Save tzram contents */
+ if (tegra_se_save_tzram() != 0) {
+ ret = PSCI_E_INTERN_FAIL;
+ }
+ }
+
+ /* enter system suspend */
+ if (ret == PSCI_E_SUCCESS) {
+ tegra_fc_soc_powerdn(mpidr);
+ }
} else if (stateid_afflvl1 == PSTATE_ID_CLUSTER_IDLE) {
- assert(stateid_afflvl0 == PSTATE_ID_CLUSTER_IDLE);
+ assert(stateid_afflvl0 == PSTATE_ID_CORE_POWERDN);
/* Prepare for cluster idle */
tegra_fc_cluster_idle(mpidr);
} else if (stateid_afflvl1 == PSTATE_ID_CLUSTER_POWERDN) {
- assert(stateid_afflvl0 == PSTATE_ID_CLUSTER_POWERDN);
+ assert(stateid_afflvl0 == PSTATE_ID_CORE_POWERDN);
/* Prepare for cluster powerdn */
tegra_fc_cluster_powerdn(mpidr);
@@ -151,17 +209,27 @@
tegra_fc_cpu_powerdn(mpidr);
} else {
- ERROR("%s: Unknown state id\n", __func__);
- return PSCI_E_NOT_SUPPORTED;
+ ERROR("%s: Unknown state id (%d, %d, %d)\n", __func__,
+ stateid_afflvl2, stateid_afflvl1, stateid_afflvl0);
+ ret = PSCI_E_NOT_SUPPORTED;
}
- return PSCI_E_SUCCESS;
+ return ret;
}
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;
+ /* platform parameter passed by the previous bootloader */
+ if (plat_params->l2_ecc_parity_prot_dis != 1) {
+ /* Enable ECC Parity Protection for Cortex-A57 CPUs */
+ val = read_l2ctlr_el1();
+ val |= (uint64_t)CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT;
+ write_l2ctlr_el1(val);
+ }
+
/*
* Check if we are exiting from SOC_POWERDN.
*/
@@ -169,6 +237,13 @@
PLAT_SYS_SUSPEND_STATE_ID) {
/*
+ * Security engine resume
+ */
+ if (tegra_chipid_is_t210_b01()) {
+ tegra_se_resume();
+ }
+
+ /*
* Lock scratch registers which hold the CPU vectors
*/
tegra_pmc_lock_cpu_vectors();
@@ -231,7 +306,7 @@
* for the PMC APB clock would not be changed due to system reset.
*/
mmio_write_32((uintptr_t)TEGRA_CAR_RESET_BASE + SCLK_BURST_POLICY,
- SCLK_BURST_POLICY_DEFAULT);
+ SCLK_BURST_POLICY_DEFAULT);
mmio_write_32((uintptr_t)TEGRA_CAR_RESET_BASE + SCLK_RATE, 0);
/* Wait 1 ms to make sure clock source/device logic is stabilized. */
diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c
index c7f7165..6246dde 100644
--- a/plat/nvidia/tegra/soc/t210/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t210/plat_setup.c
@@ -1,34 +1,21 @@
/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
+#include <bpmp.h>
+#include <cortex_a57.h>
#include <common/bl_common.h>
#include <drivers/console.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
-
+#include <platform.h>
+#include <security_engine.h>
#include <tegra_def.h>
+#include <tegra_platform.h>
#include <tegra_private.h>
-/*******************************************************************************
- * The Tegra power domain tree has a single system level power domain i.e. a
- * single root node. The first entry in the power domain descriptor specifies
- * the number of power domains at the highest power level.
- *******************************************************************************
- */
-const unsigned char tegra_power_domain_tree_desc[] = {
- /* No of root nodes */
- 1,
- /* No of clusters */
- PLATFORM_CLUSTER_COUNT,
- /* No of CPU cores - cluster0 */
- PLATFORM_MAX_CPUS_PER_CLUSTER,
- /* No of CPU cores - cluster1 */
- PLATFORM_MAX_CPUS_PER_CLUSTER
-};
-
/* sets of MMIO ranges setup */
#define MMIO_RANGE_0_ADDR 0x50000000
#define MMIO_RANGE_1_ADDR 0x60000000
@@ -39,6 +26,8 @@
* Table of regions to map using the MMU.
*/
static const mmap_region_t tegra_mmap[] = {
+ MAP_REGION_FLAT(TEGRA_IRAM_BASE, 0x40000, /* 256KB */
+ MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(MMIO_RANGE_0_ADDR, MMIO_RANGE_SIZE,
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(MMIO_RANGE_1_ADDR, MMIO_RANGE_SIZE,
@@ -53,11 +42,44 @@
******************************************************************************/
const mmap_region_t *plat_get_mmio_map(void)
{
+ /* Add the map region for security engine SE2 */
+ if (tegra_chipid_is_t210_b01()) {
+ mmap_add_region((uint64_t)TEGRA_SE2_BASE,
+ (uint64_t)TEGRA_SE2_BASE,
+ (uint64_t)TEGRA_SE2_RANGE_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE);
+ }
+
/* MMIO space */
return tegra_mmap;
}
/*******************************************************************************
+ * The Tegra power domain tree has a single system level power domain i.e. a
+ * single root node. The first entry in the power domain descriptor specifies
+ * the number of power domains at the highest power level.
+ *******************************************************************************
+ */
+const unsigned char tegra_power_domain_tree_desc[] = {
+ /* No of root nodes */
+ 1,
+ /* No of clusters */
+ PLATFORM_CLUSTER_COUNT,
+ /* No of CPU cores - cluster0 */
+ PLATFORM_MAX_CPUS_PER_CLUSTER,
+ /* No of CPU cores - cluster1 */
+ PLATFORM_MAX_CPUS_PER_CLUSTER
+};
+
+/*******************************************************************************
+ * This function returns the Tegra default topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ return tegra_power_domain_tree_desc;
+}
+
+/*******************************************************************************
* Handler to get the System Counter Frequency
******************************************************************************/
unsigned int plat_get_syscnt_freq2(void)
@@ -94,6 +116,28 @@
}
/*******************************************************************************
+ * Handler for early platform setup
+ ******************************************************************************/
+void plat_early_platform_setup(void)
+{
+ const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
+ uint64_t val;
+
+ /* platform parameter passed by the previous bootloader */
+ if (plat_params->l2_ecc_parity_prot_dis != 1) {
+ /* Enable ECC Parity Protection for Cortex-A57 CPUs */
+ val = read_l2ctlr_el1();
+ val |= (uint64_t)CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT;
+ write_l2ctlr_el1(val);
+ }
+
+ /* Initialize security engine driver */
+ if (tegra_chipid_is_t210_b01()) {
+ tegra_se_init();
+ }
+}
+
+/*******************************************************************************
* Initialize the GIC and SGIs
******************************************************************************/
void plat_gic_setup(void)
diff --git a/plat/nvidia/tegra/soc/t210/platform_t210.mk b/plat/nvidia/tegra/soc/t210/platform_t210.mk
index b0a474c..a9ab0d8 100644
--- a/plat/nvidia/tegra/soc/t210/platform_t210.mk
+++ b/plat/nvidia/tegra/soc/t210/platform_t210.mk
@@ -16,18 +16,22 @@
PLATFORM_MAX_CPUS_PER_CLUSTER := 4
$(eval $(call add_define,PLATFORM_MAX_CPUS_PER_CLUSTER))
-MAX_XLAT_TABLES := 4
+MAX_XLAT_TABLES := 10
$(eval $(call add_define,MAX_XLAT_TABLES))
-MAX_MMAP_REGIONS := 8
+MAX_MMAP_REGIONS := 10
$(eval $(call add_define,MAX_MMAP_REGIONS))
+PLAT_INCLUDES += -I${SOC_DIR}/drivers/se
+
BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \
lib/cpus/aarch64/cortex_a57.S \
+ ${COMMON_DIR}/drivers/bpmp/bpmp.c \
${COMMON_DIR}/drivers/flowctrl/flowctrl.c \
${COMMON_DIR}/drivers/memctrl/memctrl_v1.c \
${SOC_DIR}/plat_psci_handlers.c \
${SOC_DIR}/plat_setup.c \
+ ${SOC_DIR}/drivers/se/security_engine.c \
${SOC_DIR}/plat_secondary.c
# Enable workarounds for selected Cortex-A57 erratas.