blob: 627e061798f60ccdbcf2e2cf10cafc3100651905 [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{
69 reset_timer();
70 return 0;
71}
72
73/*
74 * Routine: clock_init_uart
75 * Description: init the PLL and clock for the UART(s)
76 */
77static void clock_init_uart(void)
78{
79 struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
Tom Warren41b68382011-01-27 10:58:05 +000080 u32 reg;
81
Tom Warrene1495582011-04-14 12:09:41 +000082 reg = readl(&clkrst->crc_pllp_base);
83 if (!(reg & PLL_BASE_OVRRIDE)) {
Tom Warren41b68382011-01-27 10:58:05 +000084 /* Override pllp setup for 216MHz operation. */
85 reg = (PLL_BYPASS | PLL_BASE_OVRRIDE | PLL_DIVP);
86 reg |= (((NVRM_PLLP_FIXED_FREQ_KHZ/500) << 8) | PLL_DIVM);
87 writel(reg, &clkrst->crc_pllp_base);
88
89 reg |= PLL_ENABLE;
90 writel(reg, &clkrst->crc_pllp_base);
91
92 reg &= ~PLL_BYPASS;
93 writel(reg, &clkrst->crc_pllp_base);
Tom Warren41b68382011-01-27 10:58:05 +000094 }
95
96 /* Now do the UART reset/clock enable */
97#if defined(CONFIG_TEGRA2_ENABLE_UARTA)
98 /* Assert Reset to UART */
99 reg = readl(&clkrst->crc_rst_dev_l);
100 reg |= SWR_UARTA_RST; /* SWR_UARTA_RST = 1 */
101 writel(reg, &clkrst->crc_rst_dev_l);
102
103 /* Enable clk to UART */
104 reg = readl(&clkrst->crc_clk_out_enb_l);
105 reg |= CLK_ENB_UARTA; /* CLK_ENB_UARTA = 1 */
106 writel(reg, &clkrst->crc_clk_out_enb_l);
107
108 /* Enable pllp_out0 to UART */
109 reg = readl(&clkrst->crc_clk_src_uarta);
110 reg &= 0x3FFFFFFF; /* UARTA_CLK_SRC = 00, PLLP_OUT0 */
111 writel(reg, &clkrst->crc_clk_src_uarta);
112
113 /* wait for 2us */
114 udelay(2);
115
116 /* De-assert reset to UART */
117 reg = readl(&clkrst->crc_rst_dev_l);
118 reg &= ~SWR_UARTA_RST; /* SWR_UARTA_RST = 0 */
119 writel(reg, &clkrst->crc_rst_dev_l);
120#endif /* CONFIG_TEGRA2_ENABLE_UARTA */
121#if defined(CONFIG_TEGRA2_ENABLE_UARTD)
122 /* Assert Reset to UART */
123 reg = readl(&clkrst->crc_rst_dev_u);
124 reg |= SWR_UARTD_RST; /* SWR_UARTD_RST = 1 */
125 writel(reg, &clkrst->crc_rst_dev_u);
126
127 /* Enable clk to UART */
128 reg = readl(&clkrst->crc_clk_out_enb_u);
129 reg |= CLK_ENB_UARTD; /* CLK_ENB_UARTD = 1 */
130 writel(reg, &clkrst->crc_clk_out_enb_u);
131
132 /* Enable pllp_out0 to UART */
133 reg = readl(&clkrst->crc_clk_src_uartd);
134 reg &= 0x3FFFFFFF; /* UARTD_CLK_SRC = 00, PLLP_OUT0 */
135 writel(reg, &clkrst->crc_clk_src_uartd);
136
137 /* wait for 2us */
138 udelay(2);
139
140 /* De-assert reset to UART */
141 reg = readl(&clkrst->crc_rst_dev_u);
142 reg &= ~SWR_UARTD_RST; /* SWR_UARTD_RST = 0 */
143 writel(reg, &clkrst->crc_rst_dev_u);
144#endif /* CONFIG_TEGRA2_ENABLE_UARTD */
145}
146
147/*
148 * Routine: pin_mux_uart
149 * Description: setup the pin muxes/tristate values for the UART(s)
150 */
151static void pin_mux_uart(void)
152{
153 struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
154 u32 reg;
155
156#if defined(CONFIG_TEGRA2_ENABLE_UARTA)
157 reg = readl(&pmt->pmt_ctl_c);
158 reg &= 0xFFF0FFFF; /* IRRX_/IRTX_SEL [19:16] = 00 UARTA */
159 writel(reg, &pmt->pmt_ctl_c);
160
161 reg = readl(&pmt->pmt_tri_a);
162 reg &= ~Z_IRRX; /* Z_IRRX = normal (0) */
163 reg &= ~Z_IRTX; /* Z_IRTX = normal (0) */
164 writel(reg, &pmt->pmt_tri_a);
165#endif /* CONFIG_TEGRA2_ENABLE_UARTA */
166#if defined(CONFIG_TEGRA2_ENABLE_UARTD)
167 reg = readl(&pmt->pmt_ctl_b);
168 reg &= 0xFFFFFFF3; /* GMC_SEL [3:2] = 00, UARTD */
169 writel(reg, &pmt->pmt_ctl_b);
170
171 reg = readl(&pmt->pmt_tri_a);
172 reg &= ~Z_GMC; /* Z_GMC = normal (0) */
173 writel(reg, &pmt->pmt_tri_a);
174#endif /* CONFIG_TEGRA2_ENABLE_UARTD */
175}
176
177/*
Tom Warren85f0ee42011-05-31 10:30:37 +0000178 * Routine: clock_init_mmc
179 * Description: init the PLL and clocks for the SDMMC controllers
180 */
181static void clock_init_mmc(void)
182{
183 struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
184 u32 reg;
185
186 /* Do the SDMMC resets/clock enables */
187
188 /* Assert Reset to SDMMC4 */
189 reg = readl(&clkrst->crc_rst_dev_l);
190 reg |= SWR_SDMMC4_RST; /* SWR_SDMMC4_RST = 1 */
191 writel(reg, &clkrst->crc_rst_dev_l);
192
193 /* Enable clk to SDMMC4 */
194 reg = readl(&clkrst->crc_clk_out_enb_l);
195 reg |= CLK_ENB_SDMMC4; /* CLK_ENB_SDMMC4 = 1 */
196 writel(reg, &clkrst->crc_clk_out_enb_l);
197
198 /* Enable pllp_out0 to SDMMC4 */
199 reg = readl(&clkrst->crc_clk_src_sdmmc4);
200 reg &= 0x3FFFFF00; /* SDMMC4_CLK_SRC = 00, PLLP_OUT0 */
201 reg |= (10 << 1); /* n-1, 11-1 shl 1 */
202 writel(reg, &clkrst->crc_clk_src_sdmmc4);
203
204 /*
205 * As per the Tegra2 TRM, section 5.3.4:
206 * 'Wait 2 us for the clock to flush through the pipe/logic'
207 */
208 udelay(2);
209
210 /* De-assert reset to SDMMC4 */
211 reg = readl(&clkrst->crc_rst_dev_l);
212 reg &= ~SWR_SDMMC4_RST; /* SWR_SDMMC4_RST = 0 */
213 writel(reg, &clkrst->crc_rst_dev_l);
214
215 /* Assert Reset to SDMMC3 */
216 reg = readl(&clkrst->crc_rst_dev_u);
217 reg |= SWR_SDMMC3_RST; /* SWR_SDMMC3_RST = 1 */
218 writel(reg, &clkrst->crc_rst_dev_u);
219
220 /* Enable clk to SDMMC3 */
221 reg = readl(&clkrst->crc_clk_out_enb_u);
222 reg |= CLK_ENB_SDMMC3; /* CLK_ENB_SDMMC3 = 1 */
223 writel(reg, &clkrst->crc_clk_out_enb_u);
224
225 /* Enable pllp_out0 to SDMMC4, set divisor to 11 for 20MHz */
226 reg = readl(&clkrst->crc_clk_src_sdmmc3);
227 reg &= 0x3FFFFF00; /* SDMMC3_CLK_SRC = 00, PLLP_OUT0 */
228 reg |= (10 << 1); /* n-1, 11-1 shl 1 */
229 writel(reg, &clkrst->crc_clk_src_sdmmc3);
230
231 /* wait for 2us */
232 udelay(2);
233
234 /* De-assert reset to SDMMC3 */
235 reg = readl(&clkrst->crc_rst_dev_u);
236 reg &= ~SWR_SDMMC3_RST; /* SWR_SDMMC3_RST = 0 */
237 writel(reg, &clkrst->crc_rst_dev_u);
238}
239
240/*
241 * Routine: pin_mux_mmc
242 * Description: setup the pin muxes/tristate values for the SDMMC(s)
243 */
244static void pin_mux_mmc(void)
245{
246 struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
247 u32 reg;
248
249 /* SDMMC4 */
250 /* config 2, x8 on 2nd set of pins */
251 reg = readl(&pmt->pmt_ctl_a);
252 reg |= (3 << 16); /* ATB_SEL [17:16] = 11 SDIO4 */
253 writel(reg, &pmt->pmt_ctl_a);
254 reg = readl(&pmt->pmt_ctl_b);
255 reg |= (3 << 0); /* GMA_SEL [1:0] = 11 SDIO4 */
256 writel(reg, &pmt->pmt_ctl_b);
257 reg = readl(&pmt->pmt_ctl_d);
258 reg |= (3 << 0); /* GME_SEL [1:0] = 11 SDIO4 */
259 writel(reg, &pmt->pmt_ctl_d);
260
261 reg = readl(&pmt->pmt_tri_a);
262 reg &= ~Z_ATB; /* Z_ATB = normal (0) */
263 reg &= ~Z_GMA; /* Z_GMA = normal (0) */
264 writel(reg, &pmt->pmt_tri_a);
265 reg = readl(&pmt->pmt_tri_b);
266 reg &= ~Z_GME; /* Z_GME = normal (0) */
267 writel(reg, &pmt->pmt_tri_b);
268
269 /* SDMMC3 */
270 /* SDIO3_CLK, SDIO3_CMD, SDIO3_DAT[3:0] */
271 reg = readl(&pmt->pmt_ctl_d);
272 reg &= 0xFFFF03FF;
273 reg |= (2 << 10); /* SDB_SEL [11:10] = 01 SDIO3 */
274 reg |= (2 << 12); /* SDC_SEL [13:12] = 01 SDIO3 */
275 reg |= (2 << 14); /* SDD_SEL [15:14] = 01 SDIO3 */
276 writel(reg, &pmt->pmt_ctl_d);
277
278 reg = readl(&pmt->pmt_tri_b);
279 reg &= ~Z_SDC; /* Z_SDC = normal (0) */
280 reg &= ~Z_SDD; /* Z_SDD = normal (0) */
281 writel(reg, &pmt->pmt_tri_b);
282 reg = readl(&pmt->pmt_tri_d);
283 reg &= ~Z_SDB; /* Z_SDB = normal (0) */
284 writel(reg, &pmt->pmt_tri_d);
285}
286
287/*
Tom Warren41b68382011-01-27 10:58:05 +0000288 * Routine: clock_init
289 * Description: Do individual peripheral clock reset/enables
290 */
291void clock_init(void)
292{
293 clock_init_uart();
294}
295
296/*
297 * Routine: pinmux_init
298 * Description: Do individual peripheral pinmux configs
299 */
300void pinmux_init(void)
301{
302 pin_mux_uart();
303}
304
305/*
Tom Warrene1495582011-04-14 12:09:41 +0000306 * Routine: gpio_init
307 * Description: Do individual peripheral GPIO configs
308 */
309void gpio_init(void)
310{
311 gpio_config_uart();
312}
313
314/*
Tom Warren41b68382011-01-27 10:58:05 +0000315 * Routine: board_init
316 * Description: Early hardware init.
317 */
318int board_init(void)
319{
320 /* boot param addr */
321 gd->bd->bi_boot_params = (NV_PA_SDRAM_BASE + 0x100);
322 /* board id for Linux */
323 gd->bd->bi_arch_number = CONFIG_MACH_TYPE;
324
Tom Warren41b68382011-01-27 10:58:05 +0000325 return 0;
326}
Tom Warren85f0ee42011-05-31 10:30:37 +0000327
328#ifdef CONFIG_TEGRA2_MMC
329/* this is a weak define that we are overriding */
330int board_mmc_init(bd_t *bd)
331{
332 debug("board_mmc_init called\n");
333 /* Enable clocks, muxes, etc. for SDMMC controllers */
334 clock_init_mmc();
335 pin_mux_mmc();
336
337 debug("board_mmc_init: init eMMC\n");
338 /* init dev 0, eMMC chip, with 4-bit bus */
339 tegra2_mmc_init(0, 4);
340
341 debug("board_mmc_init: init SD slot\n");
342 /* init dev 1, SD slot, with 4-bit bus */
343 tegra2_mmc_init(1, 4);
344
345 return 0;
346}
347
348/* this is a weak define that we are overriding */
349int board_mmc_getcd(u8 *cd, struct mmc *mmc)
350{
351 debug("board_mmc_getcd called\n");
352 /*
353 * Hard-code CD presence for now. Need to add GPIO inputs
354 * for Seaboard & Harmony (& Kaen/Aebl/Wario?)
355 */
356 *cd = 1;
357 return 0;
358}
359#endif