blob: 1f222756c84da6e28366e2c62534de1a43850323 [file] [log] [blame]
Jens Scharsig77e72732010-02-03 22:48:09 +01001/*
2 * (C) Copyright 2008-2009
3 * BuS Elektronik GmbH & Co. KG <www.bus-elektronik.de>
4 * Jens Scharsig <esw@bus-elektronik.de>
5 *
6 * See file CREDITS for list of people who contributed to this
7 * project.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22 * MA 02111-1307 USA
23 */
24
25#include <common.h>
26#include <exports.h>
27#include <net.h>
28#include <netdev.h>
29#include <nand.h>
30
31#include <asm/io.h>
32#include <asm/arch/hardware.h>
33#include <asm/arch/at91_pio.h>
34#include <asm/arch/at91_pmc.h>
35#include <asm/arch/at91_mc.h>
36
37#ifdef CONFIG_STATUS_LED
38#include <status_led.h>
39#endif
40
41#ifdef CONFIG_VIDEO
42#include <bus_vcxk.h>
43
44extern unsigned long display_width;
45extern unsigned long display_height;
46#endif
47
48#ifdef CONFIG_CMD_NAND
49void cpux9k2_nand_hw_init(void);
50#endif
51
52DECLARE_GLOBAL_DATA_PTR;
53
54/*
55 * Miscelaneous platform dependent initialisations
56 */
57
58int board_init(void)
59{
60 at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE;
61 /* Enable Ctrlc */
62 console_init_f();
63
64 /* Correct IRDA resistor problem / Set PA23_TXD in Output */
65 writel(AT91_PMX_AA_TXD2, &pio->pioa.oer);
66
67 gd->bd->bi_arch_number = MACH_TYPE_EB_CPUX9K2;
68 /* adress of boot parameters */
69 gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
70
71#ifdef CONFIG_STATUS_LED
72 status_led_set(STATUS_LED_BOOT, STATUS_LED_ON);
73#endif
74#ifdef CONFIG_CMD_NAND
75 cpux9k2_nand_hw_init();
76#endif
77 return 0;
78}
79
80#ifdef CONFIG_MISC_INIT_R
81
82int misc_init_r(void)
83{
84 uchar mac[8];
85 uchar tm;
86 uchar midx;
87 uchar macn6, macn7;
88
89#ifdef CONFIG_NET_MULTI
90 if (getenv("ethaddr") == NULL) {
91 if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0x00,
92 CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
93 (uchar *) &mac, sizeof(mac)) != 0) {
94 puts("Error reading MAC from EEPROM\n");
95 } else {
96 tm = 0;
97 macn6 = 0;
98 macn7 = 0xFF;
99 for (midx = 0; midx < 6; midx++) {
100 if ((mac[midx] != 0) && (mac[midx] != 0xFF))
101 tm++;
102 macn6 += mac[midx];
103 macn7 ^= mac[midx];
104 }
105 if ((macn6 != mac[6]) || (macn7 != mac[7]))
106 tm = 0;
107 if (tm)
108 eth_setenv_enetaddr("ethaddr", mac);
109 else
110 puts("Error: invalid MAC at EEPROM\n");
111 }
112 }
113#endif
114 gd->jt[XF_do_reset] = (void *) do_reset;
115
116#ifdef CONFIG_STATUS_LED
117 status_led_set(STATUS_LED_BOOT, STATUS_LED_BLINKING);
118#endif
119 return 0;
120}
121#endif
122
123#ifdef CONFIG_RESET_PHY_R
124void reset_phy(void)
125{
126 udelay(10000);
127 eth_init(gd->bd);
128}
129#endif
130
131/*
132 * DRAM initialisations
133 */
134
135int dram_init(void)
136{
137 gd->bd->bi_dram[0].start = PHYS_SDRAM;
138 gd->bd->bi_dram[0].size =
139 get_ram_size((volatile long *) PHYS_SDRAM, PHYS_SDRAM_SIZE);
140 return 0;
141}
142
143/*
144 * Ethernet initialisations
145 */
146
147#ifdef CONFIG_DRIVER_AT91EMAC
148int board_eth_init(bd_t *bis)
149{
150 int rc = 0;
151 rc = at91emac_register(bis, (u32) AT91_EMAC_BASE);
152 return rc;
153}
154#endif
155
156/*
157 * Disk On Chip (NAND) Millenium initialization.
158 * The NAND lives in the CS2* space
159 */
160#if defined(CONFIG_CMD_NAND)
161
162#define MASK_ALE (1 << 22) /* our ALE is AD22 */
163#define MASK_CLE (1 << 21) /* our CLE is AD21 */
164
165void cpux9k2_nand_hw_init(void)
166{
167 unsigned long csr;
168 at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE;
169 at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE;
170 at91_mc_t *mc = (at91_mc_t *) AT91_MC_BASE;
171
172 /* Setup Smart Media, fitst enable the address range of CS3 */
173 writel(readl(&mc->ebi.csa) | AT91_EBI_CSA_CS3A, &mc->ebi.csa);
174
175 /* RWH = 1 | RWS = 0 | TDF = 1 | NWS = 3 */
176 csr = AT91_SMC_CSR_RWHOLD(1) | AT91_SMC_CSR_TDF(1) |
177 AT91_SMC_CSR_NWS(3) |
178 AT91_SMC_CSR_ACSS_STANDARD | AT91_SMC_CSR_DBW_8 |
179 AT91_SMC_CSR_WSEN;
180 writel(csr, &mc->smc.csr[3]);
181
182 writel(AT91_PMX_CA_SMOE | AT91_PMX_CA_SMWE, &pio->pioc.asr);
183 writel(AT91_PMX_CA_BFCK | AT91_PMX_CA_SMOE | AT91_PMX_CA_SMWE,
184 &pio->pioc.pdr);
185
186 /* Configure PC2 as input (signal Nand READY ) */
187 writel(AT91_PMX_CA_BFAVD, &pio->pioc.per);
188 writel(AT91_PMX_CA_BFAVD, &pio->pioc.odr); /* disable output */
189 writel(AT91_PMX_CA_BFCK, &pio->pioc.codr);
190
191 /* PIOC clock enabling */
192 writel(1 << AT91_ID_PIOC, &pmc->pcer);
193}
194
195static void board_nand_hwcontrol(struct mtd_info *mtd,
196 int cmd, unsigned int ctrl)
197{
198 at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE;
199 struct nand_chip *this = mtd->priv;
200 ulong IO_ADDR_W = (ulong) this->IO_ADDR_W;
201
202 if (ctrl & NAND_CTRL_CHANGE) {
203 IO_ADDR_W &= ~(MASK_ALE | MASK_CLE);
204
205 if (ctrl & NAND_CLE)
206 IO_ADDR_W |= MASK_CLE;
207 if (ctrl & NAND_ALE)
208 IO_ADDR_W |= MASK_ALE;
209
210 if ((ctrl & NAND_NCE))
211 writel(1, &pio->pioc.codr);
212 else
213 writel(1, &pio->pioc.sodr);
214
215 this->IO_ADDR_W = (void *) IO_ADDR_W;
216 }
217 if (cmd != NAND_CMD_NONE)
218 writeb(cmd, this->IO_ADDR_W);
219}
220
221static int board_nand_dev_ready(struct mtd_info *mtd)
222{
223 at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE;
224 return ((readl(&pio->pioc.pdsr) & (1 << 2)) != 0);
225}
226
227int board_nand_init(struct nand_chip *nand)
228{
229 cpux9k2_nand_hw_init();
230 nand->ecc.mode = NAND_ECC_SOFT;
231 nand->cmd_ctrl = board_nand_hwcontrol;
232 nand->dev_ready = board_nand_dev_ready;
233 nand->chip_delay = 20;
234 return 0;
235}
236
237#endif
238
239#if defined(CONFIG_VIDEO)
240/*
241 * drv_video_init
242 * FUNCTION: initialize VCxK device
243 */
244
245int drv_video_init(void)
246{
247#ifdef CONFIG_SPLASH_SCREEN
248 unsigned long splash;
249#endif
250 char *s;
251 unsigned long csr;
252 at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE;
253 at91_mc_t *mc = (at91_mc_t *) AT91_MC_BASE;
254
255 printf("Init Video as ");
256 s = getenv("displaywidth");
257 if (s != NULL)
258 display_width = simple_strtoul(s, NULL, 10);
259 else
260 display_width = 256;
261 s = getenv("displayheight");
262 if (s != NULL)
263 display_height = simple_strtoul(s, NULL, 10);
264 else
265 display_height = 256;
266 printf("%ld x %ld pixel matrix\n", display_width, display_height);
267
268 /* RWH = 7 | RWS =7 | TDF = 15 | NWS = 0x7F */
269 csr = AT91_SMC_CSR_RWHOLD(7) | AT91_SMC_CSR_RWSETUP(7) |
270 AT91_SMC_CSR_TDF(15) | AT91_SMC_CSR_NWS(127) |
271 AT91_SMC_CSR_ACSS_STANDARD | AT91_SMC_CSR_DBW_16 |
272 AT91_SMC_CSR_BAT_16 | AT91_SMC_CSR_WSEN;
273 writel(csr, &mc->smc.csr[2]);
274 writel(1 << AT91_ID_PIOB, &pmc->pcer);
275
276 vcxk_init(display_width, display_height);
277#ifdef CONFIG_SPLASH_SCREEN
278 s = getenv("splashimage");
279 if (s != NULL) {
280 splash = simple_strtoul(s, NULL, 16);
281 printf("use splashimage: %lx\n", splash);
282 video_display_bitmap(splash, 0, 0);
283 }
284#endif
285 return 0;
286}
287#endif
288
289#ifdef CONFIG_SOFT_I2C
290
291void i2c_init_board(void)
292{
293 u32 pin;
294 at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE;
295 at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE;
296
297 writel(1 << AT91_ID_PIOA, &pmc->pcer);
298 pin = AT91_PMX_AA_TWD | AT91_PMX_AA_TWCK;
299 writel(pin, &pio->pioa.idr);
300 writel(pin, &pio->pioa.pudr);
301 writel(pin, &pio->pioa.per);
302 writel(pin, &pio->pioa.oer);
303 writel(pin, &pio->pioa.sodr);
304}
305
306#endif
307
308/*--------------------------------------------------------------------------*/
309
310#ifdef CONFIG_STATUS_LED
311
312void __led_toggle(led_id_t mask)
313{
314 at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE;
315
316 if (readl(&pio->piod.odsr) & mask)
317 writel(mask, &pio->piod.codr);
318 else
319 writel(mask, &pio->piod.codr);
320}
321
322void __led_init(led_id_t mask, int state)
323{
324 at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE;
325 at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE;
326
327 writel(1 << AT91_ID_PIOD, &pmc->pcer); /* Enable PIOB clock */
328 /* Disable peripherals on LEDs */
329 writel(STATUS_LED_BIT | STATUS_LED_BIT1, &pio->piod.per);
330 /* Enable pins as outputs */
331 writel(STATUS_LED_BIT | STATUS_LED_BIT1, &pio->piod.oer);
332 /* Turn all LEDs OFF */
333 writel(STATUS_LED_BIT | STATUS_LED_BIT1, &pio->piod.sodr);
334
335 __led_set(mask, state);
336}
337
338void __led_set(led_id_t mask, int state)
339{
340 at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE;
341 if (state == STATUS_LED_ON)
342 writel(mask, &pio->piod.codr);
343 else
344 writel(mask, &pio->piod.sodr);
345}
346
347#endif
348
349/*---------------------------------------------------------------------------*/
350
351int do_brightness(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
352{
353 int rcode = 0;
354 ulong side;
355 ulong bright;
356
357 switch (argc) {
358 case 3:
359 side = simple_strtoul(argv[1], NULL, 10);
360 bright = simple_strtoul(argv[2], NULL, 10);
361 if ((side >= 0) && (side <= 3) &&
362 (bright >= 0) && (bright <= 1000)) {
363 vcxk_setbrightness(side, bright);
364 rcode = 0;
365 } else {
366 printf("parameters out of range\n");
367 printf("Usage:\n%s\n", cmdtp->usage);
368 rcode = 1;
369 }
370 break;
371 default:
372 printf("Usage:\n%s\n", cmdtp->usage);
373 rcode = 1;
374 break;
375 }
376 return rcode;
377}
378
379/*---------------------------------------------------------------------------*/
380
381U_BOOT_CMD(
382 bright, 3, 0, do_brightness,
383 "bright - sets the display brightness\n",
384 " <side> <0..1000>\n side: 0/3=both; 1=first; 2=second\n"
385);
386
387/* EOF cpu9k2.c */