84b2060aedbb914ba19e270ce8c8a442f1b4912c
[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         gd->bd->bi_arch_number = MACH_TYPE_VL_MA2SC;
248         /* adress of boot parameters */
249         gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
250
251         writel(CONFIG_SYS_SMC0_MODE0_VAL, &smc->cs[0].setup);
252         writel(CONFIG_SYS_SMC0_CYCLE0_VAL, &smc->cs[0].cycle);
253         writel(CONFIG_SYS_SMC0_PULSE0_VAL, &smc->cs[0].pulse);
254         writel(CONFIG_SYS_SMC0_SETUP0_VAL, &smc->cs[0].setup);
255
256 #ifdef CONFIG_CMD_NAND
257         vl_ma2sc_nand_hw_init();
258 #endif
259 #ifdef CONFIG_MACB
260         vl_ma2sc_macb_hw_init();
261 #endif
262 #ifdef CONFIG_USB_OHCI_NEW
263         at91_uhp_hw_init();
264 #endif
265 #ifdef CONFIG_LCD
266         vl_ma2sc_lcd_hw_init();
267 #endif
268         return 0;
269 }
270
271 #ifdef CONFIG_MISC_INIT_R
272 int misc_init_r(void)
273 {
274         uchar   buffer[8];
275         at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIO;
276         u32             pin;
277
278         buffer[0] = 0x04;
279         buffer[1] = 0x00;
280         if (i2c_write(0x68, 0x0E, 1, buffer, 2) != 0)
281                 puts("error reseting rtc clock\n\0");
282
283         /* read hardware version */
284
285         pin = (readl(&pio->piod.pdsr) & 0x0F) + 0x44;
286         printf("Board: revision %c\n", pin);
287         buffer[0] = pin;
288         buffer[1] = 0;
289         setenv("revision", (char *) buffer);
290
291         pin = 0x40000000;                       /* Pullup DRxD enbable */
292         writel(pin, &pio->pioc.puer);
293         return 0;
294 }
295 #endif
296
297 int dram_init(void)
298 {
299         gd->ram_size = get_ram_size((long *) CONFIG_SYS_SDRAM_BASE,
300                         CONFIG_SYS_SDRAM_SIZE);
301         return 0;
302 }
303
304 #ifdef CONFIG_RESET_PHY_R
305 void reset_phy(void)
306 {
307 #ifdef CONFIG_MACB
308         /*
309          * Initialize ethernet HW addr prior to starting Linux,
310          * needed for nfsroot
311          */
312         eth_init(gd->bd);
313 #endif
314 }
315 #endif
316
317 int board_eth_init(bd_t *bis)
318 {
319         int rc = 0;
320 #ifdef CONFIG_MACB
321         rc = macb_eth_initialize(0, (void *) ATMEL_BASE_EMAC, 0x01);
322 #endif
323         return rc;
324 }
325
326 #ifdef CONFIG_SOFT_I2C
327 void i2c_init_board(void)
328 {
329         u32 pin;
330
331         at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC;
332         at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIO;
333         u8 sda = (1<<4);
334         u8 scl = (1<<5);
335
336         writel(1 << ATMEL_ID_PIOB, &pmc->pcer);
337         pin = sda | scl;
338         writel(pin, &pio->piob.idr);    /* Disable Interupt */
339         writel(pin, &pio->piob.pudr);
340         writel(pin, &pio->piob.per);
341         writel(pin, &pio->piob.oer);
342         writel(pin, &pio->piob.sodr);
343 }
344 #endif
345
346 void watchdog_reset(void)
347 {
348         at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIO;
349         u32     pin = 0x1;      /* PA0 */
350
351         if ((readl(&pio->pioa.odsr) & pin) > 0)
352                 writel(pin, &pio->pioa.codr);
353         else
354                 writel(pin, &pio->pioa.sodr);
355 }
356
357 void enable_caches(void)
358 {
359 #ifndef CONFIG_SYS_DCACHE_OFF
360         dcache_enable();
361 #endif
362 }
363
364 /*---------------------------------------------------------------------------*/
365
366 int do_ledtest(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
367 {
368         int rcode = 1;
369         int row;
370         int col;
371         u32 pinz;
372         u32 pins;
373         at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIO;
374
375         at91_set_pio_output(AT91_PIO_PORTB, 8, 0);      /* LCD DIM */
376
377         pins = 0x1F000000;
378         writel(pins, &pio->pioa.idr);
379         writel(pins, &pio->pioa.pudr);
380         writel(pins, &pio->pioa.per);
381         writel(pins, &pio->pioa.oer);
382         writel(pins, &pio->pioa.sodr);
383
384         pinz = 0x1F000000;
385         writel(pinz, &pio->piob.idr);
386         writel(pinz, &pio->piob.pudr);
387         writel(pinz, &pio->piob.per);
388         writel(pinz, &pio->piob.oer);
389         writel(pinz, &pio->piob.sodr);
390
391         for (row = 0; row < 5; row++) {
392                 for (col = 0; col < 5; col++) {
393                         writel((0x01000000 << col), &pio->piob.sodr);
394                         writel((0x01000000 << row), &pio->pioa.codr);
395                         printf("LED Test %d x %d\n", row, col);
396                         udelay(1000000);
397                         writel(pinz, &pio->piob.codr);
398                         writel(pins, &pio->pioa.sodr);
399                 }
400         }
401         return rcode;
402 }
403
404 void poweroff(void)
405 {
406         watchdog_reset();
407         at91_set_pio_output(AT91_PIO_PORTA, 13, 1);     /* CAN_TX -> H */
408         udelay(100);
409         at91_set_pio_output(AT91_PIO_PORTA, 12, 0);     /* CAN_STB -> L */
410         udelay(100);
411         at91_set_pio_output(AT91_PIO_PORTA, 11, 0);     /* CAN_EN -> L */
412         udelay(100);
413         while (1)
414                 watchdog_reset();
415 }
416
417 int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc,  char * const argv[])
418 {
419         int rcode = 1;
420         poweroff();
421         return rcode;
422 }
423
424 int do_beep(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
425 {
426         int i;
427         u32 freq;
428         u32 durate;
429         int rcode = 1;
430
431         freq = 1000;
432         durate = 2;
433         switch (argc) {
434         case 3:
435                 durate = simple_strtoul(argv[2], NULL, 10);
436         case 2:
437                 freq = simple_strtoul(argv[1], NULL, 10);
438         case 1:
439                 break;
440         default:
441                 cmd_usage(cmdtp);
442                 rcode = 1;
443                 break;
444         }
445         durate = durate * freq;
446         freq = 500000 / freq;
447         for (i = 0; i < durate; i++) {
448                 at91_set_pio_output(AT91_PIO_PORTB, 29, 1);     /* Sound On*/
449                 udelay(freq);
450                 at91_set_pio_output(AT91_PIO_PORTB, 29, 0);     /* Sound Off*/
451                 udelay(freq);
452         }
453         at91_set_pio_output(AT91_PIO_PORTB, 29, 0);     /* Sound Off*/
454         return rcode;
455 }
456
457 int do_keytest(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
458 {
459         int rcode = 1;
460         int row;
461         u32 col;
462         u32 pinz;
463         u32 pins;
464         at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIO;
465         at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC;
466
467         writel((1 << ATMEL_ID_PIOA), &pmc->pcer);
468
469         pins = 0x001F0000;
470         writel(pins, &pio->pioa.idr);
471         writel(pins, &pio->pioa.pudr);
472         writel(pins, &pio->pioa.per);
473         writel(pins, &pio->pioa.odr);
474
475         pinz = 0x000F0000;
476         writel(pinz, &pio->piob.idr);
477         writel(pinz, &pio->piob.pudr);
478         writel(pinz, &pio->piob.per);
479         writel(pinz, &pio->piob.oer);
480         writel(pinz, &pio->piob.codr);
481
482         while (1) {
483                 col = 0;
484                 for (row = 0; row < 4; row++) {
485                         writel((0x00010000 << row), &pio->piob.sodr);
486                         udelay(10000);
487                         col <<= 4;
488                         col |= ((readl(&pio->pioa.pdsr) >> 16) & 0xF) ^ 0xF ;
489                         writel(pinz, &pio->piob.codr);
490                 }
491                 printf("Matix: ");
492                 for (row = 0; row < 16; row++) {
493                         printf("%1.1d", col & 1);
494                         col >>= 1;
495                 }
496                 printf(" SP %d\r ",
497                         1 ^ (1 & (readl(&pio->piob.pdsr) >> 20)));
498                 if ((1 & (readl(&pio->pioa.pdsr) >> 1)) == 0) {
499                         /* SHUTDOWN */
500                         row = 0;
501                         while (row < 1000) {
502                                 if ((1 & (readl(&pio->pioa.pdsr) >> 1)) == 0)
503                                         row++;
504                                 udelay(100);
505                         }
506                         udelay(100000);
507                         row = 0;
508                         while (row < 1000) {
509                                 if ((1 & (readl(&pio->pioa.pdsr) >> 1)) > 0) {
510                                         row++;
511                                         udelay(1000);
512                                 }
513                         }
514                         poweroff();
515                         while (1)
516                                 ;
517                 }
518         }
519         return rcode;
520 }
521
522 /*****************************************************************************/
523
524 U_BOOT_CMD(
525         ledtest,        1,      0,      do_ledtest,
526         "test ledmatrix",
527         "\n"
528         );
529
530 U_BOOT_CMD(
531         keytest,        1,      0,      do_keytest,
532         "test keymatix and special keys, poweroff on pressing ON key",
533         "\n"
534         );
535
536 U_BOOT_CMD(
537         poweroff,       1,      0,      do_poweroff,
538         "power off",
539         "\n"
540         );
541
542 U_BOOT_CMD(
543         beep,   3,      0,      do_beep,
544         "[freq [duration]]",
545         "freq frequence of beep\nduration duration of beep\n"
546         );
547
548 /*****************************************************************************/