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