aboutsummaryrefslogtreecommitdiffstats
path: root/roms/u-boot/arch/arm/mach-tegra/board.c
diff options
context:
space:
mode:
Diffstat (limited to 'roms/u-boot/arch/arm/mach-tegra/board.c')
-rw-r--r--roms/u-boot/arch/arm/mach-tegra/board.c279
1 files changed, 279 insertions, 0 deletions
diff --git a/roms/u-boot/arch/arm/mach-tegra/board.c b/roms/u-boot/arch/arm/mach-tegra/board.c
new file mode 100644
index 000000000..95d6555a0
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-tegra/board.c
@@ -0,0 +1,279 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2010-2015
+ * NVIDIA Corporation <www.nvidia.com>
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <dm.h>
+#include <init.h>
+#include <log.h>
+#include <ns16550.h>
+#include <spl.h>
+#include <asm/cache.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#if IS_ENABLED(CONFIG_TEGRA_CLKRST)
+#include <asm/arch/clock.h>
+#endif
+#if IS_ENABLED(CONFIG_TEGRA_PINCTRL)
+#include <asm/arch/funcmux.h>
+#endif
+#if IS_ENABLED(CONFIG_TEGRA_MC)
+#include <asm/arch/mc.h>
+#endif
+#include <asm/arch/tegra.h>
+#include <asm/arch-tegra/ap.h>
+#include <asm/arch-tegra/board.h>
+#include <asm/arch-tegra/cboot.h>
+#include <asm/arch-tegra/pmc.h>
+#include <asm/arch-tegra/sys_proto.h>
+#include <asm/arch-tegra/warmboot.h>
+
+void save_boot_params_ret(void);
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum {
+ /* UARTs which we can enable */
+ UARTA = 1 << 0,
+ UARTB = 1 << 1,
+ UARTC = 1 << 2,
+ UARTD = 1 << 3,
+ UARTE = 1 << 4,
+ UART_COUNT = 5,
+};
+
+static bool from_spl __section(".data");
+
+#ifndef CONFIG_SPL_BUILD
+void save_boot_params(unsigned long r0, unsigned long r1, unsigned long r2,
+ unsigned long r3)
+{
+ from_spl = r0 != UBOOT_NOT_LOADED_FROM_SPL;
+
+ /*
+ * The logic for this is somewhat indirect. The purpose of the marker
+ * (UBOOT_NOT_LOADED_FROM_SPL) is in fact used to determine if U-Boot
+ * was loaded from a read-only instance of itself, which is something
+ * that can happen in secure boot setups. So basically the presence
+ * of the marker is an indication that U-Boot was loaded by one such
+ * special variant of U-Boot. Conversely, the absence of the marker
+ * indicates that this instance of U-Boot was loaded by something
+ * other than a special U-Boot. This could be SPL, but it could just
+ * as well be one of any number of other first stage bootloaders.
+ */
+ if (from_spl)
+ cboot_save_boot_params(r0, r1, r2, r3);
+
+ save_boot_params_ret();
+}
+#endif
+
+bool spl_was_boot_source(void)
+{
+ return from_spl;
+}
+
+#if defined(CONFIG_TEGRA_SUPPORT_NON_SECURE)
+#if !defined(CONFIG_TEGRA124)
+#error tegra_cpu_is_non_secure has only been validated on Tegra124
+#endif
+bool tegra_cpu_is_non_secure(void)
+{
+ /*
+ * This register reads 0xffffffff in non-secure mode. This register
+ * only implements bits 31:20, so the lower bits will always read 0 in
+ * secure mode. Thus, the lower bits are an indicator for secure vs.
+ * non-secure mode.
+ */
+ struct mc_ctlr *mc = (struct mc_ctlr *)NV_PA_MC_BASE;
+ uint32_t mc_s_cfg0 = readl(&mc->mc_security_cfg0);
+ return (mc_s_cfg0 & 1) == 1;
+}
+#endif
+
+#if IS_ENABLED(CONFIG_TEGRA_MC)
+/* Read the RAM size directly from the memory controller */
+static phys_size_t query_sdram_size(void)
+{
+ struct mc_ctlr *const mc = (struct mc_ctlr *)NV_PA_MC_BASE;
+ u32 emem_cfg;
+ phys_size_t size_bytes;
+
+ emem_cfg = readl(&mc->mc_emem_cfg);
+#if defined(CONFIG_TEGRA20)
+ debug("mc->mc_emem_cfg (MEM_SIZE_KB) = 0x%08x\n", emem_cfg);
+ size_bytes = get_ram_size((void *)PHYS_SDRAM_1, emem_cfg * 1024);
+#else
+ debug("mc->mc_emem_cfg (MEM_SIZE_MB) = 0x%08x\n", emem_cfg);
+#ifndef CONFIG_PHYS_64BIT
+ /*
+ * If >=4GB RAM is present, the byte RAM size won't fit into 32-bits
+ * and will wrap. Clip the reported size to the maximum that a 32-bit
+ * variable can represent (rounded to a page).
+ */
+ if (emem_cfg >= 4096) {
+ size_bytes = U32_MAX & ~(0x1000 - 1);
+ } else
+#endif
+ {
+ /* RAM size EMC is programmed to. */
+ size_bytes = (phys_size_t)emem_cfg * 1024 * 1024;
+#ifndef CONFIG_ARM64
+ /*
+ * If all RAM fits within 32-bits, it can be accessed without
+ * LPAE, so go test the RAM size. Otherwise, we can't access
+ * all the RAM, and get_ram_size() would get confused, so
+ * avoid using it. There's no reason we should need this
+ * validation step anyway.
+ */
+ if (emem_cfg <= (0 - PHYS_SDRAM_1) / (1024 * 1024))
+ size_bytes = get_ram_size((void *)PHYS_SDRAM_1,
+ size_bytes);
+#endif
+ }
+#endif
+
+#if defined(CONFIG_TEGRA30) || defined(CONFIG_TEGRA114)
+ /* External memory limited to 2047 MB due to IROM/HI-VEC */
+ if (size_bytes == SZ_2G)
+ size_bytes -= SZ_1M;
+#endif
+
+ return size_bytes;
+}
+#endif
+
+int dram_init(void)
+{
+ int err;
+
+ /* try to initialize DRAM from cboot DTB first */
+ err = cboot_dram_init();
+ if (err == 0)
+ return 0;
+
+#if IS_ENABLED(CONFIG_TEGRA_MC)
+ /* We do not initialise DRAM here. We just query the size */
+ gd->ram_size = query_sdram_size();
+#endif
+
+ return 0;
+}
+
+#if IS_ENABLED(CONFIG_TEGRA_PINCTRL)
+static int uart_configs[] = {
+#if defined(CONFIG_TEGRA20)
+ #if defined(CONFIG_TEGRA_UARTA_UAA_UAB)
+ FUNCMUX_UART1_UAA_UAB,
+ #elif defined(CONFIG_TEGRA_UARTA_GPU)
+ FUNCMUX_UART1_GPU,
+ #elif defined(CONFIG_TEGRA_UARTA_SDIO1)
+ FUNCMUX_UART1_SDIO1,
+ #else
+ FUNCMUX_UART1_IRRX_IRTX,
+#endif
+ FUNCMUX_UART2_UAD,
+ -1,
+ FUNCMUX_UART4_GMC,
+ -1,
+#elif defined(CONFIG_TEGRA30)
+ FUNCMUX_UART1_ULPI, /* UARTA */
+ -1,
+ -1,
+ -1,
+ -1,
+#elif defined(CONFIG_TEGRA114)
+ -1,
+ -1,
+ -1,
+ FUNCMUX_UART4_GMI, /* UARTD */
+ -1,
+#elif defined(CONFIG_TEGRA124)
+ FUNCMUX_UART1_KBC, /* UARTA */
+ -1,
+ -1,
+ FUNCMUX_UART4_GPIO, /* UARTD */
+ -1,
+#else /* Tegra210 */
+ FUNCMUX_UART1_UART1, /* UARTA */
+ -1,
+ -1,
+ FUNCMUX_UART4_UART4, /* UARTD */
+ -1,
+#endif
+};
+
+/**
+ * Set up the specified uarts
+ *
+ * @param uarts_ids Mask containing UARTs to init (UARTx)
+ */
+static void setup_uarts(int uart_ids)
+{
+ static enum periph_id id_for_uart[] = {
+ PERIPH_ID_UART1,
+ PERIPH_ID_UART2,
+ PERIPH_ID_UART3,
+ PERIPH_ID_UART4,
+ PERIPH_ID_UART5,
+ };
+ size_t i;
+
+ for (i = 0; i < UART_COUNT; i++) {
+ if (uart_ids & (1 << i)) {
+ enum periph_id id = id_for_uart[i];
+
+ funcmux_select(id, uart_configs[i]);
+ clock_ll_start_uart(id);
+ }
+ }
+}
+#endif
+
+void board_init_uart_f(void)
+{
+#if IS_ENABLED(CONFIG_TEGRA_PINCTRL)
+ int uart_ids = 0; /* bit mask of which UART ids to enable */
+
+#ifdef CONFIG_TEGRA_ENABLE_UARTA
+ uart_ids |= UARTA;
+#endif
+#ifdef CONFIG_TEGRA_ENABLE_UARTB
+ uart_ids |= UARTB;
+#endif
+#ifdef CONFIG_TEGRA_ENABLE_UARTC
+ uart_ids |= UARTC;
+#endif
+#ifdef CONFIG_TEGRA_ENABLE_UARTD
+ uart_ids |= UARTD;
+#endif
+#ifdef CONFIG_TEGRA_ENABLE_UARTE
+ uart_ids |= UARTE;
+#endif
+ setup_uarts(uart_ids);
+#endif
+}
+
+#if !CONFIG_IS_ENABLED(OF_CONTROL)
+static struct ns16550_plat ns16550_com1_pdata = {
+ .base = CONFIG_SYS_NS16550_COM1,
+ .reg_shift = 2,
+ .clock = CONFIG_SYS_NS16550_CLK,
+ .fcr = UART_FCR_DEFVAL,
+};
+
+U_BOOT_DRVINFO(ns16550_com1) = {
+ "ns16550_serial", &ns16550_com1_pdata
+};
+#endif
+
+#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) && !defined(CONFIG_ARM64)
+void enable_caches(void)
+{
+ /* Enable D-cache. I-cache is already enabled in start.S */
+ dcache_enable();
+}
+#endif