blob: 5eca5eb344b6307518ccef12650e87aa6cc2acf7 [file] [log] [blame]
Tom Warren41b68382011-01-27 10:58:05 +00001/*
2 * (C) Copyright 2010,2011
3 * NVIDIA Corporation <www.nvidia.com>
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24#include <common.h>
25#include <ns16550.h>
26#include <asm/io.h>
27#include <asm/arch/tegra2.h>
28#include <asm/arch/sys_proto.h>
29
30#include <asm/arch/clk_rst.h>
31#include <asm/arch/pinmux.h>
32#include <asm/arch/uart.h>
Tom Warren112a1882011-04-14 12:18:06 +000033#include "board.h"
Tom Warren41b68382011-01-27 10:58:05 +000034
Tom Warren85f0ee42011-05-31 10:30:37 +000035#ifdef CONFIG_TEGRA2_MMC
36#include <mmc.h>
37#endif
38
Tom Warren41b68382011-01-27 10:58:05 +000039DECLARE_GLOBAL_DATA_PTR;
40
41const struct tegra2_sysinfo sysinfo = {
42 CONFIG_TEGRA2_BOARD_STRING
43};
44
Tom Warren112a1882011-04-14 12:18:06 +000045#ifdef CONFIG_BOARD_EARLY_INIT_F
46int board_early_init_f(void)
47{
Tom Warrene1495582011-04-14 12:09:41 +000048 /* Initialize periph clocks */
49 clock_init();
50
51 /* Initialize periph pinmuxes */
52 pinmux_init();
53
54 /* Initialize periph GPIOs */
55 gpio_init();
56
57 /* Init UART, scratch regs, and start CPU */
Tom Warren112a1882011-04-14 12:18:06 +000058 tegra2_start();
59 return 0;
60}
61#endif /* EARLY_INIT */
62
Tom Warren41b68382011-01-27 10:58:05 +000063/*
64 * Routine: timer_init
65 * Description: init the timestamp and lastinc value
66 */
67int timer_init(void)
68{
Tom Warren41b68382011-01-27 10:58:05 +000069 return 0;
70}
71
72/*
73 * Routine: clock_init_uart
74 * Description: init the PLL and clock for the UART(s)
75 */
76static void clock_init_uart(void)
77{
78 struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
Tom Warren41b68382011-01-27 10:58:05 +000079 u32 reg;
80
Tom Warrene1495582011-04-14 12:09:41 +000081 reg = readl(&clkrst->crc_pllp_base);
82 if (!(reg & PLL_BASE_OVRRIDE)) {
Tom Warren41b68382011-01-27 10:58:05 +000083 /* Override pllp setup for 216MHz operation. */
84 reg = (PLL_BYPASS | PLL_BASE_OVRRIDE | PLL_DIVP);
85 reg |= (((NVRM_PLLP_FIXED_FREQ_KHZ/500) << 8) | PLL_DIVM);
86 writel(reg, &clkrst->crc_pllp_base);
87
88 reg |= PLL_ENABLE;
89 writel(reg, &clkrst->crc_pllp_base);
90
91 reg &= ~PLL_BYPASS;
92 writel(reg, &clkrst->crc_pllp_base);
Tom Warren41b68382011-01-27 10:58:05 +000093 }
94
95 /* Now do the UART reset/clock enable */
96#if defined(CONFIG_TEGRA2_ENABLE_UARTA)
97 /* Assert Reset to UART */
98 reg = readl(&clkrst->crc_rst_dev_l);
99 reg |= SWR_UARTA_RST; /* SWR_UARTA_RST = 1 */
100 writel(reg, &clkrst->crc_rst_dev_l);
101
102 /* Enable clk to UART */
103 reg = readl(&clkrst->crc_clk_out_enb_l);
104 reg |= CLK_ENB_UARTA; /* CLK_ENB_UARTA = 1 */
105 writel(reg, &clkrst->crc_clk_out_enb_l);
106
107 /* Enable pllp_out0 to UART */
108 reg = readl(&clkrst->crc_clk_src_uarta);
109 reg &= 0x3FFFFFFF; /* UARTA_CLK_SRC = 00, PLLP_OUT0 */
110 writel(reg, &clkrst->crc_clk_src_uarta);
111
112 /* wait for 2us */
113 udelay(2);
114
115 /* De-assert reset to UART */
116 reg = readl(&clkrst->crc_rst_dev_l);
117 reg &= ~SWR_UARTA_RST; /* SWR_UARTA_RST = 0 */
118 writel(reg, &clkrst->crc_rst_dev_l);
119#endif /* CONFIG_TEGRA2_ENABLE_UARTA */
120#if defined(CONFIG_TEGRA2_ENABLE_UARTD)
121 /* Assert Reset to UART */
122 reg = readl(&clkrst->crc_rst_dev_u);
123 reg |= SWR_UARTD_RST; /* SWR_UARTD_RST = 1 */
124 writel(reg, &clkrst->crc_rst_dev_u);
125
126 /* Enable clk to UART */
127 reg = readl(&clkrst->crc_clk_out_enb_u);
128 reg |= CLK_ENB_UARTD; /* CLK_ENB_UARTD = 1 */
129 writel(reg, &clkrst->crc_clk_out_enb_u);
130
131 /* Enable pllp_out0 to UART */
132 reg = readl(&clkrst->crc_clk_src_uartd);
133 reg &= 0x3FFFFFFF; /* UARTD_CLK_SRC = 00, PLLP_OUT0 */
134 writel(reg, &clkrst->crc_clk_src_uartd);
135
136 /* wait for 2us */
137 udelay(2);
138
139 /* De-assert reset to UART */
140 reg = readl(&clkrst->crc_rst_dev_u);
141 reg &= ~SWR_UARTD_RST; /* SWR_UARTD_RST = 0 */
142 writel(reg, &clkrst->crc_rst_dev_u);
143#endif /* CONFIG_TEGRA2_ENABLE_UARTD */
144}
145
146/*
147 * Routine: pin_mux_uart
148 * Description: setup the pin muxes/tristate values for the UART(s)
149 */
150static void pin_mux_uart(void)
151{
152 struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
153 u32 reg;
154
155#if defined(CONFIG_TEGRA2_ENABLE_UARTA)
156 reg = readl(&pmt->pmt_ctl_c);
157 reg &= 0xFFF0FFFF; /* IRRX_/IRTX_SEL [19:16] = 00 UARTA */
158 writel(reg, &pmt->pmt_ctl_c);
159
160 reg = readl(&pmt->pmt_tri_a);
161 reg &= ~Z_IRRX; /* Z_IRRX = normal (0) */
162 reg &= ~Z_IRTX; /* Z_IRTX = normal (0) */
163 writel(reg, &pmt->pmt_tri_a);
164#endif /* CONFIG_TEGRA2_ENABLE_UARTA */
165#if defined(CONFIG_TEGRA2_ENABLE_UARTD)
166 reg = readl(&pmt->pmt_ctl_b);
167 reg &= 0xFFFFFFF3; /* GMC_SEL [3:2] = 00, UARTD */
168 writel(reg, &pmt->pmt_ctl_b);
169
170 reg = readl(&pmt->pmt_tri_a);
171 reg &= ~Z_GMC; /* Z_GMC = normal (0) */
172 writel(reg, &pmt->pmt_tri_a);
173#endif /* CONFIG_TEGRA2_ENABLE_UARTD */
174}
175
176/*
Tom Warren85f0ee42011-05-31 10:30:37 +0000177 * Routine: clock_init_mmc
178 * Description: init the PLL and clocks for the SDMMC controllers
179 */
180static void clock_init_mmc(void)
181{
182 struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
183 u32 reg;
184
185 /* Do the SDMMC resets/clock enables */
186
187 /* Assert Reset to SDMMC4 */
188 reg = readl(&clkrst->crc_rst_dev_l);
189 reg |= SWR_SDMMC4_RST; /* SWR_SDMMC4_RST = 1 */
190 writel(reg, &clkrst->crc_rst_dev_l);
191
192 /* Enable clk to SDMMC4 */
193 reg = readl(&clkrst->crc_clk_out_enb_l);
194 reg |= CLK_ENB_SDMMC4; /* CLK_ENB_SDMMC4 = 1 */
195 writel(reg, &clkrst->crc_clk_out_enb_l);
196
197 /* Enable pllp_out0 to SDMMC4 */
198 reg = readl(&clkrst->crc_clk_src_sdmmc4);
199 reg &= 0x3FFFFF00; /* SDMMC4_CLK_SRC = 00, PLLP_OUT0 */
200 reg |= (10 << 1); /* n-1, 11-1 shl 1 */
201 writel(reg, &clkrst->crc_clk_src_sdmmc4);
202
203 /*
204 * As per the Tegra2 TRM, section 5.3.4:
205 * 'Wait 2 us for the clock to flush through the pipe/logic'
206 */
207 udelay(2);
208
209 /* De-assert reset to SDMMC4 */
210 reg = readl(&clkrst->crc_rst_dev_l);
211 reg &= ~SWR_SDMMC4_RST; /* SWR_SDMMC4_RST = 0 */
212 writel(reg, &clkrst->crc_rst_dev_l);
213
214 /* Assert Reset to SDMMC3 */
215 reg = readl(&clkrst->crc_rst_dev_u);
216 reg |= SWR_SDMMC3_RST; /* SWR_SDMMC3_RST = 1 */
217 writel(reg, &clkrst->crc_rst_dev_u);
218
219 /* Enable clk to SDMMC3 */
220 reg = readl(&clkrst->crc_clk_out_enb_u);
221 reg |= CLK_ENB_SDMMC3; /* CLK_ENB_SDMMC3 = 1 */
222 writel(reg, &clkrst->crc_clk_out_enb_u);
223
224 /* Enable pllp_out0 to SDMMC4, set divisor to 11 for 20MHz */
225 reg = readl(&clkrst->crc_clk_src_sdmmc3);
226 reg &= 0x3FFFFF00; /* SDMMC3_CLK_SRC = 00, PLLP_OUT0 */
227 reg |= (10 << 1); /* n-1, 11-1 shl 1 */
228 writel(reg, &clkrst->crc_clk_src_sdmmc3);
229
230 /* wait for 2us */
231 udelay(2);
232
233 /* De-assert reset to SDMMC3 */
234 reg = readl(&clkrst->crc_rst_dev_u);
235 reg &= ~SWR_SDMMC3_RST; /* SWR_SDMMC3_RST = 0 */
236 writel(reg, &clkrst->crc_rst_dev_u);
237}
238
239/*
240 * Routine: pin_mux_mmc
241 * Description: setup the pin muxes/tristate values for the SDMMC(s)
242 */
243static void pin_mux_mmc(void)
244{
245 struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
246 u32 reg;
247
248 /* SDMMC4 */
249 /* config 2, x8 on 2nd set of pins */
250 reg = readl(&pmt->pmt_ctl_a);
251 reg |= (3 << 16); /* ATB_SEL [17:16] = 11 SDIO4 */
252 writel(reg, &pmt->pmt_ctl_a);
253 reg = readl(&pmt->pmt_ctl_b);
254 reg |= (3 << 0); /* GMA_SEL [1:0] = 11 SDIO4 */
255 writel(reg, &pmt->pmt_ctl_b);
256 reg = readl(&pmt->pmt_ctl_d);
257 reg |= (3 << 0); /* GME_SEL [1:0] = 11 SDIO4 */
258 writel(reg, &pmt->pmt_ctl_d);
259
260 reg = readl(&pmt->pmt_tri_a);
261 reg &= ~Z_ATB; /* Z_ATB = normal (0) */
262 reg &= ~Z_GMA; /* Z_GMA = normal (0) */
263 writel(reg, &pmt->pmt_tri_a);
264 reg = readl(&pmt->pmt_tri_b);
265 reg &= ~Z_GME; /* Z_GME = normal (0) */
266 writel(reg, &pmt->pmt_tri_b);
267
268 /* SDMMC3 */
269 /* SDIO3_CLK, SDIO3_CMD, SDIO3_DAT[3:0] */
270 reg = readl(&pmt->pmt_ctl_d);
271 reg &= 0xFFFF03FF;
272 reg |= (2 << 10); /* SDB_SEL [11:10] = 01 SDIO3 */
273 reg |= (2 << 12); /* SDC_SEL [13:12] = 01 SDIO3 */
274 reg |= (2 << 14); /* SDD_SEL [15:14] = 01 SDIO3 */
275 writel(reg, &pmt->pmt_ctl_d);
276
277 reg = readl(&pmt->pmt_tri_b);
278 reg &= ~Z_SDC; /* Z_SDC = normal (0) */
279 reg &= ~Z_SDD; /* Z_SDD = normal (0) */
280 writel(reg, &pmt->pmt_tri_b);
281 reg = readl(&pmt->pmt_tri_d);
282 reg &= ~Z_SDB; /* Z_SDB = normal (0) */
283 writel(reg, &pmt->pmt_tri_d);
284}
285
286/*
Tom Warren41b68382011-01-27 10:58:05 +0000287 * Routine: clock_init
288 * Description: Do individual peripheral clock reset/enables
289 */
290void clock_init(void)
291{
292 clock_init_uart();
293}
294
295/*
296 * Routine: pinmux_init
297 * Description: Do individual peripheral pinmux configs
298 */
299void pinmux_init(void)
300{
301 pin_mux_uart();
302}
303
304/*
Tom Warrene1495582011-04-14 12:09:41 +0000305 * Routine: gpio_init
306 * Description: Do individual peripheral GPIO configs
307 */
308void gpio_init(void)
309{
310 gpio_config_uart();
311}
312
313/*
Tom Warren41b68382011-01-27 10:58:05 +0000314 * Routine: board_init
315 * Description: Early hardware init.
316 */
317int board_init(void)
318{
319 /* boot param addr */
320 gd->bd->bi_boot_params = (NV_PA_SDRAM_BASE + 0x100);
Tom Warren41b68382011-01-27 10:58:05 +0000321
Tom Warren41b68382011-01-27 10:58:05 +0000322 return 0;
323}
Tom Warren85f0ee42011-05-31 10:30:37 +0000324
325#ifdef CONFIG_TEGRA2_MMC
326/* this is a weak define that we are overriding */
327int board_mmc_init(bd_t *bd)
328{
329 debug("board_mmc_init called\n");
330 /* Enable clocks, muxes, etc. for SDMMC controllers */
331 clock_init_mmc();
332 pin_mux_mmc();
333
334 debug("board_mmc_init: init eMMC\n");
335 /* init dev 0, eMMC chip, with 4-bit bus */
336 tegra2_mmc_init(0, 4);
337
338 debug("board_mmc_init: init SD slot\n");
339 /* init dev 1, SD slot, with 4-bit bus */
340 tegra2_mmc_init(1, 4);
341
342 return 0;
343}
344
345/* this is a weak define that we are overriding */
346int board_mmc_getcd(u8 *cd, struct mmc *mmc)
347{
348 debug("board_mmc_getcd called\n");
349 /*
350 * Hard-code CD presence for now. Need to add GPIO inputs
351 * for Seaboard & Harmony (& Kaen/Aebl/Wario?)
352 */
353 *cd = 1;
354 return 0;
355}
356#endif