xref: /rk3399_rockchip-uboot/arch/arm/mach-tegra/board2.c (revision 534f9d3feffdcccc0f21def87bb21b8aebb7ba30)
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>
12237c3637SMasahiro Yamada #include <linux/compiler.h>
13237c3637SMasahiro Yamada #include <asm/io.h>
14237c3637SMasahiro Yamada #include <asm/arch/clock.h>
15237c3637SMasahiro Yamada #ifdef CONFIG_LCD
16237c3637SMasahiro Yamada #include <asm/arch/display.h>
17237c3637SMasahiro Yamada #endif
18237c3637SMasahiro Yamada #include <asm/arch/funcmux.h>
19237c3637SMasahiro Yamada #include <asm/arch/pinmux.h>
20237c3637SMasahiro Yamada #include <asm/arch/pmu.h>
21237c3637SMasahiro Yamada #ifdef CONFIG_PWM_TEGRA
22237c3637SMasahiro Yamada #include <asm/arch/pwm.h>
23237c3637SMasahiro Yamada #endif
24237c3637SMasahiro Yamada #include <asm/arch/tegra.h>
25237c3637SMasahiro Yamada #include <asm/arch-tegra/ap.h>
26237c3637SMasahiro Yamada #include <asm/arch-tegra/board.h>
27237c3637SMasahiro Yamada #include <asm/arch-tegra/clk_rst.h>
28237c3637SMasahiro Yamada #include <asm/arch-tegra/pmc.h>
29237c3637SMasahiro Yamada #include <asm/arch-tegra/sys_proto.h>
30237c3637SMasahiro Yamada #include <asm/arch-tegra/uart.h>
31237c3637SMasahiro Yamada #include <asm/arch-tegra/warmboot.h>
32237c3637SMasahiro Yamada #ifdef CONFIG_TEGRA_CLOCK_SCALING
33237c3637SMasahiro Yamada #include <asm/arch/emc.h>
34237c3637SMasahiro Yamada #endif
35237c3637SMasahiro Yamada #ifdef CONFIG_USB_EHCI_TEGRA
36237c3637SMasahiro Yamada #include <asm/arch-tegra/usb.h>
37237c3637SMasahiro Yamada #include <usb.h>
38237c3637SMasahiro Yamada #endif
39237c3637SMasahiro Yamada #ifdef CONFIG_TEGRA_MMC
40237c3637SMasahiro Yamada #include <asm/arch-tegra/tegra_mmc.h>
41237c3637SMasahiro Yamada #include <asm/arch-tegra/mmc.h>
42237c3637SMasahiro Yamada #endif
43237c3637SMasahiro Yamada #include <asm/arch-tegra/xusb-padctl.h>
44237c3637SMasahiro Yamada #include <power/as3722.h>
45237c3637SMasahiro Yamada #include <i2c.h>
46237c3637SMasahiro Yamada #include <spi.h>
47237c3637SMasahiro Yamada #include "emc.h"
48237c3637SMasahiro Yamada 
49237c3637SMasahiro Yamada DECLARE_GLOBAL_DATA_PTR;
50237c3637SMasahiro Yamada 
51237c3637SMasahiro Yamada #ifdef CONFIG_SPL_BUILD
52237c3637SMasahiro Yamada /* TODO(sjg@chromium.org): Remove once SPL supports device tree */
53237c3637SMasahiro Yamada U_BOOT_DEVICE(tegra_gpios) = {
54237c3637SMasahiro Yamada 	"gpio_tegra"
55237c3637SMasahiro Yamada };
56237c3637SMasahiro Yamada #endif
57237c3637SMasahiro Yamada 
58237c3637SMasahiro Yamada __weak void pinmux_init(void) {}
59237c3637SMasahiro Yamada __weak void pin_mux_usb(void) {}
60237c3637SMasahiro Yamada __weak void pin_mux_spi(void) {}
61237c3637SMasahiro Yamada __weak void gpio_early_init_uart(void) {}
62237c3637SMasahiro Yamada __weak void pin_mux_display(void) {}
63237c3637SMasahiro Yamada 
64237c3637SMasahiro Yamada #if defined(CONFIG_TEGRA_NAND)
65237c3637SMasahiro Yamada __weak void pin_mux_nand(void)
66237c3637SMasahiro Yamada {
67237c3637SMasahiro Yamada 	funcmux_select(PERIPH_ID_NDFLASH, FUNCMUX_DEFAULT);
68237c3637SMasahiro Yamada }
69237c3637SMasahiro Yamada #endif
70237c3637SMasahiro Yamada 
71237c3637SMasahiro Yamada /*
72237c3637SMasahiro Yamada  * Routine: power_det_init
73237c3637SMasahiro Yamada  * Description: turn off power detects
74237c3637SMasahiro Yamada  */
75237c3637SMasahiro Yamada static void power_det_init(void)
76237c3637SMasahiro Yamada {
77237c3637SMasahiro Yamada #if defined(CONFIG_TEGRA20)
78237c3637SMasahiro Yamada 	struct pmc_ctlr *const pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
79237c3637SMasahiro Yamada 
80237c3637SMasahiro Yamada 	/* turn off power detects */
81237c3637SMasahiro Yamada 	writel(0, &pmc->pmc_pwr_det_latch);
82237c3637SMasahiro Yamada 	writel(0, &pmc->pmc_pwr_det);
83237c3637SMasahiro Yamada #endif
84237c3637SMasahiro Yamada }
85237c3637SMasahiro Yamada 
86237c3637SMasahiro Yamada __weak int tegra_board_id(void)
87237c3637SMasahiro Yamada {
88237c3637SMasahiro Yamada 	return -1;
89237c3637SMasahiro Yamada }
90237c3637SMasahiro Yamada 
91237c3637SMasahiro Yamada #ifdef CONFIG_DISPLAY_BOARDINFO
92237c3637SMasahiro Yamada int checkboard(void)
93237c3637SMasahiro Yamada {
94237c3637SMasahiro Yamada 	int board_id = tegra_board_id();
95237c3637SMasahiro Yamada 
96237c3637SMasahiro Yamada 	printf("Board: %s", CONFIG_TEGRA_BOARD_STRING);
97237c3637SMasahiro Yamada 	if (board_id != -1)
98237c3637SMasahiro Yamada 		printf(", ID: %d\n", board_id);
99237c3637SMasahiro Yamada 	printf("\n");
100237c3637SMasahiro Yamada 
101237c3637SMasahiro Yamada 	return 0;
102237c3637SMasahiro Yamada }
103237c3637SMasahiro Yamada #endif	/* CONFIG_DISPLAY_BOARDINFO */
104237c3637SMasahiro Yamada 
105237c3637SMasahiro Yamada __weak int tegra_lcd_pmic_init(int board_it)
106237c3637SMasahiro Yamada {
107237c3637SMasahiro Yamada 	return 0;
108237c3637SMasahiro Yamada }
109237c3637SMasahiro Yamada 
110c96d709fSSimon Glass __weak int nvidia_board_init(void)
111c96d709fSSimon Glass {
112c96d709fSSimon Glass 	return 0;
113c96d709fSSimon Glass }
114c96d709fSSimon Glass 
115237c3637SMasahiro Yamada /*
116237c3637SMasahiro Yamada  * Routine: board_init
117237c3637SMasahiro Yamada  * Description: Early hardware init.
118237c3637SMasahiro Yamada  */
119237c3637SMasahiro Yamada int board_init(void)
120237c3637SMasahiro Yamada {
121237c3637SMasahiro Yamada 	__maybe_unused int err;
122237c3637SMasahiro Yamada 	__maybe_unused int board_id;
123237c3637SMasahiro Yamada 
124237c3637SMasahiro Yamada 	/* Do clocks and UART first so that printf() works */
125237c3637SMasahiro Yamada 	clock_init();
126237c3637SMasahiro Yamada 	clock_verify();
127237c3637SMasahiro Yamada 
128237c3637SMasahiro Yamada #ifdef CONFIG_TEGRA_SPI
129237c3637SMasahiro Yamada 	pin_mux_spi();
130237c3637SMasahiro Yamada #endif
131237c3637SMasahiro Yamada 
132237c3637SMasahiro Yamada #ifdef CONFIG_PWM_TEGRA
133237c3637SMasahiro Yamada 	if (pwm_init(gd->fdt_blob))
134237c3637SMasahiro Yamada 		debug("%s: Failed to init pwm\n", __func__);
135237c3637SMasahiro Yamada #endif
136237c3637SMasahiro Yamada #ifdef CONFIG_LCD
137237c3637SMasahiro Yamada 	pin_mux_display();
138237c3637SMasahiro Yamada 	tegra_lcd_check_next_stage(gd->fdt_blob, 0);
139237c3637SMasahiro Yamada #endif
140237c3637SMasahiro Yamada 	/* boot param addr */
141237c3637SMasahiro Yamada 	gd->bd->bi_boot_params = (NV_PA_SDRAM_BASE + 0x100);
142237c3637SMasahiro Yamada 
143237c3637SMasahiro Yamada 	power_det_init();
144237c3637SMasahiro Yamada 
145237c3637SMasahiro Yamada #ifdef CONFIG_SYS_I2C_TEGRA
146237c3637SMasahiro Yamada # ifdef CONFIG_TEGRA_PMU
147237c3637SMasahiro Yamada 	if (pmu_set_nominal())
148237c3637SMasahiro Yamada 		debug("Failed to select nominal voltages\n");
149237c3637SMasahiro Yamada #  ifdef CONFIG_TEGRA_CLOCK_SCALING
150237c3637SMasahiro Yamada 	err = board_emc_init();
151237c3637SMasahiro Yamada 	if (err)
152237c3637SMasahiro Yamada 		debug("Memory controller init failed: %d\n", err);
153237c3637SMasahiro Yamada #  endif
154237c3637SMasahiro Yamada # endif /* CONFIG_TEGRA_PMU */
155237c3637SMasahiro Yamada #ifdef CONFIG_AS3722_POWER
156237c3637SMasahiro Yamada 	err = as3722_init(NULL);
157237c3637SMasahiro Yamada 	if (err && err != -ENODEV)
158237c3637SMasahiro Yamada 		return err;
159237c3637SMasahiro Yamada #endif
160237c3637SMasahiro Yamada #endif /* CONFIG_SYS_I2C_TEGRA */
161237c3637SMasahiro Yamada 
162237c3637SMasahiro Yamada #ifdef CONFIG_USB_EHCI_TEGRA
163237c3637SMasahiro Yamada 	pin_mux_usb();
164*534f9d3fSSimon Glass # ifndef CONFIG_DM_USB
165237c3637SMasahiro Yamada 	usb_process_devicetree(gd->fdt_blob);
166237c3637SMasahiro Yamada # endif
167*534f9d3fSSimon Glass #endif
168237c3637SMasahiro Yamada 
169237c3637SMasahiro Yamada #ifdef CONFIG_LCD
170237c3637SMasahiro Yamada 	board_id = tegra_board_id();
171237c3637SMasahiro Yamada 	err = tegra_lcd_pmic_init(board_id);
172237c3637SMasahiro Yamada 	if (err)
173237c3637SMasahiro Yamada 		return err;
174237c3637SMasahiro Yamada 	tegra_lcd_check_next_stage(gd->fdt_blob, 0);
175237c3637SMasahiro Yamada #endif
176237c3637SMasahiro Yamada 
177237c3637SMasahiro Yamada #ifdef CONFIG_TEGRA_NAND
178237c3637SMasahiro Yamada 	pin_mux_nand();
179237c3637SMasahiro Yamada #endif
180237c3637SMasahiro Yamada 
181237c3637SMasahiro Yamada 	tegra_xusb_padctl_init(gd->fdt_blob);
182237c3637SMasahiro Yamada 
183237c3637SMasahiro Yamada #ifdef CONFIG_TEGRA_LP0
184237c3637SMasahiro Yamada 	/* save Sdram params to PMC 2, 4, and 24 for WB0 */
185237c3637SMasahiro Yamada 	warmboot_save_sdram_params();
186237c3637SMasahiro Yamada 
187237c3637SMasahiro Yamada 	/* prepare the WB code to LP0 location */
188237c3637SMasahiro Yamada 	warmboot_prepare_code(TEGRA_LP0_ADDR, TEGRA_LP0_SIZE);
189237c3637SMasahiro Yamada #endif
190c96d709fSSimon Glass 	return nvidia_board_init();
191237c3637SMasahiro Yamada }
192237c3637SMasahiro Yamada 
193237c3637SMasahiro Yamada #ifdef CONFIG_BOARD_EARLY_INIT_F
194237c3637SMasahiro Yamada static void __gpio_early_init(void)
195237c3637SMasahiro Yamada {
196237c3637SMasahiro Yamada }
197237c3637SMasahiro Yamada 
198237c3637SMasahiro Yamada void gpio_early_init(void) __attribute__((weak, alias("__gpio_early_init")));
199237c3637SMasahiro Yamada 
200237c3637SMasahiro Yamada int board_early_init_f(void)
201237c3637SMasahiro Yamada {
202237c3637SMasahiro Yamada 	pinmux_init();
203237c3637SMasahiro Yamada 	board_init_uart_f();
204237c3637SMasahiro Yamada 
205237c3637SMasahiro Yamada 	/* Initialize periph GPIOs */
206237c3637SMasahiro Yamada 	gpio_early_init();
207237c3637SMasahiro Yamada 	gpio_early_init_uart();
208237c3637SMasahiro Yamada #ifdef CONFIG_LCD
209237c3637SMasahiro Yamada 	tegra_lcd_early_init(gd->fdt_blob);
210237c3637SMasahiro Yamada #endif
211237c3637SMasahiro Yamada 
212237c3637SMasahiro Yamada 	return 0;
213237c3637SMasahiro Yamada }
214237c3637SMasahiro Yamada #endif	/* EARLY_INIT */
215237c3637SMasahiro Yamada 
216237c3637SMasahiro Yamada int board_late_init(void)
217237c3637SMasahiro Yamada {
218237c3637SMasahiro Yamada #ifdef CONFIG_LCD
219237c3637SMasahiro Yamada 	/* Make sure we finish initing the LCD */
220237c3637SMasahiro Yamada 	tegra_lcd_check_next_stage(gd->fdt_blob, 1);
221237c3637SMasahiro Yamada #endif
222237c3637SMasahiro Yamada #if defined(CONFIG_TEGRA_SUPPORT_NON_SECURE)
223237c3637SMasahiro Yamada 	if (tegra_cpu_is_non_secure()) {
224237c3637SMasahiro Yamada 		printf("CPU is in NS mode\n");
225237c3637SMasahiro Yamada 		setenv("cpu_ns_mode", "1");
226237c3637SMasahiro Yamada 	} else {
227237c3637SMasahiro Yamada 		setenv("cpu_ns_mode", "");
228237c3637SMasahiro Yamada 	}
229237c3637SMasahiro Yamada #endif
230237c3637SMasahiro Yamada 	return 0;
231237c3637SMasahiro Yamada }
232237c3637SMasahiro Yamada 
233237c3637SMasahiro Yamada #if defined(CONFIG_TEGRA_MMC)
234237c3637SMasahiro Yamada __weak void pin_mux_mmc(void)
235237c3637SMasahiro Yamada {
236237c3637SMasahiro Yamada }
237237c3637SMasahiro Yamada 
238237c3637SMasahiro Yamada /* this is a weak define that we are overriding */
239237c3637SMasahiro Yamada int board_mmc_init(bd_t *bd)
240237c3637SMasahiro Yamada {
241237c3637SMasahiro Yamada 	debug("%s called\n", __func__);
242237c3637SMasahiro Yamada 
243237c3637SMasahiro Yamada 	/* Enable muxes, etc. for SDMMC controllers */
244237c3637SMasahiro Yamada 	pin_mux_mmc();
245237c3637SMasahiro Yamada 
246237c3637SMasahiro Yamada 	debug("%s: init MMC\n", __func__);
247237c3637SMasahiro Yamada 	tegra_mmc_init();
248237c3637SMasahiro Yamada 
249237c3637SMasahiro Yamada 	return 0;
250237c3637SMasahiro Yamada }
251237c3637SMasahiro Yamada 
252237c3637SMasahiro Yamada void pad_init_mmc(struct mmc_host *host)
253237c3637SMasahiro Yamada {
254237c3637SMasahiro Yamada #if defined(CONFIG_TEGRA30)
255237c3637SMasahiro Yamada 	enum periph_id id = host->mmc_id;
256237c3637SMasahiro Yamada 	u32 val;
257237c3637SMasahiro Yamada 
258237c3637SMasahiro Yamada 	debug("%s: sdmmc address = %08x, id = %d\n", __func__,
259237c3637SMasahiro Yamada 		(unsigned int)host->reg, id);
260237c3637SMasahiro Yamada 
261237c3637SMasahiro Yamada 	/* Set the pad drive strength for SDMMC1 or 3 only */
262237c3637SMasahiro Yamada 	if (id != PERIPH_ID_SDMMC1 && id != PERIPH_ID_SDMMC3) {
263237c3637SMasahiro Yamada 		debug("%s: settings are only valid for SDMMC1/SDMMC3!\n",
264237c3637SMasahiro Yamada 			__func__);
265237c3637SMasahiro Yamada 		return;
266237c3637SMasahiro Yamada 	}
267237c3637SMasahiro Yamada 
268237c3637SMasahiro Yamada 	val = readl(&host->reg->sdmemcmppadctl);
269237c3637SMasahiro Yamada 	val &= 0xFFFFFFF0;
270237c3637SMasahiro Yamada 	val |= MEMCOMP_PADCTRL_VREF;
271237c3637SMasahiro Yamada 	writel(val, &host->reg->sdmemcmppadctl);
272237c3637SMasahiro Yamada 
273237c3637SMasahiro Yamada 	val = readl(&host->reg->autocalcfg);
274237c3637SMasahiro Yamada 	val &= 0xFFFF0000;
275237c3637SMasahiro Yamada 	val |= AUTO_CAL_PU_OFFSET | AUTO_CAL_PD_OFFSET | AUTO_CAL_ENABLED;
276237c3637SMasahiro Yamada 	writel(val, &host->reg->autocalcfg);
277237c3637SMasahiro Yamada #endif	/* T30 */
278237c3637SMasahiro Yamada }
279237c3637SMasahiro Yamada #endif	/* MMC */
280