]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/nvidia/common/board.c
Merge branch 'master' of git://git.denx.de/u-boot-imx
[karo-tx-uboot.git] / board / nvidia / common / board.c
1 /*
2  *  (C) Copyright 2010,2011
3  *  NVIDIA Corporation <www.nvidia.com>
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #include <common.h>
9 #include <ns16550.h>
10 #include <linux/compiler.h>
11 #include <asm/io.h>
12 #include <asm/arch/clock.h>
13 #ifdef CONFIG_LCD
14 #include <asm/arch/display.h>
15 #endif
16 #include <asm/arch/funcmux.h>
17 #include <asm/arch/pinmux.h>
18 #include <asm/arch/pmu.h>
19 #ifdef CONFIG_PWM_TEGRA
20 #include <asm/arch/pwm.h>
21 #endif
22 #include <asm/arch/tegra.h>
23 #include <asm/arch-tegra/board.h>
24 #include <asm/arch-tegra/clk_rst.h>
25 #include <asm/arch-tegra/pmc.h>
26 #include <asm/arch-tegra/sys_proto.h>
27 #include <asm/arch-tegra/uart.h>
28 #include <asm/arch-tegra/warmboot.h>
29 #ifdef CONFIG_TEGRA_CLOCK_SCALING
30 #include <asm/arch/emc.h>
31 #endif
32 #ifdef CONFIG_USB_EHCI_TEGRA
33 #include <asm/arch-tegra/usb.h>
34 #include <usb.h>
35 #endif
36 #ifdef CONFIG_TEGRA_MMC
37 #include <asm/arch-tegra/tegra_mmc.h>
38 #include <asm/arch-tegra/mmc.h>
39 #endif
40 #include <i2c.h>
41 #include <spi.h>
42 #include "emc.h"
43
44 DECLARE_GLOBAL_DATA_PTR;
45
46 const struct tegra_sysinfo sysinfo = {
47         CONFIG_TEGRA_BOARD_STRING
48 };
49
50 __weak void pinmux_init(void) {}
51 __weak void pin_mux_usb(void) {}
52 __weak void pin_mux_spi(void) {}
53 __weak void gpio_early_init_uart(void) {}
54 __weak void pin_mux_display(void) {}
55
56 #if defined(CONFIG_TEGRA_NAND)
57 __weak void pin_mux_nand(void)
58 {
59         funcmux_select(PERIPH_ID_NDFLASH, FUNCMUX_DEFAULT);
60 }
61 #endif
62
63 /*
64  * Routine: power_det_init
65  * Description: turn off power detects
66  */
67 static void power_det_init(void)
68 {
69 #if defined(CONFIG_TEGRA20)
70         struct pmc_ctlr *const pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
71
72         /* turn off power detects */
73         writel(0, &pmc->pmc_pwr_det_latch);
74         writel(0, &pmc->pmc_pwr_det);
75 #endif
76 }
77
78 /*
79  * Routine: board_init
80  * Description: Early hardware init.
81  */
82 int board_init(void)
83 {
84         __maybe_unused int err;
85
86         /* Do clocks and UART first so that printf() works */
87         clock_init();
88         clock_verify();
89
90 #ifdef CONFIG_TEGRA_SPI
91         pin_mux_spi();
92 #endif
93
94 #ifdef CONFIG_PWM_TEGRA
95         if (pwm_init(gd->fdt_blob))
96                 debug("%s: Failed to init pwm\n", __func__);
97 #endif
98 #ifdef CONFIG_LCD
99         pin_mux_display();
100         tegra_lcd_check_next_stage(gd->fdt_blob, 0);
101 #endif
102         /* boot param addr */
103         gd->bd->bi_boot_params = (NV_PA_SDRAM_BASE + 0x100);
104
105         power_det_init();
106
107 #ifdef CONFIG_SYS_I2C_TEGRA
108 #ifndef CONFIG_SYS_I2C_INIT_BOARD
109 #error "You must define CONFIG_SYS_I2C_INIT_BOARD to use i2c on Nvidia boards"
110 #endif
111         i2c_init_board();
112 # ifdef CONFIG_TEGRA_PMU
113         if (pmu_set_nominal())
114                 debug("Failed to select nominal voltages\n");
115 #  ifdef CONFIG_TEGRA_CLOCK_SCALING
116         err = board_emc_init();
117         if (err)
118                 debug("Memory controller init failed: %d\n", err);
119 #  endif
120 # endif /* CONFIG_TEGRA_PMU */
121 #endif /* CONFIG_SYS_I2C_TEGRA */
122
123 #ifdef CONFIG_USB_EHCI_TEGRA
124         pin_mux_usb();
125         usb_process_devicetree(gd->fdt_blob);
126 #endif
127
128 #ifdef CONFIG_LCD
129         tegra_lcd_check_next_stage(gd->fdt_blob, 0);
130 #endif
131
132 #ifdef CONFIG_TEGRA_NAND
133         pin_mux_nand();
134 #endif
135
136 #ifdef CONFIG_TEGRA_LP0
137         /* save Sdram params to PMC 2, 4, and 24 for WB0 */
138         warmboot_save_sdram_params();
139
140         /* prepare the WB code to LP0 location */
141         warmboot_prepare_code(TEGRA_LP0_ADDR, TEGRA_LP0_SIZE);
142 #endif
143
144         return 0;
145 }
146
147 #ifdef CONFIG_BOARD_EARLY_INIT_F
148 static void __gpio_early_init(void)
149 {
150 }
151
152 void gpio_early_init(void) __attribute__((weak, alias("__gpio_early_init")));
153
154 int board_early_init_f(void)
155 {
156         pinmux_init();
157         board_init_uart_f();
158
159         /* Initialize periph GPIOs */
160         gpio_early_init();
161         gpio_early_init_uart();
162 #ifdef CONFIG_LCD
163         tegra_lcd_early_init(gd->fdt_blob);
164 #endif
165
166         return 0;
167 }
168 #endif  /* EARLY_INIT */
169
170 int board_late_init(void)
171 {
172 #ifdef CONFIG_LCD
173         /* Make sure we finish initing the LCD */
174         tegra_lcd_check_next_stage(gd->fdt_blob, 1);
175 #endif
176         return 0;
177 }
178
179 #if defined(CONFIG_TEGRA_MMC)
180 __weak void pin_mux_mmc(void)
181 {
182 }
183
184 /* this is a weak define that we are overriding */
185 int board_mmc_init(bd_t *bd)
186 {
187         debug("%s called\n", __func__);
188
189         /* Enable muxes, etc. for SDMMC controllers */
190         pin_mux_mmc();
191
192         debug("%s: init MMC\n", __func__);
193         tegra_mmc_init();
194
195         return 0;
196 }
197
198 void pad_init_mmc(struct mmc_host *host)
199 {
200 #if defined(CONFIG_TEGRA30)
201         enum periph_id id = host->mmc_id;
202         u32 val;
203
204         debug("%s: sdmmc address = %08x, id = %d\n", __func__,
205                 (unsigned int)host->reg, id);
206
207         /* Set the pad drive strength for SDMMC1 or 3 only */
208         if (id != PERIPH_ID_SDMMC1 && id != PERIPH_ID_SDMMC3) {
209                 debug("%s: settings are only valid for SDMMC1/SDMMC3!\n",
210                         __func__);
211                 return;
212         }
213
214         val = readl(&host->reg->sdmemcmppadctl);
215         val &= 0xFFFFFFF0;
216         val |= MEMCOMP_PADCTRL_VREF;
217         writel(val, &host->reg->sdmemcmppadctl);
218
219         val = readl(&host->reg->autocalcfg);
220         val &= 0xFFFF0000;
221         val |= AUTO_CAL_PU_OFFSET | AUTO_CAL_PD_OFFSET | AUTO_CAL_ENABLED;
222         writel(val, &host->reg->autocalcfg);
223 #endif  /* T30 */
224 }
225 #endif  /* MMC */