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