]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/karo/tx6/tx6qdl.c
2596525d66fec9d27366e7027150c77f5078bd99
[karo-tx-uboot.git] / board / karo / tx6 / tx6qdl.c
1 /*
2  * Copyright (C) 2012,2013 Lothar Waßmann <LW@KARO-electronics.de>
3  *
4  * See file CREDITS for list of people who contributed to this
5  * project.
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 in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  */
17
18 #include <common.h>
19 #include <errno.h>
20 #include <libfdt.h>
21 #include <fdt_support.h>
22 #include <lcd.h>
23 #include <netdev.h>
24 #include <mmc.h>
25 #include <fsl_esdhc.h>
26 #include <video_fb.h>
27 #include <ipu.h>
28 #include <mxcfb.h>
29 #include <i2c.h>
30 #include <linux/fb.h>
31 #include <asm/io.h>
32 #include <asm/gpio.h>
33 #include <asm/arch/mx6-pins.h>
34 #include <asm/arch/clock.h>
35 #include <asm/arch/imx-regs.h>
36 #include <asm/arch/crm_regs.h>
37 #include <asm/arch/sys_proto.h>
38
39 #include "../common/karo.h"
40
41 #define TX6_FEC_RST_GPIO                IMX_GPIO_NR(7, 6)
42 #define TX6_FEC_PWR_GPIO                IMX_GPIO_NR(3, 20)
43 #define TX6_FEC_INT_GPIO                IMX_GPIO_NR(7, 1)
44 #define TX6_LED_GPIO                    IMX_GPIO_NR(2, 20)
45
46 #define TX6_LCD_PWR_GPIO                IMX_GPIO_NR(2, 31)
47 #define TX6_LCD_RST_GPIO                IMX_GPIO_NR(3, 29)
48 #define TX6_LCD_BACKLIGHT_GPIO          IMX_GPIO_NR(1, 1)
49
50 #define TX6_RESET_OUT_GPIO              IMX_GPIO_NR(7, 12)
51
52 #define TEMPERATURE_MIN                 -40
53 #define TEMPERATURE_HOT                 80
54 #define TEMPERATURE_MAX                 125
55
56 DECLARE_GLOBAL_DATA_PTR;
57
58 #define MUX_CFG_SION                    IOMUX_PAD(0, 0, IOMUX_CONFIG_SION, 0, 0, 0)
59
60 static const iomux_v3_cfg_t tx6qdl_pads[] = {
61         /* NAND flash pads */
62         MX6_PAD_NANDF_CLE__RAWNAND_CLE,
63         MX6_PAD_NANDF_ALE__RAWNAND_ALE,
64         MX6_PAD_NANDF_WP_B__RAWNAND_RESETN,
65         MX6_PAD_NANDF_RB0__RAWNAND_READY0,
66         MX6_PAD_NANDF_CS0__RAWNAND_CE0N,
67         MX6_PAD_SD4_CMD__RAWNAND_RDN,
68         MX6_PAD_SD4_CLK__RAWNAND_WRN,
69         MX6_PAD_NANDF_D0__RAWNAND_D0,
70         MX6_PAD_NANDF_D1__RAWNAND_D1,
71         MX6_PAD_NANDF_D2__RAWNAND_D2,
72         MX6_PAD_NANDF_D3__RAWNAND_D3,
73         MX6_PAD_NANDF_D4__RAWNAND_D4,
74         MX6_PAD_NANDF_D5__RAWNAND_D5,
75         MX6_PAD_NANDF_D6__RAWNAND_D6,
76         MX6_PAD_NANDF_D7__RAWNAND_D7,
77
78         /* RESET_OUT */
79         MX6_PAD_GPIO_17__GPIO_7_12,
80
81         /* UART pads */
82 #if CONFIG_MXC_UART_BASE == UART1_BASE
83         MX6_PAD_SD3_DAT7__UART1_TXD,
84         MX6_PAD_SD3_DAT6__UART1_RXD,
85         MX6_PAD_SD3_DAT1__UART1_RTS,
86         MX6_PAD_SD3_DAT0__UART1_CTS,
87 #endif
88 #if CONFIG_MXC_UART_BASE == UART2_BASE
89         MX6_PAD_SD4_DAT4__UART2_RXD,
90         MX6_PAD_SD4_DAT7__UART2_TXD,
91         MX6_PAD_SD4_DAT5__UART2_RTS,
92         MX6_PAD_SD4_DAT6__UART2_CTS,
93 #endif
94 #if CONFIG_MXC_UART_BASE == UART3_BASE
95         MX6_PAD_EIM_D24__UART3_TXD,
96         MX6_PAD_EIM_D25__UART3_RXD,
97         MX6_PAD_SD3_RST__UART3_RTS,
98         MX6_PAD_SD3_DAT3__UART3_CTS,
99 #endif
100         /* internal I2C */
101         MX6_PAD_EIM_D28__I2C1_SDA,
102         MX6_PAD_EIM_D21__I2C1_SCL,
103
104         /* FEC PHY GPIO functions */
105         MX6_PAD_EIM_D20__GPIO_3_20 | MUX_CFG_SION, /* PHY POWER */
106         MX6_PAD_SD3_DAT2__GPIO_7_6 | MUX_CFG_SION, /* PHY RESET */
107         MX6_PAD_SD3_DAT4__GPIO_7_1, /* PHY INT */
108 };
109
110 static const iomux_v3_cfg_t tx6qdl_fec_pads[] = {
111         /* FEC functions */
112         MX6_PAD_ENET_MDC__ENET_MDC,
113         MX6_PAD_ENET_MDIO__ENET_MDIO,
114         MX6_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT,
115         MX6_PAD_ENET_RX_ER__ENET_RX_ER,
116         MX6_PAD_ENET_CRS_DV__ENET_RX_EN,
117         MX6_PAD_ENET_RXD1__ENET_RDATA_1,
118         MX6_PAD_ENET_RXD0__ENET_RDATA_0,
119         MX6_PAD_ENET_TX_EN__ENET_TX_EN,
120         MX6_PAD_ENET_TXD1__ENET_TDATA_1,
121         MX6_PAD_ENET_TXD0__ENET_TDATA_0,
122 };
123
124 static const struct gpio tx6qdl_gpios[] = {
125         { TX6_RESET_OUT_GPIO, GPIOF_OUTPUT_INIT_HIGH, "#RESET_OUT", },
126         { TX6_FEC_PWR_GPIO, GPIOF_OUTPUT_INIT_HIGH, "FEC PHY PWR", },
127         { TX6_FEC_RST_GPIO, GPIOF_OUTPUT_INIT_LOW, "FEC PHY RESET", },
128         { TX6_FEC_INT_GPIO, GPIOF_INPUT, "FEC PHY INT", },
129 };
130
131 /*
132  * Functions
133  */
134 /* placed in section '.data' to prevent overwriting relocation info
135  * overlayed with bss
136  */
137 static u32 wrsr __attribute__((section(".data")));
138
139 #define WRSR_POR                        (1 << 4)
140 #define WRSR_TOUT                       (1 << 1)
141 #define WRSR_SFTW                       (1 << 0)
142
143 static void print_reset_cause(void)
144 {
145         struct src *src_regs = (struct src *)SRC_BASE_ADDR;
146         void __iomem *wdt_base = (void __iomem *)WDOG1_BASE_ADDR;
147         u32 srsr;
148         char *dlm = "";
149
150         printf("Reset cause: ");
151
152         srsr = readl(&src_regs->srsr);
153         wrsr = readw(wdt_base + 4);
154
155         if (wrsr & WRSR_POR) {
156                 printf("%sPOR", dlm);
157                 dlm = " | ";
158         }
159         if (srsr & 0x00004) {
160                 printf("%sCSU", dlm);
161                 dlm = " | ";
162         }
163         if (srsr & 0x00008) {
164                 printf("%sIPP USER", dlm);
165                 dlm = " | ";
166         }
167         if (srsr & 0x00010) {
168                 if (wrsr & WRSR_SFTW) {
169                         printf("%sSOFT", dlm);
170                         dlm = " | ";
171                 }
172                 if (wrsr & WRSR_TOUT) {
173                         printf("%sWDOG", dlm);
174                         dlm = " | ";
175                 }
176         }
177         if (srsr & 0x00020) {
178                 printf("%sJTAG HIGH-Z", dlm);
179                 dlm = " | ";
180         }
181         if (srsr & 0x00040) {
182                 printf("%sJTAG SW", dlm);
183                 dlm = " | ";
184         }
185         if (srsr & 0x10000) {
186                 printf("%sWARM BOOT", dlm);
187                 dlm = " | ";
188         }
189         if (dlm[0] == '\0')
190                 printf("unknown");
191
192         printf("\n");
193 }
194
195 int read_cpu_temperature(void);
196 int check_cpu_temperature(int boot);
197
198 static void tx6qdl_print_cpuinfo(void)
199 {
200         u32 cpurev = get_cpu_rev();
201         char *cpu_str = "?";
202
203         switch ((cpurev >> 12) & 0xff) {
204         case MXC_CPU_MX6SL:
205                 cpu_str = "SL";
206                 break;
207         case MXC_CPU_MX6DL:
208                 cpu_str = "DL";
209                 break;
210         case MXC_CPU_MX6SOLO:
211                 cpu_str = "SOLO";
212                 break;
213         case MXC_CPU_MX6Q:
214                 cpu_str = "Q";
215                 break;
216         }
217
218         printf("CPU:   Freescale i.MX6%s rev%d.%d at %d MHz\n",
219                 cpu_str,
220                 (cpurev & 0x000F0) >> 4,
221                 (cpurev & 0x0000F) >> 0,
222                 mxc_get_clock(MXC_ARM_CLK) / 1000000);
223
224         print_reset_cause();
225         check_cpu_temperature(1);
226 }
227
228 #define LTC3676_BUCK1           0x01
229 #define LTC3676_BUCK2           0x02
230 #define LTC3676_BUCK3           0x03
231 #define LTC3676_BUCK4           0x04
232 #define LTC3676_DVB1A           0x0A
233 #define LTC3676_DVB1B           0x0B
234 #define LTC3676_DVB2A           0x0C
235 #define LTC3676_DVB2B           0x0D
236 #define LTC3676_DVB3A           0x0E
237 #define LTC3676_DVB3B           0x0F
238 #define LTC3676_DVB4A           0x10
239 #define LTC3676_DVB4B           0x11
240 #define LTC3676_MSKPG           0x13
241 #define LTC3676_CLIRQ           0x1f
242
243 #define LTC3676_BUCK_DVDT_FAST  (1 << 0)
244 #define LTC3676_BUCK_KEEP_ALIVE (1 << 1)
245 #define LTC3676_BUCK_CLK_RATE_LOW (1 << 2)
246 #define LTC3676_BUCK_PHASE_SEL  (1 << 3)
247 #define LTC3676_BUCK_ENABLE_300 (1 << 4)
248 #define LTC3676_BUCK_PULSE_SKIP (0 << 5)
249 #define LTC3676_BUCK_BURST_MODE (1 << 5)
250 #define LTC3676_BUCK_CONTINUOUS (2 << 5)
251 #define LTC3676_BUCK_ENABLE     (1 << 7)
252
253 #define LTC3676_PGOOD_MASK      (1 << 5)
254
255 #define LTC3676_MSKPG_BUCK1     (1 << 0)
256 #define LTC3676_MSKPG_BUCK2     (1 << 1)
257 #define LTC3676_MSKPG_BUCK3     (1 << 2)
258 #define LTC3676_MSKPG_BUCK4     (1 << 3)
259 #define LTC3676_MSKPG_LDO2      (1 << 5)
260 #define LTC3676_MSKPG_LDO3      (1 << 6)
261 #define LTC3676_MSKPG_LDO4      (1 << 7)
262
263 #define VDD_IO_VAL              mV_to_regval(vout_to_vref(3300 * 10, 5))
264 #define VDD_IO_VAL_LP           mV_to_regval(vout_to_vref(3100 * 10, 5))
265 #define VDD_IO_VAL_2            mV_to_regval(vout_to_vref(3300 * 10, 5_2))
266 #define VDD_IO_VAL_2_LP         mV_to_regval(vout_to_vref(3100 * 10, 5_2))
267 #define VDD_SOC_VAL             mV_to_regval(vout_to_vref(1425 * 10, 6))
268 #define VDD_SOC_VAL_LP          mV_to_regval(vout_to_vref(900 * 10, 6))
269 #define VDD_DDR_VAL             mV_to_regval(vout_to_vref(1500 * 10, 7))
270 #define VDD_DDR_VAL_LP          mV_to_regval(vout_to_vref(1500 * 10, 7))
271 #define VDD_CORE_VAL            mV_to_regval(vout_to_vref(1425 * 10, 8))
272 #define VDD_CORE_VAL_LP         mV_to_regval(vout_to_vref(900 * 10, 8))
273
274 /* LDO1 */
275 #define R1_1                    470
276 #define R2_1                    150
277 /* LDO4 */
278 #define R1_4                    470
279 #define R2_4                    150
280 /* Buck1 */
281 #define R1_5                    390
282 #define R2_5                    110
283 #define R1_5_2                  470
284 #define R2_5_2                  150
285 /* Buck2 (SOC) */
286 #define R1_6                    150
287 #define R2_6                    180
288 /* Buck3 (DDR) */
289 #define R1_7                    150
290 #define R2_7                    140
291 /* Buck4 (CORE) */
292 #define R1_8                    150
293 #define R2_8                    180
294
295 /* calculate voltages in 10mV */
296 #define R1(idx)                 R1_##idx
297 #define R2(idx)                 R2_##idx
298
299 #define vout_to_vref(vout, idx) ((vout) * R2(idx) / (R1(idx) + R2(idx)))
300 #define vref_to_vout(vref, idx) DIV_ROUND_UP((vref) * (R1(idx) + R2(idx)), R2(idx))
301
302 #define mV_to_regval(mV)        DIV_ROUND(((((mV) < 4125) ? 4125 : (mV)) - 4125), 125)
303 #define regval_to_mV(v)         (((v) * 125 + 4125))
304
305 static struct ltc3673_regs {
306         u8 addr;
307         u8 val;
308         u8 mask;
309 } ltc3676_regs[] = {
310         { LTC3676_MSKPG, ~LTC3676_MSKPG_BUCK1, },
311         { LTC3676_DVB2B, VDD_SOC_VAL_LP | LTC3676_PGOOD_MASK, ~0x3f, },
312         { LTC3676_DVB3B, VDD_DDR_VAL_LP, ~0x3f, },
313         { LTC3676_DVB4B, VDD_CORE_VAL_LP | LTC3676_PGOOD_MASK, ~0x3f, },
314         { LTC3676_DVB2A, VDD_SOC_VAL, ~0x3f, },
315         { LTC3676_DVB3A, VDD_DDR_VAL, ~0x3f, },
316         { LTC3676_DVB4A, VDD_CORE_VAL, ~0x3f, },
317         { LTC3676_BUCK1, LTC3676_BUCK_BURST_MODE | LTC3676_BUCK_CLK_RATE_LOW, },
318         { LTC3676_BUCK2, LTC3676_BUCK_BURST_MODE, },
319         { LTC3676_BUCK3, LTC3676_BUCK_BURST_MODE, },
320         { LTC3676_BUCK4, LTC3676_BUCK_BURST_MODE, },
321         { LTC3676_CLIRQ, 0, }, /* clear interrupt status */
322 };
323
324 static struct ltc3673_regs ltc3676_regs_1[] = {
325         { LTC3676_DVB1B, VDD_IO_VAL_LP | LTC3676_PGOOD_MASK, ~0x3f, },
326         { LTC3676_DVB1A, VDD_IO_VAL, ~0x3f, },
327 };
328
329 static struct ltc3673_regs ltc3676_regs_2[] = {
330         { LTC3676_DVB1B, VDD_IO_VAL_2_LP | LTC3676_PGOOD_MASK, ~0x3f, },
331         { LTC3676_DVB1A, VDD_IO_VAL_2, ~0x3f, },
332 };
333
334 static int tx6_rev_2(void)
335 {
336         struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
337         struct fuse_bank5_regs *fuse = (void *)ocotp->bank[5].fuse_regs;
338         u32 pad_settings = readl(&fuse->pad_settings);
339
340         debug("Fuse pad_settings @ %p = %02x\n",
341                 &fuse->pad_settings, pad_settings);
342         return pad_settings & 1;
343 }
344
345 static int tx6_ltc3676_setup_regs(struct ltc3673_regs *r, size_t count)
346 {
347         int ret;
348         int i;
349
350         for (i = 0; i < count; i++, r++) {
351 #ifdef DEBUG
352                 unsigned char value;
353
354                 ret = i2c_read(CONFIG_SYS_I2C_SLAVE, r->addr, 1, &value, 1);
355                 if ((value & ~r->mask) != r->val) {
356                         printf("Changing PMIC reg %02x from %02x to %02x\n",
357                                 r->addr, value, r->val);
358                 }
359                 if (ret) {
360                         printf("%s: failed to read PMIC register %02x: %d\n",
361                                 __func__, r->addr, ret);
362                         return ret;
363                 }
364 #endif
365                 ret = i2c_write(CONFIG_SYS_I2C_SLAVE,
366                                 r->addr, 1, &r->val, 1);
367                 if (ret) {
368                         printf("%s: failed to write PMIC register %02x: %d\n",
369                                 __func__, r->addr, ret);
370                         return ret;
371                 }
372         }
373         return 0;
374 }
375
376 static int setup_pmic_voltages(void)
377 {
378         int ret;
379         unsigned char value;
380
381         ret = i2c_probe(CONFIG_SYS_I2C_SLAVE);
382         if (ret != 0) {
383                 printf("Failed to initialize I2C\n");
384                 return ret;
385         }
386
387         ret = i2c_read(CONFIG_SYS_I2C_SLAVE, 0x11, 1, &value, 1);
388         if (ret) {
389                 printf("%s: i2c_read error: %d\n", __func__, ret);
390                 return ret;
391         }
392
393         ret = tx6_ltc3676_setup_regs(ltc3676_regs, ARRAY_SIZE(ltc3676_regs));
394         if (ret)
395                 return ret;
396
397         printf("VDDCORE set to %umV\n",
398                 DIV_ROUND(vref_to_vout(regval_to_mV(VDD_CORE_VAL), 8), 10));
399         printf("VDDSOC  set to %umV\n",
400                 DIV_ROUND(vref_to_vout(regval_to_mV(VDD_SOC_VAL), 6), 10));
401
402         if (tx6_rev_2()) {
403                 ret = tx6_ltc3676_setup_regs(ltc3676_regs_2,
404                                 ARRAY_SIZE(ltc3676_regs_2));
405                 printf("VDDIO   set to %umV\n",
406                         DIV_ROUND(vref_to_vout(
407                                         regval_to_mV(VDD_IO_VAL_2), 5_2), 10));
408         } else {
409                 ret = tx6_ltc3676_setup_regs(ltc3676_regs_1,
410                                 ARRAY_SIZE(ltc3676_regs_1));
411         }
412         return ret;
413 }
414
415 int board_early_init_f(void)
416 {
417         gpio_request_array(tx6qdl_gpios, ARRAY_SIZE(tx6qdl_gpios));
418         imx_iomux_v3_setup_multiple_pads(tx6qdl_pads, ARRAY_SIZE(tx6qdl_pads));
419
420         return 0;
421 }
422
423 int board_init(void)
424 {
425         int ret;
426
427         /* Address of boot parameters */
428         gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x1000;
429         gd->bd->bi_arch_number = -1;
430
431         if (ctrlc()) {
432                 printf("CTRL-C detected; Skipping PMIC setup\n");
433                 return 1;
434         }
435
436         ret = setup_pmic_voltages();
437         if (ret) {
438                 printf("Failed to setup PMIC voltages\n");
439                 hang();
440         }
441         return 0;
442 }
443
444 int dram_init(void)
445 {
446         /* dram_init must store complete ramsize in gd->ram_size */
447         gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
448                                 PHYS_SDRAM_1_SIZE);
449         return 0;
450 }
451
452 void dram_init_banksize(void)
453 {
454         gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
455         gd->bd->bi_dram[0].size = get_ram_size((void *)PHYS_SDRAM_1,
456                         PHYS_SDRAM_1_SIZE);
457 #if CONFIG_NR_DRAM_BANKS > 1
458         gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
459         gd->bd->bi_dram[1].size = get_ram_size((void *)PHYS_SDRAM_2,
460                         PHYS_SDRAM_2_SIZE);
461 #endif
462 }
463
464 #ifdef  CONFIG_CMD_MMC
465 static const iomux_v3_cfg_t mmc0_pads[] = {
466         MX6_PAD_SD1_CMD__USDHC1_CMD,
467         MX6_PAD_SD1_CLK__USDHC1_CLK,
468         MX6_PAD_SD1_DAT0__USDHC1_DAT0,
469         MX6_PAD_SD1_DAT1__USDHC1_DAT1,
470         MX6_PAD_SD1_DAT2__USDHC1_DAT2,
471         MX6_PAD_SD1_DAT3__USDHC1_DAT3,
472         /* SD1 CD */
473         MX6_PAD_SD3_CMD__GPIO_7_2,
474 };
475
476 static const iomux_v3_cfg_t mmc1_pads[] = {
477         MX6_PAD_SD2_CMD__USDHC2_CMD,
478         MX6_PAD_SD2_CLK__USDHC2_CLK,
479         MX6_PAD_SD2_DAT0__USDHC2_DAT0,
480         MX6_PAD_SD2_DAT1__USDHC2_DAT1,
481         MX6_PAD_SD2_DAT2__USDHC2_DAT2,
482         MX6_PAD_SD2_DAT3__USDHC2_DAT3,
483         /* SD2 CD */
484         MX6_PAD_SD3_CLK__GPIO_7_3,
485 };
486
487 static struct tx6_esdhc_cfg {
488         const iomux_v3_cfg_t *pads;
489         int num_pads;
490         enum mxc_clock clkid;
491         struct fsl_esdhc_cfg cfg;
492         int cd_gpio;
493 } tx6qdl_esdhc_cfg[] = {
494         {
495                 .pads = mmc0_pads,
496                 .num_pads = ARRAY_SIZE(mmc0_pads),
497                 .clkid = MXC_ESDHC_CLK,
498                 .cfg = {
499                         .esdhc_base = (void __iomem *)USDHC1_BASE_ADDR,
500                         .max_bus_width = 4,
501                 },
502                 .cd_gpio = IMX_GPIO_NR(7, 2),
503         },
504         {
505                 .pads = mmc1_pads,
506                 .num_pads = ARRAY_SIZE(mmc1_pads),
507                 .clkid = MXC_ESDHC2_CLK,
508                 .cfg = {
509                         .esdhc_base = (void __iomem *)USDHC2_BASE_ADDR,
510                         .max_bus_width = 4,
511                 },
512                 .cd_gpio = IMX_GPIO_NR(7, 3),
513         },
514 };
515
516 static inline struct tx6_esdhc_cfg *to_tx6_esdhc_cfg(struct fsl_esdhc_cfg *cfg)
517 {
518         return container_of(cfg, struct tx6_esdhc_cfg, cfg);
519 }
520
521 int board_mmc_getcd(struct mmc *mmc)
522 {
523         struct tx6_esdhc_cfg *cfg = to_tx6_esdhc_cfg(mmc->priv);
524
525         if (cfg->cd_gpio < 0)
526                 return cfg->cd_gpio;
527
528         debug("SD card %d is %spresent\n",
529                 cfg - tx6qdl_esdhc_cfg,
530                 gpio_get_value(cfg->cd_gpio) ? "NOT " : "");
531         return !gpio_get_value(cfg->cd_gpio);
532 }
533
534 int board_mmc_init(bd_t *bis)
535 {
536         int i;
537
538         for (i = 0; i < ARRAY_SIZE(tx6qdl_esdhc_cfg); i++) {
539                 struct mmc *mmc;
540                 struct tx6_esdhc_cfg *cfg = &tx6qdl_esdhc_cfg[i];
541                 int ret;
542
543                 cfg->cfg.sdhc_clk = mxc_get_clock(cfg->clkid);
544                 imx_iomux_v3_setup_multiple_pads(cfg->pads, cfg->num_pads);
545
546                 ret = gpio_request_one(cfg->cd_gpio,
547                                 GPIOF_INPUT, "MMC CD");
548                 if (ret) {
549                         printf("Error %d requesting GPIO%d_%d\n",
550                                 ret, cfg->cd_gpio / 32, cfg->cd_gpio % 32);
551                         continue;
552                 }
553
554                 debug("%s: Initializing MMC slot %d\n", __func__, i);
555                 fsl_esdhc_initialize(bis, &cfg->cfg);
556
557                 mmc = find_mmc_device(i);
558                 if (mmc == NULL)
559                         continue;
560                 if (board_mmc_getcd(mmc) > 0)
561                         mmc_init(mmc);
562         }
563         return 0;
564 }
565 #endif /* CONFIG_CMD_MMC */
566
567 #ifdef CONFIG_FEC_MXC
568
569 #define FEC_PAD_CTL     (PAD_CTL_DVS | PAD_CTL_DSE_HIGH | \
570                         PAD_CTL_SRE_FAST)
571 #define FEC_PAD_CTL2    (PAD_CTL_DVS | PAD_CTL_SRE_FAST)
572 #define GPIO_PAD_CTL    (PAD_CTL_DVS | PAD_CTL_DSE_HIGH)
573
574 #ifndef ETH_ALEN
575 #define ETH_ALEN 6
576 #endif
577
578 int board_eth_init(bd_t *bis)
579 {
580         int ret;
581
582         /* delay at least 21ms for the PHY internal POR signal to deassert */
583         udelay(22000);
584
585         imx_iomux_v3_setup_multiple_pads(tx6qdl_fec_pads, ARRAY_SIZE(tx6qdl_fec_pads));
586
587         /* Deassert RESET to the external phy */
588         gpio_set_value(TX6_FEC_RST_GPIO, 1);
589
590         ret = cpu_eth_init(bis);
591         if (ret)
592                 printf("cpu_eth_init() failed: %d\n", ret);
593
594         return ret;
595 }
596 #endif /* CONFIG_FEC_MXC */
597
598 enum {
599         LED_STATE_INIT = -1,
600         LED_STATE_OFF,
601         LED_STATE_ON,
602 };
603
604 static inline int calc_blink_rate(int tmp)
605 {
606         return CONFIG_SYS_HZ + CONFIG_SYS_HZ / 10 -
607                 (tmp - TEMPERATURE_MIN) * CONFIG_SYS_HZ /
608                 (TEMPERATURE_HOT - TEMPERATURE_MIN);
609 }
610
611 void show_activity(int arg)
612 {
613         static int led_state = LED_STATE_INIT;
614         static int blink_rate;
615         static ulong last;
616
617         if (led_state == LED_STATE_INIT) {
618                 last = get_timer(0);
619                 gpio_set_value(TX6_LED_GPIO, 1);
620                 led_state = LED_STATE_ON;
621                 blink_rate = calc_blink_rate(check_cpu_temperature(0));
622         } else {
623                 if (get_timer(last) > blink_rate) {
624                         blink_rate = calc_blink_rate(check_cpu_temperature(0));
625                         last = get_timer_masked();
626                         if (led_state == LED_STATE_ON) {
627                                 gpio_set_value(TX6_LED_GPIO, 0);
628                         } else {
629                                 gpio_set_value(TX6_LED_GPIO, 1);
630                         }
631                         led_state = 1 - led_state;
632                 }
633         }
634 }
635
636 static const iomux_v3_cfg_t stk5_pads[] = {
637         /* SW controlled LED on STK5 baseboard */
638         MX6_PAD_EIM_A18__GPIO_2_20,
639
640         /* I2C bus on DIMM pins 40/41 */
641         MX6_PAD_GPIO_6__I2C3_SDA,
642         MX6_PAD_GPIO_3__I2C3_SCL,
643
644         /* TSC200x PEN IRQ */
645         MX6_PAD_EIM_D26__GPIO_3_26,
646
647         /* EDT-FT5x06 Polytouch panel */
648         MX6_PAD_NANDF_CS2__GPIO_6_15, /* IRQ */
649         MX6_PAD_EIM_A16__GPIO_2_22, /* RESET */
650         MX6_PAD_EIM_A17__GPIO_2_21, /* WAKE */
651
652         /* USBH1 */
653         MX6_PAD_EIM_D31__GPIO_3_31, /* VBUSEN */
654         MX6_PAD_EIM_D30__GPIO_3_30, /* OC */
655         /* USBOTG */
656         MX6_PAD_EIM_D23__GPIO_3_23, /* USBOTG ID */
657         MX6_PAD_GPIO_7__GPIO_1_7, /* VBUSEN */
658         MX6_PAD_GPIO_8__GPIO_1_8, /* OC */
659 };
660
661 static const struct gpio stk5_gpios[] = {
662         { TX6_LED_GPIO, GPIOF_OUTPUT_INIT_LOW, "HEARTBEAT LED", },
663
664         { IMX_GPIO_NR(3, 23), GPIOF_INPUT, "USBOTG ID", },
665         { IMX_GPIO_NR(1, 8), GPIOF_INPUT, "USBOTG OC", },
666         { IMX_GPIO_NR(1, 7), GPIOF_OUTPUT_INIT_LOW, "USBOTG VBUS enable", },
667         { IMX_GPIO_NR(3, 30), GPIOF_INPUT, "USBH1 OC", },
668         { IMX_GPIO_NR(3, 31), GPIOF_OUTPUT_INIT_LOW, "USBH1 VBUS enable", },
669 };
670
671 #ifdef CONFIG_LCD
672 static u16 tx6_cmap[256];
673 vidinfo_t panel_info = {
674         /* set to max. size supported by SoC */
675         .vl_col = 1920,
676         .vl_row = 1080,
677
678         .vl_bpix = LCD_COLOR24,    /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */
679         .cmap = tx6_cmap,
680 };
681
682 static struct fb_videomode tx6_fb_modes[] = {
683 #ifndef CONFIG_SYS_LVDS_IF
684         {
685                 /* Standard VGA timing */
686                 .name           = "VGA",
687                 .refresh        = 60,
688                 .xres           = 640,
689                 .yres           = 480,
690                 .pixclock       = KHZ2PICOS(25175),
691                 .left_margin    = 48,
692                 .hsync_len      = 96,
693                 .right_margin   = 16,
694                 .upper_margin   = 31,
695                 .vsync_len      = 2,
696                 .lower_margin   = 12,
697                 .sync           = FB_SYNC_CLK_LAT_FALL,
698         },
699         {
700                 /* Emerging ETV570 640 x 480 display. Syncs low active,
701                  * DE high active, 115.2 mm x 86.4 mm display area
702                  * VGA compatible timing
703                  */
704                 .name           = "ETV570",
705                 .refresh        = 60,
706                 .xres           = 640,
707                 .yres           = 480,
708                 .pixclock       = KHZ2PICOS(25175),
709                 .left_margin    = 114,
710                 .hsync_len      = 30,
711                 .right_margin   = 16,
712                 .upper_margin   = 32,
713                 .vsync_len      = 3,
714                 .lower_margin   = 10,
715                 .sync           = FB_SYNC_CLK_LAT_FALL,
716         },
717         {
718                 /* Emerging ET0350G0DH6 320 x 240 display.
719                  * 70.08 mm x 52.56 mm display area.
720                  */
721                 .name           = "ET0350",
722                 .refresh        = 60,
723                 .xres           = 320,
724                 .yres           = 240,
725                 .pixclock       = KHZ2PICOS(6500),
726                 .left_margin    = 68 - 34,
727                 .hsync_len      = 34,
728                 .right_margin   = 20,
729                 .upper_margin   = 18 - 3,
730                 .vsync_len      = 3,
731                 .lower_margin   = 4,
732                 .sync           = FB_SYNC_CLK_LAT_FALL,
733         },
734         {
735                 /* Emerging ET0430G0DH6 480 x 272 display.
736                  * 95.04 mm x 53.856 mm display area.
737                  */
738                 .name           = "ET0430",
739                 .refresh        = 60,
740                 .xres           = 480,
741                 .yres           = 272,
742                 .pixclock       = KHZ2PICOS(9000),
743                 .left_margin    = 2,
744                 .hsync_len      = 41,
745                 .right_margin   = 2,
746                 .upper_margin   = 2,
747                 .vsync_len      = 10,
748                 .lower_margin   = 2,
749                 .sync           = FB_SYNC_CLK_LAT_FALL,
750         },
751         {
752                 /* Emerging ET0500G0DH6 800 x 480 display.
753                  * 109.6 mm x 66.4 mm display area.
754                  */
755                 .name           = "ET0500",
756                 .refresh        = 60,
757                 .xres           = 800,
758                 .yres           = 480,
759                 .pixclock       = KHZ2PICOS(33260),
760                 .left_margin    = 216 - 128,
761                 .hsync_len      = 128,
762                 .right_margin   = 1056 - 800 - 216,
763                 .upper_margin   = 35 - 2,
764                 .vsync_len      = 2,
765                 .lower_margin   = 525 - 480 - 35,
766                 .sync           = FB_SYNC_CLK_LAT_FALL,
767         },
768         {
769                 /* Emerging ETQ570G0DH6 320 x 240 display.
770                  * 115.2 mm x 86.4 mm display area.
771                  */
772                 .name           = "ETQ570",
773                 .refresh        = 60,
774                 .xres           = 320,
775                 .yres           = 240,
776                 .pixclock       = KHZ2PICOS(6400),
777                 .left_margin    = 38,
778                 .hsync_len      = 30,
779                 .right_margin   = 30,
780                 .upper_margin   = 16, /* 15 according to datasheet */
781                 .vsync_len      = 3, /* TVP -> 1>x>5 */
782                 .lower_margin   = 4, /* 4.5 according to datasheet */
783                 .sync           = FB_SYNC_CLK_LAT_FALL,
784         },
785         {
786                 /* Emerging ET0700G0DH6 800 x 480 display.
787                  * 152.4 mm x 91.44 mm display area.
788                  */
789                 .name           = "ET0700",
790                 .refresh        = 60,
791                 .xres           = 800,
792                 .yres           = 480,
793                 .pixclock       = KHZ2PICOS(33260),
794                 .left_margin    = 216 - 128,
795                 .hsync_len      = 128,
796                 .right_margin   = 1056 - 800 - 216,
797                 .upper_margin   = 35 - 2,
798                 .vsync_len      = 2,
799                 .lower_margin   = 525 - 480 - 35,
800                 .sync           = FB_SYNC_CLK_LAT_FALL,
801         },
802         {
803                 /* Emerging ET070001DM6 800 x 480 display.
804                  * 152.4 mm x 91.44 mm display area.
805                  */
806                 .name           = "ET070001DM6",
807                 .refresh        = 60,
808                 .xres           = 800,
809                 .yres           = 480,
810                 .pixclock       = KHZ2PICOS(33260),
811                 .left_margin    = 216 - 128,
812                 .hsync_len      = 128,
813                 .right_margin   = 1056 - 800 - 216,
814                 .upper_margin   = 35 - 2,
815                 .vsync_len      = 2,
816                 .lower_margin   = 525 - 480 - 35,
817                 .sync           = 0,
818         },
819 #else
820         {
821                 /* HannStar HSD100PXN1
822                  * 202.7m mm x 152.06 mm display area.
823                  */
824                 .name           = "HSD100PXN1",
825                 .refresh        = 60,
826                 .xres           = 1024,
827                 .yres           = 768,
828                 .pixclock       = KHZ2PICOS(65000),
829                 .left_margin    = 0,
830                 .hsync_len      = 0,
831                 .right_margin   = 320,
832                 .upper_margin   = 0,
833                 .vsync_len      = 0,
834                 .lower_margin   = 38,
835                 .sync           = FB_SYNC_CLK_LAT_FALL,
836         },
837 #endif
838         {
839                 /* unnamed entry for assigning parameters parsed from 'video_mode' string */
840                 .refresh        = 60,
841                 .left_margin    = 48,
842                 .hsync_len      = 96,
843                 .right_margin   = 16,
844                 .upper_margin   = 31,
845                 .vsync_len      = 2,
846                 .lower_margin   = 12,
847                 .sync           = FB_SYNC_CLK_LAT_FALL,
848         },
849 };
850
851 static int lcd_enabled = 1;
852 static int lcd_bl_polarity;
853
854 static int lcd_backlight_polarity(void)
855 {
856         return lcd_bl_polarity;
857 }
858
859 void lcd_enable(void)
860 {
861         /* HACK ALERT:
862          * global variable from common/lcd.c
863          * Set to 0 here to prevent messages from going to LCD
864          * rather than serial console
865          */
866         lcd_is_enabled = 0;
867
868         karo_load_splashimage(1);
869
870         if (lcd_enabled) {
871                 debug("Switching LCD on\n");
872                 gpio_set_value(TX6_LCD_PWR_GPIO, 1);
873                 udelay(100);
874                 gpio_set_value(TX6_LCD_RST_GPIO, 1);
875                 udelay(300000);
876                 gpio_set_value(TX6_LCD_BACKLIGHT_GPIO,
877                         lcd_backlight_polarity());
878         }
879 }
880
881 void lcd_disable(void)
882 {
883         if (lcd_enabled) {
884                 printf("Disabling LCD\n");
885                 ipuv3_fb_shutdown();
886         }
887 }
888
889 void lcd_panel_disable(void)
890 {
891         if (lcd_enabled) {
892                 debug("Switching LCD off\n");
893                 gpio_set_value(TX6_LCD_BACKLIGHT_GPIO,
894                         !lcd_backlight_polarity());
895                 gpio_set_value(TX6_LCD_RST_GPIO, 0);
896                 gpio_set_value(TX6_LCD_PWR_GPIO, 0);
897         }
898 }
899
900 static const iomux_v3_cfg_t stk5_lcd_pads[] = {
901         /* LCD RESET */
902         MX6_PAD_EIM_D29__GPIO_3_29,
903         /* LCD POWER_ENABLE */
904         MX6_PAD_EIM_EB3__GPIO_2_31,
905         /* LCD Backlight (PWM) */
906         MX6_PAD_GPIO_1__GPIO_1_1,
907
908 #ifndef CONFIG_SYS_LVDS_IF
909         /* Display */
910         MX6_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0,
911         MX6_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1,
912         MX6_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2,
913         MX6_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3,
914         MX6_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4,
915         MX6_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5,
916         MX6_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6,
917         MX6_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7,
918         MX6_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8,
919         MX6_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9,
920         MX6_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10,
921         MX6_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11,
922         MX6_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12,
923         MX6_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13,
924         MX6_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14,
925         MX6_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15,
926         MX6_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16,
927         MX6_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17,
928         MX6_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18,
929         MX6_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19,
930         MX6_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20,
931         MX6_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21,
932         MX6_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22,
933         MX6_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23,
934         MX6_PAD_DI0_PIN2__IPU1_DI0_PIN2, /* HSYNC */
935         MX6_PAD_DI0_PIN3__IPU1_DI0_PIN3, /* VSYNC */
936         MX6_PAD_DI0_PIN15__IPU1_DI0_PIN15, /* OE_ACD */
937         MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK, /* LSCLK */
938 #endif
939 };
940
941 static const struct gpio stk5_lcd_gpios[] = {
942         { TX6_LCD_RST_GPIO, GPIOF_OUTPUT_INIT_LOW, "LCD RESET", },
943         { TX6_LCD_PWR_GPIO, GPIOF_OUTPUT_INIT_LOW, "LCD POWER", },
944         { TX6_LCD_BACKLIGHT_GPIO, GPIOF_OUTPUT_INIT_HIGH, "LCD BACKLIGHT", },
945 };
946
947 void lcd_ctrl_init(void *lcdbase)
948 {
949         int color_depth = 24;
950         const char *video_mode = karo_get_vmode(getenv("video_mode"));
951         const char *vm;
952         unsigned long val;
953         int refresh = 60;
954         struct fb_videomode *p = &tx6_fb_modes[0];
955         struct fb_videomode fb_mode;
956         int xres_set = 0, yres_set = 0, bpp_set = 0, refresh_set = 0;
957         int pix_fmt;
958         int lcd_bus_width;
959         unsigned long di_clk_rate = 65000000;
960
961         if (!lcd_enabled) {
962                 debug("LCD disabled\n");
963                 return;
964         }
965
966         if (had_ctrlc() || (wrsr & WRSR_TOUT)) {
967                 debug("Disabling LCD\n");
968                 lcd_enabled = 0;
969                 setenv("splashimage", NULL);
970                 return;
971         }
972
973         karo_fdt_move_fdt();
974         lcd_bl_polarity = karo_fdt_get_backlight_polarity(working_fdt);
975
976         if (video_mode == NULL) {
977                 debug("Disabling LCD\n");
978                 lcd_enabled = 0;
979                 return;
980         }
981         vm = video_mode;
982         if (karo_fdt_get_fb_mode(working_fdt, video_mode, &fb_mode) == 0) {
983                 p = &fb_mode;
984                 debug("Using video mode from FDT\n");
985                 vm += strlen(vm);
986                 if (fb_mode.xres > panel_info.vl_col ||
987                         fb_mode.yres > panel_info.vl_row) {
988                         printf("video resolution from DT: %dx%d exceeds hardware limits: %dx%d\n",
989                                 fb_mode.xres, fb_mode.yres,
990                                 panel_info.vl_col, panel_info.vl_row);
991                         lcd_enabled = 0;
992                         return;
993                 }
994         }
995         if (p->name != NULL)
996                 debug("Trying compiled-in video modes\n");
997         while (p->name != NULL) {
998                 if (strcmp(p->name, vm) == 0) {
999                         debug("Using video mode: '%s'\n", p->name);
1000                         vm += strlen(vm);
1001                         break;
1002                 }
1003                 p++;
1004         }
1005         if (*vm != '\0')
1006                 debug("Trying to decode video_mode: '%s'\n", vm);
1007         while (*vm != '\0') {
1008                 if (*vm >= '0' && *vm <= '9') {
1009                         char *end;
1010
1011                         val = simple_strtoul(vm, &end, 0);
1012                         if (end > vm) {
1013                                 if (!xres_set) {
1014                                         if (val > panel_info.vl_col)
1015                                                 val = panel_info.vl_col;
1016                                         p->xres = val;
1017                                         panel_info.vl_col = val;
1018                                         xres_set = 1;
1019                                 } else if (!yres_set) {
1020                                         if (val > panel_info.vl_row)
1021                                                 val = panel_info.vl_row;
1022                                         p->yres = val;
1023                                         panel_info.vl_row = val;
1024                                         yres_set = 1;
1025                                 } else if (!bpp_set) {
1026                                         switch (val) {
1027                                         case 32:
1028                                         case 24:
1029                                                 if (is_lvds())
1030                                                         pix_fmt = IPU_PIX_FMT_LVDS888;
1031                                                 /* fallthru */
1032                                         case 16:
1033                                         case 8:
1034                                                 color_depth = val;
1035                                                 break;
1036
1037                                         case 18:
1038                                                 if (is_lvds()) {
1039                                                         color_depth = val;
1040                                                         break;
1041                                                 }
1042                                                 /* fallthru */
1043                                         default:
1044                                                 printf("Invalid color depth: '%.*s' in video_mode; using default: '%u'\n",
1045                                                         end - vm, vm, color_depth);
1046                                         }
1047                                         bpp_set = 1;
1048                                 } else if (!refresh_set) {
1049                                         refresh = val;
1050                                         refresh_set = 1;
1051                                 }
1052                         }
1053                         vm = end;
1054                 }
1055                 switch (*vm) {
1056                 case '@':
1057                         bpp_set = 1;
1058                         /* fallthru */
1059                 case '-':
1060                         yres_set = 1;
1061                         /* fallthru */
1062                 case 'x':
1063                         xres_set = 1;
1064                         /* fallthru */
1065                 case 'M':
1066                 case 'R':
1067                         vm++;
1068                         break;
1069
1070                 default:
1071                         if (*vm != '\0')
1072                                 vm++;
1073                 }
1074         }
1075         if (p->xres == 0 || p->yres == 0) {
1076                 printf("Invalid video mode: %s\n", getenv("video_mode"));
1077                 lcd_enabled = 0;
1078                 printf("Supported video modes are:");
1079                 for (p = &tx6_fb_modes[0]; p->name != NULL; p++) {
1080                         printf(" %s", p->name);
1081                 }
1082                 printf("\n");
1083                 return;
1084         }
1085         if (p->xres > panel_info.vl_col || p->yres > panel_info.vl_row) {
1086                 printf("video resolution: %dx%d exceeds hardware limits: %dx%d\n",
1087                         p->xres, p->yres, panel_info.vl_col, panel_info.vl_row);
1088                 lcd_enabled = 0;
1089                 return;
1090         }
1091         panel_info.vl_col = p->xres;
1092         panel_info.vl_row = p->yres;
1093
1094         switch (color_depth) {
1095         case 8:
1096                 panel_info.vl_bpix = LCD_COLOR8;
1097                 break;
1098         case 16:
1099                 panel_info.vl_bpix = LCD_COLOR16;
1100                 break;
1101         default:
1102                 panel_info.vl_bpix = LCD_COLOR24;
1103         }
1104
1105         p->pixclock = KHZ2PICOS(refresh *
1106                 (p->xres + p->left_margin + p->right_margin + p->hsync_len) *
1107                 (p->yres + p->upper_margin + p->lower_margin + p->vsync_len) /
1108                                 1000);
1109         debug("Pixel clock set to %lu.%03lu MHz\n",
1110                 PICOS2KHZ(p->pixclock) / 1000, PICOS2KHZ(p->pixclock) % 1000);
1111
1112         if (p != &fb_mode) {
1113                 int ret;
1114
1115                 debug("Creating new display-timing node from '%s'\n",
1116                         video_mode);
1117                 ret = karo_fdt_create_fb_mode(working_fdt, video_mode, p);
1118                 if (ret)
1119                         printf("Failed to create new display-timing node from '%s': %d\n",
1120                                 video_mode, ret);
1121         }
1122
1123         gpio_request_array(stk5_lcd_gpios, ARRAY_SIZE(stk5_lcd_gpios));
1124         imx_iomux_v3_setup_multiple_pads(stk5_lcd_pads,
1125                                         ARRAY_SIZE(stk5_lcd_pads));
1126
1127         lcd_bus_width = karo_fdt_get_lcd_bus_width(working_fdt, 24);
1128         switch (lcd_bus_width) {
1129         case 24:
1130                 pix_fmt = is_lvds() ? IPU_PIX_FMT_LVDS888 : IPU_PIX_FMT_RGB24;
1131                 break;
1132
1133         case 18:
1134                 pix_fmt = is_lvds() ? IPU_PIX_FMT_LVDS666 : IPU_PIX_FMT_RGB666;
1135                 break;
1136
1137         case 16:
1138                 if (!is_lvds()) {
1139                         pix_fmt = IPU_PIX_FMT_RGB565;
1140                         break;
1141                 }
1142                 /* fallthru */
1143         default:
1144                 lcd_enabled = 0;
1145                 printf("Invalid %s bus width: %d\n", is_lvds() ? "LVDS" : "LCD",
1146                         lcd_bus_width);
1147                 return;
1148         }
1149         if (is_lvds()) {
1150                 int lvds_mapping = karo_fdt_get_lvds_mapping(working_fdt, 0);
1151                 int lvds_chan_mask = karo_fdt_get_lvds_channels(working_fdt);
1152                 uint32_t gpr2;
1153
1154                 if (lvds_chan_mask == 0) {
1155                         printf("No LVDS channel active\n");
1156                         lcd_enabled = 0;
1157                         return;
1158                 }
1159
1160                 gpr2 = (lvds_mapping << 6) | (lvds_mapping << 8);
1161                 if (lcd_bus_width == 24)
1162                         gpr2 |= (1 << 5) | (1 << 7);
1163                 gpr2 |= (lvds_chan_mask & 1) ? 1 << 0 : 0;
1164                 gpr2 |= (lvds_chan_mask & 2) ? 3 << 2 : 0;
1165                 debug("writing %08x to GPR2[%08x]\n", gpr2, IOMUXC_BASE_ADDR + 8);
1166                 writel(gpr2, IOMUXC_BASE_ADDR + 8);
1167         }
1168         if (karo_load_splashimage(0) == 0) {
1169                 int ret;
1170
1171                 debug("Initializing LCD controller\n");
1172                 ret = ipuv3_fb_init(p, 0, pix_fmt, DI_PCLK_PLL3, di_clk_rate, -1);
1173                 if (ret) {
1174                         printf("Failed to initialize FB driver: %d\n", ret);
1175                         lcd_enabled = 0;
1176                 }
1177         } else {
1178                 debug("Skipping initialization of LCD controller\n");
1179         }
1180 }
1181 #else
1182 #define lcd_enabled 0
1183 #endif /* CONFIG_LCD */
1184
1185 static void stk5_board_init(void)
1186 {
1187         gpio_request_array(stk5_gpios, ARRAY_SIZE(stk5_gpios));
1188         imx_iomux_v3_setup_multiple_pads(stk5_pads, ARRAY_SIZE(stk5_pads));
1189 }
1190
1191 static void stk5v3_board_init(void)
1192 {
1193         stk5_board_init();
1194 }
1195
1196 static void stk5v5_board_init(void)
1197 {
1198         stk5_board_init();
1199
1200         gpio_request_one(IMX_GPIO_NR(4, 21), GPIOF_OUTPUT_INIT_HIGH,
1201                         "Flexcan Transceiver");
1202         imx_iomux_v3_setup_pad(MX6_PAD_DISP0_DAT0__GPIO_4_21);
1203 }
1204
1205 static void tx6qdl_set_cpu_clock(void)
1206 {
1207         unsigned long cpu_clk = getenv_ulong("cpu_clk", 10, 0);
1208
1209         if (had_ctrlc() || (wrsr & WRSR_TOUT))
1210                 return;
1211
1212         if (cpu_clk == 0 || cpu_clk == mxc_get_clock(MXC_ARM_CLK) / 1000000)
1213                 return;
1214
1215         if (mxc_set_clock(CONFIG_SYS_MX6_HCLK, cpu_clk, MXC_ARM_CLK) == 0) {
1216                 cpu_clk = mxc_get_clock(MXC_ARM_CLK);
1217                 printf("CPU clock set to %lu.%03lu MHz\n",
1218                         cpu_clk / 1000000, cpu_clk / 1000 % 1000);
1219         } else {
1220                 printf("Error: Failed to set CPU clock to %lu MHz\n", cpu_clk);
1221         }
1222 }
1223
1224 static void tx6_init_mac(void)
1225 {
1226         u8 mac[ETH_ALEN];
1227
1228         imx_get_mac_from_fuse(-1, mac);
1229         if (!is_valid_ether_addr(mac)) {
1230                 printf("No valid MAC address programmed\n");
1231                 return;
1232         }
1233
1234         printf("MAC addr from fuse: %pM\n", mac);
1235         eth_setenv_enetaddr("ethaddr", mac);
1236 }
1237
1238 int board_late_init(void)
1239 {
1240         int ret = 0;
1241         const char *baseboard;
1242
1243         tx6qdl_set_cpu_clock();
1244         karo_fdt_move_fdt();
1245
1246         baseboard = getenv("baseboard");
1247         if (!baseboard)
1248                 goto exit;
1249
1250         printf("Baseboard: %s\n", baseboard);
1251
1252         if (strncmp(baseboard, "stk5", 4) == 0) {
1253                 if ((strlen(baseboard) == 4) ||
1254                         strcmp(baseboard, "stk5-v3") == 0) {
1255                         stk5v3_board_init();
1256                 } else if (strcmp(baseboard, "stk5-v5") == 0) {
1257                         const char *otg_mode = getenv("otg_mode");
1258
1259                         if (otg_mode && strcmp(otg_mode, "host") == 0) {
1260                                 printf("otg_mode='%s' is incompatible with baseboard %s; setting to 'none'\n",
1261                                         otg_mode, baseboard);
1262                                 setenv("otg_mode", "none");
1263                         }
1264                         stk5v5_board_init();
1265                 } else {
1266                         printf("WARNING: Unsupported STK5 board rev.: %s\n",
1267                                 baseboard + 4);
1268                 }
1269         } else {
1270                 printf("WARNING: Unsupported baseboard: '%s'\n",
1271                         baseboard);
1272                 ret = -EINVAL;
1273         }
1274
1275 exit:
1276         tx6_init_mac();
1277
1278         gpio_set_value(TX6_RESET_OUT_GPIO, 1);
1279         clear_ctrlc();
1280         return ret;
1281 }
1282
1283 int checkboard(void)
1284 {
1285         u32 cpurev = get_cpu_rev();
1286         int cpu_variant = (cpurev >> 12) & 0xff;
1287
1288         tx6qdl_print_cpuinfo();
1289
1290         printf("Board: Ka-Ro TX6%c-%d%d1%d\n",
1291                 cpu_variant == MXC_CPU_MX6Q ? 'Q' : 'U',
1292                 cpu_variant == MXC_CPU_MX6Q ? 1 : 8,
1293                 is_lvds(), 1 - PHYS_SDRAM_1_WIDTH / 64);
1294
1295         return 0;
1296 }
1297
1298 #ifdef CONFIG_SERIAL_TAG
1299 void get_board_serial(struct tag_serialnr *serialnr)
1300 {
1301         struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
1302         struct fuse_bank0_regs *fuse = (void *)ocotp->bank[0].fuse_regs;
1303
1304         serialnr->low = readl(&fuse->cfg0);
1305         serialnr->high = readl(&fuse->cfg1);
1306 }
1307 #endif
1308
1309 #if defined(CONFIG_OF_BOARD_SETUP)
1310 #ifdef CONFIG_FDT_FIXUP_PARTITIONS
1311 #include <jffs2/jffs2.h>
1312 #include <mtd_node.h>
1313 static struct node_info nodes[] = {
1314         { "fsl,imx6q-gpmi-nand", MTD_DEV_TYPE_NAND, },
1315 };
1316 #else
1317 #define fdt_fixup_mtdparts(b,n,c) do { } while (0)
1318 #endif
1319
1320 static const char *tx6_touchpanels[] = {
1321         "ti,tsc2007",
1322         "edt,edt-ft5x06",
1323         "eeti,egalax_ts",
1324 };
1325
1326 void ft_board_setup(void *blob, bd_t *bd)
1327 {
1328         const char *baseboard = getenv("baseboard");
1329         int stk5_v5 = baseboard != NULL && (strcmp(baseboard, "stk5-v5") == 0);
1330         const char *video_mode = karo_get_vmode(getenv("video_mode"));
1331         int ret;
1332
1333         ret = fdt_increase_size(blob, 4096);
1334         if (ret)
1335                 printf("Failed to increase FDT size: %s\n", fdt_strerror(ret));
1336
1337         if (stk5_v5)
1338                 karo_fdt_enable_node(blob, "stk5led", 0);
1339
1340         fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
1341         fdt_fixup_ethernet(blob);
1342
1343         karo_fdt_fixup_touchpanel(blob, tx6_touchpanels,
1344                                 ARRAY_SIZE(tx6_touchpanels));
1345         karo_fdt_fixup_usb_otg(blob, "usbotg", "fsl,usbphy");
1346         karo_fdt_fixup_flexcan(blob, stk5_v5);
1347
1348         karo_fdt_update_fb_mode(blob, video_mode);
1349 }
1350 #endif /* CONFIG_OF_BOARD_SETUP */