]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/karo/tx48/tx48.c
compile tx48_move_fdt() only with CONFIG_OF_LIBFDT
[karo-tx-uboot.git] / board / karo / tx48 / tx48.c
1 /*
2  * tx48.c
3  * Copyright (C) 2012 Lothar Waßmann <LW@KARO-electronics.de>
4  *
5  * based on evm.c
6  * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
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 version 2.
11  *
12  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
13  * kind, whether express or implied; without even the implied warranty
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  */
17
18 #include <common.h>
19 #include <errno.h>
20 #include <miiphy.h>
21 #include <netdev.h>
22 #include <serial.h>
23 #include <libfdt.h>
24 #include <lcd.h>
25 #include <fdt_support.h>
26 #include <nand.h>
27 #include <net.h>
28 #include <linux/mtd/nand.h>
29 #include <asm/gpio.h>
30 #include <asm/cache.h>
31 #include <asm/omap_common.h>
32 #include <asm/io.h>
33 #include <asm/arch/cpu.h>
34 #include <asm/arch/hardware.h>
35 #include <asm/arch/mmc_host_def.h>
36 #include <asm/arch/sys_proto.h>
37 #include <asm/arch/nand.h>
38 #include <asm/arch/clock.h>
39 #include <asm/arch/common_def.h>
40 #include <video_fb.h>
41 #include <asm/arch/da8xx-fb.h>
42
43 DECLARE_GLOBAL_DATA_PTR;
44
45 #define TX48_LED_GPIO           AM33XX_GPIO_NR(1, 26)
46 #define TX48_ETH_PHY_RST_GPIO   AM33XX_GPIO_NR(3, 8)
47 #define TX48_LCD_RST_GPIO       AM33XX_GPIO_NR(1, 19)
48 #define TX48_LCD_PWR_GPIO       AM33XX_GPIO_NR(1, 22)
49 #define TX48_LCD_BACKLIGHT_GPIO AM33XX_GPIO_NR(3, 14)
50
51 #define GMII_SEL                (CTRL_BASE + 0x650)
52
53 /* UART Defines */
54 #define UART_SYSCFG_OFFSET      0x54
55 #define UART_SYSSTS_OFFSET      0x58
56
57 #define UART_RESET              (0x1 << 1)
58 #define UART_CLK_RUNNING_MASK   0x1
59 #define UART_SMART_IDLE_EN      (0x1 << 0x3)
60
61 /* Timer Defines */
62 #define TSICR_REG               0x54
63 #define TIOCP_CFG_REG           0x10
64 #define TCLR_REG                0x38
65
66 /* RGMII mode define */
67 #define RGMII_MODE_ENABLE       0xA
68 #define RMII_MODE_ENABLE        0x5
69 #define MII_MODE_ENABLE         0x0
70
71 #define NO_OF_MAC_ADDR          1
72 #define ETH_ALEN                6
73
74 #define MUX_CFG(value, offset)  {                                       \
75         __raw_writel(value, (CTRL_BASE + (offset)));                    \
76         }
77
78 /* PAD Control Fields */
79 #define SLEWCTRL        (0x1 << 6)
80 #define RXACTIVE        (0x1 << 5)
81 #define PULLUP_EN       (0x1 << 4) /* Pull UP Selection */
82 #define PULLUDEN        (0x0 << 3) /* Pull up enabled */
83 #define PULLUDDIS       (0x1 << 3) /* Pull up disabled */
84 #define MODE(val)       (val)
85
86 /*
87  * PAD CONTROL OFFSETS
88  * Field names corresponds to the pad signal name
89  */
90 struct pad_signals {
91         int gpmc_ad0;
92         int gpmc_ad1;
93         int gpmc_ad2;
94         int gpmc_ad3;
95         int gpmc_ad4;
96         int gpmc_ad5;
97         int gpmc_ad6;
98         int gpmc_ad7;
99         int gpmc_ad8;
100         int gpmc_ad9;
101         int gpmc_ad10;
102         int gpmc_ad11;
103         int gpmc_ad12;
104         int gpmc_ad13;
105         int gpmc_ad14;
106         int gpmc_ad15;
107         int gpmc_a0;
108         int gpmc_a1;
109         int gpmc_a2;
110         int gpmc_a3;
111         int gpmc_a4;
112         int gpmc_a5;
113         int gpmc_a6;
114         int gpmc_a7;
115         int gpmc_a8;
116         int gpmc_a9;
117         int gpmc_a10;
118         int gpmc_a11;
119         int gpmc_wait0;
120         int gpmc_wpn;
121         int gpmc_be1n;
122         int gpmc_csn0;
123         int gpmc_csn1;
124         int gpmc_csn2;
125         int gpmc_csn3;
126         int gpmc_clk;
127         int gpmc_advn_ale;
128         int gpmc_oen_ren;
129         int gpmc_wen;
130         int gpmc_be0n_cle;
131         int lcd_data0;
132         int lcd_data1;
133         int lcd_data2;
134         int lcd_data3;
135         int lcd_data4;
136         int lcd_data5;
137         int lcd_data6;
138         int lcd_data7;
139         int lcd_data8;
140         int lcd_data9;
141         int lcd_data10;
142         int lcd_data11;
143         int lcd_data12;
144         int lcd_data13;
145         int lcd_data14;
146         int lcd_data15;
147         int lcd_vsync;
148         int lcd_hsync;
149         int lcd_pclk;
150         int lcd_ac_bias_en;
151         int mmc0_dat3;
152         int mmc0_dat2;
153         int mmc0_dat1;
154         int mmc0_dat0;
155         int mmc0_clk;
156         int mmc0_cmd;
157         int mii1_col;
158         int mii1_crs;
159         int mii1_rxerr;
160         int mii1_txen;
161         int mii1_rxdv;
162         int mii1_txd3;
163         int mii1_txd2;
164         int mii1_txd1;
165         int mii1_txd0;
166         int mii1_txclk;
167         int mii1_rxclk;
168         int mii1_rxd3;
169         int mii1_rxd2;
170         int mii1_rxd1;
171         int mii1_rxd0;
172         int rmii1_refclk;
173         int mdio_data;
174         int mdio_clk;
175         int spi0_sclk;
176         int spi0_d0;
177         int spi0_d1;
178         int spi0_cs0;
179         int spi0_cs1;
180         int ecap0_in_pwm0_out;
181         int uart0_ctsn;
182         int uart0_rtsn;
183         int uart0_rxd;
184         int uart0_txd;
185         int uart1_ctsn;
186         int uart1_rtsn;
187         int uart1_rxd;
188         int uart1_txd;
189         int i2c0_sda;
190         int i2c0_scl;
191         int mcasp0_aclkx;
192         int mcasp0_fsx;
193         int mcasp0_axr0;
194         int mcasp0_ahclkr;
195         int mcasp0_aclkr;
196         int mcasp0_fsr;
197         int mcasp0_axr1;
198         int mcasp0_ahclkx;
199         int xdma_event_intr0;
200         int xdma_event_intr1;
201         int nresetin_out;
202         int porz;
203         int nnmi;
204         int osc0_in;
205         int osc0_out;
206         int rsvd1;
207         int tms;
208         int tdi;
209         int tdo;
210         int tck;
211         int ntrst;
212         int emu0;
213         int emu1;
214         int osc1_in;
215         int osc1_out;
216         int pmic_power_en;
217         int rtc_porz;
218         int rsvd2;
219         int ext_wakeup;
220         int enz_kaldo_1p8v;
221         int usb0_dm;
222         int usb0_dp;
223         int usb0_ce;
224         int usb0_id;
225         int usb0_vbus;
226         int usb0_drvvbus;
227         int usb1_dm;
228         int usb1_dp;
229         int usb1_ce;
230         int usb1_id;
231         int usb1_vbus;
232         int usb1_drvvbus;
233         int ddr_resetn;
234         int ddr_csn0;
235         int ddr_cke;
236         int ddr_ck;
237         int ddr_nck;
238         int ddr_casn;
239         int ddr_rasn;
240         int ddr_wen;
241         int ddr_ba0;
242         int ddr_ba1;
243         int ddr_ba2;
244         int ddr_a0;
245         int ddr_a1;
246         int ddr_a2;
247         int ddr_a3;
248         int ddr_a4;
249         int ddr_a5;
250         int ddr_a6;
251         int ddr_a7;
252         int ddr_a8;
253         int ddr_a9;
254         int ddr_a10;
255         int ddr_a11;
256         int ddr_a12;
257         int ddr_a13;
258         int ddr_a14;
259         int ddr_a15;
260         int ddr_odt;
261         int ddr_d0;
262         int ddr_d1;
263         int ddr_d2;
264         int ddr_d3;
265         int ddr_d4;
266         int ddr_d5;
267         int ddr_d6;
268         int ddr_d7;
269         int ddr_d8;
270         int ddr_d9;
271         int ddr_d10;
272         int ddr_d11;
273         int ddr_d12;
274         int ddr_d13;
275         int ddr_d14;
276         int ddr_d15;
277         int ddr_dqm0;
278         int ddr_dqm1;
279         int ddr_dqs0;
280         int ddr_dqsn0;
281         int ddr_dqs1;
282         int ddr_dqsn1;
283         int ddr_vref;
284         int ddr_vtp;
285         int ddr_strben0;
286         int ddr_strben1;
287         int ain7;
288         int ain6;
289         int ain5;
290         int ain4;
291         int ain3;
292         int ain2;
293         int ain1;
294         int ain0;
295         int vrefp;
296         int vrefn;
297 };
298
299 struct pin_mux {
300         short reg_offset;
301         uint8_t val;
302 };
303
304 #define PAD_CTRL_BASE   0x800
305 #define OFFSET(x)       (unsigned int) (&((struct pad_signals *) \
306                                 (PAD_CTRL_BASE))->x)
307 /*
308  * Configure the pin mux for the module
309  */
310 static void tx48_set_pin_mux(const struct pin_mux *pin_mux,
311                         int num_pins)
312 {
313         int i;
314
315         for (i = 0; i < num_pins; i++)
316                 MUX_CFG(pin_mux[i].val, pin_mux[i].reg_offset);
317 }
318
319 #define PRM_RSTST_GLOBAL_COLD_RST       (1 << 0)
320 #define PRM_RSTST_GLOBAL_WARM_SW_RST    (1 << 1)
321 #define PRM_RSTST_WDT1_RST              (1 << 4)
322 #define PRM_RSTST_EXTERNAL_WARM_RST     (1 << 5)
323 #define PRM_RSTST_ICEPICK_RST           (1 << 9)
324
325 struct prm_device {
326         unsigned int prmrstctrl;        /* offset 0x00 */
327         unsigned int prmrsttime;        /* offset 0x04 */
328         unsigned int prmrstst;          /* offset 0x08 */
329         /* ... */
330 };
331
332 /*
333  * Basic board specific setup
334  */
335 static const struct pin_mux stk5_pads[] = {
336         /* heartbeat LED */
337         { OFFSET(gpmc_a10), MODE(7) | PULLUDEN, },
338         /* LCD RESET */
339         { OFFSET(gpmc_a3), MODE(7) | PULLUDEN, },
340         /* LCD POWER_ENABLE */
341         { OFFSET(gpmc_a6), MODE(7) | PULLUDEN, },
342         /* LCD Backlight (PWM) */
343         { OFFSET(mcasp0_aclkx), MODE(7) | PULLUDEN, },
344 };
345
346 static const struct pin_mux stk5_lcd_pads[] = {
347         /* LCD data bus */
348         { OFFSET(lcd_data0), MODE(0) | PULLUDEN, },
349         { OFFSET(lcd_data1), MODE(0) | PULLUDEN, },
350         { OFFSET(lcd_data2), MODE(0) | PULLUDEN, },
351         { OFFSET(lcd_data3), MODE(0) | PULLUDEN, },
352         { OFFSET(lcd_data4), MODE(0) | PULLUDEN, },
353         { OFFSET(lcd_data5), MODE(0) | PULLUDEN, },
354         { OFFSET(lcd_data6), MODE(0) | PULLUDEN, },
355         { OFFSET(lcd_data7), MODE(0) | PULLUDEN, },
356         { OFFSET(lcd_data8), MODE(0) | PULLUDEN, },
357         { OFFSET(lcd_data9), MODE(0) | PULLUDEN, },
358         { OFFSET(lcd_data10), MODE(0) | PULLUDEN, },
359         { OFFSET(lcd_data11), MODE(0) | PULLUDEN, },
360         { OFFSET(lcd_data12), MODE(0) | PULLUDEN, },
361         { OFFSET(lcd_data13), MODE(0) | PULLUDEN, },
362         { OFFSET(lcd_data14), MODE(0) | PULLUDEN, },
363         { OFFSET(lcd_data15), MODE(0) | PULLUDEN, },
364         /* LCD control signals */
365         { OFFSET(lcd_hsync), MODE(0) | PULLUDEN, },
366         { OFFSET(lcd_vsync), MODE(0) | PULLUDEN, },
367         { OFFSET(lcd_pclk), MODE(0) | PULLUDEN, },
368         { OFFSET(lcd_ac_bias_en), MODE(0) | PULLUDEN, },
369 };
370
371 static const struct gpio stk5_gpios[] = {
372         { AM33XX_GPIO_NR(1, 26), GPIOF_OUTPUT_INIT_LOW, "HEARTBEAT LED", },
373 };
374
375 static const struct gpio stk5_lcd_gpios[] = {
376         { AM33XX_GPIO_NR(1, 19), GPIOF_OUTPUT_INIT_HIGH, "LCD RESET", },
377         { AM33XX_GPIO_NR(1, 22), GPIOF_OUTPUT_INIT_HIGH, "LCD POWER", },
378         { AM33XX_GPIO_NR(3, 14), GPIOF_OUTPUT_INIT_LOW, "LCD BACKLIGHT", },
379 };
380
381 static const struct gpio stk5_no_lcd_gpios[] = {
382         { AM33XX_GPIO_NR(1, 19), GPIOF_OUTPUT_INIT_LOW, "LCD RESET", },
383         { AM33XX_GPIO_NR(1, 22), GPIOF_OUTPUT_INIT_LOW, "LCD POWER", },
384         { AM33XX_GPIO_NR(3, 14), GPIOF_OUTPUT_INIT_HIGH, "LCD BACKLIGHT", },
385 };
386
387 static const struct pin_mux stk5v5_pads[] = {
388         /* CAN transceiver control */
389         { OFFSET(gpmc_ad8), MODE(7) | PULLUDEN, },
390 };
391
392 static const struct gpio stk5v5_gpios[] = {
393         { AM33XX_GPIO_NR(0, 22), GPIOF_OUTPUT_INIT_HIGH, "CAN XCVR", },
394 };
395
396 static u32 prm_rstst __attribute__((section(".data")));
397
398 #ifdef CONFIG_LCD
399 static u16 tx48_cmap[256];
400 vidinfo_t panel_info = {
401         /* set to max. size supported by SoC */
402         .vl_col = 1366,
403         .vl_row = 768,
404
405         .vl_bpix = LCD_COLOR24,    /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */
406         .cmap = tx48_cmap,
407 };
408
409 static struct da8xx_panel tx48_lcd_panel = {
410         .name = "640x480MR@60",
411         .width = 640,
412         .height = 480,
413         .hfp = 12,
414         .hbp = 144,
415         .hsw = 30,
416         .vfp = 10,
417         .vbp = 35,
418         .vsw = 3,
419         .pxl_clk = 25000000,
420         .invert_pxl_clk = 1,
421 };
422
423 void *lcd_base;                 /* Start of framebuffer memory  */
424 void *lcd_console_address;      /* Start of console buffer      */
425
426 int lcd_line_length;
427 int lcd_color_fg;
428 int lcd_color_bg;
429
430 short console_col;
431 short console_row;
432
433 void lcd_initcolregs(void)
434 {
435 }
436
437 void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue)
438 {
439 }
440
441 void lcd_enable(void)
442 {
443         /* HACK ALERT:
444          * global variable from common/lcd.c
445          * Set to 0 here to prevent messages from going to LCD
446          * rather than serial console
447          */
448         lcd_is_enabled = 0;
449 }
450
451 void lcd_disable(void)
452 {
453 }
454
455 void lcd_panel_disable(void)
456 {
457 }
458
459 static int lcd_enabled = 1;
460
461 static inline int tx48_load_splashimage(void)
462 {
463         int ret = 0;
464 #if defined(CONFIG_SPLASH_SCREEN) && defined(CONFIG_LCD)
465         int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
466         cmd_tbl_t *cmd = find_cmd("nand");
467         char *loadaddr = getenv("splashimage");
468         char *argv[] = {
469                 "nand",
470                 "read",
471                 loadaddr,
472                 "logo",
473         };
474         const int argc = ARRAY_SIZE(argv);
475         unsigned long la;
476
477         if (!loadaddr)
478                 return 0;
479
480         if (tstc() || (prm_rstst & PRM_RSTST_WDT1_RST)) {
481                 return -ENODEV;
482         }
483
484         if (!cmd)
485                 return -EINVAL;
486
487         la = simple_strtoul(loadaddr, NULL, 16);
488         if (la == 0)
489                 return -EINVAL;
490
491         /* clear BMP header in memory */
492         memset((void *)la, 0, 64);
493
494         ret = do_nand(cmd, 0, argc, argv);
495         if (ret) {
496                 printf("Failed to load logo: %d\n", ret);
497                 return ret;
498         }
499 #endif
500         return ret;
501 }
502
503 void lcd_ctrl_init(void *lcdbase)
504 {
505         int color_depth = 24;
506         char *vm;
507         unsigned long val;
508         struct da8xx_panel *p = &tx48_lcd_panel;
509         int refresh = 60;
510
511         if (!lcd_enabled) {
512                 printf("LCD disabled\n");
513                 return;
514         }
515
516         if (tstc() || (prm_rstst & PRM_RSTST_WDT1_RST)) {
517                 lcd_enabled = 0;
518                 return;
519         }
520
521         vm = getenv("video_mode");
522         if (vm == NULL) {
523                 lcd_enabled = 0;
524                 return;
525         }
526
527         strncpy((char *)p->name, vm, sizeof(p->name));
528
529         val = simple_strtoul(vm, &vm, 0);
530         if (val != 0) {
531                 if (val > panel_info.vl_col)
532                         val = panel_info.vl_col;
533                 p->width = val;
534                 panel_info.vl_col = val;
535         }
536         if (*vm == 'x') {
537                 val = simple_strtoul(vm + 1, &vm, 0);
538                 if (val > panel_info.vl_row)
539                         val = panel_info.vl_row;
540                 p->height = val;
541                 panel_info.vl_row = val;
542         }
543         while (*vm != '\0') {
544                 switch (*vm) {
545                 case 'M':
546                 case 'R':
547                         vm++;
548                         break;
549
550                 case '-':
551                         color_depth = simple_strtoul(vm + 1, &vm, 10);
552                         break;
553
554                 case '@':
555                         refresh = simple_strtoul(vm + 1, &vm, 10);
556                         break;
557
558                 default:
559                         debug("Ignoring '%c'\n", *vm);
560                         vm++;
561                 }
562         }
563         switch (color_depth) {
564         case 8:
565                 panel_info.vl_bpix = 3;
566                 break;
567
568         case 16:
569                 panel_info.vl_bpix = 4;
570                 break;
571
572         case 24:
573                 panel_info.vl_bpix = 5;
574                 break;
575
576         default:
577                 printf("Invalid color_depth %u from video_mode '%s'; using default: %u\n",
578                         color_depth, getenv("video_mode"), 24);
579         }
580         lcd_line_length = NBITS(panel_info.vl_bpix) / 8 * panel_info.vl_col;
581         p->pxl_clk = refresh *
582                 (p->width + p->hfp + p->hbp + p->hsw) *
583                 (p->height + p->vfp + p->vbp + p->vsw);
584         debug("Pixel clock set to %u.%03uMHz\n",
585                 p->pxl_clk / 1000000, p->pxl_clk / 1000 % 1000);
586
587         tx48_set_pin_mux(stk5_lcd_pads, ARRAY_SIZE(stk5_lcd_pads));
588         debug("Initializing FB driver\n");
589         da8xx_video_init(&tx48_lcd_panel, color_depth);
590
591         if (tx48_load_splashimage() == 0) {
592                 debug("Initializing LCD controller\n");
593                 video_hw_init();
594         } else {
595                 debug("Skipping initialization of LCD controller\n");
596         }
597 }
598
599 ulong calc_fbsize(void)
600 {
601         return panel_info.vl_row * panel_info.vl_col * 2 *
602                 NBITS(panel_info.vl_bpix) / 8;
603 }
604 #else
605 #define lcd_enabled 0
606 #endif /* CONFIG_LCD */
607
608 static void stk5_board_init(void)
609 {
610         tx48_set_pin_mux(stk5_pads, ARRAY_SIZE(stk5_pads));
611
612         if (lcd_enabled) {
613                 tx48_set_pin_mux(stk5_lcd_pads, ARRAY_SIZE(stk5_lcd_pads));
614         }
615         gpio_request_array(stk5_no_lcd_gpios,
616                         ARRAY_SIZE(stk5_no_lcd_gpios));
617 }
618
619 static void stk5v3_board_init(void)
620 {
621         stk5_board_init();
622 }
623
624 static void stk5v5_board_init(void)
625 {
626         stk5_board_init();
627         tx48_set_pin_mux(stk5v5_pads, ARRAY_SIZE(stk5v5_pads));
628         gpio_request_array(stk5v5_gpios, ARRAY_SIZE(stk5v5_gpios));
629 }
630
631 /* called with default environment! */
632 int board_init(void)
633 {
634         /* mach type passed to kernel */
635 #ifdef CONFIG_OF_LIBFDT
636         gd->bd->bi_arch_number = -1;
637 #endif
638         /* address of boot parameters */
639         gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
640
641         return 0;
642 }
643
644 static void show_reset_cause(u32 prm_rstst)
645 {
646         const char *dlm = "";
647
648         printf("RESET cause: ");
649         if (prm_rstst & PRM_RSTST_GLOBAL_COLD_RST) {
650                 printf("%sPOR", dlm);
651                 dlm = " | ";
652         }
653         if (prm_rstst & PRM_RSTST_GLOBAL_WARM_SW_RST) {
654                 printf("%sSW", dlm);
655                 dlm = " | ";
656         }
657         if (prm_rstst & PRM_RSTST_WDT1_RST) {
658                 printf("%sWATCHDOG", dlm);
659                 dlm = " | ";
660         }
661         if (prm_rstst & PRM_RSTST_EXTERNAL_WARM_RST) {
662                 printf("%sWARM", dlm);
663                 dlm = " | ";
664         }
665         if (prm_rstst & PRM_RSTST_ICEPICK_RST) {
666                 printf("%sJTAG", dlm);
667                 dlm = " | ";
668         }
669         if (*dlm == '\0')
670                 printf("unknown");
671
672         printf(" RESET\n");
673 }
674
675 #ifdef CONFIG_OF_LIBFDT
676 /* called with default environment! */
677 static void tx48_move_fdt(void)
678 {
679         unsigned long fdt_addr = getenv_ulong("fdtcontroladdr", 16, 0);
680         void *fdt = NULL;
681
682 #ifdef CONFIG_OF_EMBED
683         fdt = _binary_dt_dtb_start;
684 #elif defined CONFIG_OF_SEPARATE
685         fdt = (void *)(_end_ofs + _TEXT_BASE);
686 #endif
687         if (fdt && fdt_addr != 0) {
688                 if (fdt_check_header(fdt) == 0) {
689                         size_t fdt_len = fdt_totalsize(fdt);
690
691                         memmove((void *)fdt_addr, fdt, fdt_len);
692                 } else {
693                         printf("ERROR: No valid FDT found at %p\n", fdt);
694                 }
695         }
696 }
697 #endif
698
699 /* called with default environment! */
700 int checkboard(void)
701 {
702         struct prm_device *prmdev = (struct prm_device *)PRM_DEVICE;
703
704         prm_rstst = readl(&prmdev->prmrstst);
705         show_reset_cause(prm_rstst);
706
707 #ifdef CONFIG_OF_LIBFDT
708         printf("Board: Ka-Ro TX48-7020 with FDT support\n");
709         tx48_move_fdt();
710 #else
711         printf("Board: Ka-Ro TX48-7020\n");
712 #endif
713
714 #ifdef TIMER_TEST
715         {
716                 unsigned long start = get_timer(0);
717                 unsigned long last = gd->tbl;
718                 unsigned long loop = 0;
719                 unsigned long cnt = 0;
720                 struct gptimer *timer_base = (struct gptimer *)CONFIG_SYS_TIMERBASE;
721
722                 printf("clock tick rate: %lu.%03lukHz\n",
723                         gd->timer_rate_hz / 1000, gd->timer_rate_hz % 1000);
724                 printf("ticks/us=%lu\n", gd->timer_rate_hz / CONFIG_SYS_HZ / 1000);
725
726                 while (!tstc()) {
727                         unsigned long elapsed = get_timer(start);
728                         unsigned long diff = gd->tbl - last;
729
730                         loop++;
731                         last = gd->tbl;
732
733                         printf("loop %4lu: t=%08lx diff=%08lx steps=%5lu elapsed time: %4lu",
734                                 loop, gd->tbl, diff, cnt, elapsed / CONFIG_SYS_HZ);
735                         cnt = 0;
736                         while (get_timer(elapsed + start) < CONFIG_SYS_HZ) {
737                                 cnt++;
738                                 udelay(10);
739                         }
740                         printf(" tcrr=%08x\n", readl(&timer_base->tcrr));
741                 }
742         }
743 #endif
744         return 0;
745 }
746
747 /* called with environment from NAND or MMC */
748 int board_late_init(void)
749 {
750         const char *baseboard;
751
752         baseboard = getenv("baseboard");
753         if (!baseboard)
754                 return 0;
755
756         if (strncmp(baseboard, "stk5", 4) == 0) {
757                 printf("Baseboard: %s\n", baseboard);
758                 if ((strlen(baseboard) == 4) ||
759                         strcmp(baseboard, "stk5-v3") == 0) {
760                         stk5v3_board_init();
761                 } else if (strcmp(baseboard, "stk5-v5") == 0) {
762                         stk5v5_board_init();
763                 } else {
764                         printf("WARNING: Unsupported STK5 board rev.: %s\n",
765                                 baseboard + 4);
766                 }
767         } else {
768                 printf("WARNING: Unsupported baseboard: '%s'\n",
769                         baseboard);
770                 return -EINVAL;
771         }
772
773         if (lcd_enabled) {
774                 gpio_set_value(TX48_LCD_PWR_GPIO, 1);
775                 gpio_set_value(TX48_LCD_RST_GPIO, 1);
776                 udelay(200000);
777                 gpio_set_value(TX48_LCD_BACKLIGHT_GPIO, 0);
778         }
779         return 0;
780 }
781
782 #ifdef CONFIG_DRIVER_TI_CPSW
783 static void tx48_phy_init(char *name, int addr)
784 {
785         debug("%s: Resetting ethernet PHY\n", __func__);
786
787         gpio_direction_output(TX48_ETH_PHY_RST_GPIO, 0);
788
789         udelay(25000);
790
791         /* Release nRST */
792         gpio_set_value(TX48_ETH_PHY_RST_GPIO, 1);
793 }
794
795 static void cpsw_control(int enabled)
796 {
797         /* nothing for now */
798         /* TODO : VTP was here before */
799 }
800
801 static struct cpsw_slave_data cpsw_slaves[] = {
802         {
803                 .slave_reg_ofs  = 0x208,
804                 .sliver_reg_ofs = 0xd80,
805                 .phy_id         = 0,
806         },
807 };
808
809 static struct cpsw_platform_data cpsw_data = {
810         .mdio_base              = CPSW_MDIO_BASE,
811         .cpsw_base              = CPSW_BASE,
812         .mdio_div               = 0xff,
813         .channels               = 8,
814         .cpdma_reg_ofs          = 0x800,
815         .slaves                 = ARRAY_SIZE(cpsw_slaves),
816         .slave_data             = cpsw_slaves,
817         .ale_reg_ofs            = 0xd00,
818         .ale_entries            = 1024,
819         .host_port_reg_ofs      = 0x108,
820         .hw_stats_reg_ofs       = 0x900,
821         .mac_control            = (1 << 5) /* MIIEN */,
822         .control                = cpsw_control,
823         .phy_init               = tx48_phy_init,
824         .gigabit_en             = 0,
825         .host_port_num          = 0,
826         .version                = CPSW_CTRL_VERSION_2,
827 };
828
829 int board_eth_init(bd_t *bis)
830 {
831         uint8_t mac_addr[ETH_ALEN];
832         uint32_t mac_hi, mac_lo;
833
834         /* try reading mac address from efuse */
835         mac_lo = __raw_readl(MAC_ID0_LO);
836         mac_hi = __raw_readl(MAC_ID0_HI);
837
838         mac_addr[0] = mac_hi & 0xFF;
839         mac_addr[1] = (mac_hi & 0xFF00) >> 8;
840         mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
841         mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
842         mac_addr[4] = mac_lo & 0xFF;
843         mac_addr[5] = (mac_lo & 0xFF00) >> 8;
844
845         if (is_valid_ether_addr(mac_addr)) {
846                 debug("MAC addr set to: %02x:%02x:%02x:%02x:%02x:%02x\n",
847                         mac_addr[0], mac_addr[1], mac_addr[2],
848                         mac_addr[3], mac_addr[4], mac_addr[5]);
849                 eth_setenv_enetaddr("ethaddr", mac_addr);
850         } else {
851                 printf("ERROR: Did not find a valid mac address in e-fuse\n");
852         }
853
854         __raw_writel(RMII_MODE_ENABLE, MAC_MII_SEL);
855         __raw_writel(0x5D, GMII_SEL);
856         return cpsw_register(&cpsw_data);
857 }
858 #endif /* CONFIG_DRIVER_TI_CPSW */
859
860 #ifndef CONFIG_SPL_BUILD
861 #ifdef CONFIG_NAND_AM33XX
862 /******************************************************************************
863  * Command to switch between NAND HW and SW ecc
864  *****************************************************************************/
865 static int do_switch_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
866 {
867         int type = 0;
868
869         if (argc < 2)
870                 goto usage;
871
872         if (strncmp(argv[1], "hw", 2) == 0) {
873                 if (argc == 3)
874                         type = simple_strtoul(argv[2], NULL, 10);
875                 am33xx_nand_switch_ecc(NAND_ECC_HW, type);
876         }
877         else if (strncmp(argv[1], "sw", 2) == 0)
878                 am33xx_nand_switch_ecc(NAND_ECC_SOFT, 0);
879         else
880                 goto usage;
881
882         return 0;
883
884 usage:
885         printf("Usage: nandecc %s\n", cmdtp->usage);
886         return 1;
887 }
888
889 U_BOOT_CMD(
890         nandecc, 3, 1,  do_switch_ecc,
891         "Switch NAND ECC calculation algorithm b/w hardware and software",
892         "[sw|hw <hw_type>] \n"
893         "   [sw|hw]- Switch b/w hardware(hw) & software(sw) ecc algorithm\n"
894         "   hw_type- 0 for Hamming code\n"
895         "            1 for bch4\n"
896         "            2 for bch8\n"
897         "            3 for bch16\n"
898 );
899
900 #endif /* CONFIG_NAND_AM33XX */
901 #endif /* CONFIG_SPL_BUILD */
902
903 enum {
904         LED_STATE_INIT = -1,
905         LED_STATE_OFF,
906         LED_STATE_ON,
907 };
908
909 void show_activity(int arg)
910 {
911         static int led_state = LED_STATE_INIT;
912         static ulong last;
913
914         if (led_state == LED_STATE_INIT) {
915                 last = get_timer(0);
916                 gpio_set_value(TX48_LED_GPIO, 1);
917                 led_state = LED_STATE_ON;
918         } else {
919                 if (get_timer(last) > CONFIG_SYS_HZ) {
920                         last = get_timer(0);
921                         if (led_state == LED_STATE_ON) {
922                                 gpio_set_value(TX48_LED_GPIO, 0);
923                         } else {
924                                 gpio_set_value(TX48_LED_GPIO, 1);
925                         }
926                         led_state = 1 - led_state;
927                 }
928         }
929 }
930
931 #ifdef CONFIG_OF_BOARD_SETUP
932 #ifdef CONFIG_FDT_FIXUP_PARTITIONS
933 #include <jffs2/jffs2.h>
934 #include <mtd_node.h>
935 struct node_info nodes[] = {
936         { "ti,omap2-nand", MTD_DEV_TYPE_NAND, },
937 };
938
939 #else
940 #define fdt_fixup_mtdparts(b,n,c) do { } while (0)
941 #endif /* CONFIG_FDT_FIXUP_PARTITIONS */
942
943 static const char *tx48_touchpanels[] = {
944         "ti,tsc2007",
945         "edt,edt-ft5x06",
946 };
947
948 static void tx48_fixup_touchpanel(void *blob)
949 {
950         int i;
951         const char *model = getenv("touchpanel");
952
953         for (i = 0; i < ARRAY_SIZE(tx48_touchpanels); i++) {
954                 int offs;
955                 const char *tp = tx48_touchpanels[i];
956
957                 if (model != NULL && strcmp(model, tp) == 0)
958                         continue;
959
960                 tp = strchr(tp, ',');
961                 if (tp != NULL && *tp != '\0' && strcmp(model, tp + 1) == 0)
962                         continue;
963
964                 offs = fdt_node_offset_by_compatible(blob, -1,
965                                                 tx48_touchpanels[i]);
966                 if (offs < 0) {
967                         debug("node '%s' not found: %d\n",
968                                 tx48_touchpanels[i], offs);
969                         continue;
970                 }
971                 debug("Removing node '%s' at offset %d\n",
972                         tx48_touchpanels[i], offs);
973                 fdt_del_node(blob, offs);
974         }
975 }
976
977 void ft_board_setup(void *blob, bd_t *bd)
978 {
979         fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
980         fdt_fixup_ethernet(blob);
981
982         tx48_fixup_touchpanel(blob);
983 }
984 #endif /* CONFIG_OF_BOARD_SETUP */