1
2
3
4
5
6
7
8#include <common.h>
9#include <asm/arch/clock.h>
10#include <asm/arch/crm_regs.h>
11#include <asm/arch/mx6-pins.h>
12#include <asm/arch/mxc_hdmi.h>
13#include <asm/arch/sys_proto.h>
14#include <asm/global_data.h>
15#include <asm/gpio.h>
16#include <asm/mach-imx/boot_mode.h>
17#include <asm/mach-imx/video.h>
18#include <asm/setup.h>
19#include <env.h>
20#include <hwconfig.h>
21#include <linux/ctype.h>
22#include <miiphy.h>
23#include <mtd_node.h>
24#include <linux/delay.h>
25#include <power/pmic.h>
26#include <fdt_support.h>
27#include <jffs2/load_kernel.h>
28
29#include "gsc.h"
30#include "common.h"
31
32DECLARE_GLOBAL_DATA_PTR;
33
34
35
36
37
38
39struct ventana_board_info ventana_info;
40static int board_type;
41
42
43int board_phy_config(struct phy_device *phydev)
44{
45 unsigned short val;
46
47
48 if (phydev->phy_id == 0x1410dd1) {
49 puts("MV88E1510");
50
51
52
53
54
55 phy_write(phydev, MDIO_DEVAD_NONE, 22, 3);
56 val = phy_read(phydev, MDIO_DEVAD_NONE, 16);
57 val &= 0xff00;
58 val |= 0x0017;
59 phy_write(phydev, MDIO_DEVAD_NONE, 16, val);
60 phy_write(phydev, MDIO_DEVAD_NONE, 22, 0);
61 }
62
63
64 else if (phydev->phy_id == 0x2000a231) {
65 puts("TIDP83867 ");
66
67 val = 0;
68 val |= 0x5 << 4;
69 val |= 0xb << 8;
70 phy_write(phydev, MDIO_DEVAD_NONE, 24, val);
71
72
73 phy_write(phydev, MDIO_DEVAD_NONE, 13, 0x001f);
74 phy_write(phydev, MDIO_DEVAD_NONE, 14, 0x0170);
75 phy_write(phydev, MDIO_DEVAD_NONE, 13, 0x401f);
76 val = phy_read(phydev, MDIO_DEVAD_NONE, 14);
77 val &= ~0x1f00;
78 val |= 0x0b00;
79 phy_write(phydev, MDIO_DEVAD_NONE, 14, val);
80 }
81
82 if (phydev->drv->config)
83 phydev->drv->config(phydev);
84
85 return 0;
86}
87
88#ifdef CONFIG_MV88E61XX_SWITCH
89int mv88e61xx_hw_reset(struct phy_device *phydev)
90{
91 struct mii_dev *bus = phydev->bus;
92
93
94 debug("enabling RGMII_REFCLK\n");
95 bus->write(bus, 0x1c , 0,
96 0x1a ,
97 (1 << 15) | (0x62 << 8) | 0xfe);
98 bus->write(bus, 0x1c , 0,
99 0x1a ,
100 (1 << 15) | (0x68 << 8) | 7);
101
102
103 debug("setting port%d RGMII rx/tx delay\n", CONFIG_MV88E61XX_CPU_PORT);
104
105 bus->write(bus, 0x10 + CONFIG_MV88E61XX_CPU_PORT, 0, 1, 0xc0fe);
106 phydev->autoneg = AUTONEG_DISABLE;
107 phydev->speed = SPEED_1000;
108 phydev->duplex = DUPLEX_FULL;
109
110
111 bus->write(bus, 0x10, 0, 0x16, 0x8088);
112 bus->write(bus, 0x11, 0, 0x16, 0x8088);
113 bus->write(bus, 0x12, 0, 0x16, 0x8088);
114 bus->write(bus, 0x13, 0, 0x16, 0x8088);
115
116 return 0;
117}
118#endif
119
120#if defined(CONFIG_VIDEO_IPUV3)
121static void enable_hdmi(struct display_info_t const *dev)
122{
123 imx_enable_hdmi_phy();
124}
125
126static int detect_lvds(struct display_info_t const *dev)
127{
128
129 switch (board_type) {
130 case GW52xx:
131 case GW53xx:
132 case GW54xx:
133 case GW560x:
134 case GW5905:
135 case GW5909:
136 break;
137 default:
138 return 0;
139 }
140
141 return i2c_set_bus_num(dev->bus) == 0 &&
142 i2c_probe(dev->addr) == 0;
143}
144
145static void enable_lvds(struct display_info_t const *dev)
146{
147 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
148
149
150 u32 reg = readl(&iomux->gpr[2]);
151 reg |= IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT;
152 writel(reg, &iomux->gpr[2]);
153
154
155 switch (board_type) {
156 case GW52xx:
157 case GW53xx:
158 case GW54xx:
159 if (!strncmp(dev->mode.name, "Hannstar", 8)) {
160 SETUP_IOMUX_PAD(PAD_SD2_CLK__GPIO1_IO10 | DIO_PAD_CFG);
161 gpio_request(IMX_GPIO_NR(1, 10), "cabc");
162 gpio_direction_output(IMX_GPIO_NR(1, 10), 0);
163 } else if (!strncmp(dev->mode.name, "DLC", 3)) {
164 SETUP_IOMUX_PAD(PAD_SD2_CLK__GPIO1_IO10 | DIO_PAD_CFG);
165 gpio_request(IMX_GPIO_NR(1, 10), "touch_rst#");
166 gpio_direction_output(IMX_GPIO_NR(1, 10), 1);
167 }
168 break;
169 default:
170 break;
171 }
172
173
174 gpio_request(IMX_GPIO_NR(1, 18), "bklt_en");
175 SETUP_IOMUX_PAD(PAD_SD1_CMD__GPIO1_IO18 | DIO_PAD_CFG);
176 gpio_direction_output(IMX_GPIO_NR(1, 18), 1);
177}
178
179struct display_info_t const displays[] = {{
180
181 .bus = -1,
182 .addr = 0,
183 .pixfmt = IPU_PIX_FMT_RGB24,
184 .detect = detect_hdmi,
185 .enable = enable_hdmi,
186 .mode = {
187 .name = "HDMI",
188 .refresh = 60,
189 .xres = 1024,
190 .yres = 768,
191 .pixclock = 15385,
192 .left_margin = 220,
193 .right_margin = 40,
194 .upper_margin = 21,
195 .lower_margin = 7,
196 .hsync_len = 60,
197 .vsync_len = 10,
198 .sync = FB_SYNC_EXT,
199 .vmode = FB_VMODE_NONINTERLACED
200} }, {
201
202 .bus = 2,
203 .addr = 0x4,
204 .pixfmt = IPU_PIX_FMT_LVDS666,
205 .detect = detect_lvds,
206 .enable = enable_lvds,
207 .mode = {
208 .name = "Hannstar-XGA",
209 .refresh = 60,
210 .xres = 1024,
211 .yres = 768,
212 .pixclock = 15385,
213 .left_margin = 220,
214 .right_margin = 40,
215 .upper_margin = 21,
216 .lower_margin = 7,
217 .hsync_len = 60,
218 .vsync_len = 10,
219 .sync = FB_SYNC_EXT,
220 .vmode = FB_VMODE_NONINTERLACED
221} }, {
222
223 .bus = 2,
224 .addr = 0x38,
225 .detect = detect_lvds,
226 .enable = enable_lvds,
227 .pixfmt = IPU_PIX_FMT_LVDS666,
228 .mode = {
229 .name = "DLC700JMGT4",
230 .refresh = 60,
231 .xres = 1024,
232 .yres = 600,
233 .pixclock = 15385,
234 .left_margin = 220,
235 .right_margin = 40,
236 .upper_margin = 21,
237 .lower_margin = 7,
238 .hsync_len = 60,
239 .vsync_len = 10,
240 .sync = FB_SYNC_EXT,
241 .vmode = FB_VMODE_NONINTERLACED
242} }, {
243
244 .bus = 2,
245 .addr = 0x38,
246 .detect = detect_lvds,
247 .enable = enable_lvds,
248 .pixfmt = IPU_PIX_FMT_LVDS666,
249 .mode = {
250 .name = "DLC0700XDP21LF",
251 .refresh = 60,
252 .xres = 1024,
253 .yres = 600,
254 .pixclock = 15385,
255 .left_margin = 220,
256 .right_margin = 40,
257 .upper_margin = 21,
258 .lower_margin = 7,
259 .hsync_len = 60,
260 .vsync_len = 10,
261 .sync = FB_SYNC_EXT,
262 .vmode = FB_VMODE_NONINTERLACED
263} }, {
264
265 .bus = 2,
266 .addr = 0x14,
267 .detect = detect_lvds,
268 .enable = enable_lvds,
269 .pixfmt = IPU_PIX_FMT_LVDS666,
270 .mode = {
271 .name = "DLC800FIGT3",
272 .refresh = 60,
273 .xres = 1024,
274 .yres = 768,
275 .pixclock = 15385,
276 .left_margin = 220,
277 .right_margin = 40,
278 .upper_margin = 21,
279 .lower_margin = 7,
280 .hsync_len = 60,
281 .vsync_len = 10,
282 .sync = FB_SYNC_EXT,
283 .vmode = FB_VMODE_NONINTERLACED
284} }, {
285 .bus = 2,
286 .addr = 0x5d,
287 .detect = detect_lvds,
288 .enable = enable_lvds,
289 .pixfmt = IPU_PIX_FMT_LVDS666,
290 .mode = {
291 .name = "Z101WX01",
292 .refresh = 60,
293 .xres = 1280,
294 .yres = 800,
295 .pixclock = 15385,
296 .left_margin = 220,
297 .right_margin = 40,
298 .upper_margin = 21,
299 .lower_margin = 7,
300 .hsync_len = 60,
301 .vsync_len = 10,
302 .sync = FB_SYNC_EXT,
303 .vmode = FB_VMODE_NONINTERLACED
304 }
305},
306};
307size_t display_count = ARRAY_SIZE(displays);
308
309static void setup_display(void)
310{
311 struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
312 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
313 int reg;
314
315 enable_ipu_clock();
316 imx_setup_hdmi();
317
318 reg = __raw_readl(&mxc_ccm->CCGR3);
319 reg |= MXC_CCM_CCGR3_LDB_DI0_MASK;
320 writel(reg, &mxc_ccm->CCGR3);
321
322
323 reg = readl(&mxc_ccm->cs2cdr);
324 reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
325 |MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
326 reg |= (3<<MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
327 |(3<<MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
328 writel(reg, &mxc_ccm->cs2cdr);
329
330 reg = readl(&mxc_ccm->cscmr2);
331 reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
332 writel(reg, &mxc_ccm->cscmr2);
333
334 reg = readl(&mxc_ccm->chsccdr);
335 reg |= (CHSCCDR_CLK_SEL_LDB_DI0
336 <<MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
337 writel(reg, &mxc_ccm->chsccdr);
338
339 reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
340 |IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH
341 |IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
342 |IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG
343 |IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT
344 |IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
345 |IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT
346 |IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED
347 |IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0;
348 writel(reg, &iomux->gpr[2]);
349
350 reg = readl(&iomux->gpr[3]);
351 reg = (reg & ~IOMUXC_GPR3_LVDS0_MUX_CTL_MASK)
352 | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
353 <<IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
354 writel(reg, &iomux->gpr[3]);
355}
356#endif
357
358
359int power_init_board(void)
360{
361 setup_pmic();
362 return 0;
363}
364
365
366
367
368
369
370#define MAX_PCI_DEVS 32
371struct pci_dev {
372 pci_dev_t devfn;
373 struct udevice *dev;
374 unsigned short vendor;
375 unsigned short device;
376 unsigned short class;
377 unsigned short busno;
378 struct pci_dev *ppar;
379};
380struct pci_dev pci_devs[MAX_PCI_DEVS];
381int pci_devno;
382int pci_bridgeno;
383
384void board_pci_fixup_dev(struct udevice *bus, struct udevice *udev)
385{
386 struct pci_child_plat *pdata = dev_get_parent_plat(udev);
387 struct pci_dev *pdev = &pci_devs[pci_devno++];
388 unsigned short vendor = pdata->vendor;
389 unsigned short device = pdata->device;
390 unsigned int class = pdata->class;
391 pci_dev_t dev = dm_pci_get_bdf(udev);
392 int i;
393
394 debug("%s: %02d:%02d.%02d: %04x:%04x\n", __func__,
395 PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev), vendor, device);
396
397
398 pdev->dev = udev;
399 pdev->devfn = dev;
400 pdev->vendor = vendor;
401 pdev->device = device;
402 pdev->class = class;
403 pdev->ppar = NULL;
404 if (class == PCI_CLASS_BRIDGE_PCI)
405 pdev->busno = ++pci_bridgeno;
406 else
407 pdev->busno = 0;
408
409
410 if (PCI_BUS(dev) == 0)
411 pdev->devfn = 0;
412
413
414 for (i = 0; i < pci_devno; i++) {
415 if (pci_devs[i].busno == PCI_BUS(pdev->devfn)) {
416 pdev->ppar = &pci_devs[i];
417 break;
418 }
419 }
420
421
422 if (vendor == PCI_VENDOR_ID_PLX &&
423 (device & 0xfff0) == 0x8600 &&
424 PCI_DEV(dev) == 0 && PCI_FUNC(dev) == 0) {
425 ulong val;
426 debug("configuring PLX 860X downstream PERST#\n");
427 pci_bus_read_config(bus, dev, 0x62c, &val, PCI_SIZE_32);
428 val |= 0xaaa8;
429 pci_bus_write_config(bus, dev, 0x62c, val, PCI_SIZE_32);
430
431 pci_bus_read_config(bus, dev, 0x644, &val, PCI_SIZE_32);
432 val |= 0xfe;
433 pci_bus_write_config(bus, dev, 0x644, val, PCI_SIZE_32);
434
435 mdelay(100);
436 }
437}
438
439#ifdef CONFIG_SERIAL_TAG
440
441
442
443
444
445
446void get_board_serial(struct tag_serialnr *serialnr)
447{
448 char *serial = env_get("serial#");
449
450 if (serial) {
451 serialnr->high = 0;
452 serialnr->low = dectoul(serial, NULL);
453 } else if (ventana_info.model[0]) {
454 serialnr->high = 0;
455 serialnr->low = ventana_info.serial;
456 } else {
457 serialnr->high = 0;
458 serialnr->low = 0;
459 }
460}
461#endif
462
463
464
465
466
467int board_early_init_f(void)
468{
469#if defined(CONFIG_VIDEO_IPUV3)
470 setup_display();
471#endif
472 return 0;
473}
474
475int dram_init(void)
476{
477 gd->ram_size = imx_ddr_size();
478 return 0;
479}
480
481int board_init(void)
482{
483 struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
484
485 clrsetbits_le32(&iomuxc_regs->gpr[1],
486 IOMUXC_GPR1_OTG_ID_MASK,
487 IOMUXC_GPR1_OTG_ID_GPIO1);
488
489
490 gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
491
492
493 setup_ventana_i2c(0);
494 board_type = read_eeprom(CONFIG_I2C_GSC, &ventana_info);
495
496 setup_ventana_i2c(1);
497 setup_ventana_i2c(2);
498
499 setup_iomux_gpio(board_type, &ventana_info);
500
501 return 0;
502}
503
504int board_fit_config_name_match(const char *name)
505{
506 static char init;
507 const char *dtb;
508 char buf[32];
509 int i = 0;
510
511 do {
512 dtb = gsc_get_dtb_name(i++, buf, sizeof(buf));
513 if (dtb && !strcmp(dtb, name)) {
514 if (!init++)
515 printf("DTB: %s\n", name);
516 return 0;
517 }
518 } while (dtb);
519
520 return -1;
521}
522
523#if defined(CONFIG_DISPLAY_BOARDINFO_LATE)
524
525
526
527
528
529int checkboard(void)
530{
531 struct ventana_board_info *info = &ventana_info;
532 unsigned char buf[4];
533 const char *p;
534 int quiet;
535
536 quiet = 0;
537 p = env_get("quiet");
538 if (p)
539 quiet = simple_strtol(p, NULL, 10);
540 else
541 env_set("quiet", "0");
542
543 puts("\nGateworks Corporation Copyright 2014\n");
544 if (info->model[0]) {
545 printf("Model: %s\n", info->model);
546 printf("MFGDate: %02x-%02x-%02x%02x\n",
547 info->mfgdate[0], info->mfgdate[1],
548 info->mfgdate[2], info->mfgdate[3]);
549 printf("Serial:%d\n", info->serial);
550 } else {
551 puts("Invalid EEPROM - board will not function fully\n");
552 }
553 if (quiet)
554 return 0;
555
556
557 gsc_info(0);
558
559
560 if (!gsc_i2c_read(GSC_RTC_ADDR, 0x00, 1, buf, 4)) {
561 printf("RTC: %d\n",
562 buf[0] | buf[1]<<8 | buf[2]<<16 | buf[3]<<24);
563 }
564
565 return 0;
566}
567#endif
568
569#ifdef CONFIG_CMD_BMODE
570
571
572
573
574
575
576
577
578
579
580
581
582static const struct boot_mode board_boot_modes[] = {
583
584 { "nand", MAKE_CFGVAL(0x80, 0x02, 0x00, 0x00) },
585 { "emmc2", MAKE_CFGVAL(0x60, 0x48, 0x00, 0x00) },
586 { "emmc3", MAKE_CFGVAL(0x60, 0x50, 0x00, 0x00) },
587 { NULL, 0 },
588};
589#endif
590
591
592int misc_init_r(void)
593{
594 struct ventana_board_info *info = &ventana_info;
595 char buf[256];
596 int i;
597
598
599 if (ventana_info.model[0]) {
600 char str[16], fdt[36];
601 char *p;
602 const char *cputype = "";
603
604
605
606
607
608
609
610 if (is_cpu_type(MXC_CPU_MX6Q) ||
611 is_cpu_type(MXC_CPU_MX6D))
612 cputype = "imx6q";
613 else if (is_cpu_type(MXC_CPU_MX6DL) ||
614 is_cpu_type(MXC_CPU_MX6SOLO))
615 cputype = "imx6dl";
616 env_set("soctype", cputype);
617 if (8 << (ventana_info.nand_flash_size-1) >= 2048)
618 env_set("flash_layout", "large");
619 else
620 env_set("flash_layout", "normal");
621 memset(str, 0, sizeof(str));
622 for (i = 0; i < (sizeof(str)-1) && info->model[i]; i++)
623 str[i] = tolower(info->model[i]);
624 env_set("model", str);
625 if (!env_get("fdt_file")) {
626 sprintf(fdt, "%s-%s.dtb", cputype, str);
627 env_set("fdt_file", fdt);
628 }
629 p = strchr(str, '-');
630 if (p) {
631 *p++ = 0;
632
633 env_set("model_base", str);
634 sprintf(fdt, "%s-%s.dtb", cputype, str);
635 env_set("fdt_file1", fdt);
636 if (board_type != GW551x &&
637 board_type != GW552x &&
638 board_type != GW553x &&
639 board_type != GW560x)
640 str[4] = 'x';
641 str[5] = 'x';
642 str[6] = 0;
643 sprintf(fdt, "%s-%s.dtb", cputype, str);
644 env_set("fdt_file2", fdt);
645 }
646
647
648 if (test_bit(EECONFIG_ETH0, info->config) &&
649 !env_get("ethaddr")) {
650 eth_env_set_enetaddr("ethaddr", info->mac0);
651 }
652 if (test_bit(EECONFIG_ETH1, info->config) &&
653 !env_get("eth1addr")) {
654 eth_env_set_enetaddr("eth1addr", info->mac1);
655 }
656
657
658 sprintf(str, "%6d", info->serial);
659 env_set("serial#", str);
660
661
662 sprintf(str, "%d", (int) (gd->ram_size >> 20));
663 env_set("mem_mb", str);
664 }
665
666
667 if (!strcmp(env_get("hwconfig"), "_UNKNOWN_")) {
668 buf[0] = 0;
669 if (gpio_cfg[board_type].rs232_en)
670 strcat(buf, "rs232;");
671 for (i = 0; i < gpio_cfg[board_type].dio_num; i++) {
672 char buf1[32];
673 sprintf(buf1, "dio%d:mode=gpio;", i);
674 if (strlen(buf) + strlen(buf1) < sizeof(buf))
675 strcat(buf, buf1);
676 }
677 env_set("hwconfig", buf);
678 }
679
680
681 setup_board_gpio(board_type, info);
682
683#ifdef CONFIG_CMD_BMODE
684 add_board_boot_modes(board_boot_modes);
685#endif
686
687
688 gsc_boot_wd_disable();
689
690 return 0;
691}
692
693#ifdef CONFIG_OF_BOARD_SETUP
694
695static int ft_sethdmiinfmt(void *blob, char *mode)
696{
697 int off;
698
699 if (!mode)
700 return -EINVAL;
701
702 off = fdt_node_offset_by_compatible(blob, -1, "nxp,tda1997x");
703 if (off < 0)
704 return off;
705
706 if (0 == strcasecmp(mode, "yuv422bt656")) {
707 u8 cfg[] = { 0x00, 0x00, 0x00, 0x82, 0x81, 0x00,
708 0x00, 0x00, 0x00 };
709 mode = "422_ccir";
710 fdt_setprop(blob, off, "vidout_fmt", mode, strlen(mode) + 1);
711 fdt_setprop_u32(blob, off, "vidout_trc", 1);
712 fdt_setprop_u32(blob, off, "vidout_blc", 1);
713 fdt_setprop(blob, off, "vidout_portcfg", cfg, sizeof(cfg));
714 printf(" set HDMI input mode to %s\n", mode);
715 } else if (0 == strcasecmp(mode, "yuv422smp")) {
716 u8 cfg[] = { 0x00, 0x00, 0x00, 0x88, 0x87, 0x00,
717 0x82, 0x81, 0x00 };
718 mode = "422_smp";
719 fdt_setprop(blob, off, "vidout_fmt", mode, strlen(mode) + 1);
720 fdt_setprop_u32(blob, off, "vidout_trc", 0);
721 fdt_setprop_u32(blob, off, "vidout_blc", 0);
722 fdt_setprop(blob, off, "vidout_portcfg", cfg, sizeof(cfg));
723 printf(" set HDMI input mode to %s\n", mode);
724 } else {
725 return -EINVAL;
726 }
727
728 return 0;
729}
730
731#if defined(CONFIG_CMD_PCI)
732#define PCI_ID(x) ( \
733 (PCI_BUS(x->devfn)<<16)| \
734 (PCI_DEV(x->devfn)<<11)| \
735 (PCI_FUNC(x->devfn)<<8) \
736 )
737int fdt_add_pci_node(void *blob, int par, struct pci_dev *dev)
738{
739 uint32_t reg[5];
740 char node[32];
741 int np;
742
743 sprintf(node, "pcie@%d,%d,%d", PCI_BUS(dev->devfn),
744 PCI_DEV(dev->devfn), PCI_FUNC(dev->devfn));
745
746 np = fdt_subnode_offset(blob, par, node);
747 if (np >= 0)
748 return np;
749 np = fdt_add_subnode(blob, par, node);
750 if (np < 0) {
751 printf(" %s failed: no space\n", __func__);
752 return np;
753 }
754
755 memset(reg, 0, sizeof(reg));
756 reg[0] = cpu_to_fdt32(PCI_ID(dev));
757 fdt_setprop(blob, np, "reg", reg, sizeof(reg));
758
759 return np;
760}
761
762
763int fdt_add_pci_path(void *blob, struct pci_dev *dev)
764{
765 struct pci_dev *bridges[MAX_PCI_DEVS];
766 int k, np;
767
768
769 np = fdt_node_offset_by_compatible(blob, -1, "fsl,imx6q-pcie");
770 if (np < 0)
771 return np;
772
773 k = 0;
774 while (dev) {
775 bridges[k++] = dev;
776 dev = dev->ppar;
777 };
778
779
780 while (k--) {
781 np = fdt_add_pci_node(blob, np, bridges[k]);
782 if (np < 0)
783 break;
784 }
785
786 return np;
787}
788
789
790
791
792
793
794
795int fdt_fixup_gw16082(void *blob, int np, struct pci_dev *dev)
796{
797 int len;
798 int host;
799 uint32_t imap_new[8*4*4];
800 const uint32_t *imap;
801 uint32_t irq[4];
802 uint32_t reg[4];
803 int i;
804
805
806 host = fdt_node_offset_by_compatible(blob, -1, "fsl,imx6q-pcie");
807 if (host < 0) {
808 printf(" %s failed: missing host\n", __func__);
809 return host;
810 }
811
812
813 imap = fdt_getprop(blob, host, "interrupt-map", &len);
814 if (!imap || len != 128) {
815 printf(" %s failed: invalid interrupt-map\n",
816 __func__);
817 return -FDT_ERR_NOTFOUND;
818 }
819
820
821 for (i = 0; i < 4; i++)
822 irq[(fdt32_to_cpu(imap[(i*8)+3])-1)%4] = imap[(i*8)+6];
823
824
825
826
827
828
829 struct pci_dev *d;
830 int b;
831 b = 0;
832 d = dev->ppar;
833 while(d && d->ppar) {
834 b += PCI_DEV(d->devfn);
835 d = d->ppar;
836 }
837
838
839
840
841
842
843
844
845 for (i = 0; i < 4; i++) {
846
847 u32 addr = dev->busno << 16 | (12+i) << 11;
848
849
850 memcpy(&imap_new[i*32], imap, 128);
851
852 imap_new[(i*32)+(0*8)+0] = cpu_to_fdt32(addr);
853 imap_new[(i*32)+(1*8)+0] = cpu_to_fdt32(addr);
854 imap_new[(i*32)+(2*8)+0] = cpu_to_fdt32(addr);
855 imap_new[(i*32)+(3*8)+0] = cpu_to_fdt32(addr);
856
857 imap_new[(i*32)+(0*8)+3] = cpu_to_fdt32(1);
858 imap_new[(i*32)+(1*8)+3] = cpu_to_fdt32(2);
859 imap_new[(i*32)+(2*8)+3] = cpu_to_fdt32(3);
860 imap_new[(i*32)+(3*8)+3] = cpu_to_fdt32(4);
861
862 imap_new[(i*32)+(0*8)+6] = irq[(15-(12+i)+b+0)%4];
863 imap_new[(i*32)+(1*8)+6] = irq[(15-(12+i)+b+1)%4];
864 imap_new[(i*32)+(2*8)+6] = irq[(15-(12+i)+b+2)%4];
865 imap_new[(i*32)+(3*8)+6] = irq[(15-(12+i)+b+3)%4];
866 }
867 fdt_setprop(blob, np, "interrupt-map", imap_new,
868 sizeof(imap_new));
869 reg[0] = cpu_to_fdt32(0xfff00);
870 reg[1] = 0;
871 reg[2] = 0;
872 reg[3] = cpu_to_fdt32(0x7);
873 fdt_setprop(blob, np, "interrupt-map-mask", reg, sizeof(reg));
874 fdt_setprop_cell(blob, np, "#interrupt-cells", 1);
875 fdt_setprop_string(blob, np, "device_type", "pci");
876 fdt_setprop_cell(blob, np, "#address-cells", 3);
877 fdt_setprop_cell(blob, np, "#size-cells", 2);
878 printf(" Added custom interrupt-map for GW16082\n");
879
880 return 0;
881}
882
883
884int fdt_fixup_sky2(void *blob, int np, struct pci_dev *dev)
885{
886 char *tmp, *end;
887 char mac[16];
888 unsigned char mac_addr[6];
889 int j;
890
891 sprintf(mac, "eth1addr");
892 tmp = env_get(mac);
893 if (tmp) {
894 for (j = 0; j < 6; j++) {
895 mac_addr[j] = tmp ?
896 hextoul(tmp, &end) : 0;
897 if (tmp)
898 tmp = (*end) ? end+1 : end;
899 }
900 fdt_setprop(blob, np, "local-mac-address", mac_addr,
901 sizeof(mac_addr));
902 printf(" Added mac addr for eth1\n");
903 return 0;
904 }
905
906 return -1;
907}
908
909
910
911
912
913
914void ft_board_pci_fixup(void *blob, struct bd_info *bd)
915{
916 int i, np;
917 struct pci_dev *dev;
918
919 for (i = 0; i < pci_devno; i++) {
920 dev = &pci_devs[i];
921
922
923
924
925
926 if ((dev->vendor == PCI_VENDOR_ID_TI) &&
927 (dev->device == 0x8240) &&
928 (i2c_set_bus_num(1) == 0) &&
929 (i2c_probe(0x50) == 0))
930 {
931 np = fdt_add_pci_path(blob, dev);
932 if (np > 0)
933 fdt_fixup_gw16082(blob, np, dev);
934 }
935
936
937 else if ((dev->vendor == PCI_VENDOR_ID_MARVELL) &&
938 (dev->device == 0x4380))
939 {
940 np = fdt_add_pci_path(blob, dev);
941 if (np > 0)
942 fdt_fixup_sky2(blob, np, dev);
943 }
944 }
945}
946#endif
947
948
949
950
951
952
953
954
955
956
957#define PWM0_ADDR 0x2080000
958int ft_board_setup(void *blob, struct bd_info *bd)
959{
960 struct ventana_board_info *info = &ventana_info;
961 struct ventana_eeprom_config *cfg;
962 static const struct node_info nand_nodes[] = {
963 { "sst,w25q256", MTD_DEV_TYPE_NOR, },
964 { "fsl,imx6q-gpmi-nand", MTD_DEV_TYPE_NAND, },
965 };
966 const char *model = env_get("model");
967 const char *display = env_get("display");
968 int i;
969 char rev = 0;
970
971
972 for (i = sizeof(ventana_info.model) - 1; i > 0; i--) {
973 if (ventana_info.model[i] >= 'A') {
974 rev = ventana_info.model[i];
975 break;
976 }
977 }
978
979 if (env_get("fdt_noauto")) {
980 puts(" Skiping ft_board_setup (fdt_noauto defined)\n");
981 return 0;
982 }
983
984
985 puts(" Updating MTD partitions...\n");
986 fdt_fixup_mtdparts(blob, nand_nodes, ARRAY_SIZE(nand_nodes));
987
988
989 if (display) {
990 if (fdt_fixup_display(blob, fdt_get_alias(blob, "lvds0"),
991 display) >= 0)
992 printf(" Set display timings for %s...\n", display);
993 }
994
995 printf(" Adjusting FDT per EEPROM for %s...\n", model);
996
997
998 fdt_setprop(blob, 0, "system-serial", env_get("serial#"),
999 strlen(env_get("serial#")) + 1);
1000
1001
1002 fdt_setprop(blob, 0, "board", info->model,
1003 strlen((const char *)info->model) + 1);
1004
1005
1006 ft_sethdmiinfmt(blob, env_get("hdmiinfmt"));
1007
1008
1009 ft_early_fixup(blob, board_type);
1010
1011
1012 for (i = 0; i < gpio_cfg[board_type].dio_num; i++) {
1013 struct dio_cfg *cfg = &gpio_cfg[board_type].dio_cfg[i];
1014 char arg[10];
1015
1016 sprintf(arg, "dio%d", i);
1017 if (!hwconfig(arg))
1018 continue;
1019 if (hwconfig_subarg_cmp(arg, "mode", "pwm") && cfg->pwm_param)
1020 {
1021 phys_addr_t addr;
1022 int off;
1023
1024 printf(" Enabling pwm%d for DIO%d\n",
1025 cfg->pwm_param, i);
1026 addr = PWM0_ADDR + (0x4000 * (cfg->pwm_param - 1));
1027 off = fdt_node_offset_by_compat_reg(blob,
1028 "fsl,imx6q-pwm",
1029 addr);
1030 if (off)
1031 fdt_status_okay(blob, off);
1032 }
1033 }
1034
1035#if defined(CONFIG_CMD_PCI)
1036 if (!env_get("nopcifixup"))
1037 ft_board_pci_fixup(blob, bd);
1038#endif
1039
1040
1041
1042
1043
1044 i = fdt_node_offset_by_compatible(blob, -1, "fsl,imx6q-fec");
1045 if (i)
1046 fdt_delprop(blob, i, "phy-reset-gpios");
1047
1048
1049
1050
1051
1052
1053 if (env_get("fdt_noconfig")) {
1054 puts(" Skiping periperhal config (fdt_noconfig defined)\n");
1055 return 0;
1056 }
1057 cfg = econfig;
1058 while (cfg->name) {
1059 if (!test_bit(cfg->bit, info->config)) {
1060 fdt_del_node_and_alias(blob, cfg->dtalias ?
1061 cfg->dtalias : cfg->name);
1062 }
1063 cfg++;
1064 }
1065
1066 return 0;
1067}
1068#endif
1069