xref: /rk3399_rockchip-uboot/arch/arm/mach-tegra/board2.c (revision 382bee57f19b4454e2015bc19a010bc2d0ab9337)
1237c3637SMasahiro Yamada /*
2237c3637SMasahiro Yamada  *  (C) Copyright 2010,2011
3237c3637SMasahiro Yamada  *  NVIDIA Corporation <www.nvidia.com>
4237c3637SMasahiro Yamada  *
5237c3637SMasahiro Yamada  * SPDX-License-Identifier:	GPL-2.0+
6237c3637SMasahiro Yamada  */
7237c3637SMasahiro Yamada 
8237c3637SMasahiro Yamada #include <common.h>
9237c3637SMasahiro Yamada #include <dm.h>
10237c3637SMasahiro Yamada #include <errno.h>
11237c3637SMasahiro Yamada #include <ns16550.h>
1203bc3f18SSimon Glass #include <usb.h>
13237c3637SMasahiro Yamada #include <asm/io.h>
14237c3637SMasahiro Yamada #include <asm/arch-tegra/ap.h>
15237c3637SMasahiro Yamada #include <asm/arch-tegra/board.h>
16237c3637SMasahiro Yamada #include <asm/arch-tegra/clk_rst.h>
17237c3637SMasahiro Yamada #include <asm/arch-tegra/pmc.h>
18237c3637SMasahiro Yamada #include <asm/arch-tegra/sys_proto.h>
19237c3637SMasahiro Yamada #include <asm/arch-tegra/uart.h>
20237c3637SMasahiro Yamada #include <asm/arch-tegra/warmboot.h>
21871d78edSAlexandre Courbot #include <asm/arch-tegra/gpu.h>
2203bc3f18SSimon Glass #include <asm/arch-tegra/usb.h>
2303bc3f18SSimon Glass #include <asm/arch-tegra/xusb-padctl.h>
2403bc3f18SSimon Glass #include <asm/arch/clock.h>
2503bc3f18SSimon Glass #include <asm/arch/funcmux.h>
2603bc3f18SSimon Glass #include <asm/arch/pinmux.h>
2703bc3f18SSimon Glass #include <asm/arch/pmu.h>
2803bc3f18SSimon Glass #include <asm/arch/tegra.h>
29237c3637SMasahiro Yamada #ifdef CONFIG_TEGRA_CLOCK_SCALING
30237c3637SMasahiro Yamada #include <asm/arch/emc.h>
31237c3637SMasahiro Yamada #endif
32237c3637SMasahiro Yamada #include "emc.h"
33237c3637SMasahiro Yamada 
34237c3637SMasahiro Yamada DECLARE_GLOBAL_DATA_PTR;
35237c3637SMasahiro Yamada 
36237c3637SMasahiro Yamada #ifdef CONFIG_SPL_BUILD
37237c3637SMasahiro Yamada /* TODO(sjg@chromium.org): Remove once SPL supports device tree */
38237c3637SMasahiro Yamada U_BOOT_DEVICE(tegra_gpios) = {
39237c3637SMasahiro Yamada 	"gpio_tegra"
40237c3637SMasahiro Yamada };
41237c3637SMasahiro Yamada #endif
42237c3637SMasahiro Yamada 
pinmux_init(void)43237c3637SMasahiro Yamada __weak void pinmux_init(void) {}
pin_mux_usb(void)44237c3637SMasahiro Yamada __weak void pin_mux_usb(void) {}
pin_mux_spi(void)45237c3637SMasahiro Yamada __weak void pin_mux_spi(void) {}
pin_mux_mmc(void)46c0be77dbSStephen Warren __weak void pin_mux_mmc(void) {}
gpio_early_init_uart(void)47237c3637SMasahiro Yamada __weak void gpio_early_init_uart(void) {}
pin_mux_display(void)48237c3637SMasahiro Yamada __weak void pin_mux_display(void) {}
start_cpu_fan(void)4966999892STom Warren __weak void start_cpu_fan(void) {}
50237c3637SMasahiro Yamada 
51237c3637SMasahiro Yamada #if defined(CONFIG_TEGRA_NAND)
pin_mux_nand(void)52237c3637SMasahiro Yamada __weak void pin_mux_nand(void)
53237c3637SMasahiro Yamada {
54237c3637SMasahiro Yamada 	funcmux_select(PERIPH_ID_NDFLASH, FUNCMUX_DEFAULT);
55237c3637SMasahiro Yamada }
56237c3637SMasahiro Yamada #endif
57237c3637SMasahiro Yamada 
58237c3637SMasahiro Yamada /*
59237c3637SMasahiro Yamada  * Routine: power_det_init
60237c3637SMasahiro Yamada  * Description: turn off power detects
61237c3637SMasahiro Yamada  */
power_det_init(void)62237c3637SMasahiro Yamada static void power_det_init(void)
63237c3637SMasahiro Yamada {
64237c3637SMasahiro Yamada #if defined(CONFIG_TEGRA20)
65237c3637SMasahiro Yamada 	struct pmc_ctlr *const pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
66237c3637SMasahiro Yamada 
67237c3637SMasahiro Yamada 	/* turn off power detects */
68237c3637SMasahiro Yamada 	writel(0, &pmc->pmc_pwr_det_latch);
69237c3637SMasahiro Yamada 	writel(0, &pmc->pmc_pwr_det);
70237c3637SMasahiro Yamada #endif
71237c3637SMasahiro Yamada }
72237c3637SMasahiro Yamada 
tegra_board_id(void)73237c3637SMasahiro Yamada __weak int tegra_board_id(void)
74237c3637SMasahiro Yamada {
75237c3637SMasahiro Yamada 	return -1;
76237c3637SMasahiro Yamada }
77237c3637SMasahiro Yamada 
78237c3637SMasahiro Yamada #ifdef CONFIG_DISPLAY_BOARDINFO
checkboard(void)79237c3637SMasahiro Yamada int checkboard(void)
80237c3637SMasahiro Yamada {
81237c3637SMasahiro Yamada 	int board_id = tegra_board_id();
82237c3637SMasahiro Yamada 
83237c3637SMasahiro Yamada 	printf("Board: %s", CONFIG_TEGRA_BOARD_STRING);
84237c3637SMasahiro Yamada 	if (board_id != -1)
85237c3637SMasahiro Yamada 		printf(", ID: %d\n", board_id);
86237c3637SMasahiro Yamada 	printf("\n");
87237c3637SMasahiro Yamada 
88237c3637SMasahiro Yamada 	return 0;
89237c3637SMasahiro Yamada }
90237c3637SMasahiro Yamada #endif	/* CONFIG_DISPLAY_BOARDINFO */
91237c3637SMasahiro Yamada 
tegra_lcd_pmic_init(int board_it)92237c3637SMasahiro Yamada __weak int tegra_lcd_pmic_init(int board_it)
93237c3637SMasahiro Yamada {
94237c3637SMasahiro Yamada 	return 0;
95237c3637SMasahiro Yamada }
96237c3637SMasahiro Yamada 
nvidia_board_init(void)97c96d709fSSimon Glass __weak int nvidia_board_init(void)
98c96d709fSSimon Glass {
99c96d709fSSimon Glass 	return 0;
100c96d709fSSimon Glass }
101c96d709fSSimon Glass 
102237c3637SMasahiro Yamada /*
103237c3637SMasahiro Yamada  * Routine: board_init
104237c3637SMasahiro Yamada  * Description: Early hardware init.
105237c3637SMasahiro Yamada  */
board_init(void)106237c3637SMasahiro Yamada int board_init(void)
107237c3637SMasahiro Yamada {
108237c3637SMasahiro Yamada 	__maybe_unused int err;
109237c3637SMasahiro Yamada 	__maybe_unused int board_id;
110237c3637SMasahiro Yamada 
111237c3637SMasahiro Yamada 	/* Do clocks and UART first so that printf() works */
112237c3637SMasahiro Yamada 	clock_init();
113237c3637SMasahiro Yamada 	clock_verify();
114237c3637SMasahiro Yamada 
115eca676bdSAlexandre Courbot 	tegra_gpu_config();
116871d78edSAlexandre Courbot 
117237c3637SMasahiro Yamada #ifdef CONFIG_TEGRA_SPI
118237c3637SMasahiro Yamada 	pin_mux_spi();
119237c3637SMasahiro Yamada #endif
120237c3637SMasahiro Yamada 
1211d2c0506SMasahiro Yamada #ifdef CONFIG_MMC_SDHCI_TEGRA
122c0be77dbSStephen Warren 	pin_mux_mmc();
123c0be77dbSStephen Warren #endif
124c0be77dbSStephen Warren 
1253f2997a4SSimon Glass 	/* Init is handled automatically in the driver-model case */
126e007633bSSimon Glass #if defined(CONFIG_DM_VIDEO)
127237c3637SMasahiro Yamada 	pin_mux_display();
128135a87efSSimon Glass #endif
129237c3637SMasahiro Yamada 	/* boot param addr */
130237c3637SMasahiro Yamada 	gd->bd->bi_boot_params = (NV_PA_SDRAM_BASE + 0x100);
131237c3637SMasahiro Yamada 
132237c3637SMasahiro Yamada 	power_det_init();
133237c3637SMasahiro Yamada 
134237c3637SMasahiro Yamada #ifdef CONFIG_SYS_I2C_TEGRA
135237c3637SMasahiro Yamada # ifdef CONFIG_TEGRA_PMU
136237c3637SMasahiro Yamada 	if (pmu_set_nominal())
137237c3637SMasahiro Yamada 		debug("Failed to select nominal voltages\n");
138237c3637SMasahiro Yamada #  ifdef CONFIG_TEGRA_CLOCK_SCALING
139237c3637SMasahiro Yamada 	err = board_emc_init();
140237c3637SMasahiro Yamada 	if (err)
141237c3637SMasahiro Yamada 		debug("Memory controller init failed: %d\n", err);
142237c3637SMasahiro Yamada #  endif
143237c3637SMasahiro Yamada # endif /* CONFIG_TEGRA_PMU */
144237c3637SMasahiro Yamada #endif /* CONFIG_SYS_I2C_TEGRA */
145237c3637SMasahiro Yamada 
146237c3637SMasahiro Yamada #ifdef CONFIG_USB_EHCI_TEGRA
147237c3637SMasahiro Yamada 	pin_mux_usb();
148534f9d3fSSimon Glass #endif
149237c3637SMasahiro Yamada 
150e007633bSSimon Glass #if defined(CONFIG_DM_VIDEO)
151237c3637SMasahiro Yamada 	board_id = tegra_board_id();
152237c3637SMasahiro Yamada 	err = tegra_lcd_pmic_init(board_id);
15350d8c4a4SSimon Glass 	if (err) {
15450d8c4a4SSimon Glass 		debug("Failed to set up LCD PMIC\n");
155237c3637SMasahiro Yamada 		return err;
15650d8c4a4SSimon Glass 	}
157135a87efSSimon Glass #endif
158237c3637SMasahiro Yamada 
159237c3637SMasahiro Yamada #ifdef CONFIG_TEGRA_NAND
160237c3637SMasahiro Yamada 	pin_mux_nand();
161237c3637SMasahiro Yamada #endif
162237c3637SMasahiro Yamada 
163be789092SSimon Glass 	tegra_xusb_padctl_init();
164237c3637SMasahiro Yamada 
165237c3637SMasahiro Yamada #ifdef CONFIG_TEGRA_LP0
166237c3637SMasahiro Yamada 	/* save Sdram params to PMC 2, 4, and 24 for WB0 */
167237c3637SMasahiro Yamada 	warmboot_save_sdram_params();
168237c3637SMasahiro Yamada 
169237c3637SMasahiro Yamada 	/* prepare the WB code to LP0 location */
170237c3637SMasahiro Yamada 	warmboot_prepare_code(TEGRA_LP0_ADDR, TEGRA_LP0_SIZE);
171237c3637SMasahiro Yamada #endif
172c96d709fSSimon Glass 	return nvidia_board_init();
173237c3637SMasahiro Yamada }
174237c3637SMasahiro Yamada 
175237c3637SMasahiro Yamada #ifdef CONFIG_BOARD_EARLY_INIT_F
__gpio_early_init(void)176237c3637SMasahiro Yamada static void __gpio_early_init(void)
177237c3637SMasahiro Yamada {
178237c3637SMasahiro Yamada }
179237c3637SMasahiro Yamada 
180237c3637SMasahiro Yamada void gpio_early_init(void) __attribute__((weak, alias("__gpio_early_init")));
181237c3637SMasahiro Yamada 
board_early_init_f(void)182237c3637SMasahiro Yamada int board_early_init_f(void)
183237c3637SMasahiro Yamada {
18446864cc8SSimon Glass 	if (!clock_early_init_done())
18546864cc8SSimon Glass 		clock_early_init();
18646864cc8SSimon Glass 
187dd8204deSStephen Warren #if defined(CONFIG_TEGRA_DISCONNECT_UDC_ON_BOOT)
188dd8204deSStephen Warren #define USBCMD_FS2 (1 << 15)
189dd8204deSStephen Warren 	{
190dd8204deSStephen Warren 		struct usb_ctlr *usbctlr = (struct usb_ctlr *)0x7d000000;
191dd8204deSStephen Warren 		writel(USBCMD_FS2, &usbctlr->usb_cmd);
192dd8204deSStephen Warren 	}
193dd8204deSStephen Warren #endif
194dd8204deSStephen Warren 
195aa441877SThierry Reding 	/* Do any special system timer/TSC setup */
196aa441877SThierry Reding #if defined(CONFIG_TEGRA_SUPPORT_NON_SECURE)
197aa441877SThierry Reding 	if (!tegra_cpu_is_non_secure())
198aa441877SThierry Reding #endif
199aa441877SThierry Reding 		arch_timer_init();
200aa441877SThierry Reding 
201237c3637SMasahiro Yamada 	pinmux_init();
202237c3637SMasahiro Yamada 	board_init_uart_f();
203237c3637SMasahiro Yamada 
204237c3637SMasahiro Yamada 	/* Initialize periph GPIOs */
205237c3637SMasahiro Yamada 	gpio_early_init();
206237c3637SMasahiro Yamada 	gpio_early_init_uart();
207237c3637SMasahiro Yamada 
208237c3637SMasahiro Yamada 	return 0;
209237c3637SMasahiro Yamada }
210237c3637SMasahiro Yamada #endif	/* EARLY_INIT */
211237c3637SMasahiro Yamada 
board_late_init(void)212237c3637SMasahiro Yamada int board_late_init(void)
213237c3637SMasahiro Yamada {
214237c3637SMasahiro Yamada #if defined(CONFIG_TEGRA_SUPPORT_NON_SECURE)
215237c3637SMasahiro Yamada 	if (tegra_cpu_is_non_secure()) {
216237c3637SMasahiro Yamada 		printf("CPU is in NS mode\n");
217*382bee57SSimon Glass 		env_set("cpu_ns_mode", "1");
218237c3637SMasahiro Yamada 	} else {
219*382bee57SSimon Glass 		env_set("cpu_ns_mode", "");
220237c3637SMasahiro Yamada 	}
221237c3637SMasahiro Yamada #endif
22266999892STom Warren 	start_cpu_fan();
22366999892STom Warren 
224237c3637SMasahiro Yamada 	return 0;
225237c3637SMasahiro Yamada }
226237c3637SMasahiro Yamada 
227bbc1b99eSStephen Warren /*
228bbc1b99eSStephen Warren  * In some SW environments, a memory carve-out exists to house a secure
229bbc1b99eSStephen Warren  * monitor, a trusted OS, and/or various statically allocated media buffers.
230bbc1b99eSStephen Warren  *
231bbc1b99eSStephen Warren  * This carveout exists at the highest possible address that is within a
232bbc1b99eSStephen Warren  * 32-bit physical address space.
233bbc1b99eSStephen Warren  *
234bbc1b99eSStephen Warren  * This function returns the total size of this carve-out. At present, the
235bbc1b99eSStephen Warren  * returned value is hard-coded for simplicity. In the future, it may be
236bbc1b99eSStephen Warren  * possible to determine the carve-out size:
237bbc1b99eSStephen Warren  * - By querying some run-time information source, such as:
238bbc1b99eSStephen Warren  *   - A structure passed to U-Boot by earlier boot software.
239bbc1b99eSStephen Warren  *   - SoC registers.
240bbc1b99eSStephen Warren  *   - A call into the secure monitor.
241bbc1b99eSStephen Warren  * - In the per-board U-Boot configuration header, based on knowledge of the
242bbc1b99eSStephen Warren  *   SW environment that U-Boot is being built for.
243bbc1b99eSStephen Warren  *
244bbc1b99eSStephen Warren  * For now, we support two configurations in U-Boot:
245bbc1b99eSStephen Warren  * - 32-bit ports without any form of carve-out.
246bbc1b99eSStephen Warren  * - 64 bit ports which are assumed to use a carve-out of a conservatively
247bbc1b99eSStephen Warren  *   hard-coded size.
248bbc1b99eSStephen Warren  */
carveout_size(void)249bbc1b99eSStephen Warren static ulong carveout_size(void)
250bbc1b99eSStephen Warren {
25100f782a9SThierry Reding #ifdef CONFIG_ARM64
252bbc1b99eSStephen Warren 	return SZ_512M;
253bbc1b99eSStephen Warren #else
254bbc1b99eSStephen Warren 	return 0;
255bbc1b99eSStephen Warren #endif
256bbc1b99eSStephen Warren }
257bbc1b99eSStephen Warren 
258bbc1b99eSStephen Warren /*
259bbc1b99eSStephen Warren  * Determine the amount of usable RAM below 4GiB, taking into account any
260bbc1b99eSStephen Warren  * carve-out that may be assigned.
261bbc1b99eSStephen Warren  */
usable_ram_size_below_4g(void)262bbc1b99eSStephen Warren static ulong usable_ram_size_below_4g(void)
263bbc1b99eSStephen Warren {
264bbc1b99eSStephen Warren 	ulong total_size_below_4g;
265bbc1b99eSStephen Warren 	ulong usable_size_below_4g;
266bbc1b99eSStephen Warren 
267bbc1b99eSStephen Warren 	/*
268bbc1b99eSStephen Warren 	 * The total size of RAM below 4GiB is the lesser address of:
269bbc1b99eSStephen Warren 	 * (a) 2GiB itself (RAM starts at 2GiB, and 4GiB - 2GiB == 2GiB).
270bbc1b99eSStephen Warren 	 * (b) The size RAM physically present in the system.
271bbc1b99eSStephen Warren 	 */
272bbc1b99eSStephen Warren 	if (gd->ram_size < SZ_2G)
273bbc1b99eSStephen Warren 		total_size_below_4g = gd->ram_size;
274bbc1b99eSStephen Warren 	else
275bbc1b99eSStephen Warren 		total_size_below_4g = SZ_2G;
276bbc1b99eSStephen Warren 
277bbc1b99eSStephen Warren 	/* Calculate usable RAM by subtracting out any carve-out size */
278bbc1b99eSStephen Warren 	usable_size_below_4g = total_size_below_4g - carveout_size();
279bbc1b99eSStephen Warren 
280bbc1b99eSStephen Warren 	return usable_size_below_4g;
281bbc1b99eSStephen Warren }
282bbc1b99eSStephen Warren 
283bbc1b99eSStephen Warren /*
284bbc1b99eSStephen Warren  * Represent all available RAM in either one or two banks.
285bbc1b99eSStephen Warren  *
286bbc1b99eSStephen Warren  * The first bank describes any usable RAM below 4GiB.
287bbc1b99eSStephen Warren  * The second bank describes any RAM above 4GiB.
288bbc1b99eSStephen Warren  *
289bbc1b99eSStephen Warren  * This split is driven by the following requirements:
290bbc1b99eSStephen Warren  * - The NVIDIA L4T kernel requires separate entries in the DT /memory/reg
291bbc1b99eSStephen Warren  *   property for memory below and above the 4GiB boundary. The layout of that
292bbc1b99eSStephen Warren  *   DT property is directly driven by the entries in the U-Boot bank array.
293bbc1b99eSStephen Warren  * - The potential existence of a carve-out at the end of RAM below 4GiB can
294bbc1b99eSStephen Warren  *   only be represented using multiple banks.
295bbc1b99eSStephen Warren  *
296bbc1b99eSStephen Warren  * Explicitly removing the carve-out RAM from the bank entries makes the RAM
297bbc1b99eSStephen Warren  * layout a bit more obvious, e.g. when running "bdinfo" at the U-Boot
298bbc1b99eSStephen Warren  * command-line.
299bbc1b99eSStephen Warren  *
300bbc1b99eSStephen Warren  * This does mean that the DT U-Boot passes to the Linux kernel will not
301bbc1b99eSStephen Warren  * include this RAM in /memory/reg at all. An alternative would be to include
302bbc1b99eSStephen Warren  * all RAM in the U-Boot banks (and hence DT), and add a /memreserve/ node
303bbc1b99eSStephen Warren  * into DT to stop the kernel from using the RAM. IIUC, I don't /think/ the
304bbc1b99eSStephen Warren  * Linux kernel will ever need to access any RAM in* the carve-out via a CPU
305bbc1b99eSStephen Warren  * mapping, so either way is acceptable.
306bbc1b99eSStephen Warren  *
307bbc1b99eSStephen Warren  * On 32-bit systems, we never define a bank for RAM above 4GiB, since the
308bbc1b99eSStephen Warren  * start address of that bank cannot be represented in the 32-bit .size
309bbc1b99eSStephen Warren  * field.
310bbc1b99eSStephen Warren  */
dram_init_banksize(void)31176b00acaSSimon Glass int dram_init_banksize(void)
312bbc1b99eSStephen Warren {
313bbc1b99eSStephen Warren 	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
314bbc1b99eSStephen Warren 	gd->bd->bi_dram[0].size = usable_ram_size_below_4g();
315bbc1b99eSStephen Warren 
316e81ca884SSimon Glass #ifdef CONFIG_PCI
317e81ca884SSimon Glass 	gd->pci_ram_top = gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size;
318e81ca884SSimon Glass #endif
319e81ca884SSimon Glass 
320bbc1b99eSStephen Warren #ifdef CONFIG_PHYS_64BIT
321bbc1b99eSStephen Warren 	if (gd->ram_size > SZ_2G) {
322bbc1b99eSStephen Warren 		gd->bd->bi_dram[1].start = 0x100000000;
323bbc1b99eSStephen Warren 		gd->bd->bi_dram[1].size = gd->ram_size - SZ_2G;
324bbc1b99eSStephen Warren 	} else
325bbc1b99eSStephen Warren #endif
326bbc1b99eSStephen Warren 	{
327bbc1b99eSStephen Warren 		gd->bd->bi_dram[1].start = 0;
328bbc1b99eSStephen Warren 		gd->bd->bi_dram[1].size = 0;
329bbc1b99eSStephen Warren 	}
33076b00acaSSimon Glass 
33176b00acaSSimon Glass 	return 0;
332bbc1b99eSStephen Warren }
333bbc1b99eSStephen Warren 
33400f782a9SThierry Reding /*
33500f782a9SThierry Reding  * Most hardware on 64-bit Tegra is still restricted to DMA to the lower
33600f782a9SThierry Reding  * 32-bits of the physical address space. Cap the maximum usable RAM area
33700f782a9SThierry Reding  * at 4 GiB to avoid DMA buffers from being allocated beyond the 32-bit
338bbc1b99eSStephen Warren  * boundary that most devices can address. Also, don't let U-Boot use any
339bbc1b99eSStephen Warren  * carve-out, as mentioned above.
340424afc0aSStephen Warren  *
341bbc1b99eSStephen Warren  * This function is called before dram_init_banksize(), so we can't simply
342bbc1b99eSStephen Warren  * return gd->bd->bi_dram[1].start + gd->bd->bi_dram[1].size.
34300f782a9SThierry Reding  */
board_get_usable_ram_top(ulong total_size)34400f782a9SThierry Reding ulong board_get_usable_ram_top(ulong total_size)
34500f782a9SThierry Reding {
346bbc1b99eSStephen Warren 	return CONFIG_SYS_SDRAM_BASE + usable_ram_size_below_4g();
34700f782a9SThierry Reding }
348