blob: 40de72dc575fd1a84d097461edeb251fa04c12b5 [file] [log] [blame]
Tom Warren3f82b1d2011-01-27 10:58:05 +00001/*
Tom Warren7aaa5a62015-03-04 16:36:00 -07002 * (C) Copyright 2010-2015
Tom Warren3f82b1d2011-01-27 10:58:05 +00003 * NVIDIA Corporation <www.nvidia.com>
4 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02005 * SPDX-License-Identifier: GPL-2.0+
Tom Warren3f82b1d2011-01-27 10:58:05 +00006 */
7
8#include <common.h>
Simon Glass537e9672015-05-13 07:02:29 -06009#include <spl.h>
Tom Warren3f82b1d2011-01-27 10:58:05 +000010#include <asm/io.h>
Simon Glassbb6997f2011-11-28 15:04:39 +000011#include <asm/arch/clock.h>
12#include <asm/arch/funcmux.h>
Marcel Ziswiler8c33ba72014-10-10 23:32:32 +020013#include <asm/arch/mc.h>
Tom Warren150c2492012-09-19 15:50:56 -070014#include <asm/arch/tegra.h>
Stephen Warren73c38932015-01-19 16:25:52 -070015#include <asm/arch-tegra/ap.h>
Lucas Stach516f00b2012-09-29 10:02:08 +000016#include <asm/arch-tegra/board.h>
Tom Warren150c2492012-09-19 15:50:56 -070017#include <asm/arch-tegra/pmc.h>
18#include <asm/arch-tegra/sys_proto.h>
19#include <asm/arch-tegra/warmboot.h>
Tom Warren3f82b1d2011-01-27 10:58:05 +000020
Tom Warren659a0752015-07-08 08:05:35 -070021void save_boot_params_ret(void);
22
Tom Warren3f82b1d2011-01-27 10:58:05 +000023DECLARE_GLOBAL_DATA_PTR;
24
Simon Glassbb6997f2011-11-28 15:04:39 +000025enum {
26 /* UARTs which we can enable */
27 UARTA = 1 << 0,
28 UARTB = 1 << 1,
Tom Warrene23bb6a2013-01-28 13:32:10 +000029 UARTC = 1 << 2,
Simon Glassbb6997f2011-11-28 15:04:39 +000030 UARTD = 1 << 3,
Tom Warrene23bb6a2013-01-28 13:32:10 +000031 UARTE = 1 << 4,
32 UART_COUNT = 5,
Simon Glassbb6997f2011-11-28 15:04:39 +000033};
34
Simon Glass537e9672015-05-13 07:02:29 -060035static bool from_spl __attribute__ ((section(".data")));
36
37#ifndef CONFIG_SPL_BUILD
38void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3)
39{
40 from_spl = r0 != UBOOT_NOT_LOADED_FROM_SPL;
41 save_boot_params_ret();
42}
43#endif
44
45bool spl_was_boot_source(void)
46{
47 return from_spl;
48}
49
Stephen Warren73c38932015-01-19 16:25:52 -070050#if defined(CONFIG_TEGRA_SUPPORT_NON_SECURE)
51#if !defined(CONFIG_TEGRA124)
52#error tegra_cpu_is_non_secure has only been validated on Tegra124
53#endif
54bool tegra_cpu_is_non_secure(void)
55{
56 /*
57 * This register reads 0xffffffff in non-secure mode. This register
58 * only implements bits 31:20, so the lower bits will always read 0 in
59 * secure mode. Thus, the lower bits are an indicator for secure vs.
60 * non-secure mode.
61 */
62 struct mc_ctlr *mc = (struct mc_ctlr *)NV_PA_MC_BASE;
63 uint32_t mc_s_cfg0 = readl(&mc->mc_security_cfg0);
64 return (mc_s_cfg0 & 1) == 1;
65}
66#endif
67
Stephen Warrenaeb3fcb2014-07-02 14:12:30 -060068/* Read the RAM size directly from the memory controller */
69unsigned int query_sdram_size(void)
70{
71 struct mc_ctlr *const mc = (struct mc_ctlr *)NV_PA_MC_BASE;
Stephen Warren3a2cab52014-12-23 10:34:50 -070072 u32 emem_cfg, size_bytes;
Stephen Warrenaeb3fcb2014-07-02 14:12:30 -060073
Stephen Warren3a2cab52014-12-23 10:34:50 -070074 emem_cfg = readl(&mc->mc_emem_cfg);
Marcel Ziswiler8c33ba72014-10-10 23:32:32 +020075#if defined(CONFIG_TEGRA20)
Stephen Warren3a2cab52014-12-23 10:34:50 -070076 debug("mc->mc_emem_cfg (MEM_SIZE_KB) = 0x%08x\n", emem_cfg);
77 size_bytes = get_ram_size((void *)PHYS_SDRAM_1, emem_cfg * 1024);
Marcel Ziswiler8c33ba72014-10-10 23:32:32 +020078#else
Stephen Warren3a2cab52014-12-23 10:34:50 -070079 debug("mc->mc_emem_cfg (MEM_SIZE_MB) = 0x%08x\n", emem_cfg);
Stephen Warren56519c42014-12-23 10:34:51 -070080 /*
81 * If >=4GB RAM is present, the byte RAM size won't fit into 32-bits
82 * and will wrap. Clip the reported size to the maximum that a 32-bit
83 * variable can represent (rounded to a page).
84 */
85 if (emem_cfg >= 4096) {
86 size_bytes = U32_MAX & ~(0x1000 - 1);
87 } else {
88 /* RAM size EMC is programmed to. */
89 size_bytes = emem_cfg * 1024 * 1024;
90 /*
91 * If all RAM fits within 32-bits, it can be accessed without
92 * LPAE, so go test the RAM size. Otherwise, we can't access
93 * all the RAM, and get_ram_size() would get confused, so
94 * avoid using it. There's no reason we should need this
95 * validation step anyway.
96 */
97 if (emem_cfg <= (0 - PHYS_SDRAM_1) / (1024 * 1024))
98 size_bytes = get_ram_size((void *)PHYS_SDRAM_1,
99 size_bytes);
100 }
Stephen Warrenaeb3fcb2014-07-02 14:12:30 -0600101#endif
Tom Warren3f82b1d2011-01-27 10:58:05 +0000102
Marcel Ziswiler8c33ba72014-10-10 23:32:32 +0200103#if defined(CONFIG_TEGRA30) || defined(CONFIG_TEGRA114)
104 /* External memory limited to 2047 MB due to IROM/HI-VEC */
Stephen Warren3a2cab52014-12-23 10:34:50 -0700105 if (size_bytes == SZ_2G)
106 size_bytes -= SZ_1M;
Marcel Ziswiler8c33ba72014-10-10 23:32:32 +0200107#endif
108
Stephen Warren3a2cab52014-12-23 10:34:50 -0700109 return size_bytes;
Marcel Ziswiler8c33ba72014-10-10 23:32:32 +0200110}
111
Tom Warren3f82b1d2011-01-27 10:58:05 +0000112int dram_init(void)
113{
Tom Warren3f82b1d2011-01-27 10:58:05 +0000114 /* We do not initialise DRAM here. We just query the size */
Simon Glass7f8c0702011-11-05 03:56:57 +0000115 gd->ram_size = query_sdram_size();
Tom Warren3f82b1d2011-01-27 10:58:05 +0000116 return 0;
117}
118
Stephen Warrenb9607e72012-05-14 13:13:45 +0000119static int uart_configs[] = {
Tom Warrenb2871032012-12-11 13:34:15 +0000120#if defined(CONFIG_TEGRA20)
121 #if defined(CONFIG_TEGRA_UARTA_UAA_UAB)
Stephen Warrenb9607e72012-05-14 13:13:45 +0000122 FUNCMUX_UART1_UAA_UAB,
Tom Warrenb2871032012-12-11 13:34:15 +0000123 #elif defined(CONFIG_TEGRA_UARTA_GPU)
Stephen Warrene21649b2012-05-16 05:59:59 +0000124 FUNCMUX_UART1_GPU,
Tom Warrenb2871032012-12-11 13:34:15 +0000125 #elif defined(CONFIG_TEGRA_UARTA_SDIO1)
Lucas Stacha2cfe632012-05-16 08:21:02 +0000126 FUNCMUX_UART1_SDIO1,
Tom Warrenb2871032012-12-11 13:34:15 +0000127 #else
Stephen Warrenb9607e72012-05-14 13:13:45 +0000128 FUNCMUX_UART1_IRRX_IRTX,
Stephen Warren4727a132013-01-22 06:20:08 +0000129#endif
130 FUNCMUX_UART2_UAD,
Stephen Warrenb9607e72012-05-14 13:13:45 +0000131 -1,
132 FUNCMUX_UART4_GMC,
133 -1,
Tom Warrene23bb6a2013-01-28 13:32:10 +0000134#elif defined(CONFIG_TEGRA30)
Tom Warrenb2871032012-12-11 13:34:15 +0000135 FUNCMUX_UART1_ULPI, /* UARTA */
136 -1,
137 -1,
138 -1,
139 -1,
Tom Warren2f5dac92014-01-24 12:46:16 -0700140#elif defined(CONFIG_TEGRA114)
Tom Warrene23bb6a2013-01-28 13:32:10 +0000141 -1,
142 -1,
143 -1,
144 FUNCMUX_UART4_GMI, /* UARTD */
145 -1,
Tom Warren7aaa5a62015-03-04 16:36:00 -0700146#elif defined(CONFIG_TEGRA124)
Tom Warren2f5dac92014-01-24 12:46:16 -0700147 FUNCMUX_UART1_KBC, /* UARTA */
148 -1,
149 -1,
150 FUNCMUX_UART4_GPIO, /* UARTD */
151 -1,
Tom Warren7aaa5a62015-03-04 16:36:00 -0700152#else /* Tegra210 */
153 FUNCMUX_UART1_UART1, /* UARTA */
154 -1,
155 -1,
156 FUNCMUX_UART4_UART4, /* UARTD */
157 -1,
Tom Warrenb2871032012-12-11 13:34:15 +0000158#endif
Stephen Warrenb9607e72012-05-14 13:13:45 +0000159};
160
Simon Glassbb6997f2011-11-28 15:04:39 +0000161/**
162 * Set up the specified uarts
163 *
164 * @param uarts_ids Mask containing UARTs to init (UARTx)
165 */
166static void setup_uarts(int uart_ids)
167{
168 static enum periph_id id_for_uart[] = {
169 PERIPH_ID_UART1,
170 PERIPH_ID_UART2,
171 PERIPH_ID_UART3,
172 PERIPH_ID_UART4,
Tom Warrene23bb6a2013-01-28 13:32:10 +0000173 PERIPH_ID_UART5,
Simon Glassbb6997f2011-11-28 15:04:39 +0000174 };
175 size_t i;
176
177 for (i = 0; i < UART_COUNT; i++) {
178 if (uart_ids & (1 << i)) {
179 enum periph_id id = id_for_uart[i];
180
Stephen Warrenb9607e72012-05-14 13:13:45 +0000181 funcmux_select(id, uart_configs[i]);
Simon Glassbb6997f2011-11-28 15:04:39 +0000182 clock_ll_start_uart(id);
183 }
184 }
185}
186
187void board_init_uart_f(void)
188{
189 int uart_ids = 0; /* bit mask of which UART ids to enable */
190
Tom Warren29f3e3f2012-09-04 17:00:24 -0700191#ifdef CONFIG_TEGRA_ENABLE_UARTA
Simon Glassbb6997f2011-11-28 15:04:39 +0000192 uart_ids |= UARTA;
193#endif
Tom Warren29f3e3f2012-09-04 17:00:24 -0700194#ifdef CONFIG_TEGRA_ENABLE_UARTB
Simon Glassbb6997f2011-11-28 15:04:39 +0000195 uart_ids |= UARTB;
196#endif
Tom Warrene23bb6a2013-01-28 13:32:10 +0000197#ifdef CONFIG_TEGRA_ENABLE_UARTC
198 uart_ids |= UARTC;
199#endif
Tom Warren29f3e3f2012-09-04 17:00:24 -0700200#ifdef CONFIG_TEGRA_ENABLE_UARTD
Simon Glassbb6997f2011-11-28 15:04:39 +0000201 uart_ids |= UARTD;
202#endif
Tom Warrene23bb6a2013-01-28 13:32:10 +0000203#ifdef CONFIG_TEGRA_ENABLE_UARTE
204 uart_ids |= UARTE;
205#endif
Simon Glassbb6997f2011-11-28 15:04:39 +0000206 setup_uarts(uart_ids);
207}
Simon Glassbd29cb02012-01-09 13:22:15 +0000208
Thierry Reding32b32342015-07-27 11:45:25 -0600209#if !defined(CONFIG_SYS_DCACHE_OFF) && !defined(CONFIG_ARM64)
Simon Glassbd29cb02012-01-09 13:22:15 +0000210void enable_caches(void)
211{
212 /* Enable D-cache. I-cache is already enabled in start.S */
213 dcache_enable();
214}
215#endif