From 5b94b6f6b28fcb93b3440e12282e3384e17972c8 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Wed, 20 Aug 2014 23:30:36 -0700 Subject: imx: ventana: updated notes regarding NAND boot errata Signed-off-by: Tim Harvey --- board/gateworks/gw_ventana/gw_ventana.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'board') diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c index a222921978..6ab2bd4c41 100644 --- a/board/gateworks/gw_ventana/gw_ventana.c +++ b/board/gateworks/gw_ventana/gw_ventana.c @@ -1341,10 +1341,11 @@ int misc_init_r(void) * The Gateworks System Controller implements a boot * watchdog (always enabled) as a workaround for IMX6 boot related * errata such as: - * ERR005768 - no fix - * ERR006282 - fixed in silicon r1.3 + * ERR005768 - no fix scheduled + * ERR006282 - fixed in silicon r1.2 * ERR007117 - fixed in silicon r1.3 * ERR007220 - fixed in silicon r1.3 + * ERR007926 - no fix scheduled * see http://cache.freescale.com/files/32bit/doc/errata/IMX6DQCE.pdf * * Disable the boot watchdog and display/clear the timeout flag if set -- cgit v1.2.1 From c91e4b8b082b54faf329e5d9bbe7c2c588af6654 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Wed, 20 Aug 2014 23:31:11 -0700 Subject: imx: ventana: base SPL MMDC calibration on width and size not board The IMX6 MMDC calibration registers depend on propagation delay and capacitive loading between the SoC's MMDC and the DDR3 chips. On the Ventana boards the board layout varies little in trace-lengths such that propagation delays are irrelevant thus we can simply things by using calibration values obtained from various board layouts based on a common SoC and DDR chip configuration. This eliminates board-model from being needed allowing more flexibility. These values were tested on a large sample size of Gateworks Ventana boards ranging in layout, and memory configuration over the entire temperature range supported. Signed-off-by: Tim Harvey --- board/gateworks/gw_ventana/gw_ventana_spl.c | 189 ++++++++++++++++------------ 1 file changed, 109 insertions(+), 80 deletions(-) (limited to 'board') diff --git a/board/gateworks/gw_ventana/gw_ventana_spl.c b/board/gateworks/gw_ventana/gw_ventana_spl.c index e943879303..9fc253bb82 100644 --- a/board/gateworks/gw_ventana/gw_ventana_spl.c +++ b/board/gateworks/gw_ventana/gw_ventana_spl.c @@ -201,55 +201,79 @@ static struct mx6_ddr3_cfg mt41k128m16jt_125 = { .trasmin = 3500, }; -/* GW54xx specific calibration */ -static struct mx6_mmdc_calibration gw54xxq_mmdc_calib = { +/* MT41K256M16HA-125 */ +static struct mx6_ddr3_cfg mt41k256m16ha_125 = { + .mem_speed = 1600, + .density = 4, + .width = 16, + .banks = 8, + .rowaddr = 15, + .coladdr = 10, + .pagesz = 2, + .trcd = 1375, + .trcmin = 4875, + .trasmin = 3500, +}; + +/* + * calibration - these are the various CPU/DDR3 combinations we support + */ + +static struct mx6_mmdc_calibration mx6dq_128x32_mmdc_calib = { /* write leveling calibration determine */ - .p0_mpwldectrl0 = 0x00190018, - .p0_mpwldectrl1 = 0x0021001D, - .p1_mpwldectrl0 = 0x00160027, - .p1_mpwldectrl1 = 0x0012001E, + .p0_mpwldectrl0 = 0x00190017, + .p0_mpwldectrl1 = 0x00140026, /* Read DQS Gating calibration */ - .p0_mpdgctrl0 = 0x43370346, - .p0_mpdgctrl1 = 0x032A0321, - .p1_mpdgctrl0 = 0x433A034D, - .p1_mpdgctrl1 = 0x032F0235, + .p0_mpdgctrl0 = 0x43380347, + .p0_mpdgctrl1 = 0x433C034D, /* Read Calibration: DQS delay relative to DQ read access */ .p0_mprddlctl = 0x3C313539, - .p1_mprddlctl = 0x37333140, /* Write Calibration: DQ/DM delay relative to DQS write access */ - .p0_mpwrdlctl = 0x37393C38, - .p1_mpwrdlctl = 0x42334538, + .p0_mpwrdlctl = 0x36393C39, +}; + +static struct mx6_mmdc_calibration mx6sdl_128x32_mmdc_calib = { + /* write leveling calibration determine */ + .p0_mpwldectrl0 = 0x003C003C, + .p0_mpwldectrl1 = 0x001F002A, + /* Read DQS Gating calibration */ + .p0_mpdgctrl0 = 0x42410244, + .p0_mpdgctrl1 = 0x4234023A, + /* Read Calibration: DQS delay relative to DQ read access */ + .p0_mprddlctl = 0x484A4C4B, + /* Write Calibration: DQ/DM delay relative to DQS write access */ + .p0_mpwrdlctl = 0x33342B32, }; -/* GW53xx specific calibration */ -static struct mx6_mmdc_calibration gw53xxq_mmdc_calib = { +static struct mx6_mmdc_calibration mx6dq_128x64_mmdc_calib = { /* write leveling calibration determine */ - .p0_mpwldectrl0 = 0x00160013, - .p0_mpwldectrl1 = 0x00090024, - .p1_mpwldectrl0 = 0x001F0018, - .p1_mpwldectrl1 = 0x000C001C, + .p0_mpwldectrl0 = 0x00190017, + .p0_mpwldectrl1 = 0x00140026, + .p1_mpwldectrl0 = 0x0021001C, + .p1_mpwldectrl1 = 0x0011001D, /* Read DQS Gating calibration */ - .p0_mpdgctrl0 = 0x433A034C, - .p0_mpdgctrl1 = 0x0336032F, - .p1_mpdgctrl0 = 0x4343034A, - .p1_mpdgctrl1 = 0x03370222, + .p0_mpdgctrl0 = 0x43380347, + .p0_mpdgctrl1 = 0x433C034D, + .p1_mpdgctrl0 = 0x032C0324, + .p1_mpdgctrl1 = 0x03310232, /* Read Calibration: DQS delay relative to DQ read access */ - .p0_mprddlctl = 0x3F343638, - .p1_mprddlctl = 0x38373442, + .p0_mprddlctl = 0x3C313539, + .p1_mprddlctl = 0x37343141, /* Write Calibration: DQ/DM delay relative to DQS write access */ - .p0_mpwrdlctl = 0x343A3E39, - .p1_mpwrdlctl = 0x44344239, + .p0_mpwrdlctl = 0x36393C39, + .p1_mpwrdlctl = 0x42344438, }; -static struct mx6_mmdc_calibration gw53xxdl_mmdc_calib = { + +static struct mx6_mmdc_calibration mx6sdl_128x64_mmdc_calib = { /* write leveling calibration determine */ .p0_mpwldectrl0 = 0x003C003C, - .p0_mpwldectrl1 = 0x00330038, - .p1_mpwldectrl0 = 0x001F002A, + .p0_mpwldectrl1 = 0x001F002A, + .p1_mpwldectrl0 = 0x00330038, .p1_mpwldectrl1 = 0x0022003F, /* Read DQS Gating calibration */ .p0_mpdgctrl0 = 0x42410244, - .p0_mpdgctrl1 = 0x022D022D, - .p1_mpdgctrl0 = 0x4234023A, + .p0_mpdgctrl1 = 0x4234023A, + .p1_mpdgctrl0 = 0x022D022D, .p1_mpdgctrl1 = 0x021C0228, /* Read Calibration: DQS delay relative to DQ read access */ .p0_mprddlctl = 0x484A4C4B, @@ -259,51 +283,42 @@ static struct mx6_mmdc_calibration gw53xxdl_mmdc_calib = { .p1_mpwrdlctl = 0x3933332B, }; -/* GW52xx specific calibration */ -static struct mx6_mmdc_calibration gw52xxdl_mmdc_calib = { - /* write leveling calibration determine */ - .p0_mpwldectrl0 = 0x0040003F, - .p0_mpwldectrl1 = 0x00370037, - /* Read DQS Gating calibration */ - .p0_mpdgctrl0 = 0x42420244, - .p0_mpdgctrl1 = 0x022F022F, - /* Read Calibration: DQS delay relative to DQ read access */ - .p0_mprddlctl = 0x49464B4A, - /* Write Calibration: DQ/DM delay relative to DQS write access */ - .p0_mpwrdlctl = 0x32362C32, -}; - -/* GW51xx specific calibration */ -static struct mx6_mmdc_calibration gw51xxq_mmdc_calib = { +static struct mx6_mmdc_calibration mx6dq_256x32_mmdc_calib = { /* write leveling calibration determine */ - .p0_mpwldectrl0 = 0x00150016, - .p0_mpwldectrl1 = 0x001F0017, + .p0_mpwldectrl0 = 0x001E001A, + .p0_mpwldectrl1 = 0x0026001F, /* Read DQS Gating calibration */ - .p0_mpdgctrl0 = 0x433D034D, - .p0_mpdgctrl1 = 0x033D032F, + .p0_mpdgctrl0 = 0x43370349, + .p0_mpdgctrl1 = 0x032D0327, /* Read Calibration: DQS delay relative to DQ read access */ - .p0_mprddlctl = 0x3F313639, + .p0_mprddlctl = 0x3D303639, /* Write Calibration: DQ/DM delay relative to DQS write access */ - .p0_mpwrdlctl = 0x33393F36, + .p0_mpwrdlctl = 0x32363934, }; -static struct mx6_mmdc_calibration gw51xxdl_mmdc_calib = { +static struct mx6_mmdc_calibration mx6dq_256x64_mmdc_calib = { /* write leveling calibration determine */ - .p0_mpwldectrl0 = 0x003D003F, - .p0_mpwldectrl1 = 0x002F0038, + .p0_mpwldectrl0 = 0X00220021, + .p0_mpwldectrl1 = 0X00200030, + .p1_mpwldectrl0 = 0X002D0027, + .p1_mpwldectrl1 = 0X00150026, /* Read DQS Gating calibration */ - .p0_mpdgctrl0 = 0x423A023A, - .p0_mpdgctrl1 = 0x022A0228, + .p0_mpdgctrl0 = 0x43330342, + .p0_mpdgctrl1 = 0x0339034A, + .p1_mpdgctrl0 = 0x032F0325, + .p1_mpdgctrl1 = 0x032F022E, /* Read Calibration: DQS delay relative to DQ read access */ - .p0_mprddlctl = 0x48494C4C, + .p0_mprddlctl = 0X3A2E3437, + .p1_mprddlctl = 0X35312F3F, /* Write Calibration: DQ/DM delay relative to DQS write access */ - .p0_mpwrdlctl = 0x34352D31, + .p0_mpwrdlctl = 0X33363B37, + .p1_mpwrdlctl = 0X40304239, }; -static void spl_dram_init(int width, int size, int board_model) +static void spl_dram_init(int width, int size_mb, int board_model) { - struct mx6_ddr3_cfg *mem = &mt41k128m16jt_125; - struct mx6_mmdc_calibration *calib; + struct mx6_ddr3_cfg *mem = NULL; + struct mx6_mmdc_calibration *calib = NULL; struct mx6_ddr_sysinfo sysinfo = { /* width of data bus:0=16,1=32,2=64 */ .dsize = width/32, @@ -329,29 +344,43 @@ static void spl_dram_init(int width, int size, int board_model) /* * MMDC Calibration requires the following data: * mx6_mmdc_calibration - board-specific calibration (routing delays) + * these calibration values depend on board routing, SoC, and DDR * mx6_ddr_sysinfo - board-specific memory architecture (width/cs/etc) * mx6_ddr_cfg - chip specific timing/layout details */ - switch (board_model) { - default: - case GW51xx: + if (width == 32 && size_mb == 512) { + mem = &mt41k128m16jt_125; if (is_cpu_type(MXC_CPU_MX6Q)) - calib = &gw51xxq_mmdc_calib; + calib = &mx6dq_128x32_mmdc_calib; else - calib = &gw51xxdl_mmdc_calib; - break; - case GW52xx: - calib = &gw52xxdl_mmdc_calib; - break; - case GW53xx: + calib = &mx6sdl_128x32_mmdc_calib; + debug("2gB density\n"); + } else if (width == 64 && size_mb == 1024) { + mem = &mt41k128m16jt_125; if (is_cpu_type(MXC_CPU_MX6Q)) - calib = &gw53xxq_mmdc_calib; + calib = &mx6dq_128x64_mmdc_calib; else - calib = &gw53xxdl_mmdc_calib; - break; - case GW54xx: - calib = &gw54xxq_mmdc_calib; - break; + calib = &mx6sdl_128x64_mmdc_calib; + debug("2gB density\n"); + } else if (width == 32 && size_mb == 1024) { + mem = &mt41k256m16ha_125; + if (is_cpu_type(MXC_CPU_MX6Q)) + calib = &mx6dq_256x32_mmdc_calib; + debug("4gB density\n"); + } else if (width == 64 && size_mb == 2048) { + mem = &mt41k256m16ha_125; + if (is_cpu_type(MXC_CPU_MX6Q)) + calib = &mx6dq_256x64_mmdc_calib; + debug("4gB density\n"); + } + + if (!mem) { + puts("Error: Invalid Memory Configuration\n"); + hang(); + } + if (!calib) { + puts("Error: Invalid Board Calibration Configuration\n"); + hang(); } if (is_cpu_type(MXC_CPU_MX6Q)) -- cgit v1.2.1 From 3aa226740fd2224ccba4bb63eb0b351bbfa498eb Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Wed, 20 Aug 2014 23:35:14 -0700 Subject: imx: ventana: add GW5520 support The GW5520 has an IMX6Q SoC with 512MB of DDR3, 256MB of NAND flash as well as: * 2x MiniPCIe sockets * 2x USB host sockets * 2x i210 GigE * HDMI out * digital I/O expansion Signed-off-by: Tim Harvey --- board/gateworks/gw_ventana/eeprom.c | 3 ++ board/gateworks/gw_ventana/gsc.c | 4 ++ board/gateworks/gw_ventana/gw_ventana.c | 80 ++++++++++++++++++++++++++--- board/gateworks/gw_ventana/ventana_eeprom.h | 1 + 4 files changed, 81 insertions(+), 7 deletions(-) (limited to 'board') diff --git a/board/gateworks/gw_ventana/eeprom.c b/board/gateworks/gw_ventana/eeprom.c index 3edc9151d9..ab3bab847a 100644 --- a/board/gateworks/gw_ventana/eeprom.c +++ b/board/gateworks/gw_ventana/eeprom.c @@ -80,6 +80,9 @@ read_eeprom(int bus, struct ventana_board_info *info) case '4': type = GW54xx; break; + case '5': + type = GW552x; + break; default: printf("EEPROM: Unknown model in EEPROM: %s\n", info->model); type = GW_UNKNOWN; diff --git a/board/gateworks/gw_ventana/gsc.c b/board/gateworks/gw_ventana/gsc.c index 1cf38d4046..a34a9a84c8 100644 --- a/board/gateworks/gw_ventana/gsc.c +++ b/board/gateworks/gw_ventana/gsc.c @@ -117,6 +117,10 @@ int do_gsc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) read_hwmon("VDD_SOC", GSC_HWMON_VDD_SOC, 3, MINMAX(1375, 10)); read_hwmon("VDD_1P0", GSC_HWMON_VDD_1P0, 3, MINMAX(1000, 10)); break; + case '5': /* GW55xx */ + read_hwmon("VDD_CORE", GSC_HWMON_VDD_CORE, 3, MINMAX(1175, 10)); + read_hwmon("VDD_SOC", GSC_HWMON_VDD_SOC, 3, MINMAX(1175, 10)); + break; } return 0; } diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c index 6ab2bd4c41..5c98eb4908 100644 --- a/board/gateworks/gw_ventana/gw_ventana.c +++ b/board/gateworks/gw_ventana/gw_ventana.c @@ -299,6 +299,7 @@ int board_ehci_hcd_init(int port) /* Reset USB HUB (present on GW54xx/GW53xx) */ switch (info->model[3]) { case '3': /* GW53xx */ + case '5': /* GW552x */ SETUP_IOMUX_PAD(PAD_GPIO_9__GPIO1_IO09 | DIO_PAD_CFG); gpio_direction_output(IMX_GPIO_NR(1, 9), 0); mdelay(2); @@ -392,7 +393,8 @@ int board_eth_init(bd_t *bis) setup_iomux_enet(); #ifdef CONFIG_FEC_MXC - cpu_eth_init(bis); + if (board_type != GW552x) + cpu_eth_init(bis); #endif #ifdef CONFIG_CI_UDC @@ -614,15 +616,14 @@ static iomux_v3_cfg_t const gw53xx_gpio_pads[] = { IOMUX_PADS(PAD_KEY_COL0__GPIO4_IO06 | DIO_PAD_CFG), /* PANLEDR# */ IOMUX_PADS(PAD_KEY_ROW0__GPIO4_IO07 | DIO_PAD_CFG), + /* MX6_LOCLED# */ + IOMUX_PADS(PAD_KEY_ROW4__GPIO4_IO15 | DIO_PAD_CFG), /* IOEXP_PWREN# */ IOMUX_PADS(PAD_EIM_A19__GPIO2_IO19 | DIO_PAD_CFG), /* IOEXP_IRQ# */ IOMUX_PADS(PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(IRQ_PAD_CTRL)), /* DIOI2C_DIS# */ IOMUX_PADS(PAD_GPIO_19__GPIO4_IO05 | DIO_PAD_CFG), - - /* MX6_LOCLED# */ - IOMUX_PADS(PAD_KEY_ROW4__GPIO4_IO15 | DIO_PAD_CFG), /* GPS_SHDN */ IOMUX_PADS(PAD_ENET_RXD0__GPIO1_IO27 | DIO_PAD_CFG), /* VID_EN */ @@ -660,6 +661,30 @@ static iomux_v3_cfg_t const gw54xx_gpio_pads[] = { IOMUX_PADS(PAD_DISP0_DAT23__GPIO5_IO17 | DIO_PAD_CFG), }; +static iomux_v3_cfg_t const gw552x_gpio_pads[] = { + /* PANLEDG# */ + IOMUX_PADS(PAD_KEY_COL0__GPIO4_IO06 | DIO_PAD_CFG), + /* PANLEDR# */ + IOMUX_PADS(PAD_KEY_ROW0__GPIO4_IO07 | DIO_PAD_CFG), + /* MX6_LOCLED# */ + IOMUX_PADS(PAD_KEY_ROW4__GPIO4_IO15 | DIO_PAD_CFG), + /* PCI_RST# */ + IOMUX_PADS(PAD_ENET_TXD1__GPIO1_IO29 | DIO_PAD_CFG), + /* MX6_DIO[4:9] */ + IOMUX_PADS(PAD_CSI0_PIXCLK__GPIO5_IO18 | DIO_PAD_CFG), + IOMUX_PADS(PAD_CSI0_DATA_EN__GPIO5_IO20 | DIO_PAD_CFG), + IOMUX_PADS(PAD_CSI0_VSYNC__GPIO5_IO21 | DIO_PAD_CFG), + IOMUX_PADS(PAD_CSI0_DAT4__GPIO5_IO22 | DIO_PAD_CFG), + IOMUX_PADS(PAD_CSI0_DAT5__GPIO5_IO23 | DIO_PAD_CFG), + IOMUX_PADS(PAD_CSI0_DAT7__GPIO5_IO25 | DIO_PAD_CFG), + /* PCIEGBE1_OFF# */ + IOMUX_PADS(PAD_GPIO_1__GPIO1_IO01 | DIO_PAD_CFG), + /* PCIEGBE2_OFF# */ + IOMUX_PADS(PAD_GPIO_2__GPIO1_IO02 | DIO_PAD_CFG), + /* PCIESKT_WDIS# */ + IOMUX_PADS(PAD_GPIO_17__GPIO7_IO12 | DIO_PAD_CFG), +}; + /* * each baseboard has 4 user configurable Digital IO lines which can * be pinmuxed as a GPIO or in some cases a PWM @@ -908,6 +933,44 @@ struct ventana gpio_cfg[] = { .pcie_sson = IMX_GPIO_NR(1, 20), .wdis = IMX_GPIO_NR(5, 17), }, + + /* GW552x */ + { + .gpio_pads = gw552x_gpio_pads, + .num_pads = ARRAY_SIZE(gw552x_gpio_pads)/2, + .dio_cfg = { + { + { IOMUX_PADS(PAD_SD1_DAT0__GPIO1_IO16) }, + IMX_GPIO_NR(1, 16), + { 0, 0 }, + 0 + }, + { + { IOMUX_PADS(PAD_SD1_DAT2__GPIO1_IO19) }, + IMX_GPIO_NR(1, 19), + { IOMUX_PADS(PAD_SD1_DAT2__PWM2_OUT) }, + 2 + }, + { + { IOMUX_PADS(PAD_SD1_DAT1__GPIO1_IO17) }, + IMX_GPIO_NR(1, 17), + { IOMUX_PADS(PAD_SD1_DAT1__PWM3_OUT) }, + 3 + }, + { + { IOMUX_PADS(PAD_SD1_CLK__GPIO1_IO20) }, + IMX_GPIO_NR(2, 10), + { 0, 0 }, + 0 + }, + }, + .leds = { + IMX_GPIO_NR(4, 6), + IMX_GPIO_NR(4, 7), + IMX_GPIO_NR(4, 15), + }, + .pcie_rst = IMX_GPIO_NR(1, 29), + }, }; /* setup board specific PMIC */ @@ -1003,8 +1066,10 @@ static void setup_board_gpio(int board) } /* Expansion Mezzanine IO */ - gpio_direction_output(gpio_cfg[board].mezz_pwren, 0); - gpio_direction_input(gpio_cfg[board].mezz_irq); + if (gpio_cfg[board].mezz_pwren) + gpio_direction_output(gpio_cfg[board].mezz_pwren, 0); + if (gpio_cfg[board].mezz_irq) + gpio_direction_input(gpio_cfg[board].mezz_irq); /* RS485 Transmit Enable */ if (gpio_cfg[board].rs485en) @@ -1305,7 +1370,8 @@ int misc_init_r(void) sprintf(fdt, "%s-%s.dtb", cputype, str); setenv("fdt_file1", fdt); } - str[4] = 'x'; + if (board_type != GW552x) + str[4] = 'x'; str[5] = 'x'; str[6] = 0; if (!getenv("fdt_file2")) { diff --git a/board/gateworks/gw_ventana/ventana_eeprom.h b/board/gateworks/gw_ventana/ventana_eeprom.h index d64b9107c6..af12711ac2 100644 --- a/board/gateworks/gw_ventana/ventana_eeprom.h +++ b/board/gateworks/gw_ventana/ventana_eeprom.h @@ -109,6 +109,7 @@ enum { GW52xx, GW53xx, GW54xx, + GW552x, GW_UNKNOWN, GW_BADCRC, }; -- cgit v1.2.1 From a7c67d7c496952da0d453f253c27f7f5b591a269 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Thu, 7 Aug 2014 22:35:42 -0700 Subject: imx: ventana: added cputype env var There are many similarities between the IMX6QUAD/IMX6DUAL and there are many similarities between the IMX6SOLO/IMX6DUALITE. Add a 'soctype' env variable that tells you which type you have. Signed-off-by: Tim Harvey --- board/gateworks/gw_ventana/gw_ventana.c | 1 + 1 file changed, 1 insertion(+) (limited to 'board') diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c index 5c98eb4908..452a9053f5 100644 --- a/board/gateworks/gw_ventana/gw_ventana.c +++ b/board/gateworks/gw_ventana/gw_ventana.c @@ -1348,6 +1348,7 @@ int misc_init_r(void) else if (is_cpu_type(MXC_CPU_MX6DL) || is_cpu_type(MXC_CPU_MX6SOLO)) cputype = "imx6dl"; + setenv("soctype", cputype); if (8 << (ventana_info.nand_flash_size-1) >= 2048) setenv("flash_layout", "large"); else -- cgit v1.2.1 From 52658fda7abc4319ff7f8fe934d2e7c0a32202d7 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Wed, 20 Aug 2014 15:08:52 +0300 Subject: compulab: eeprom: add support for defining eeprom i2c bus Create CONFIG_SYS_I2C_EEPROM_BUS #define to tell the EEPROM module what I2C bus the EEPROM is located at. Make cl_eeprom_read() switch to that bus when reading EEPROM. Cc: Igor Grinberg Cc: Dmitry Lifshitz Cc: Tom Rini Cc: Marek Vasut Acked-by: Igor Grinberg Acked-by: Dmitry Lifshitz Reviewed-by: Marek Vasut Signed-off-by: Nikita Kiryanov --- board/compulab/common/eeprom.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'board') diff --git a/board/compulab/common/eeprom.c b/board/compulab/common/eeprom.c index 20fe3e1960..85442cd103 100644 --- a/board/compulab/common/eeprom.c +++ b/board/compulab/common/eeprom.c @@ -31,8 +31,19 @@ static int cl_eeprom_layout; /* Implicitly LAYOUT_INVALID */ static int cl_eeprom_read(uint offset, uchar *buf, int len) { - return i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, offset, + int res; + unsigned int current_i2c_bus = i2c_get_bus_num(); + + res = i2c_set_bus_num(CONFIG_SYS_I2C_EEPROM_BUS); + if (res < 0) + return res; + + res = i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, offset, CONFIG_SYS_I2C_EEPROM_ADDR_LEN, buf, len); + + i2c_set_bus_num(current_i2c_bus); + + return res; } static int cl_eeprom_setup_layout(void) -- cgit v1.2.1 From e32028a70ba2be17732b21f98b242d9fe3d977cf Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Sun, 7 Sep 2014 18:59:29 +0300 Subject: arm: mx6: add support for Compulab cm-fx6 CoM Add initial support for Compulab CM-FX6 CoM. Support includes MMC, SPI flash, and SPL with dynamic DRAM detection. Cc: Igor Grinberg Cc: Stefano Babic Cc: Tom Rini Cc: Marek Vasut Cc: Simon Glass Acked-by: Marek Vasut Signed-off-by: Nikita Kiryanov --- board/compulab/cm_fx6/Kconfig | 23 +++ board/compulab/cm_fx6/MAINTAINERS | 6 + board/compulab/cm_fx6/Makefile | 12 ++ board/compulab/cm_fx6/cm_fx6.c | 111 ++++++++++++ board/compulab/cm_fx6/common.c | 84 +++++++++ board/compulab/cm_fx6/common.h | 20 +++ board/compulab/cm_fx6/imximage.cfg | 8 + board/compulab/cm_fx6/spl.c | 355 +++++++++++++++++++++++++++++++++++++ 8 files changed, 619 insertions(+) create mode 100644 board/compulab/cm_fx6/Kconfig create mode 100644 board/compulab/cm_fx6/MAINTAINERS create mode 100644 board/compulab/cm_fx6/Makefile create mode 100644 board/compulab/cm_fx6/cm_fx6.c create mode 100644 board/compulab/cm_fx6/common.c create mode 100644 board/compulab/cm_fx6/common.h create mode 100644 board/compulab/cm_fx6/imximage.cfg create mode 100644 board/compulab/cm_fx6/spl.c (limited to 'board') diff --git a/board/compulab/cm_fx6/Kconfig b/board/compulab/cm_fx6/Kconfig new file mode 100644 index 0000000000..42a84380f2 --- /dev/null +++ b/board/compulab/cm_fx6/Kconfig @@ -0,0 +1,23 @@ +if TARGET_CM_FX6 + +config SYS_CPU + string + default "armv7" + +config SYS_BOARD + string + default "cm_fx6" + +config SYS_VENDOR + string + default "compulab" + +config SYS_SOC + string + default "mx6" + +config SYS_CONFIG_NAME + string + default "cm_fx6" + +endif diff --git a/board/compulab/cm_fx6/MAINTAINERS b/board/compulab/cm_fx6/MAINTAINERS new file mode 100644 index 0000000000..5b2623a664 --- /dev/null +++ b/board/compulab/cm_fx6/MAINTAINERS @@ -0,0 +1,6 @@ +CM_FX6 BOARD +M: Nikita Kiryanov +S: Maintained +F: board/compulab/cm_fx6/ +F: include/configs/cm_fx6.h +F: configs/cm_fx6_defconfig diff --git a/board/compulab/cm_fx6/Makefile b/board/compulab/cm_fx6/Makefile new file mode 100644 index 0000000000..3e5c9034df --- /dev/null +++ b/board/compulab/cm_fx6/Makefile @@ -0,0 +1,12 @@ +# +# (C) Copyright 2014 CompuLab, Ltd. +# +# Authors: Nikita Kiryanov +# +# SPDX-License-Identifier: GPL-2.0+ +# +ifdef CONFIG_SPL_BUILD +obj-y = common.o spl.o +else +obj-y = common.o cm_fx6.o +endif diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c new file mode 100644 index 0000000000..b5895816cb --- /dev/null +++ b/board/compulab/cm_fx6/cm_fx6.c @@ -0,0 +1,111 @@ +/* + * Board functions for Compulab CM-FX6 board + * + * Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/ + * + * Author: Nikita Kiryanov + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include "common.h" + +DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_FSL_ESDHC +static struct fsl_esdhc_cfg usdhc_cfg[3] = { + {USDHC1_BASE_ADDR}, + {USDHC2_BASE_ADDR}, + {USDHC3_BASE_ADDR}, +}; + +static enum mxc_clock usdhc_clk[3] = { + MXC_ESDHC_CLK, + MXC_ESDHC2_CLK, + MXC_ESDHC3_CLK, +}; + +int board_mmc_init(bd_t *bis) +{ + int i; + + cm_fx6_set_usdhc_iomux(); + for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { + usdhc_cfg[i].sdhc_clk = mxc_get_clock(usdhc_clk[i]); + usdhc_cfg[i].max_bus_width = 4; + fsl_esdhc_initialize(bis, &usdhc_cfg[i]); + enable_usdhc_clk(1, i); + } + + return 0; +} +#endif + +int board_init(void) +{ + gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; + return 0; +} + +int checkboard(void) +{ + puts("Board: CM-FX6\n"); + return 0; +} + +void dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[1].start = PHYS_SDRAM_2; + + switch (gd->ram_size) { + case 0x10000000: /* DDR_16BIT_256MB */ + gd->bd->bi_dram[0].size = 0x10000000; + gd->bd->bi_dram[1].size = 0; + break; + case 0x20000000: /* DDR_32BIT_512MB */ + gd->bd->bi_dram[0].size = 0x20000000; + gd->bd->bi_dram[1].size = 0; + break; + case 0x40000000: + if (is_cpu_type(MXC_CPU_MX6SOLO)) { /* DDR_32BIT_1GB */ + gd->bd->bi_dram[0].size = 0x20000000; + gd->bd->bi_dram[1].size = 0x20000000; + } else { /* DDR_64BIT_1GB */ + gd->bd->bi_dram[0].size = 0x40000000; + gd->bd->bi_dram[1].size = 0; + } + break; + case 0x80000000: /* DDR_64BIT_2GB */ + gd->bd->bi_dram[0].size = 0x40000000; + gd->bd->bi_dram[1].size = 0x40000000; + break; + case 0xEFF00000: /* DDR_64BIT_4GB */ + gd->bd->bi_dram[0].size = 0x70000000; + gd->bd->bi_dram[1].size = 0x7FF00000; + break; + } +} + +int dram_init(void) +{ + gd->ram_size = imx_ddr_size(); + switch (gd->ram_size) { + case 0x10000000: + case 0x20000000: + case 0x40000000: + case 0x80000000: + break; + case 0xF0000000: + gd->ram_size -= 0x100000; + break; + default: + printf("ERROR: Unsupported DRAM size 0x%lx\n", gd->ram_size); + return -1; + } + + return 0; +} diff --git a/board/compulab/cm_fx6/common.c b/board/compulab/cm_fx6/common.c new file mode 100644 index 0000000000..1f3967995f --- /dev/null +++ b/board/compulab/cm_fx6/common.c @@ -0,0 +1,84 @@ +/* + * Code used by both U-Boot and SPL for Compulab CM-FX6 + * + * Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/ + * + * Author: Nikita Kiryanov + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include "common.h" + +DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_FSL_ESDHC +#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \ + PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \ + PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +static iomux_v3_cfg_t const usdhc_pads[] = { + IOMUX_PADS(PAD_SD1_CLK__SD1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD1_CMD__SD1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD1_DAT0__SD1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD1_DAT1__SD1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD1_DAT2__SD1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD1_DAT3__SD1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + + IOMUX_PADS(PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + + IOMUX_PADS(PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), +}; + +void cm_fx6_set_usdhc_iomux(void) +{ + SETUP_IOMUX_PADS(usdhc_pads); +} + +/* CINS bit doesn't work, so always try to access the MMC card */ +int board_mmc_getcd(struct mmc *mmc) +{ + return 1; +} +#endif + +#ifdef CONFIG_MXC_SPI +#define ECSPI_PAD_CTRL (PAD_CTL_SRE_FAST | PAD_CTL_SPEED_MED | \ + PAD_CTL_PUS_100K_DOWN | PAD_CTL_DSE_40ohm | PAD_CTL_HYS) + +static iomux_v3_cfg_t const ecspi_pads[] = { + IOMUX_PADS(PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(ECSPI_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(ECSPI_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(ECSPI_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_EB2__GPIO2_IO30 | MUX_PAD_CTRL(ECSPI_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D19__ECSPI1_SS1 | MUX_PAD_CTRL(ECSPI_PAD_CTRL)), +}; + +void cm_fx6_set_ecspi_iomux(void) +{ + SETUP_IOMUX_PADS(ecspi_pads); +} + +int board_spi_cs_gpio(unsigned bus, unsigned cs) +{ + return (bus == 0 && cs == 0) ? (CM_FX6_ECSPI_BUS0_CS0) : -1; +} +#endif diff --git a/board/compulab/cm_fx6/common.h b/board/compulab/cm_fx6/common.h new file mode 100644 index 0000000000..347d07b0b9 --- /dev/null +++ b/board/compulab/cm_fx6/common.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/ + * + * Author: Nikita Kiryanov + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ + PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +#define CM_FX6_ECSPI_BUS0_CS0 IMX_GPIO_NR(2, 30) +#define CM_FX6_GREEN_LED IMX_GPIO_NR(2, 31) + +void cm_fx6_set_usdhc_iomux(void); +void cm_fx6_set_ecspi_iomux(void); diff --git a/board/compulab/cm_fx6/imximage.cfg b/board/compulab/cm_fx6/imximage.cfg new file mode 100644 index 0000000000..420947e9ca --- /dev/null +++ b/board/compulab/cm_fx6/imximage.cfg @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/ + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +IMAGE_VERSION 2 +BOOT_FROM sd diff --git a/board/compulab/cm_fx6/spl.c b/board/compulab/cm_fx6/spl.c new file mode 100644 index 0000000000..a3abc7b3f3 --- /dev/null +++ b/board/compulab/cm_fx6/spl.c @@ -0,0 +1,355 @@ +/* + * SPL specific code for Compulab CM-FX6 board + * + * Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/ + * + * Author: Nikita Kiryanov + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" + +DECLARE_GLOBAL_DATA_PTR; + +enum ddr_config { + DDR_16BIT_256MB, + DDR_32BIT_512MB, + DDR_32BIT_1GB, + DDR_64BIT_1GB, + DDR_64BIT_2GB, + DDR_64BIT_4GB, + DDR_UNKNOWN, +}; + +/* + * Below DRAM_RESET[DDR_SEL] = 0 which is incorrect according to + * Freescale QRM, but this is exactly the value used by the automatic + * calibration script and it works also in all our tests, so we leave + * it as is at this point. + */ +#define CM_FX6_DDR_IOMUX_CFG \ + .dram_sdqs0 = 0x00000038, \ + .dram_sdqs1 = 0x00000038, \ + .dram_sdqs2 = 0x00000038, \ + .dram_sdqs3 = 0x00000038, \ + .dram_sdqs4 = 0x00000038, \ + .dram_sdqs5 = 0x00000038, \ + .dram_sdqs6 = 0x00000038, \ + .dram_sdqs7 = 0x00000038, \ + .dram_dqm0 = 0x00000038, \ + .dram_dqm1 = 0x00000038, \ + .dram_dqm2 = 0x00000038, \ + .dram_dqm3 = 0x00000038, \ + .dram_dqm4 = 0x00000038, \ + .dram_dqm5 = 0x00000038, \ + .dram_dqm6 = 0x00000038, \ + .dram_dqm7 = 0x00000038, \ + .dram_cas = 0x00000038, \ + .dram_ras = 0x00000038, \ + .dram_sdclk_0 = 0x00000038, \ + .dram_sdclk_1 = 0x00000038, \ + .dram_sdcke0 = 0x00003000, \ + .dram_sdcke1 = 0x00003000, \ + .dram_reset = 0x00000038, \ + .dram_sdba2 = 0x00000000, \ + .dram_sdodt0 = 0x00000038, \ + .dram_sdodt1 = 0x00000038, + +#define CM_FX6_GPR_IOMUX_CFG \ + .grp_b0ds = 0x00000038, \ + .grp_b1ds = 0x00000038, \ + .grp_b2ds = 0x00000038, \ + .grp_b3ds = 0x00000038, \ + .grp_b4ds = 0x00000038, \ + .grp_b5ds = 0x00000038, \ + .grp_b6ds = 0x00000038, \ + .grp_b7ds = 0x00000038, \ + .grp_addds = 0x00000038, \ + .grp_ddrmode_ctl = 0x00020000, \ + .grp_ddrpke = 0x00000000, \ + .grp_ddrmode = 0x00020000, \ + .grp_ctlds = 0x00000038, \ + .grp_ddr_type = 0x000C0000, + +static struct mx6sdl_iomux_ddr_regs ddr_iomux_s = { CM_FX6_DDR_IOMUX_CFG }; +static struct mx6sdl_iomux_grp_regs grp_iomux_s = { CM_FX6_GPR_IOMUX_CFG }; +static struct mx6dq_iomux_ddr_regs ddr_iomux_q = { CM_FX6_DDR_IOMUX_CFG }; +static struct mx6dq_iomux_grp_regs grp_iomux_q = { CM_FX6_GPR_IOMUX_CFG }; + +static struct mx6_mmdc_calibration cm_fx6_calib_s = { + .p0_mpwldectrl0 = 0x005B0061, + .p0_mpwldectrl1 = 0x004F0055, + .p0_mpdgctrl0 = 0x0314030C, + .p0_mpdgctrl1 = 0x025C0268, + .p0_mprddlctl = 0x42464646, + .p0_mpwrdlctl = 0x36322C34, +}; + +static struct mx6_ddr_sysinfo cm_fx6_sysinfo_s = { + .cs1_mirror = 1, + .cs_density = 16, + .bi_on = 1, + .rtt_nom = 1, + .rtt_wr = 0, + .ralat = 5, + .walat = 1, + .mif3_mode = 3, + .rst_to_cke = 0x23, + .sde_to_rst = 0x10, +}; + +static struct mx6_ddr3_cfg cm_fx6_ddr3_cfg_s = { + .mem_speed = 800, + .density = 4, + .rowaddr = 14, + .coladdr = 10, + .pagesz = 2, + .trcd = 1800, + .trcmin = 5200, + .trasmin = 3600, + .SRT = 0, +}; + +static void spl_mx6s_dram_init(enum ddr_config dram_config, bool reset) +{ + if (reset) + ((struct mmdc_p_regs *)MX6_MMDC_P0_MDCTL)->mdmisc = 2; + + switch (dram_config) { + case DDR_16BIT_256MB: + cm_fx6_sysinfo_s.dsize = 0; + cm_fx6_sysinfo_s.ncs = 1; + break; + case DDR_32BIT_512MB: + cm_fx6_sysinfo_s.dsize = 1; + cm_fx6_sysinfo_s.ncs = 1; + break; + case DDR_32BIT_1GB: + cm_fx6_sysinfo_s.dsize = 1; + cm_fx6_sysinfo_s.ncs = 2; + break; + default: + puts("Tried to setup invalid DDR configuration\n"); + hang(); + } + + mx6_dram_cfg(&cm_fx6_sysinfo_s, &cm_fx6_calib_s, &cm_fx6_ddr3_cfg_s); + udelay(100); +} + +static struct mx6_mmdc_calibration cm_fx6_calib_q = { + .p0_mpwldectrl0 = 0x00630068, + .p0_mpwldectrl1 = 0x0068005D, + .p0_mpdgctrl0 = 0x04140428, + .p0_mpdgctrl1 = 0x037C037C, + .p0_mprddlctl = 0x3C30303A, + .p0_mpwrdlctl = 0x3A344038, + .p1_mpwldectrl0 = 0x0035004C, + .p1_mpwldectrl1 = 0x00170026, + .p1_mpdgctrl0 = 0x0374037C, + .p1_mpdgctrl1 = 0x0350032C, + .p1_mprddlctl = 0x30322A3C, + .p1_mpwrdlctl = 0x48304A3E, +}; + +static struct mx6_ddr_sysinfo cm_fx6_sysinfo_q = { + .cs_density = 16, + .cs1_mirror = 1, + .bi_on = 1, + .rtt_nom = 1, + .rtt_wr = 0, + .ralat = 5, + .walat = 1, + .mif3_mode = 3, + .rst_to_cke = 0x23, + .sde_to_rst = 0x10, +}; + +static struct mx6_ddr3_cfg cm_fx6_ddr3_cfg_q = { + .mem_speed = 1066, + .density = 4, + .rowaddr = 14, + .coladdr = 10, + .pagesz = 2, + .trcd = 1324, + .trcmin = 59500, + .trasmin = 9750, + .SRT = 0, +}; + +static void spl_mx6q_dram_init(enum ddr_config dram_config, bool reset) +{ + if (reset) + ((struct mmdc_p_regs *)MX6_MMDC_P0_MDCTL)->mdmisc = 2; + + cm_fx6_ddr3_cfg_q.rowaddr = 14; + switch (dram_config) { + case DDR_16BIT_256MB: + cm_fx6_sysinfo_q.dsize = 0; + cm_fx6_sysinfo_q.ncs = 1; + break; + case DDR_32BIT_512MB: + cm_fx6_sysinfo_q.dsize = 1; + cm_fx6_sysinfo_q.ncs = 1; + break; + case DDR_64BIT_1GB: + cm_fx6_sysinfo_q.dsize = 2; + cm_fx6_sysinfo_q.ncs = 1; + break; + case DDR_64BIT_2GB: + cm_fx6_sysinfo_q.dsize = 2; + cm_fx6_sysinfo_q.ncs = 2; + break; + case DDR_64BIT_4GB: + cm_fx6_sysinfo_q.dsize = 2; + cm_fx6_sysinfo_q.ncs = 2; + cm_fx6_ddr3_cfg_q.rowaddr = 15; + break; + default: + puts("Tried to setup invalid DDR configuration\n"); + hang(); + } + + mx6_dram_cfg(&cm_fx6_sysinfo_q, &cm_fx6_calib_q, &cm_fx6_ddr3_cfg_q); + udelay(100); +} + +static int cm_fx6_spl_dram_init(void) +{ + unsigned long bank1_size, bank2_size; + + switch (get_cpu_type()) { + case MXC_CPU_MX6SOLO: + mx6sdl_dram_iocfg(64, &ddr_iomux_s, &grp_iomux_s); + + spl_mx6s_dram_init(DDR_32BIT_1GB, false); + bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000); + if (bank1_size == 0x40000000) + return 0; + + if (bank1_size == 0x20000000) { + spl_mx6s_dram_init(DDR_32BIT_512MB, true); + return 0; + } + + spl_mx6s_dram_init(DDR_16BIT_256MB, true); + bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000); + if (bank1_size == 0x10000000) + return 0; + + break; + case MXC_CPU_MX6D: + case MXC_CPU_MX6Q: + mx6dq_dram_iocfg(64, &ddr_iomux_q, &grp_iomux_q); + + spl_mx6q_dram_init(DDR_64BIT_4GB, false); + bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000); + if (bank1_size == 0x80000000) + return 0; + + if (bank1_size == 0x40000000) { + bank2_size = get_ram_size((long int *)PHYS_SDRAM_2, + 0x80000000); + if (bank2_size == 0x40000000) { + /* Don't do a full reset here */ + spl_mx6q_dram_init(DDR_64BIT_2GB, false); + } else { + spl_mx6q_dram_init(DDR_64BIT_1GB, true); + } + + return 0; + } + + spl_mx6q_dram_init(DDR_32BIT_512MB, true); + bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000); + if (bank1_size == 0x20000000) + return 0; + + spl_mx6q_dram_init(DDR_16BIT_256MB, true); + bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000); + if (bank1_size == 0x10000000) + return 0; + + break; + } + + return -1; +} + +static iomux_v3_cfg_t const uart4_pads[] = { + IOMUX_PADS(PAD_KEY_COL0__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), + IOMUX_PADS(PAD_KEY_ROW0__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), +}; + +static void cm_fx6_setup_uart(void) +{ + SETUP_IOMUX_PADS(uart4_pads); + enable_uart_clk(1); +} + +#ifdef CONFIG_SPL_SPI_SUPPORT +static void cm_fx6_setup_ecspi(void) +{ + cm_fx6_set_ecspi_iomux(); + enable_cspi_clock(1, 0); +} +#else +static void cm_fx6_setup_ecspi(void) { } +#endif + +void board_init_f(ulong dummy) +{ + gd = &gdata; + arch_cpu_init(); + timer_init(); + cm_fx6_setup_ecspi(); + cm_fx6_setup_uart(); + get_clocks(); + preloader_console_init(); + gpio_direction_output(CM_FX6_GREEN_LED, 1); + if (cm_fx6_spl_dram_init()) { + puts("!!!ERROR!!! DRAM detection failed!!!\n"); + hang(); + } + + memset(__bss_start, 0, __bss_end - __bss_start); + board_init_r(NULL, 0); +} + +void spl_board_init(void) +{ + u32 boot_device = spl_boot_device(); + + if (boot_device == BOOT_DEVICE_SPI) + puts("Booting from SPI flash\n"); + else if (boot_device == BOOT_DEVICE_MMC1) + puts("Booting from MMC\n"); + else + puts("Unknown boot device\n"); +} + +#ifdef CONFIG_SPL_MMC_SUPPORT +static struct fsl_esdhc_cfg usdhc_cfg = { + .esdhc_base = USDHC3_BASE_ADDR, + .max_bus_width = 4, +}; + +int board_mmc_init(bd_t *bis) +{ + cm_fx6_set_usdhc_iomux(); + + usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); + + return fsl_esdhc_initialize(bis, &usdhc_cfg); +} +#endif -- cgit v1.2.1 From a6b0652bb5040351eeb1a2580270bd3988cb0a59 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Wed, 20 Aug 2014 15:09:01 +0300 Subject: arm: mx6: cm_fx6: add nand support Add NAND support for Compulab CM-FX6 CoM. Cc: Igor Grinberg Cc: Stefano Babic Cc: Tom Rini Acked-by: Igor Grinberg Signed-off-by: Nikita Kiryanov --- board/compulab/cm_fx6/cm_fx6.c | 37 +++++++++++++++++++++++++++++++++++++ board/compulab/cm_fx6/spl.c | 11 +++++++++++ 2 files changed, 48 insertions(+) (limited to 'board') diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c index b5895816cb..17c3ee5aef 100644 --- a/board/compulab/cm_fx6/cm_fx6.c +++ b/board/compulab/cm_fx6/cm_fx6.c @@ -10,11 +10,46 @@ #include #include +#include #include +#include #include "common.h" DECLARE_GLOBAL_DATA_PTR; +#ifdef CONFIG_NAND_MXS +static iomux_v3_cfg_t const nand_pads[] = { + IOMUX_PADS(PAD_NANDF_CLE__NAND_CLE | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_NANDF_ALE__NAND_ALE | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_NANDF_CS0__NAND_CE0_B | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_NANDF_D0__NAND_DATA00 | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_NANDF_D1__NAND_DATA01 | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_NANDF_D2__NAND_DATA02 | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_NANDF_D3__NAND_DATA03 | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_NANDF_D4__NAND_DATA04 | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_NANDF_D5__NAND_DATA05 | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_NANDF_D6__NAND_DATA06 | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_NANDF_D7__NAND_DATA07 | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_SD4_CMD__NAND_RE_B | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_SD4_CLK__NAND_WE_B | MUX_PAD_CTRL(NO_PAD_CTRL)), +}; + +static void cm_fx6_setup_gpmi_nand(void) +{ + SETUP_IOMUX_PADS(nand_pads); + /* Enable clock roots */ + enable_usdhc_clk(1, 3); + enable_usdhc_clk(1, 4); + + setup_gpmi_io_clk(MXC_CCM_CS2CDR_ENFC_CLK_PODF(0xf) | + MXC_CCM_CS2CDR_ENFC_CLK_PRED(1) | + MXC_CCM_CS2CDR_ENFC_CLK_SEL(0)); +} +#else +static void cm_fx6_setup_gpmi_nand(void) {} +#endif + #ifdef CONFIG_FSL_ESDHC static struct fsl_esdhc_cfg usdhc_cfg[3] = { {USDHC1_BASE_ADDR}, @@ -47,6 +82,8 @@ int board_mmc_init(bd_t *bis) int board_init(void) { gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; + cm_fx6_setup_gpmi_nand(); + return 0; } diff --git a/board/compulab/cm_fx6/spl.c b/board/compulab/cm_fx6/spl.c index a3abc7b3f3..3948ba23ae 100644 --- a/board/compulab/cm_fx6/spl.c +++ b/board/compulab/cm_fx6/spl.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include "common.h" @@ -309,7 +310,17 @@ static void cm_fx6_setup_ecspi(void) { } void board_init_f(ulong dummy) { + struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + gd = &gdata; + /* + * We don't use DMA in SPL, but we do need it in U-Boot. U-Boot + * initializes DMA very early (before all board code), so the only + * opportunity we have to initialize APBHDMA clocks is in SPL. + */ + setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK); + enable_usdhc_clk(1, 2); + arch_cpu_init(); timer_init(); cm_fx6_setup_ecspi(); -- cgit v1.2.1 From 02b1343e4a1430dc9ed750b95ed7cd961f06a456 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Wed, 20 Aug 2014 15:09:02 +0300 Subject: arm: mx6: cm_fx6: add ethernet support Add ethernet support for Compulab CM-FX6 CoM Cc: Igor Grinberg Cc: Stefano Babic Cc: Tom Rini Acked-by: Igor Grinberg Signed-off-by: Nikita Kiryanov --- board/compulab/cm_fx6/cm_fx6.c | 100 +++++++++++++++++++++++++++++++++++++++++ board/compulab/cm_fx6/common.h | 1 + 2 files changed, 101 insertions(+) (limited to 'board') diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c index 17c3ee5aef..681b1eeb49 100644 --- a/board/compulab/cm_fx6/cm_fx6.c +++ b/board/compulab/cm_fx6/cm_fx6.c @@ -10,13 +10,100 @@ #include #include +#include +#include +#include #include #include #include +#include #include "common.h" DECLARE_GLOBAL_DATA_PTR; +#ifdef CONFIG_FEC_MXC +#define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_HYS) + +static int mx6_rgmii_rework(struct phy_device *phydev) +{ + unsigned short val; + + /* Ar8031 phy SmartEEE feature cause link status generates glitch, + * which cause ethernet link down/up issue, so disable SmartEEE + */ + phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x3); + phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x805d); + phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4003); + val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe); + val &= ~(0x1 << 8); + phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val); + + /* To enable AR8031 ouput a 125MHz clk from CLK_25M */ + phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7); + phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016); + phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007); + + val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe); + val &= 0xffe3; + val |= 0x18; + phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val); + + /* introduce tx clock delay */ + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5); + val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e); + val |= 0x0100; + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val); + + return 0; +} + +int board_phy_config(struct phy_device *phydev) +{ + mx6_rgmii_rework(phydev); + + if (phydev->drv->config) + return phydev->drv->config(phydev); + + return 0; +} + +static iomux_v3_cfg_t const enet_pads[] = { + IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_GPIO_0__CCM_CLKO1 | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_GPIO_3__CCM_CLKO2 | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_SD4_DAT0__GPIO2_IO08 | MUX_PAD_CTRL(0x84)), + IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK | + MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL | + MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL | + MUX_PAD_CTRL(ENET_PAD_CTRL)), +}; + +int board_eth_init(bd_t *bis) +{ + SETUP_IOMUX_PADS(enet_pads); + /* phy reset */ + gpio_direction_output(CM_FX6_ENET_NRST, 0); + udelay(500); + gpio_set_value(CM_FX6_ENET_NRST, 1); + enable_enet_clk(1); + return cpu_eth_init(bis); +} +#endif + #ifdef CONFIG_NAND_MXS static iomux_v3_cfg_t const nand_pads[] = { IOMUX_PADS(PAD_NANDF_CLE__NAND_CLE | MUX_PAD_CTRL(NO_PAD_CTRL)), @@ -79,6 +166,19 @@ int board_mmc_init(bd_t *bis) } #endif +#ifdef CONFIG_OF_BOARD_SETUP +void ft_board_setup(void *blob, bd_t *bd) +{ + uint8_t enetaddr[6]; + + /* MAC addr */ + if (eth_getenv_enetaddr("ethaddr", enetaddr)) { + fdt_find_and_setprop(blob, "/fec", "local-mac-address", + enetaddr, 6, 1); + } +} +#endif + int board_init(void) { gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; diff --git a/board/compulab/cm_fx6/common.h b/board/compulab/cm_fx6/common.h index 347d07b0b9..1b19f16b2e 100644 --- a/board/compulab/cm_fx6/common.h +++ b/board/compulab/cm_fx6/common.h @@ -15,6 +15,7 @@ #define CM_FX6_ECSPI_BUS0_CS0 IMX_GPIO_NR(2, 30) #define CM_FX6_GREEN_LED IMX_GPIO_NR(2, 31) +#define CM_FX6_ENET_NRST IMX_GPIO_NR(2, 8) void cm_fx6_set_usdhc_iomux(void); void cm_fx6_set_ecspi_iomux(void); -- cgit v1.2.1 From 0f3effb99fdabf41e6152e5aec2e5fceee7616f9 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Wed, 20 Aug 2014 15:09:03 +0300 Subject: arm: mx6: cm_fx6: add usb support Add USB and USB OTG host support for Compulab CM-FX6 CoM. Cc: Igor Grinberg Cc: Stefano Babic Cc: Tom Rini Signed-off-by: Nikita Kiryanov --- board/compulab/cm_fx6/cm_fx6.c | 76 ++++++++++++++++++++++++++++++++++++++++++ board/compulab/cm_fx6/common.h | 3 ++ 2 files changed, 79 insertions(+) (limited to 'board') diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c index 681b1eeb49..26f04171ee 100644 --- a/board/compulab/cm_fx6/cm_fx6.c +++ b/board/compulab/cm_fx6/cm_fx6.c @@ -15,12 +15,88 @@ #include #include #include +#include #include #include #include "common.h" DECLARE_GLOBAL_DATA_PTR; +#ifdef CONFIG_USB_EHCI_MX6 +#define WEAK_PULLDOWN (PAD_CTL_PUS_100K_DOWN | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ + PAD_CTL_HYS | PAD_CTL_SRE_SLOW) + +static int cm_fx6_usb_hub_reset(void) +{ + int err; + + err = gpio_request(CM_FX6_USB_HUB_RST, "usb hub rst"); + if (err) { + printf("USB hub rst gpio request failed: %d\n", err); + return -1; + } + + SETUP_IOMUX_PAD(PAD_SD3_RST__GPIO7_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(CM_FX6_USB_HUB_RST, 0); + udelay(10); + gpio_direction_output(CM_FX6_USB_HUB_RST, 1); + mdelay(1); + + return 0; +} + +static int cm_fx6_init_usb_otg(void) +{ + int ret; + struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; + + ret = gpio_request(SB_FX6_USB_OTG_PWR, "usb-pwr"); + if (ret) { + printf("USB OTG pwr gpio request failed: %d\n", ret); + return ret; + } + + SETUP_IOMUX_PAD(PAD_EIM_D22__GPIO3_IO22 | MUX_PAD_CTRL(NO_PAD_CTRL)); + SETUP_IOMUX_PAD(PAD_ENET_RX_ER__USB_OTG_ID | + MUX_PAD_CTRL(WEAK_PULLDOWN)); + clrbits_le32(&iomux->gpr[1], IOMUXC_GPR1_OTG_ID_MASK); + /* disable ext. charger detect, or it'll affect signal quality at dp. */ + return gpio_direction_output(SB_FX6_USB_OTG_PWR, 0); +} + +#define MX6_USBNC_BASEADDR 0x2184800 +#define USBNC_USB_H1_PWR_POL (1 << 9) +int board_ehci_hcd_init(int port) +{ + u32 *usbnc_usb_uh1_ctrl = (u32 *)(MX6_USBNC_BASEADDR + 4); + + switch (port) { + case 0: + return cm_fx6_init_usb_otg(); + case 1: + SETUP_IOMUX_PAD(PAD_GPIO_0__USB_H1_PWR | + MUX_PAD_CTRL(NO_PAD_CTRL)); + + /* Set PWR polarity to match power switch's enable polarity */ + setbits_le32(usbnc_usb_uh1_ctrl, USBNC_USB_H1_PWR_POL); + return cm_fx6_usb_hub_reset(); + default: + break; + } + + return 0; +} + +int board_ehci_power(int port, int on) +{ + if (port == 0) + return gpio_direction_output(SB_FX6_USB_OTG_PWR, on); + + return 0; +} +#endif + #ifdef CONFIG_FEC_MXC #define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ PAD_CTL_DSE_40ohm | PAD_CTL_HYS) diff --git a/board/compulab/cm_fx6/common.h b/board/compulab/cm_fx6/common.h index 1b19f16b2e..f841c90c54 100644 --- a/board/compulab/cm_fx6/common.h +++ b/board/compulab/cm_fx6/common.h @@ -16,6 +16,9 @@ #define CM_FX6_ECSPI_BUS0_CS0 IMX_GPIO_NR(2, 30) #define CM_FX6_GREEN_LED IMX_GPIO_NR(2, 31) #define CM_FX6_ENET_NRST IMX_GPIO_NR(2, 8) +#define CM_FX6_ENET_NRST IMX_GPIO_NR(2, 8) +#define CM_FX6_USB_HUB_RST IMX_GPIO_NR(7, 8) +#define SB_FX6_USB_OTG_PWR IMX_GPIO_NR(3, 22) void cm_fx6_set_usdhc_iomux(void); void cm_fx6_set_ecspi_iomux(void); -- cgit v1.2.1 From f42b2f606161d0051c14ccaccdc7fdef4bb2fc96 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Wed, 20 Aug 2014 15:09:04 +0300 Subject: arm: mx6: cm_fx6: add i2c support Add support for all 3 I2C busses on Compulab CM-FX6 CoM. Cc: Igor Grinberg Cc: Stefano Babic Cc: Tom Rini Acked-by: Igor Grinberg Signed-off-by: Nikita Kiryanov --- board/compulab/cm_fx6/cm_fx6.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'board') diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c index 26f04171ee..d21c561e66 100644 --- a/board/compulab/cm_fx6/cm_fx6.c +++ b/board/compulab/cm_fx6/cm_fx6.c @@ -16,12 +16,53 @@ #include #include #include +#include #include #include #include "common.h" DECLARE_GLOBAL_DATA_PTR; +#ifdef CONFIG_SYS_I2C_MXC +#define I2C_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ + PAD_CTL_ODE | PAD_CTL_SRE_FAST) + +I2C_PADS(i2c0_pads, + PAD_EIM_D21__I2C1_SCL | MUX_PAD_CTRL(I2C_PAD_CTRL), + PAD_EIM_D21__GPIO3_IO21 | MUX_PAD_CTRL(I2C_PAD_CTRL), + IMX_GPIO_NR(3, 21), + PAD_EIM_D28__I2C1_SDA | MUX_PAD_CTRL(I2C_PAD_CTRL), + PAD_EIM_D28__GPIO3_IO28 | MUX_PAD_CTRL(I2C_PAD_CTRL), + IMX_GPIO_NR(3, 28)); + +I2C_PADS(i2c1_pads, + PAD_KEY_COL3__I2C2_SCL | MUX_PAD_CTRL(I2C_PAD_CTRL), + PAD_KEY_COL3__GPIO4_IO12 | MUX_PAD_CTRL(I2C_PAD_CTRL), + IMX_GPIO_NR(4, 12), + PAD_KEY_ROW3__I2C2_SDA | MUX_PAD_CTRL(I2C_PAD_CTRL), + PAD_KEY_ROW3__GPIO4_IO13 | MUX_PAD_CTRL(I2C_PAD_CTRL), + IMX_GPIO_NR(4, 13)); + +I2C_PADS(i2c2_pads, + PAD_GPIO_3__I2C3_SCL | MUX_PAD_CTRL(I2C_PAD_CTRL), + PAD_GPIO_3__GPIO1_IO03 | MUX_PAD_CTRL(I2C_PAD_CTRL), + IMX_GPIO_NR(1, 3), + PAD_GPIO_6__I2C3_SDA | MUX_PAD_CTRL(I2C_PAD_CTRL), + PAD_GPIO_6__GPIO1_IO06 | MUX_PAD_CTRL(I2C_PAD_CTRL), + IMX_GPIO_NR(1, 6)); + + +static void cm_fx6_setup_i2c(void) +{ + setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, I2C_PADS_INFO(i2c0_pads)); + setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, I2C_PADS_INFO(i2c1_pads)); + setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, I2C_PADS_INFO(i2c2_pads)); +} +#else +static void cm_fx6_setup_i2c(void) { } +#endif + #ifdef CONFIG_USB_EHCI_MX6 #define WEAK_PULLDOWN (PAD_CTL_PUS_100K_DOWN | \ PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ @@ -259,6 +300,7 @@ int board_init(void) { gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; cm_fx6_setup_gpmi_nand(); + cm_fx6_setup_i2c(); return 0; } -- cgit v1.2.1 From f66113c0ef8108cb4b14d54d1b805c776e91cd21 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Wed, 20 Aug 2014 15:09:05 +0300 Subject: arm: mx6: cm_fx6: use eeprom Use Compulab eeprom module to obtain revision number, serial number, and mac address from the EEPROM. Cc: Igor Grinberg Cc: Stefano Babic Cc: Tom Rini Signed-off-by: Nikita Kiryanov --- board/compulab/cm_fx6/cm_fx6.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'board') diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c index d21c561e66..1664fe866e 100644 --- a/board/compulab/cm_fx6/cm_fx6.c +++ b/board/compulab/cm_fx6/cm_fx6.c @@ -20,6 +20,7 @@ #include #include #include "common.h" +#include "../common/eeprom.h" DECLARE_GLOBAL_DATA_PTR; @@ -209,8 +210,31 @@ static iomux_v3_cfg_t const enet_pads[] = { MUX_PAD_CTRL(ENET_PAD_CTRL)), }; +static int handle_mac_address(void) +{ + unsigned char enetaddr[6]; + int rc; + + rc = eth_getenv_enetaddr("ethaddr", enetaddr); + if (rc) + return 0; + + rc = cl_eeprom_read_mac_addr(enetaddr); + if (rc) + return rc; + + if (!is_valid_ether_addr(enetaddr)) + return -1; + + return eth_setenv_enetaddr("ethaddr", enetaddr); +} + int board_eth_init(bd_t *bis) { + int res = handle_mac_address(); + if (res) + puts("No MAC address found\n"); + SETUP_IOMUX_PADS(enet_pads); /* phy reset */ gpio_direction_output(CM_FX6_ENET_NRST, 0); @@ -364,3 +388,9 @@ int dram_init(void) return 0; } + +u32 get_board_rev(void) +{ + return cl_eeprom_get_board_rev(); +} + -- cgit v1.2.1 From 206f38f727e9610709fe73db5c460b7623755eb7 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Wed, 20 Aug 2014 15:09:06 +0300 Subject: arm: mx6: cm_fx6: add sata support Add support for SATA. Cc: Igor Grinberg Cc: Stefano Babic Cc: Tom Rini Signed-off-by: Nikita Kiryanov --- board/compulab/cm_fx6/cm_fx6.c | 87 ++++++++++++++++++++++++++++++++++++++++++ board/compulab/cm_fx6/common.h | 13 +++++++ 2 files changed, 100 insertions(+) (limited to 'board') diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c index 1664fe866e..fdb8ebf9e7 100644 --- a/board/compulab/cm_fx6/cm_fx6.c +++ b/board/compulab/cm_fx6/cm_fx6.c @@ -13,10 +13,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include "common.h" @@ -24,6 +26,91 @@ DECLARE_GLOBAL_DATA_PTR; +#ifdef CONFIG_DWC_AHSATA +static int cm_fx6_issd_gpios[] = { + /* The order of the GPIOs in the array is important! */ + CM_FX6_SATA_PHY_SLP, + CM_FX6_SATA_NRSTDLY, + CM_FX6_SATA_PWREN, + CM_FX6_SATA_NSTANDBY1, + CM_FX6_SATA_NSTANDBY2, + CM_FX6_SATA_LDO_EN, +}; + +static void cm_fx6_sata_power(int on) +{ + int i; + + if (!on) { /* tell the iSSD that the power will be removed */ + gpio_direction_output(CM_FX6_SATA_PWLOSS_INT, 1); + mdelay(10); + } + + for (i = 0; i < ARRAY_SIZE(cm_fx6_issd_gpios); i++) { + gpio_direction_output(cm_fx6_issd_gpios[i], on); + udelay(100); + } + + if (!on) /* for compatibility lower the power loss interrupt */ + gpio_direction_output(CM_FX6_SATA_PWLOSS_INT, 0); +} + +static iomux_v3_cfg_t const sata_pads[] = { + /* SATA PWR */ + IOMUX_PADS(PAD_ENET_TX_EN__GPIO1_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_A22__GPIO2_IO16 | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D20__GPIO3_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_A25__GPIO5_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL)), + /* SATA CTRL */ + IOMUX_PADS(PAD_ENET_TXD0__GPIO1_IO30 | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D23__GPIO3_IO23 | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D29__GPIO3_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_A23__GPIO6_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_BCLK__GPIO6_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL)), +}; + +static void cm_fx6_setup_issd(void) +{ + SETUP_IOMUX_PADS(sata_pads); + /* Make sure this gpio has logical 0 value */ + gpio_direction_output(CM_FX6_SATA_PWLOSS_INT, 0); + udelay(100); + + cm_fx6_sata_power(0); + mdelay(250); + cm_fx6_sata_power(1); +} + +#define CM_FX6_SATA_INIT_RETRIES 10 +int sata_initialize(void) +{ + int err, i; + + cm_fx6_setup_issd(); + for (i = 0; i < CM_FX6_SATA_INIT_RETRIES; i++) { + err = setup_sata(); + if (err) { + printf("SATA setup failed: %d\n", err); + return err; + } + + udelay(100); + + err = __sata_initialize(); + if (!err) + break; + + /* There is no device on the SATA port */ + if (sata_port_status(0, 0) == 0) + break; + + /* There's a device, but link not established. Retry */ + } + + return err; +} +#endif + #ifdef CONFIG_SYS_I2C_MXC #define I2C_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ diff --git a/board/compulab/cm_fx6/common.h b/board/compulab/cm_fx6/common.h index f841c90c54..76097f80af 100644 --- a/board/compulab/cm_fx6/common.h +++ b/board/compulab/cm_fx6/common.h @@ -19,6 +19,19 @@ #define CM_FX6_ENET_NRST IMX_GPIO_NR(2, 8) #define CM_FX6_USB_HUB_RST IMX_GPIO_NR(7, 8) #define SB_FX6_USB_OTG_PWR IMX_GPIO_NR(3, 22) +#define CM_FX6_ENET_NRST IMX_GPIO_NR(2, 8) +#define CM_FX6_USB_HUB_RST IMX_GPIO_NR(7, 8) +#define SB_FX6_USB_OTG_PWR IMX_GPIO_NR(3, 22) +#define CM_FX6_SATA_PWREN IMX_GPIO_NR(1, 28) +#define CM_FX6_SATA_VDDC_CTRL IMX_GPIO_NR(1, 30) +#define CM_FX6_SATA_LDO_EN IMX_GPIO_NR(2, 16) +#define CM_FX6_SATA_NSTANDBY1 IMX_GPIO_NR(3, 20) +#define CM_FX6_SATA_PHY_SLP IMX_GPIO_NR(3, 23) +#define CM_FX6_SATA_STBY_REQ IMX_GPIO_NR(3, 29) +#define CM_FX6_SATA_NSTANDBY2 IMX_GPIO_NR(5, 2) +#define CM_FX6_SATA_NRSTDLY IMX_GPIO_NR(6, 6) +#define CM_FX6_SATA_PWLOSS_INT IMX_GPIO_NR(6, 31) + void cm_fx6_set_usdhc_iomux(void); void cm_fx6_set_ecspi_iomux(void); -- cgit v1.2.1 From dad08286eaa84779349fe4cec427e1e29beaffac Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Thu, 7 Aug 2014 22:49:57 -0700 Subject: imx: ventana: add pci fixup for PLX PEX860x switch GPIO Most Gateworks Ventana boards use a PLX PEX860x PCIe switch for PCIe expansion. These boards use GPIO on the PLX device as PERST# for the downstream ports thus we assert this when the PLX is enumerated. Signed-off-by: Tim Harvey --- board/gateworks/gw_ventana/gw_ventana.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'board') diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c index 452a9053f5..9a1b6dd9ce 100644 --- a/board/gateworks/gw_ventana/gw_ventana.c +++ b/board/gateworks/gw_ventana/gw_ventana.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -1157,6 +1158,35 @@ int imx6_pcie_toggle_reset(void) } return 0; } + +/* + * Most Ventana boards have a PLX PEX860x PCIe switch onboard and use its + * GPIO's as PERST# signals for its downstream ports - configure the GPIO's + * properly and assert reset for 100ms. + */ +void board_pci_fixup_dev(struct pci_controller *hose, pci_dev_t dev, + unsigned short vendor, unsigned short device, + unsigned short class) +{ + u32 dw; + + debug("%s: %02d:%02d.%02d: %04x:%04x\n", __func__, + PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev), vendor, device); + if (vendor == PCI_VENDOR_ID_PLX && + (device & 0xfff0) == 0x8600 && + PCI_DEV(dev) == 0 && PCI_FUNC(dev) == 0) { + debug("configuring PLX 860X downstream PERST#\n"); + pci_hose_read_config_dword(hose, dev, 0x62c, &dw); + dw |= 0xaaa8; /* GPIO1-7 outputs */ + pci_hose_write_config_dword(hose, dev, 0x62c, dw); + + pci_hose_read_config_dword(hose, dev, 0x644, &dw); + dw |= 0xfe; /* GPIO1-7 output high */ + pci_hose_write_config_dword(hose, dev, 0x644, dw); + + mdelay(100); + } +} #endif /* CONFIG_CMD_PCI */ #ifdef CONFIG_SERIAL_TAG -- cgit v1.2.1 From dc73cbe7b05851a3ff76beabdc0589d2b3ebb9a3 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 22 Aug 2014 09:46:35 +0200 Subject: imx: ventana: Avoid undefined behaviour The leds array within struct ventana has space for 3 elements, but the setup_board_gpio() function tries to set up 4 GPIOs for LEDs. Recent versions of GCC complain about that: board/gateworks/gw_ventana/gw_ventana.c: In function 'setup_board_gpio': board/gateworks/gw_ventana/gw_ventana.c:987:27: warning: iteration 3u invokes undefined behavior [-Waggressive-loop-optimizations] if (gpio_cfg[board].leds[i]) ^ board/gateworks/gw_ventana/gw_ventana.c:986:2: note: containing loop for (i = 0; i < 4; i++) { ^ Fix this by making the upper bound of the loop match the array size. Signed-off-by: Thierry Reding Acked-by: Tim Harvey --- board/gateworks/gw_ventana/gw_ventana.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'board') diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c index 9a1b6dd9ce..8d086f84ab 100644 --- a/board/gateworks/gw_ventana/gw_ventana.c +++ b/board/gateworks/gw_ventana/gw_ventana.c @@ -1061,7 +1061,7 @@ static void setup_board_gpio(int board) #endif /* turn off (active-high) user LED's */ - for (i = 0; i < 4; i++) { + for (i = 0; i < ARRAY_SIZE(gpio_cfg[board].leds); i++) { if (gpio_cfg[board].leds[i]) gpio_direction_output(gpio_cfg[board].leds[i], 1); } -- cgit v1.2.1 From f4fb5ef045e1c53fc92b34d53e58a3c2ebabd4e1 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 21 Aug 2014 10:02:25 -0300 Subject: mx6dlsabresd: Use its own DCD table Currently mx6dlsabresd shares the same DCD settings with the nitrogen board. Provide a DCD configuration file specific to mx6dlsabresd with the settings recommended by the Freescale hardware team. Signed-off-by: Fabio Estevam --- board/freescale/mx6sabresd/mx6dlsabresd.cfg | 131 ++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 board/freescale/mx6sabresd/mx6dlsabresd.cfg (limited to 'board') diff --git a/board/freescale/mx6sabresd/mx6dlsabresd.cfg b/board/freescale/mx6sabresd/mx6dlsabresd.cfg new file mode 100644 index 0000000000..f35f22ea82 --- /dev/null +++ b/board/freescale/mx6sabresd/mx6dlsabresd.cfg @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Refer docs/README.imxmage for more details about how-to configure + * and create imximage boot image + * + * The syntax is taken as close as possible with the kwbimage + */ + +/* image version */ + +IMAGE_VERSION 2 + +/* + * Boot Device : one of + * spi, sd (the board has no nand neither onenand) + */ + +BOOT_FROM sd + +/* + * Device Configuration Data (DCD) + * + * Each entry must have the format: + * Addr-type Address Value + * + * where: + * Addr-type register length (1,2 or 4 bytes) + * Address absolute address of the register + * value value to be stored in the register + */ +DATA 4 0x020e0774 0x000C0000 +DATA 4 0x020e0754 0x00000000 +DATA 4 0x020e04ac 0x00000030 +DATA 4 0x020e04b0 0x00000030 +DATA 4 0x020e0464 0x00000030 +DATA 4 0x020e0490 0x00000030 +DATA 4 0x020e074c 0x00000030 +DATA 4 0x020e0494 0x00000030 +DATA 4 0x020e04a0 0x00000000 +DATA 4 0x020e04b4 0x00000030 +DATA 4 0x020e04b8 0x00000030 +DATA 4 0x020e076c 0x00000030 +DATA 4 0x020e0750 0x00020000 +DATA 4 0x020e04bc 0x00000030 +DATA 4 0x020e04c0 0x00000030 +DATA 4 0x020e04c4 0x00000030 +DATA 4 0x020e04c8 0x00000030 +DATA 4 0x020e04cc 0x00000030 +DATA 4 0x020e04d0 0x00000030 +DATA 4 0x020e04d4 0x00000030 +DATA 4 0x020e04d8 0x00000030 +DATA 4 0x020e0760 0x00020000 +DATA 4 0x020e0764 0x00000030 +DATA 4 0x020e0770 0x00000030 +DATA 4 0x020e0778 0x00000030 +DATA 4 0x020e077c 0x00000030 +DATA 4 0x020e0780 0x00000030 +DATA 4 0x020e0784 0x00000030 +DATA 4 0x020e078c 0x00000030 +DATA 4 0x020e0748 0x00000030 +DATA 4 0x020e0470 0x00000030 +DATA 4 0x020e0474 0x00000030 +DATA 4 0x020e0478 0x00000030 +DATA 4 0x020e047c 0x00000030 +DATA 4 0x020e0480 0x00000030 +DATA 4 0x020e0484 0x00000030 +DATA 4 0x020e0488 0x00000030 +DATA 4 0x020e048c 0x00000030 +DATA 4 0x021b0800 0xa1390003 +DATA 4 0x021b080c 0x001F001F +DATA 4 0x021b0810 0x001F001F +DATA 4 0x021b480c 0x001F001F +DATA 4 0x021b4810 0x001F001F +DATA 4 0x021b083c 0x4220021F +DATA 4 0x021b0840 0x0207017E +DATA 4 0x021b483c 0x4201020C +DATA 4 0x021b4840 0x01660172 +DATA 4 0x021b0848 0x4A4D4E4D +DATA 4 0x021b4848 0x4A4F5049 +DATA 4 0x021b0850 0x3F3C3D31 +DATA 4 0x021b4850 0x3238372B +DATA 4 0x021b081c 0x33333333 +DATA 4 0x021b0820 0x33333333 +DATA 4 0x021b0824 0x33333333 +DATA 4 0x021b0828 0x33333333 +DATA 4 0x021b481c 0x33333333 +DATA 4 0x021b4820 0x33333333 +DATA 4 0x021b4824 0x33333333 +DATA 4 0x021b4828 0x33333333 +DATA 4 0x021b08b8 0x00000800 +DATA 4 0x021b48b8 0x00000800 +DATA 4 0x021b0004 0x0002002D +DATA 4 0x021b0008 0x00333030 +DATA 4 0x021b000c 0x3F435313 +DATA 4 0x021b0010 0xB66E8B63 +DATA 4 0x021b0014 0x01FF00DB +DATA 4 0x021b0018 0x00001740 +DATA 4 0x021b001c 0x00008000 +DATA 4 0x021b002c 0x000026d2 +DATA 4 0x021b0030 0x00431023 +DATA 4 0x021b0040 0x00000027 +DATA 4 0x021b0000 0x831A0000 +DATA 4 0x021b001c 0x04008032 +DATA 4 0x021b001c 0x00008033 +DATA 4 0x021b001c 0x00048031 +DATA 4 0x021b001c 0x05208030 +DATA 4 0x021b001c 0x04008040 +DATA 4 0x021b0020 0x00005800 +DATA 4 0x021b0818 0x00011117 +DATA 4 0x021b4818 0x00011117 +DATA 4 0x021b0004 0x0002556D +DATA 4 0x021b0404 0x00011006 +DATA 4 0x021b001c 0x00000000 + +/* set the default clock gate to save power */ +DATA 4 0x020c4068 0x00C03F3F +DATA 4 0x020c406c 0x0030FC03 +DATA 4 0x020c4070 0x0FFFC000 +DATA 4 0x020c4074 0x3FF00000 +DATA 4 0x020c4078 0x00FFF300 +DATA 4 0x020c407c 0x0F0000C3 +DATA 4 0x020c4080 0x000003FF + +/* enable AXI cache for VDOA/VPU/IPU */ +DATA 4 0x020e0010 0xF00000CF +/* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */ +DATA 4 0x020e0018 0x007F007F +DATA 4 0x020e001c 0x007F007F -- cgit v1.2.1