62ed6fb432b1e75766de8ff3dc7fe58fd26152fb
[karo-tx-uboot.git] / board / BuS / vl_ma2sc / vl_ma2sc.c
1 /*
2  * (C) Copyright 2009-2012
3  * Jens Scharsig  <esw@bus-elekronik.de>
4  * BuS Elektronik GmbH & Co. KG
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 <config.h>
26 #include <common.h>
27 #include <asm/sizes.h>
28 #include <asm/io.h>
29 #include <asm/arch/hardware.h>
30 #include <asm/arch/clk.h>
31 #include <asm/arch/at91_matrix.h>
32 #include <asm/arch/at91sam9_smc.h>
33 #include <asm/arch/at91_pmc.h>
34 #include <asm/arch/at91_pio.h>
35 #include <asm/arch/at91_rstc.h>
36 #include <asm/arch/at91sam9263.h>
37 #include <asm/arch/gpio.h>
38 #include <asm/arch/at91_common.h>
39 #include <lcd.h>
40 #include <i2c.h>
41 #include <atmel_lcdc.h>
42 #if defined(CONFIG_RESET_PHY_R) && defined(CONFIG_MACB)
43 #include <net.h>
44 #endif
45 #include <netdev.h>
46
47 DECLARE_GLOBAL_DATA_PTR;
48
49 #ifdef CONFIG_CMD_NAND
50 static void vl_ma2sc_nand_hw_init(void)
51 {
52         unsigned long csa;
53         at91_smc_t      *smc    = (at91_smc_t *) ATMEL_BASE_SMC0;
54         at91_matrix_t   *matrix = (at91_matrix_t *) ATMEL_BASE_MATRIX;
55         at91_pmc_t      *pmc    = (at91_pmc_t *) ATMEL_BASE_PMC;
56
57         at91_set_pio_output(AT91_PIO_PORTA, 13, 1);     /* CAN_TX -> H */
58         at91_set_pio_output(AT91_PIO_PORTA, 12, 1);     /* CAN_STB -> H */
59         at91_set_pio_output(AT91_PIO_PORTA, 11, 1);     /* CAN_EN -> H */
60
61         /* Enable CS3 */
62         csa = readl(&matrix->csa[0]) | AT91_MATRIX_CSA_EBI_CS3A;
63         writel(csa, &matrix->csa[0]);
64
65         /* Configure SMC CS3 for NAND/SmartMedia */
66         writel(AT91_SMC_SETUP_NWE(1) | AT91_SMC_SETUP_NCS_WR(0) |
67                 AT91_SMC_SETUP_NRD(1) | AT91_SMC_SETUP_NCS_RD(0),
68                 &smc->cs[3].setup);
69
70         writel(AT91_SMC_PULSE_NWE(3) | AT91_SMC_PULSE_NCS_WR(3) |
71                 AT91_SMC_PULSE_NRD(3) | AT91_SMC_PULSE_NCS_RD(3),
72                 &smc->cs[3].pulse);
73
74         writel(AT91_SMC_CYCLE_NWE(5) | AT91_SMC_CYCLE_NRD(5),
75                 &smc->cs[3].cycle);
76         writel(AT91_SMC_MODE_RM_NRD | AT91_SMC_MODE_WM_NWE |
77                 AT91_SMC_MODE_DBW_8 |
78                 AT91_SMC_MODE_TDF_CYCLE(2),
79                 &smc->cs[3].mode);
80         writel((1 << ATMEL_ID_PIOB) | (1 << ATMEL_ID_PIOCDE),
81                 &pmc->pcer);
82
83         /* Configure RDY/BSY */
84 #ifdef CONFIG_SYS_NAND_READY_PIN
85         at91_set_pio_input(CONFIG_SYS_NAND_READY_PIN, 1);
86 #endif
87         /* Enable NandFlash */
88         at91_set_pio_output(CONFIG_SYS_NAND_ENABLE_PIN, 1);
89 }
90 #endif
91
92 #ifdef CONFIG_MACB
93 static void vl_ma2sc_macb_hw_init(void)
94 {
95         unsigned long   erstl;
96         at91_pmc_t      *pmc    = (at91_pmc_t *) ATMEL_BASE_PMC;
97         at91_rstc_t     *rstc   = (at91_rstc_t *) ATMEL_BASE_RSTC;
98         /* Enable clock */
99         writel(1 << ATMEL_ID_EMAC, &pmc->pcer);
100
101         erstl = readl(&rstc->mr) & AT91_RSTC_MR_ERSTL_MASK;
102
103         /* Need to reset PHY -> 500ms reset */
104         writel(AT91_RSTC_KEY | AT91_RSTC_MR_ERSTL(0x0D) |
105                 AT91_RSTC_MR_URSTEN, &rstc->mr);
106
107         writel(AT91_RSTC_KEY | AT91_RSTC_CR_EXTRST, &rstc->cr);
108         /* Wait for end hardware reset */
109         while (!(readl(&rstc->sr) & AT91_RSTC_SR_NRSTL))
110                 ;
111
112         /* Restore NRST value */
113         writel(AT91_RSTC_KEY | erstl | AT91_RSTC_MR_URSTEN, &rstc->mr);
114
115         at91_macb_hw_init();
116 }
117 #endif
118
119 #ifdef CONFIG_LCD
120 vidinfo_t panel_info = {
121         .vl_col =               320,
122         .vl_row =               240,
123         .vl_clk =               6500000,
124         .vl_sync =              ATMEL_LCDC_INVDVAL_INVERTED |
125                                 ATMEL_LCDC_INVLINE_INVERTED |
126                                 ATMEL_LCDC_INVVD_INVERTED   |
127                                 ATMEL_LCDC_INVFRAME_INVERTED,
128         .vl_bpix =              (ATMEL_LCDC_PIXELSIZE_8 >> 5),
129         .vl_tft =               1,
130         .vl_hsync_len =         5,      /* Horiz Sync Pulse Width */
131         .vl_left_margin =       68,     /* horiz back porch */
132         .vl_right_margin =      20,     /* horiz front porch */
133         .vl_vsync_len =         2,      /* vert Sync Pulse Width */
134         .vl_upper_margin =      18,     /* vert back porch */
135         .vl_lower_margin =      4,      /* vert front porch */
136         .mmio =                 ATMEL_BASE_LCDC,
137 };
138
139 void lcd_enable(void)
140 {
141 }
142
143 void lcd_disable(void)
144 {
145 }
146
147 static void vl_ma2sc_lcd_hw_init(void)
148 {
149         at91_pmc_t      *pmc    = (at91_pmc_t *) ATMEL_BASE_PMC;
150
151         at91_set_a_periph(AT91_PIO_PORTC, 0, 0);        /* LCDVSYNC */
152         at91_set_a_periph(AT91_PIO_PORTC, 1, 0);        /* LCDHSYNC */
153         at91_set_a_periph(AT91_PIO_PORTC, 2, 0);        /* LCDDOTCK */
154         at91_set_a_periph(AT91_PIO_PORTC, 3, 0);        /* LCDDEN */
155         at91_set_b_periph(AT91_PIO_PORTB, 9, 0);        /* LCDCC */
156
157         at91_set_a_periph(AT91_PIO_PORTC, 4, 0);        /* LCDD0 */
158         at91_set_a_periph(AT91_PIO_PORTC, 5, 0);        /* LCDD1 */
159         at91_set_a_periph(AT91_PIO_PORTC, 6, 0);        /* LCDD2 */
160         at91_set_a_periph(AT91_PIO_PORTC, 7, 0);        /* LCDD3 */
161         at91_set_a_periph(AT91_PIO_PORTC, 8, 0);        /* LCDD4 */
162         at91_set_a_periph(AT91_PIO_PORTC, 9, 0);        /* LCDD5 */
163         at91_set_a_periph(AT91_PIO_PORTC, 10, 0);       /* LCDD6 */
164         at91_set_a_periph(AT91_PIO_PORTC, 11, 0);       /* LCDD7 */
165
166         at91_set_a_periph(AT91_PIO_PORTC, 13, 0);       /* LCDD9 */
167         at91_set_a_periph(AT91_PIO_PORTC, 14, 0);       /* LCDD10 */
168         at91_set_a_periph(AT91_PIO_PORTC, 15, 0);       /* LCDD11 */
169         at91_set_a_periph(AT91_PIO_PORTC, 16, 0);       /* LCDD12 */
170         at91_set_b_periph(AT91_PIO_PORTC, 12, 0);       /* LCDD13 */
171         at91_set_a_periph(AT91_PIO_PORTC, 18, 0);       /* LCDD14 */
172         at91_set_a_periph(AT91_PIO_PORTC, 19, 0);       /* LCDD15 */
173
174         at91_set_a_periph(AT91_PIO_PORTC, 20, 0);       /* LCDD26 */
175         at91_set_a_periph(AT91_PIO_PORTC, 21, 0);       /* LCDD17 */
176         at91_set_a_periph(AT91_PIO_PORTC, 22, 0);       /* LCDD18 */
177         at91_set_a_periph(AT91_PIO_PORTC, 23, 0);       /* LCDD19 */
178         at91_set_a_periph(AT91_PIO_PORTC, 24, 0);       /* LCDD20 */
179         at91_set_b_periph(AT91_PIO_PORTC, 17, 0);       /* LCDD21 */
180         at91_set_a_periph(AT91_PIO_PORTC, 26, 0);       /* LCDD22 */
181         at91_set_a_periph(AT91_PIO_PORTC, 27, 0);       /* LCDD23 */
182
183         at91_set_pio_output(AT91_PIO_PORTE, 0, 0);      /* LCD QXH */
184
185         at91_set_pio_output(AT91_PIO_PORTE, 2, 0);      /* LCD SHUT */
186         at91_set_pio_output(AT91_PIO_PORTE, 3, 1);      /* LCD TopBottom */
187         at91_set_pio_output(AT91_PIO_PORTE, 4, 0);      /* LCD REV */
188         at91_set_pio_output(AT91_PIO_PORTE, 5, 1);      /* LCD RightLeft */
189         at91_set_pio_output(AT91_PIO_PORTE, 6, 0);      /* LCD Color Mode CM */
190         at91_set_pio_output(AT91_PIO_PORTE, 7, 0);      /* LCD BGR */
191
192         at91_set_pio_output(AT91_PIO_PORTB, 9, 0);      /* LCD CC */
193
194         writel(1 << ATMEL_ID_LCDC, &pmc->pcer);
195         gd->fb_base = ATMEL_BASE_SRAM0;
196 }
197 #endif /* Config LCD */
198
199 #ifdef CONFIG_BOARD_EARLY_INIT_F
200 int board_early_init_f(void)
201 {
202         struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
203
204         /* Enable clocks for all PIOs */
205         writel((1 << ATMEL_ID_PIOA) | (1 << ATMEL_ID_PIOB) |
206                 (1 << ATMEL_ID_PIOCDE),
207                 &pmc->pcer);
208
209         at91_seriald_hw_init();
210
211         return 0;
212 }
213 #endif
214
215 int board_init(void)
216 {
217         at91_smc_t      *smc    = (at91_smc_t *) ATMEL_BASE_SMC0;
218         at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIO;
219         u32             pin;
220
221         pin = 0x1F000001;
222         writel(pin, &pio->pioa.idr);
223         writel(pin, &pio->pioa.pudr);
224         writel(pin, &pio->pioa.per);
225         writel(pin, &pio->pioa.oer);
226         writel(pin, &pio->pioa.sodr);
227         writel((1 << 25), &pio->pioa.codr);
228
229         pin = 0x1F000100;
230         writel(pin, &pio->piob.idr);
231         writel(pin, &pio->piob.pudr);
232         writel(pin, &pio->piob.per);
233         writel(pin, &pio->piob.oer);
234         writel(pin, &pio->piob.codr);
235         writel((1 << 24), &pio->piob.sodr);
236
237         pin = 0x40000000;                       /* Pullup DRxD enbable */
238         writel(pin, &pio->pioc.puer);
239
240         pin = 0x0000000F;                       /* HWversion als Input */
241         writel(pin, &pio->piod.idr);
242         writel(pin, &pio->piod.puer);
243         writel(pin, &pio->piod.per);
244         writel(pin, &pio->piod.odr);
245         writel(pin, &pio->piod.owdr);
246
247         /* Enable Ctrlc */
248         console_init_f();
249
250         gd->bd->bi_arch_number = MACH_TYPE_VL_MA2SC;
251         /* adress of boot parameters */
252         gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
253
254         writel(CONFIG_SYS_SMC0_MODE0_VAL, &smc->cs[0].setup);
255         writel(CONFIG_SYS_SMC0_CYCLE0_VAL, &smc->cs[0].cycle);
256         writel(CONFIG_SYS_SMC0_PULSE0_VAL, &smc->cs[0].pulse);
257         writel(CONFIG_SYS_SMC0_SETUP0_VAL, &smc->cs[0].setup);
258
259 #ifdef CONFIG_CMD_NAND
260         vl_ma2sc_nand_hw_init();
261 #endif
262 #ifdef CONFIG_MACB
263         vl_ma2sc_macb_hw_init();
264 #endif
265 #ifdef CONFIG_USB_OHCI_NEW
266         at91_uhp_hw_init();
267 #endif
268 #ifdef CONFIG_LCD
269         vl_ma2sc_lcd_hw_init();
270 #endif
271         return 0;
272 }
273
274 #ifdef CONFIG_MISC_INIT_R
275 int misc_init_r(void)
276 {
277         uchar   buffer[8];
278         at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIO;
279         u32             pin;
280
281         buffer[0] = 0x04;
282         buffer[1] = 0x00;
283         if (i2c_write(0x68, 0x0E, 1, buffer, 2) != 0)
284                 puts("error reseting rtc clock\n\0");
285
286         /* read hardware version */
287
288         pin = (readl(&pio->piod.pdsr) & 0x0F) + 0x44;
289         printf("Board: revision %c\n", pin);
290         buffer[0] = pin;
291         buffer[1] = 0;
292         setenv("revision", (char *) buffer);
293
294         pin = 0x40000000;                       /* Pullup DRxD enbable */
295         writel(pin, &pio->pioc.puer);
296         return 0;
297 }
298 #endif
299
300 int dram_init(void)
301 {
302         gd->ram_size = get_ram_size((long *) CONFIG_SYS_SDRAM_BASE,
303                         CONFIG_SYS_SDRAM_SIZE);
304         return 0;
305 }
306
307 #ifdef CONFIG_RESET_PHY_R
308 void reset_phy(void)
309 {
310 #ifdef CONFIG_MACB
311         /*
312          * Initialize ethernet HW addr prior to starting Linux,
313          * needed for nfsroot
314          */
315         eth_init(gd->bd);
316 #endif
317 }
318 #endif
319
320 int board_eth_init(bd_t *bis)
321 {
322         int rc = 0;
323 #ifdef CONFIG_MACB
324         rc = macb_eth_initialize(0, (void *) ATMEL_BASE_EMAC, 0x01);
325 #endif
326         return rc;
327 }
328
329 #ifdef CONFIG_SOFT_I2C
330 void i2c_init_board(void)
331 {
332         u32 pin;
333
334         at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC;
335         at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIO;
336         u8 sda = (1<<4);
337         u8 scl = (1<<5);
338
339         writel(1 << ATMEL_ID_PIOB, &pmc->pcer);
340         pin = sda | scl;
341         writel(pin, &pio->piob.idr);    /* Disable Interupt */
342         writel(pin, &pio->piob.pudr);
343         writel(pin, &pio->piob.per);
344         writel(pin, &pio->piob.oer);
345         writel(pin, &pio->piob.sodr);
346 }
347 #endif
348
349 void watchdog_reset(void)
350 {
351         at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIO;
352         u32     pin = 0x1;      /* PA0 */
353
354         if ((readl(&pio->pioa.odsr) & pin) > 0)
355                 writel(pin, &pio->pioa.codr);
356         else
357                 writel(pin, &pio->pioa.sodr);
358 }
359
360 void enable_caches(void)
361 {
362 #ifndef CONFIG_SYS_DCACHE_OFF
363         dcache_enable();
364 #endif
365 }
366
367 /*---------------------------------------------------------------------------*/
368
369 int do_ledtest(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
370 {
371         int rcode = 1;
372         int row;
373         int col;
374         u32 pinz;
375         u32 pins;
376         at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIO;
377
378         at91_set_pio_output(AT91_PIO_PORTB, 8, 0);      /* LCD DIM */
379
380         pins = 0x1F000000;
381         writel(pins, &pio->pioa.idr);
382         writel(pins, &pio->pioa.pudr);
383         writel(pins, &pio->pioa.per);
384         writel(pins, &pio->pioa.oer);
385         writel(pins, &pio->pioa.sodr);
386
387         pinz = 0x1F000000;
388         writel(pinz, &pio->piob.idr);
389         writel(pinz, &pio->piob.pudr);
390         writel(pinz, &pio->piob.per);
391         writel(pinz, &pio->piob.oer);
392         writel(pinz, &pio->piob.sodr);
393
394         for (row = 0; row < 5; row++) {
395                 for (col = 0; col < 5; col++) {
396                         writel((0x01000000 << col), &pio->piob.sodr);
397                         writel((0x01000000 << row), &pio->pioa.codr);
398                         printf("LED Test %d x %d\n", row, col);
399                         udelay(1000000);
400                         writel(pinz, &pio->piob.codr);
401                         writel(pins, &pio->pioa.sodr);
402                 }
403         }
404         return rcode;
405 }
406
407 void poweroff(void)
408 {
409         watchdog_reset();
410         at91_set_pio_output(AT91_PIO_PORTA, 13, 1);     /* CAN_TX -> H */
411         udelay(100);
412         at91_set_pio_output(AT91_PIO_PORTA, 12, 0);     /* CAN_STB -> L */
413         udelay(100);
414         at91_set_pio_output(AT91_PIO_PORTA, 11, 0);     /* CAN_EN -> L */
415         udelay(100);
416         while (1)
417                 watchdog_reset();
418 }
419
420 int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc,  char * const argv[])
421 {
422         int rcode = 1;
423         poweroff();
424         return rcode;
425 }
426
427 int do_beep(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
428 {
429         int i;
430         u32 freq;
431         u32 durate;
432         int rcode = 1;
433
434         freq = 1000;
435         durate = 2;
436         switch (argc) {
437         case 3:
438                 durate = simple_strtoul(argv[2], NULL, 10);
439         case 2:
440                 freq = simple_strtoul(argv[1], NULL, 10);
441         case 1:
442                 break;
443         default:
444                 cmd_usage(cmdtp);
445                 rcode = 1;
446                 break;
447         }
448         durate = durate * freq;
449         freq = 500000 / freq;
450         for (i = 0; i < durate; i++) {
451                 at91_set_pio_output(AT91_PIO_PORTB, 29, 1);     /* Sound On*/
452                 udelay(freq);
453                 at91_set_pio_output(AT91_PIO_PORTB, 29, 0);     /* Sound Off*/
454                 udelay(freq);
455         }
456         at91_set_pio_output(AT91_PIO_PORTB, 29, 0);     /* Sound Off*/
457         return rcode;
458 }
459
460 int do_keytest(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
461 {
462         int rcode = 1;
463         int row;
464         u32 col;
465         u32 pinz;
466         u32 pins;
467         at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIO;
468         at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC;
469
470         writel((1 << ATMEL_ID_PIOA), &pmc->pcer);
471
472         pins = 0x001F0000;
473         writel(pins, &pio->pioa.idr);
474         writel(pins, &pio->pioa.pudr);
475         writel(pins, &pio->pioa.per);
476         writel(pins, &pio->pioa.odr);
477
478         pinz = 0x000F0000;
479         writel(pinz, &pio->piob.idr);
480         writel(pinz, &pio->piob.pudr);
481         writel(pinz, &pio->piob.per);
482         writel(pinz, &pio->piob.oer);
483         writel(pinz, &pio->piob.codr);
484
485         while (1) {
486                 col = 0;
487                 for (row = 0; row < 4; row++) {
488                         writel((0x00010000 << row), &pio->piob.sodr);
489                         udelay(10000);
490                         col <<= 4;
491                         col |= ((readl(&pio->pioa.pdsr) >> 16) & 0xF) ^ 0xF ;
492                         writel(pinz, &pio->piob.codr);
493                 }
494                 printf("Matix: ");
495                 for (row = 0; row < 16; row++) {
496                         printf("%1.1d", col & 1);
497                         col >>= 1;
498                 }
499                 printf(" SP %d\r ",
500                         1 ^ (1 & (readl(&pio->piob.pdsr) >> 20)));
501                 if ((1 & (readl(&pio->pioa.pdsr) >> 1)) == 0) {
502                         /* SHUTDOWN */
503                         row = 0;
504                         while (row < 1000) {
505                                 if ((1 & (readl(&pio->pioa.pdsr) >> 1)) == 0)
506                                         row++;
507                                 udelay(100);
508                         }
509                         udelay(100000);
510                         row = 0;
511                         while (row < 1000) {
512                                 if ((1 & (readl(&pio->pioa.pdsr) >> 1)) > 0) {
513                                         row++;
514                                         udelay(1000);
515                                 }
516                         }
517                         poweroff();
518                         while (1)
519                                 ;
520                 }
521         }
522         return rcode;
523 }
524
525 /*****************************************************************************/
526
527 U_BOOT_CMD(
528         ledtest,        1,      0,      do_ledtest,
529         "test ledmatrix",
530         "\n"
531         );
532
533 U_BOOT_CMD(
534         keytest,        1,      0,      do_keytest,
535         "test keymatix and special keys, poweroff on pressing ON key",
536         "\n"
537         );
538
539 U_BOOT_CMD(
540         poweroff,       1,      0,      do_poweroff,
541         "power off",
542         "\n"
543         );
544
545 U_BOOT_CMD(
546         beep,   3,      0,      do_beep,
547         "[freq [duration]]",
548         "freq frequence of beep\nduration duration of beep\n"
549         );
550
551 /*****************************************************************************/