]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/karo/tx48/tx48.c
Merge branch 'tx48-fixes' into uboot-rel
[karo-tx-uboot.git] / board / karo / tx48 / tx48.c
1 /*
2  * Copyright (C) 2012-2013 Lothar Waßmann <LW@KARO-electronics.de>
3  *
4  * based on evm.c
5  * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * version 2 as published by the Free Software Foundation.
10  *
11  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
12  * kind, whether express or implied; without even the implied warranty
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  */
16
17 #include <common.h>
18 #include <errno.h>
19 #include <miiphy.h>
20 #include <netdev.h>
21 #include <serial.h>
22 #include <libfdt.h>
23 #include <lcd.h>
24 #include <fdt_support.h>
25 #include <nand.h>
26 #include <net.h>
27 #include <linux/mtd/nand.h>
28 #include <linux/fb.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/clock.h>
38 #include <video_fb.h>
39 #include <asm/arch/da8xx-fb.h>
40
41 #include "../common/karo.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 /* PAD Control Fields */
75 #define SLEWCTRL        (0x1 << 6)
76 #define RXACTIVE        (0x1 << 5)
77 #define PULLUP_EN       (0x1 << 4) /* Pull UP Selection */
78 #define PULLUDEN        (0x0 << 3) /* Pull up enabled */
79 #define PULLUDDIS       (0x1 << 3) /* Pull up disabled */
80 #define MODE(val)       (val)
81
82 /*
83  * PAD CONTROL OFFSETS
84  * Field names corresponds to the pad signal name
85  */
86 struct pad_signals {
87         int gpmc_ad0;
88         int gpmc_ad1;
89         int gpmc_ad2;
90         int gpmc_ad3;
91         int gpmc_ad4;
92         int gpmc_ad5;
93         int gpmc_ad6;
94         int gpmc_ad7;
95         int gpmc_ad8;
96         int gpmc_ad9;
97         int gpmc_ad10;
98         int gpmc_ad11;
99         int gpmc_ad12;
100         int gpmc_ad13;
101         int gpmc_ad14;
102         int gpmc_ad15;
103         int gpmc_a0;
104         int gpmc_a1;
105         int gpmc_a2;
106         int gpmc_a3;
107         int gpmc_a4;
108         int gpmc_a5;
109         int gpmc_a6;
110         int gpmc_a7;
111         int gpmc_a8;
112         int gpmc_a9;
113         int gpmc_a10;
114         int gpmc_a11;
115         int gpmc_wait0;
116         int gpmc_wpn;
117         int gpmc_be1n;
118         int gpmc_csn0;
119         int gpmc_csn1;
120         int gpmc_csn2;
121         int gpmc_csn3;
122         int gpmc_clk;
123         int gpmc_advn_ale;
124         int gpmc_oen_ren;
125         int gpmc_wen;
126         int gpmc_be0n_cle;
127         int lcd_data0;
128         int lcd_data1;
129         int lcd_data2;
130         int lcd_data3;
131         int lcd_data4;
132         int lcd_data5;
133         int lcd_data6;
134         int lcd_data7;
135         int lcd_data8;
136         int lcd_data9;
137         int lcd_data10;
138         int lcd_data11;
139         int lcd_data12;
140         int lcd_data13;
141         int lcd_data14;
142         int lcd_data15;
143         int lcd_vsync;
144         int lcd_hsync;
145         int lcd_pclk;
146         int lcd_ac_bias_en;
147         int mmc0_dat3;
148         int mmc0_dat2;
149         int mmc0_dat1;
150         int mmc0_dat0;
151         int mmc0_clk;
152         int mmc0_cmd;
153         int mii1_col;
154         int mii1_crs;
155         int mii1_rxerr;
156         int mii1_txen;
157         int mii1_rxdv;
158         int mii1_txd3;
159         int mii1_txd2;
160         int mii1_txd1;
161         int mii1_txd0;
162         int mii1_txclk;
163         int mii1_rxclk;
164         int mii1_rxd3;
165         int mii1_rxd2;
166         int mii1_rxd1;
167         int mii1_rxd0;
168         int rmii1_refclk;
169         int mdio_data;
170         int mdio_clk;
171         int spi0_sclk;
172         int spi0_d0;
173         int spi0_d1;
174         int spi0_cs0;
175         int spi0_cs1;
176         int ecap0_in_pwm0_out;
177         int uart0_ctsn;
178         int uart0_rtsn;
179         int uart0_rxd;
180         int uart0_txd;
181         int uart1_ctsn;
182         int uart1_rtsn;
183         int uart1_rxd;
184         int uart1_txd;
185         int i2c0_sda;
186         int i2c0_scl;
187         int mcasp0_aclkx;
188         int mcasp0_fsx;
189         int mcasp0_axr0;
190         int mcasp0_ahclkr;
191         int mcasp0_aclkr;
192         int mcasp0_fsr;
193         int mcasp0_axr1;
194         int mcasp0_ahclkx;
195         int xdma_event_intr0;
196         int xdma_event_intr1;
197         int nresetin_out;
198         int porz;
199         int nnmi;
200         int osc0_in;
201         int osc0_out;
202         int rsvd1;
203         int tms;
204         int tdi;
205         int tdo;
206         int tck;
207         int ntrst;
208         int emu0;
209         int emu1;
210         int osc1_in;
211         int osc1_out;
212         int pmic_power_en;
213         int rtc_porz;
214         int rsvd2;
215         int ext_wakeup;
216         int enz_kaldo_1p8v;
217         int usb0_dm;
218         int usb0_dp;
219         int usb0_ce;
220         int usb0_id;
221         int usb0_vbus;
222         int usb0_drvvbus;
223         int usb1_dm;
224         int usb1_dp;
225         int usb1_ce;
226         int usb1_id;
227         int usb1_vbus;
228         int usb1_drvvbus;
229         int ddr_resetn;
230         int ddr_csn0;
231         int ddr_cke;
232         int ddr_ck;
233         int ddr_nck;
234         int ddr_casn;
235         int ddr_rasn;
236         int ddr_wen;
237         int ddr_ba0;
238         int ddr_ba1;
239         int ddr_ba2;
240         int ddr_a0;
241         int ddr_a1;
242         int ddr_a2;
243         int ddr_a3;
244         int ddr_a4;
245         int ddr_a5;
246         int ddr_a6;
247         int ddr_a7;
248         int ddr_a8;
249         int ddr_a9;
250         int ddr_a10;
251         int ddr_a11;
252         int ddr_a12;
253         int ddr_a13;
254         int ddr_a14;
255         int ddr_a15;
256         int ddr_odt;
257         int ddr_d0;
258         int ddr_d1;
259         int ddr_d2;
260         int ddr_d3;
261         int ddr_d4;
262         int ddr_d5;
263         int ddr_d6;
264         int ddr_d7;
265         int ddr_d8;
266         int ddr_d9;
267         int ddr_d10;
268         int ddr_d11;
269         int ddr_d12;
270         int ddr_d13;
271         int ddr_d14;
272         int ddr_d15;
273         int ddr_dqm0;
274         int ddr_dqm1;
275         int ddr_dqs0;
276         int ddr_dqsn0;
277         int ddr_dqs1;
278         int ddr_dqsn1;
279         int ddr_vref;
280         int ddr_vtp;
281         int ddr_strben0;
282         int ddr_strben1;
283         int ain7;
284         int ain6;
285         int ain5;
286         int ain4;
287         int ain3;
288         int ain2;
289         int ain1;
290         int ain0;
291         int vrefp;
292         int vrefn;
293 };
294
295 struct pin_mux {
296         short reg_offset;
297         uint8_t val;
298 };
299
300 #define PAD_CTRL_BASE   0x800
301 #define OFFSET(x)       (unsigned int) (&((struct pad_signals *) \
302                                 (PAD_CTRL_BASE))->x)
303
304 /*
305  * Configure the pin mux for the module
306  */
307 static inline void tx48_set_pin_mux(const struct pin_mux *pin_mux,
308                         int num_pins)
309 {
310         int i;
311
312         for (i = 0; i < num_pins; i++)
313                 writel(pin_mux[i].val, CTRL_BASE + pin_mux[i].reg_offset);
314 }
315
316 #define PRM_RSTST_GLOBAL_COLD_RST       (1 << 0)
317 #define PRM_RSTST_GLOBAL_WARM_SW_RST    (1 << 1)
318 #define PRM_RSTST_WDT1_RST              (1 << 4)
319 #define PRM_RSTST_EXTERNAL_WARM_RST     (1 << 5)
320 #define PRM_RSTST_ICEPICK_RST           (1 << 9)
321
322 static u32 prm_rstst __attribute__((section(".data")));
323
324 /*
325  * Basic board specific setup
326  */
327 static const struct pin_mux stk5_pads[] = {
328         /* heartbeat LED */
329         { OFFSET(gpmc_a10), MODE(7) | PULLUDEN, },
330         /* LCD RESET */
331         { OFFSET(gpmc_a3), MODE(7) | PULLUDEN, },
332         /* LCD POWER_ENABLE */
333         { OFFSET(gpmc_a6), MODE(7) | PULLUDEN, },
334         /* LCD Backlight (PWM) */
335         { OFFSET(mcasp0_aclkx), MODE(7) | PULLUDEN, },
336 };
337
338 static const struct gpio stk5_gpios[] = {
339         { AM33XX_GPIO_NR(1, 26), GPIOF_OUTPUT_INIT_LOW, "HEARTBEAT LED", },
340 };
341
342 static const struct pin_mux stk5_lcd_pads[] = {
343         /* LCD data bus */
344         { OFFSET(lcd_data0), MODE(0) | PULLUDEN, },
345         { OFFSET(lcd_data1), MODE(0) | PULLUDEN, },
346         { OFFSET(lcd_data2), MODE(0) | PULLUDEN, },
347         { OFFSET(lcd_data3), MODE(0) | PULLUDEN, },
348         { OFFSET(lcd_data4), MODE(0) | PULLUDEN, },
349         { OFFSET(lcd_data5), MODE(0) | PULLUDEN, },
350         { OFFSET(lcd_data6), MODE(0) | PULLUDEN, },
351         { OFFSET(lcd_data7), MODE(0) | PULLUDEN, },
352         { OFFSET(lcd_data8), MODE(0) | PULLUDEN, },
353         { OFFSET(lcd_data9), MODE(0) | PULLUDEN, },
354         { OFFSET(lcd_data10), MODE(0) | PULLUDEN, },
355         { OFFSET(lcd_data11), MODE(0) | PULLUDEN, },
356         { OFFSET(lcd_data12), MODE(0) | PULLUDEN, },
357         { OFFSET(lcd_data13), MODE(0) | PULLUDEN, },
358         { OFFSET(lcd_data14), MODE(0) | PULLUDEN, },
359         { OFFSET(lcd_data15), MODE(0) | PULLUDEN, },
360         /* LCD control signals */
361         { OFFSET(lcd_hsync), MODE(0) | PULLUDEN, },
362         { OFFSET(lcd_vsync), MODE(0) | PULLUDEN, },
363         { OFFSET(lcd_pclk), MODE(0) | PULLUDEN, },
364         { OFFSET(lcd_ac_bias_en), MODE(0) | PULLUDEN, },
365 };
366
367 static const struct gpio stk5_lcd_gpios[] = {
368         { AM33XX_GPIO_NR(1, 19), GPIOF_OUTPUT_INIT_LOW, "LCD RESET", },
369         { AM33XX_GPIO_NR(1, 22), GPIOF_OUTPUT_INIT_LOW, "LCD POWER", },
370         { AM33XX_GPIO_NR(3, 14), GPIOF_OUTPUT_INIT_HIGH, "LCD BACKLIGHT", },
371 };
372
373 static const struct pin_mux stk5v5_pads[] = {
374         /* CAN transceiver control */
375         { OFFSET(gpmc_ad8), MODE(7) | PULLUDEN, },
376 };
377
378 static const struct gpio stk5v5_gpios[] = {
379         { AM33XX_GPIO_NR(0, 22), GPIOF_OUTPUT_INIT_HIGH, "CAN XCVR", },
380 };
381
382 #ifdef CONFIG_LCD
383 static u16 tx48_cmap[256];
384 vidinfo_t panel_info = {
385         /* set to max. size supported by SoC */
386         .vl_col = 1366,
387         .vl_row = 768,
388
389         .vl_bpix = LCD_COLOR24,    /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */
390         .cmap = tx48_cmap,
391 };
392
393 #define FB_SYNC_OE_LOW_ACT      (1 << 31)
394 #define FB_SYNC_CLK_LAT_FALL    (1 << 30)
395
396 static struct fb_videomode tx48_fb_modes[] = {
397         {
398                 /* Standard VGA timing */
399                 .name           = "VGA",
400                 .refresh        = 60,
401                 .xres           = 640,
402                 .yres           = 480,
403                 .pixclock       = KHZ2PICOS(25175),
404                 .left_margin    = 48,
405                 .hsync_len      = 96,
406                 .right_margin   = 16,
407                 .upper_margin   = 31,
408                 .vsync_len      = 2,
409                 .lower_margin   = 12,
410                 .sync           = FB_SYNC_CLK_LAT_FALL,
411         },
412         {
413                 /* Emerging ETV570 640 x 480 display. Syncs low active,
414                  * DE high active, 115.2 mm x 86.4 mm display area
415                  * VGA compatible timing
416                  */
417                 .name           = "ETV570",
418                 .refresh        = 60,
419                 .xres           = 640,
420                 .yres           = 480,
421                 .pixclock       = KHZ2PICOS(25175),
422                 .left_margin    = 114,
423                 .hsync_len      = 30,
424                 .right_margin   = 16,
425                 .upper_margin   = 32,
426                 .vsync_len      = 3,
427                 .lower_margin   = 10,
428                 .sync           = FB_SYNC_CLK_LAT_FALL,
429         },
430         {
431                 /* Emerging ET0350G0DH6 320 x 240 display.
432                  * 70.08 mm x 52.56 mm display area.
433                  */
434                 .name           = "ET0350",
435                 .refresh        = 60,
436                 .xres           = 320,
437                 .yres           = 240,
438                 .pixclock       = KHZ2PICOS(6500),
439                 .left_margin    = 68 - 34,
440                 .hsync_len      = 34,
441                 .right_margin   = 20,
442                 .upper_margin   = 18 - 3,
443                 .vsync_len      = 3,
444                 .lower_margin   = 4,
445                 .sync           = FB_SYNC_CLK_LAT_FALL,
446         },
447         {
448                 /* Emerging ET0430G0DH6 480 x 272 display.
449                  * 95.04 mm x 53.856 mm display area.
450                  */
451                 .name           = "ET0430",
452                 .refresh        = 60,
453                 .xres           = 480,
454                 .yres           = 272,
455                 .pixclock       = KHZ2PICOS(9000),
456                 .left_margin    = 2,
457                 .hsync_len      = 41,
458                 .right_margin   = 2,
459                 .upper_margin   = 2,
460                 .vsync_len      = 10,
461                 .lower_margin   = 2,
462         },
463         {
464                 /* Emerging ET0500G0DH6 800 x 480 display.
465                  * 109.6 mm x 66.4 mm display area.
466                  */
467                 .name           = "ET0500",
468                 .refresh        = 60,
469                 .xres           = 800,
470                 .yres           = 480,
471                 .pixclock       = KHZ2PICOS(33260),
472                 .left_margin    = 216 - 128,
473                 .hsync_len      = 128,
474                 .right_margin   = 1056 - 800 - 216,
475                 .upper_margin   = 35 - 2,
476                 .vsync_len      = 2,
477                 .lower_margin   = 525 - 480 - 35,
478                 .sync           = FB_SYNC_CLK_LAT_FALL,
479         },
480         {
481                 /* Emerging ETQ570G0DH6 320 x 240 display.
482                  * 115.2 mm x 86.4 mm display area.
483                  */
484                 .name           = "ETQ570",
485                 .refresh        = 60,
486                 .xres           = 320,
487                 .yres           = 240,
488                 .pixclock       = KHZ2PICOS(6400),
489                 .left_margin    = 38,
490                 .hsync_len      = 30,
491                 .right_margin   = 30,
492                 .upper_margin   = 16, /* 15 according to datasheet */
493                 .vsync_len      = 3, /* TVP -> 1>x>5 */
494                 .lower_margin   = 4, /* 4.5 according to datasheet */
495                 .sync           = FB_SYNC_CLK_LAT_FALL,
496         },
497         {
498                 /* Emerging ET0700G0DH6 800 x 480 display.
499                  * 152.4 mm x 91.44 mm display area.
500                  */
501                 .name           = "ET0700",
502                 .refresh        = 60,
503                 .xres           = 800,
504                 .yres           = 480,
505                 .pixclock       = KHZ2PICOS(33260),
506                 .left_margin    = 216 - 128,
507                 .hsync_len      = 128,
508                 .right_margin   = 1056 - 800 - 216,
509                 .upper_margin   = 35 - 2,
510                 .vsync_len      = 2,
511                 .lower_margin   = 525 - 480 - 35,
512                 .sync           = FB_SYNC_CLK_LAT_FALL,
513         },
514         {
515                 /* unnamed entry for assigning parameters parsed from 'video_mode' string */
516                 .refresh        = 60,
517                 .left_margin    = 48,
518                 .hsync_len      = 96,
519                 .right_margin   = 16,
520                 .upper_margin   = 31,
521                 .vsync_len      = 2,
522                 .lower_margin   = 12,
523                 .sync           = FB_SYNC_CLK_LAT_FALL,
524         },
525 };
526
527 void *lcd_base;                 /* Start of framebuffer memory  */
528 void *lcd_console_address;      /* Start of console buffer      */
529
530 int lcd_color_fg;
531 int lcd_color_bg;
532
533 short console_col;
534 short console_row;
535
536 static int lcd_enabled = 1;
537
538 void lcd_initcolregs(void)
539 {
540 }
541
542 void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue)
543 {
544 }
545
546 void lcd_enable(void)
547 {
548         /* HACK ALERT:
549          * global variable from common/lcd.c
550          * Set to 0 here to prevent messages from going to LCD
551          * rather than serial console
552          */
553         lcd_is_enabled = 0;
554
555         if (lcd_enabled) {
556                 karo_load_splashimage(1);
557
558                 debug("Switching LCD on\n");
559                 gpio_set_value(TX48_LCD_PWR_GPIO, 1);
560                 udelay(100);
561                 gpio_set_value(TX48_LCD_RST_GPIO, 1);
562                 udelay(300000);
563                 gpio_set_value(TX48_LCD_BACKLIGHT_GPIO, 0);
564         }
565 }
566
567 void lcd_disable(void)
568 {
569         if (lcd_enabled) {
570                 printf("Disabling LCD\n");
571                 da8xx_fb_disable();
572                 lcd_enabled = 0;
573         }
574 }
575
576 static void tx48_lcd_panel_setup(struct da8xx_panel *p,
577                                 struct fb_videomode *fb)
578 {
579         p->pxl_clk = PICOS2KHZ(fb->pixclock) * 1000;
580
581         p->width = fb->xres;
582         p->hbp = fb->left_margin;
583         p->hsw = fb->hsync_len;
584         p->hfp = fb->right_margin;
585
586         p->height = fb->yres;
587         p->vbp = fb->upper_margin;
588         p->vsw = fb->vsync_len;
589         p->vfp = fb->lower_margin;
590
591         p->invert_pxl_clk = !!(fb->sync & FB_SYNC_CLK_LAT_FALL);
592 }
593
594 void lcd_panel_disable(void)
595 {
596         if (lcd_enabled) {
597                 debug("Switching LCD off\n");
598                 gpio_set_value(TX48_LCD_BACKLIGHT_GPIO, 1);
599                 gpio_set_value(TX48_LCD_PWR_GPIO, 0);
600                 gpio_set_value(TX48_LCD_RST_GPIO, 0);
601         }
602 }
603
604 void lcd_ctrl_init(void *lcdbase)
605 {
606         int color_depth = 24;
607         const char *video_mode = getenv("video_mode");
608         const char *vm;
609         unsigned long val;
610         int refresh = 60;
611         struct fb_videomode *p = &tx48_fb_modes[0];
612         struct fb_videomode fb_mode;
613         int xres_set = 0, yres_set = 0, bpp_set = 0, refresh_set = 0;
614
615         if (!lcd_enabled) {
616                 debug("LCD disabled\n");
617                 return;
618         }
619
620         if (had_ctrlc() || (prm_rstst & PRM_RSTST_WDT1_RST)) {
621                 debug("Disabling LCD\n");
622                 lcd_enabled = 0;
623                 setenv("splashimage", NULL);
624                 return;
625         }
626
627         karo_fdt_move_fdt();
628
629         vm = karo_fdt_set_display(video_mode, "/panel", NULL);
630         if (vm == NULL) {
631                 debug("Disabling LCD\n");
632                 lcd_enabled = 0;
633                 return;
634         }
635         video_mode = vm;
636         if (karo_fdt_get_fb_mode(working_fdt, vm, &fb_mode) == 0) {
637                 p = &fb_mode;
638                 debug("Using video mode from FDT\n");
639                 vm += strlen(vm);
640                 if (fb_mode.xres > panel_info.vl_col ||
641                         fb_mode.yres > panel_info.vl_row) {
642                         printf("video resolution from DT: %dx%d exceeds hardware limits: %dx%d\n",
643                                 fb_mode.xres, fb_mode.yres,
644                                 panel_info.vl_col, panel_info.vl_row);
645                         lcd_enabled = 0;
646                         return;
647                 }
648         }
649         if (p->name != NULL)
650                 debug("Trying compiled-in video modes\n");
651         while (p->name != NULL) {
652                 if (strcmp(p->name, vm) == 0) {
653                         debug("Using video mode: '%s'\n", p->name);
654                         vm += strlen(vm);
655                         break;
656                 }
657                 p++;
658         }
659         if (*vm != '\0')
660                 debug("Trying to decode video_mode: '%s'\n", vm);
661         while (*vm != '\0') {
662                 if (*vm >= '0' && *vm <= '9') {
663                         char *end;
664
665                         val = simple_strtoul(vm, &end, 0);
666                         if (end > vm) {
667                                 if (!xres_set) {
668                                         if (val > panel_info.vl_col)
669                                                 val = panel_info.vl_col;
670                                         p->xres = val;
671                                         panel_info.vl_col = val;
672                                         xres_set = 1;
673                                 } else if (!yres_set) {
674                                         if (val > panel_info.vl_row)
675                                                 val = panel_info.vl_row;
676                                         p->yres = val;
677                                         panel_info.vl_row = val;
678                                         yres_set = 1;
679                                 } else if (!bpp_set) {
680                                         switch (val) {
681                                         case 24:
682                                         case 16:
683                                         case 8:
684                                                 color_depth = val;
685                                                 break;
686
687                                         default:
688                                                 printf("Invalid color depth: '%.*s' in video_mode; using default: '%u'\n",
689                                                         end - vm, vm, color_depth);
690                                         }
691                                         bpp_set = 1;
692                                 } else if (!refresh_set) {
693                                         refresh = val;
694                                         refresh_set = 1;
695                                 }
696                         }
697                         vm = end;
698                 }
699                 switch (*vm) {
700                 case '@':
701                         bpp_set = 1;
702                         /* fallthru */
703                 case '-':
704                         yres_set = 1;
705                         /* fallthru */
706                 case 'x':
707                         xres_set = 1;
708                         /* fallthru */
709                 case 'M':
710                 case 'R':
711                         vm++;
712                         break;
713
714                 default:
715                         if (*vm != '\0')
716                                 vm++;
717                 }
718         }
719         if (p->xres == 0 || p->yres == 0) {
720                 printf("Invalid video mode: %s\n", getenv("video_mode"));
721                 lcd_enabled = 0;
722                 printf("Supported video modes are:");
723                 for (p = &tx48_fb_modes[0]; p->name != NULL; p++) {
724                         printf(" %s", p->name);
725                 }
726                 printf("\n");
727                 return;
728         }
729         if (p->xres > panel_info.vl_col || p->yres > panel_info.vl_row) {
730                 printf("video resolution: %dx%d exceeds hardware limits: %dx%d\n",
731                         p->xres, p->yres, panel_info.vl_col, panel_info.vl_row);
732                 lcd_enabled = 0;
733                 return;
734         }
735         panel_info.vl_col = p->xres;
736         panel_info.vl_row = p->yres;
737
738         switch (color_depth) {
739         case 8:
740                 panel_info.vl_bpix = LCD_COLOR8;
741                 break;
742         case 16:
743                 panel_info.vl_bpix = LCD_COLOR16;
744                 break;
745         default:
746                 panel_info.vl_bpix = LCD_COLOR24;
747         }
748
749         p->pixclock = KHZ2PICOS(refresh *
750                 (p->xres + p->left_margin + p->right_margin + p->hsync_len) *
751                 (p->yres + p->upper_margin + p->lower_margin + p->vsync_len)
752                 / 1000);
753         debug("Pixel clock set to %lu.%03lu MHz\n",
754                 PICOS2KHZ(p->pixclock) / 1000,
755                 PICOS2KHZ(p->pixclock) % 1000);
756
757         if (p != &fb_mode) {
758                 int ret;
759
760                 debug("Creating new display-timing node from '%s'\n",
761                         video_mode);
762                 ret = karo_fdt_create_fb_mode(working_fdt, video_mode, p);
763                 if (ret)
764                         printf("Failed to create new display-timing node from '%s': %d\n",
765                                 video_mode, ret);
766         }
767
768         gpio_request_array(stk5_lcd_gpios, ARRAY_SIZE(stk5_lcd_gpios));
769         tx48_set_pin_mux(stk5_lcd_pads, ARRAY_SIZE(stk5_lcd_pads));
770
771         if (karo_load_splashimage(0) == 0) {
772                 struct da8xx_panel da8xx_panel = { };
773
774                 debug("Initializing FB driver\n");
775                 tx48_lcd_panel_setup(&da8xx_panel, p);
776                 da8xx_video_init(&da8xx_panel, color_depth);
777
778                 debug("Initializing LCD controller\n");
779                 video_hw_init();
780         } else {
781                 debug("Skipping initialization of LCD controller\n");
782         }
783 }
784 #else
785 #define lcd_enabled 0
786 #endif /* CONFIG_LCD */
787
788 static void stk5_board_init(void)
789 {
790         gpio_request_array(stk5_gpios, ARRAY_SIZE(stk5_gpios));
791         tx48_set_pin_mux(stk5_pads, ARRAY_SIZE(stk5_pads));
792 }
793
794 static void stk5v3_board_init(void)
795 {
796         stk5_board_init();
797 }
798
799 static void stk5v5_board_init(void)
800 {
801         stk5_board_init();
802
803         gpio_request_array(stk5v5_gpios, ARRAY_SIZE(stk5v5_gpios));
804         tx48_set_pin_mux(stk5v5_pads, ARRAY_SIZE(stk5v5_pads));
805 }
806
807 /* called with default environment! */
808 int board_init(void)
809 {
810         /* mach type passed to kernel */
811 #ifdef CONFIG_OF_LIBFDT
812         gd->bd->bi_arch_number = -1;
813 #endif
814         /* address of boot parameters */
815         gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
816
817         if (ctrlc())
818                 printf("CTRL-C detected\n");
819
820         return 0;
821 }
822
823 static void show_reset_cause(u32 prm_rstst)
824 {
825         const char *dlm = "";
826
827         printf("RESET cause: ");
828         if (prm_rstst & PRM_RSTST_GLOBAL_COLD_RST) {
829                 printf("%sPOR", dlm);
830                 dlm = " | ";
831         }
832         if (prm_rstst & PRM_RSTST_GLOBAL_WARM_SW_RST) {
833                 printf("%sSW", dlm);
834                 dlm = " | ";
835         }
836         if (prm_rstst & PRM_RSTST_WDT1_RST) {
837                 printf("%sWATCHDOG", dlm);
838                 dlm = " | ";
839         }
840         if (prm_rstst & PRM_RSTST_EXTERNAL_WARM_RST) {
841                 printf("%sWARM", dlm);
842                 dlm = " | ";
843         }
844         if (prm_rstst & PRM_RSTST_ICEPICK_RST) {
845                 printf("%sJTAG", dlm);
846                 dlm = " | ";
847         }
848         if (*dlm == '\0')
849                 printf("unknown");
850
851         printf(" RESET\n");
852 }
853
854 /* called with default environment! */
855 int checkboard(void)
856 {
857         prm_rstst = readl(PRM_RSTST);
858         show_reset_cause(prm_rstst);
859
860 #ifdef CONFIG_OF_LIBFDT
861         printf("Board: Ka-Ro TX48-7020 with FDT support\n");
862 #else
863         printf("Board: Ka-Ro TX48-7020\n");
864 #endif
865         timer_init();
866         return 0;
867 }
868
869 static void tx48_set_cpu_clock(void)
870 {
871         unsigned long cpu_clk = getenv_ulong("cpu_clk", 10, 0);
872
873         if (had_ctrlc() || (prm_rstst & PRM_RSTST_WDT1_RST))
874                 return;
875
876         if (cpu_clk == 0 || cpu_clk == mpu_clk_rate() / 1000000)
877                 return;
878
879         mpu_pll_config_val(cpu_clk);
880
881         printf("CPU clock set to %lu.%03lu MHz\n",
882                 mpu_clk_rate() / 1000000,
883                 mpu_clk_rate() / 1000 % 1000);
884 }
885
886 static void tx48_init_mac(void)
887 {
888         uint8_t mac_addr[ETH_ALEN];
889         uint32_t mac_hi, mac_lo;
890
891         /* try reading mac address from efuse */
892         mac_lo = __raw_readl(MAC_ID0_LO);
893         mac_hi = __raw_readl(MAC_ID0_HI);
894
895         mac_addr[0] = mac_hi & 0xFF;
896         mac_addr[1] = (mac_hi & 0xFF00) >> 8;
897         mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
898         mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
899         mac_addr[4] = mac_lo & 0xFF;
900         mac_addr[5] = (mac_lo & 0xFF00) >> 8;
901
902         if (!is_valid_ether_addr(mac_addr)) {
903                 printf("No valid MAC address programmed\n");
904                 return;
905         }
906         printf("MAC addr from fuse: %pM\n", mac_addr);
907         eth_setenv_enetaddr("ethaddr", mac_addr);
908 }
909
910 /* called with environment from NAND or MMC */
911 int board_late_init(void)
912 {
913         int ret = 0;
914         const char *baseboard;
915
916         tx48_set_cpu_clock();
917         karo_fdt_move_fdt();
918
919         baseboard = getenv("baseboard");
920         if (!baseboard)
921                 goto exit;
922
923         if (strncmp(baseboard, "stk5", 4) == 0) {
924                 printf("Baseboard: %s\n", baseboard);
925                 if ((strlen(baseboard) == 4) ||
926                         strcmp(baseboard, "stk5-v3") == 0) {
927                         stk5v3_board_init();
928                 } else if (strcmp(baseboard, "stk5-v5") == 0) {
929                         stk5v5_board_init();
930                 } else {
931                         printf("WARNING: Unsupported STK5 board rev.: %s\n",
932                                 baseboard + 4);
933                 }
934         } else {
935                 printf("WARNING: Unsupported baseboard: '%s'\n",
936                         baseboard);
937                 ret = -EINVAL;
938         }
939 exit:
940         tx48_init_mac();
941         clear_ctrlc();
942         return ret;
943 }
944
945 #ifdef CONFIG_DRIVER_TI_CPSW
946 static void tx48_phy_init(char *name, int addr)
947 {
948         debug("%s: Resetting ethernet PHY\n", __func__);
949
950         gpio_direction_output(TX48_ETH_PHY_RST_GPIO, 0);
951
952         udelay(100);
953
954         /* Release nRST */
955         gpio_set_value(TX48_ETH_PHY_RST_GPIO, 1);
956
957         /* Wait for PHY internal POR signal to deassert */
958         udelay(25000);
959 }
960
961 static void cpsw_control(int enabled)
962 {
963         /* nothing for now */
964         /* TODO : VTP was here before */
965 }
966
967 static struct cpsw_slave_data cpsw_slaves[] = {
968         {
969                 .slave_reg_ofs  = 0x208,
970                 .sliver_reg_ofs = 0xd80,
971                 .phy_id         = 0,
972                 .phy_if         = PHY_INTERFACE_MODE_RMII,
973         },
974 };
975
976 void s_init(void)
977 {
978         /* Nothing to be done here */
979 }
980
981 static struct cpsw_platform_data cpsw_data = {
982         .mdio_base              = CPSW_MDIO_BASE,
983         .cpsw_base              = CPSW_BASE,
984         .mdio_div               = 0xff,
985         .channels               = 8,
986         .cpdma_reg_ofs          = 0x800,
987         .slaves                 = ARRAY_SIZE(cpsw_slaves),
988         .slave_data             = cpsw_slaves,
989         .ale_reg_ofs            = 0xd00,
990         .ale_entries            = 1024,
991         .host_port_reg_ofs      = 0x108,
992         .hw_stats_reg_ofs       = 0x900,
993         .mac_control            = (1 << 5) /* MIIEN */,
994         .control                = cpsw_control,
995         .phy_init               = tx48_phy_init,
996         .gigabit_en             = 0,
997         .host_port_num          = 0,
998         .version                = CPSW_CTRL_VERSION_2,
999 };
1000
1001 int board_eth_init(bd_t *bis)
1002 {
1003         __raw_writel(RMII_MODE_ENABLE, MAC_MII_SEL);
1004         __raw_writel(0x5D, GMII_SEL);
1005         return cpsw_register(&cpsw_data);
1006 }
1007 #endif /* CONFIG_DRIVER_TI_CPSW */
1008
1009 void tx48_disable_watchdog(void)
1010 {
1011         struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
1012
1013         while (readl(&wdtimer->wdtwwps) & (1 << 4))
1014                 ;
1015         writel(0xaaaa, &wdtimer->wdtwspr);
1016         while (readl(&wdtimer->wdtwwps) & (1 << 4))
1017                 ;
1018         writel(0x5555, &wdtimer->wdtwspr);
1019 }
1020
1021 enum {
1022         LED_STATE_INIT = -1,
1023         LED_STATE_OFF,
1024         LED_STATE_ON,
1025 };
1026
1027 void show_activity(int arg)
1028 {
1029         static int led_state = LED_STATE_INIT;
1030         static ulong last;
1031
1032         if (led_state == LED_STATE_INIT) {
1033                 last = get_timer(0);
1034                 gpio_set_value(TX48_LED_GPIO, 1);
1035                 led_state = LED_STATE_ON;
1036         } else {
1037                 if (get_timer(last) > CONFIG_SYS_HZ) {
1038                         last = get_timer(0);
1039                         if (led_state == LED_STATE_ON) {
1040                                 gpio_set_value(TX48_LED_GPIO, 0);
1041                         } else {
1042                                 gpio_set_value(TX48_LED_GPIO, 1);
1043                         }
1044                         led_state = 1 - led_state;
1045                 }
1046         }
1047 }
1048
1049 #ifdef CONFIG_OF_BOARD_SETUP
1050 #ifdef CONFIG_FDT_FIXUP_PARTITIONS
1051 #include <jffs2/jffs2.h>
1052 #include <mtd_node.h>
1053 static struct node_info nodes[] = {
1054         { "ti,omap2-nand", MTD_DEV_TYPE_NAND, },
1055         { "ti,am3352-gpmc", MTD_DEV_TYPE_NAND, },
1056 };
1057
1058 #else
1059 #define fdt_fixup_mtdparts(b,n,c) do { } while (0)
1060 #endif /* CONFIG_FDT_FIXUP_PARTITIONS */
1061
1062 void ft_board_setup(void *blob, bd_t *bd)
1063 {
1064         const char *baseboard = getenv("baseboard");
1065         int stk5_v5 = baseboard != NULL && (strcmp(baseboard, "stk5-v5") == 0);
1066         const char *video_mode = getenv("video_mode");
1067
1068         fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
1069         fdt_fixup_ethernet(blob);
1070
1071         karo_fdt_fixup_touchpanel(blob);
1072         karo_fdt_fixup_flexcan(blob, stk5_v5);
1073
1074         video_mode = karo_fdt_set_display(video_mode, "/panel", NULL);
1075         karo_fdt_update_fb_mode(blob, video_mode);
1076
1077         tx48_disable_watchdog();
1078 }
1079 #endif /* CONFIG_OF_BOARD_SETUP */