Merge branch 'u-boot-imx/master' into 'u-boot-arm/master'
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 22f0f09..f9331233 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -424,6 +424,9 @@
 config RMOBILE
 	bool "Renesas ARM SoCs"
 
+config TARGET_CM_FX6
+	bool "Support cm_fx6"
+
 config TARGET_S5P_GONI
 	bool "Support s5p_goni"
 
@@ -579,6 +582,7 @@
 source "board/cm4008/Kconfig"
 source "board/cm41xx/Kconfig"
 source "board/compulab/cm_t335/Kconfig"
+source "board/compulab/cm_fx6/Kconfig"
 source "board/congatec/cgtqmx6eval/Kconfig"
 source "board/creative/xfi3/Kconfig"
 source "board/davedenx/qong/Kconfig"
diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c
index 820b8d5..336e557 100644
--- a/arch/arm/cpu/armv7/mx6/clock.c
+++ b/arch/arm/cpu/armv7/mx6/clock.c
@@ -36,6 +36,35 @@
 }
 #endif
 
+#ifdef CONFIG_NAND_MXS
+void setup_gpmi_io_clk(u32 cfg)
+{
+	/* Disable clocks per ERR007177 from MX6 errata */
+	clrbits_le32(&imx_ccm->CCGR4,
+		     MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK |
+		     MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK |
+		     MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK |
+		     MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK |
+		     MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_MASK);
+
+	clrbits_le32(&imx_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK);
+
+	clrsetbits_le32(&imx_ccm->cs2cdr,
+			MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK |
+			MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK |
+			MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK,
+			cfg);
+
+	setbits_le32(&imx_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK);
+	setbits_le32(&imx_ccm->CCGR4,
+		     MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK |
+		     MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK |
+		     MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK |
+		     MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK |
+		     MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_MASK);
+}
+#endif
+
 void enable_usboh3_clk(unsigned char enable)
 {
 	u32 reg;
@@ -47,7 +76,68 @@
 		reg &= ~(MXC_CCM_CCGR6_USBOH3_MASK);
 	__raw_writel(reg, &imx_ccm->CCGR6);
 
+}
+
+#if defined(CONFIG_FEC_MXC) && !defined(CONFIG_MX6SX)
+void enable_enet_clk(unsigned char enable)
+{
+	u32 mask = MXC_CCM_CCGR1_ENET_CLK_ENABLE_MASK;
+
+	if (enable)
+		setbits_le32(&imx_ccm->CCGR1, mask);
+	else
+		clrbits_le32(&imx_ccm->CCGR1, mask);
+}
+#endif
+
+#ifdef CONFIG_MXC_UART
+void enable_uart_clk(unsigned char enable)
+{
+	u32 mask = MXC_CCM_CCGR5_UART_MASK | MXC_CCM_CCGR5_UART_SERIAL_MASK;
+
+	if (enable)
+		setbits_le32(&imx_ccm->CCGR5, mask);
+	else
+		clrbits_le32(&imx_ccm->CCGR5, mask);
+}
+#endif
+
+#ifdef CONFIG_SPI
+/* spi_num can be from 0 - 4 */
+int enable_cspi_clock(unsigned char enable, unsigned spi_num)
+{
+	u32 mask;
+
+	if (spi_num > 4)
+		return -EINVAL;
+
+	mask = MXC_CCM_CCGR_CG_MASK << (spi_num * 2);
+	if (enable)
+		setbits_le32(&imx_ccm->CCGR1, mask);
+	else
+		clrbits_le32(&imx_ccm->CCGR1, mask);
+
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_MMC
+int enable_usdhc_clk(unsigned char enable, unsigned bus_num)
+{
+	u32 mask;
+
+	if (bus_num > 3)
+		return -EINVAL;
+
+	mask = MXC_CCM_CCGR_CG_MASK << (bus_num * 2 + 2);
+	if (enable)
+		setbits_le32(&imx_ccm->CCGR6, mask);
+	else
+		clrbits_le32(&imx_ccm->CCGR6, mask);
+
+	return 0;
 }
+#endif
 
 #ifdef CONFIG_SYS_I2C_MXC
 /* i2c_num can be from 0 - 2 */
@@ -509,6 +599,7 @@
 	struct anatop_regs *anatop_regs =
 		(struct anatop_regs *)ANATOP_BASE_ADDR;
 	struct mxc_ccm_reg *ccm_regs = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+	u32 lvds1_clk_sel;
 
 	/*
 	 * Here be dragons!
@@ -518,17 +609,25 @@
 	 * marked as ANATOP_MISC1 is actually documented in the PMU section
 	 * of the datasheet as PMU_MISC1.
 	 *
-	 * Switch LVDS clock source to SATA (0xb), disable clock INPUT and
-	 * enable clock OUTPUT. This is important for PCI express link that
-	 * is clocked from the i.MX6.
+	 * Switch LVDS clock source to SATA (0xb) on mx6q/dl or PCI (0xa) on
+	 * mx6sx, disable clock INPUT and enable clock OUTPUT. This is important
+	 * for PCI express link that is clocked from the i.MX6.
 	 */
 #define ANADIG_ANA_MISC1_LVDSCLK1_IBEN		(1 << 12)
 #define ANADIG_ANA_MISC1_LVDSCLK1_OBEN		(1 << 10)
 #define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_MASK	0x0000001F
+#define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_PCIE_REF	0xa
+#define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_SATA_REF	0xb
+
+	if (is_cpu_type(MXC_CPU_MX6SX))
+		lvds1_clk_sel = ANADIG_ANA_MISC1_LVDS1_CLK_SEL_PCIE_REF;
+	else
+		lvds1_clk_sel = ANADIG_ANA_MISC1_LVDS1_CLK_SEL_SATA_REF;
+
 	clrsetbits_le32(&anatop_regs->ana_misc1,
 			ANADIG_ANA_MISC1_LVDSCLK1_IBEN |
 			ANADIG_ANA_MISC1_LVDS1_CLK_SEL_MASK,
-			ANADIG_ANA_MISC1_LVDSCLK1_OBEN | 0xb);
+			ANADIG_ANA_MISC1_LVDSCLK1_OBEN | lvds1_clk_sel);
 
 	/* PCIe reference clock sourced from AXI. */
 	clrbits_le32(&ccm_regs->cbcmr, MXC_CCM_CBCMR_PCIE_AXI_CLK_SEL);
diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c
index 1ab69f6..7b5c1e4 100644
--- a/arch/arm/cpu/armv7/mx6/ddr.c
+++ b/arch/arm/cpu/armv7/mx6/ddr.c
@@ -184,18 +184,18 @@
  */
 #define MR(val, ba, cmd, cs1) \
 	((val << 16) | (1 << 15) | (cmd << 4) | (cs1 << 3) | ba)
-void mx6_dram_cfg(const struct mx6_ddr_sysinfo *i,
-		  const struct mx6_mmdc_calibration *c,
-		  const struct mx6_ddr3_cfg *m)
+void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo,
+		  const struct mx6_mmdc_calibration *calib,
+		  const struct mx6_ddr3_cfg *ddr3_cfg)
 {
 	volatile struct mmdc_p_regs *mmdc0;
 	volatile struct mmdc_p_regs *mmdc1;
-	u32 reg;
+	u32 val;
 	u8 tcke, tcksrx, tcksre, txpdll, taofpd, taonpd, trrd;
 	u8 todtlon, taxpd, tanpd, tcwl, txp, tfaw, tcl;
 	u8 todt_idle_off = 0x4; /* from DDR3 Script Aid spreadsheet */
 	u16 trcd, trc, tras, twr, tmrd, trtp, trp, twtr, trfc, txs, txpr;
-	u16 CS0_END;
+	u16 cs0_end;
 	u16 tdllk = 0x1ff; /* DLL locking time: 512 cycles (JEDEC DDR3) */
 	u8 coladdr;
 	int clkper; /* clock period in picoseconds */
@@ -215,13 +215,12 @@
 		clock = 400;
 		tcwl = 3;
 	}
-	clkper = (1000*1000)/clock; /* ps */
+	clkper = (1000 * 1000) / clock; /* pico seconds */
 	todtlon = tcwl;
 	taxpd = tcwl;
 	tanpd = tcwl;
-	tcwl = tcwl;
 
-	switch (m->density) {
+	switch (ddr3_cfg->density) {
 	case 1: /* 1Gb per chip */
 		trfc = DIV_ROUND_UP(110000, clkper) - 1;
 		txs = DIV_ROUND_UP(120000, clkper) - 1;
@@ -240,80 +239,82 @@
 		break;
 	default:
 		/* invalid density */
-		printf("invalid chip density\n");
+		puts("invalid chip density\n");
 		hang();
 		break;
 	}
 	txpr = txs;
 
-	switch (m->mem_speed) {
+	switch (ddr3_cfg->mem_speed) {
 	case 800:
-		txp = DIV_ROUND_UP(MAX(3*clkper, 7500), clkper) - 1;
-		tcke = DIV_ROUND_UP(MAX(3*clkper, 7500), clkper) - 1;
-		if (m->pagesz == 1) {
+		txp = DIV_ROUND_UP(MAX(3 * clkper, 7500), clkper) - 1;
+		tcke = DIV_ROUND_UP(MAX(3 * clkper, 7500), clkper) - 1;
+		if (ddr3_cfg->pagesz == 1) {
 			tfaw = DIV_ROUND_UP(40000, clkper) - 1;
-			trrd = DIV_ROUND_UP(MAX(4*clkper, 10000), clkper) - 1;
+			trrd = DIV_ROUND_UP(MAX(4 * clkper, 10000), clkper) - 1;
 		} else {
 			tfaw = DIV_ROUND_UP(50000, clkper) - 1;
-			trrd = DIV_ROUND_UP(MAX(4*clkper, 10000), clkper) - 1;
+			trrd = DIV_ROUND_UP(MAX(4 * clkper, 10000), clkper) - 1;
 		}
 		break;
 	case 1066:
-		txp = DIV_ROUND_UP(MAX(3*clkper, 7500), clkper) - 1;
-		tcke = DIV_ROUND_UP(MAX(3*clkper, 5625), clkper) - 1;
-		if (m->pagesz == 1) {
+		txp = DIV_ROUND_UP(MAX(3 * clkper, 7500), clkper) - 1;
+		tcke = DIV_ROUND_UP(MAX(3 * clkper, 5625), clkper) - 1;
+		if (ddr3_cfg->pagesz == 1) {
 			tfaw = DIV_ROUND_UP(37500, clkper) - 1;
-			trrd = DIV_ROUND_UP(MAX(4*clkper, 7500), clkper) - 1;
+			trrd = DIV_ROUND_UP(MAX(4 * clkper, 7500), clkper) - 1;
 		} else {
 			tfaw = DIV_ROUND_UP(50000, clkper) - 1;
-			trrd = DIV_ROUND_UP(MAX(4*clkper, 10000), clkper) - 1;
+			trrd = DIV_ROUND_UP(MAX(4 * clkper, 10000), clkper) - 1;
 		}
 		break;
 	case 1333:
-		txp = DIV_ROUND_UP(MAX(3*clkper, 6000), clkper) - 1;
-		tcke = DIV_ROUND_UP(MAX(3*clkper, 5625), clkper) - 1;
-		if (m->pagesz == 1) {
+		txp = DIV_ROUND_UP(MAX(3 * clkper, 6000), clkper) - 1;
+		tcke = DIV_ROUND_UP(MAX(3 * clkper, 5625), clkper) - 1;
+		if (ddr3_cfg->pagesz == 1) {
 			tfaw = DIV_ROUND_UP(30000, clkper) - 1;
-			trrd = DIV_ROUND_UP(MAX(4*clkper, 6000), clkper) - 1;
+			trrd = DIV_ROUND_UP(MAX(4 * clkper, 6000), clkper) - 1;
 		} else {
 			tfaw = DIV_ROUND_UP(45000, clkper) - 1;
-			trrd = DIV_ROUND_UP(MAX(4*clkper, 7500), clkper) - 1;
+			trrd = DIV_ROUND_UP(MAX(4 * clkper, 7500), clkper) - 1;
 		}
 		break;
 	case 1600:
-		txp = DIV_ROUND_UP(MAX(3*clkper, 6000), clkper) - 1;
-		tcke = DIV_ROUND_UP(MAX(3*clkper, 5000), clkper) - 1;
-		if (m->pagesz == 1) {
+		txp = DIV_ROUND_UP(MAX(3 * clkper, 6000), clkper) - 1;
+		tcke = DIV_ROUND_UP(MAX(3 * clkper, 5000), clkper) - 1;
+		if (ddr3_cfg->pagesz == 1) {
 			tfaw = DIV_ROUND_UP(30000, clkper) - 1;
-			trrd = DIV_ROUND_UP(MAX(4*clkper, 6000), clkper) - 1;
+			trrd = DIV_ROUND_UP(MAX(4 * clkper, 6000), clkper) - 1;
 		} else {
 			tfaw = DIV_ROUND_UP(40000, clkper) - 1;
-			trrd = DIV_ROUND_UP(MAX(4*clkper, 7500), clkper) - 1;
+			trrd = DIV_ROUND_UP(MAX(4 * clkper, 7500), clkper) - 1;
 		}
 		break;
 	default:
-		printf("invalid memory speed\n");
+		puts("invalid memory speed\n");
 		hang();
 		break;
 	}
-	txpdll = DIV_ROUND_UP(MAX(10*clkper, 24000), clkper) - 1;
-	tcl = DIV_ROUND_UP(m->trcd, clkper/10) - 3;
-	tcksre = DIV_ROUND_UP(MAX(5*clkper, 10000), clkper);
-	tcksrx = tcksre;
+	txpdll = DIV_ROUND_UP(MAX(10 * clkper, 24000), clkper) - 1;
+	tcksre = DIV_ROUND_UP(MAX(5 * clkper, 10000), clkper);
 	taonpd = DIV_ROUND_UP(2000, clkper) - 1;
+	tcksrx = tcksre;
 	taofpd = taonpd;
-	trp = DIV_ROUND_UP(m->trcd, clkper/10) - 1;
+	twr  = DIV_ROUND_UP(15000, clkper) - 1;
+	tmrd = DIV_ROUND_UP(MAX(12 * clkper, 15000), clkper) - 1;
+	trc  = DIV_ROUND_UP(ddr3_cfg->trcmin, clkper / 10) - 1;
+	tras = DIV_ROUND_UP(ddr3_cfg->trasmin, clkper / 10) - 1;
+	tcl  = DIV_ROUND_UP(ddr3_cfg->trcd, clkper / 10) - 3;
+	trp  = DIV_ROUND_UP(ddr3_cfg->trcd, clkper / 10) - 1;
+	twtr = ROUND(MAX(4 * clkper, 7500) / clkper, 1) - 1;
 	trcd = trp;
-	trc = DIV_ROUND_UP(m->trcmin, clkper/10) - 1;
-	tras = DIV_ROUND_UP(m->trasmin, clkper/10) - 1;
-	twr = DIV_ROUND_UP(15000, clkper) - 1;
-	tmrd = DIV_ROUND_UP(MAX(12*clkper, 15000), clkper) - 1;
-	twtr = ROUND(MAX(4*clkper, 7500)/clkper, 1) - 1;
 	trtp = twtr;
-	CS0_END = ((4*i->cs_density) <= 120) ? (4*i->cs_density)+7 : 127;
-	debug("density:%d Gb (%d Gb per chip)\n", i->cs_density, m->density);
+	cs0_end = 4 * sysinfo->cs_density - 1;
+
+	debug("density:%d Gb (%d Gb per chip)\n",
+	      sysinfo->cs_density, ddr3_cfg->density);
 	debug("clock: %dMHz (%d ps)\n", clock, clkper);
-	debug("memspd:%d\n", m->mem_speed);
+	debug("memspd:%d\n", ddr3_cfg->mem_speed);
 	debug("tcke=%d\n", tcke);
 	debug("tcksrx=%d\n", tcksrx);
 	debug("tcksre=%d\n", tcksre);
@@ -340,11 +341,11 @@
 	debug("twtr=%d\n", twtr);
 	debug("trrd=%d\n", trrd);
 	debug("txpr=%d\n", txpr);
-	debug("CS0_END=%d\n", CS0_END);
-	debug("ncs=%d\n", i->ncs);
-	debug("Rtt_wr=%d\n", i->rtt_wr);
-	debug("Rtt_nom=%d\n", i->rtt_nom);
-	debug("SRT=%d\n", m->SRT);
+	debug("cs0_end=%d\n", cs0_end);
+	debug("ncs=%d\n", sysinfo->ncs);
+	debug("Rtt_wr=%d\n", sysinfo->rtt_wr);
+	debug("Rtt_nom=%d\n", sysinfo->rtt_nom);
+	debug("SRT=%d\n", ddr3_cfg->SRT);
 	debug("tcl=%d\n", tcl);
 	debug("twr=%d\n", twr);
 
@@ -354,142 +355,136 @@
 	 *  see:
 	 *   appnote, ddr3 spreadsheet
 	 */
-	mmdc0->mpwldectrl0 = c->p0_mpwldectrl0;
-	mmdc0->mpwldectrl1 = c->p0_mpwldectrl1;
-	mmdc0->mpdgctrl0 = c->p0_mpdgctrl0;
-	mmdc0->mpdgctrl1 = c->p0_mpdgctrl1;
-	mmdc0->mprddlctl = c->p0_mprddlctl;
-	mmdc0->mpwrdlctl = c->p0_mpwrdlctl;
-	if (i->dsize > 1) {
-		mmdc1->mpwldectrl0 = c->p1_mpwldectrl0;
-		mmdc1->mpwldectrl1 = c->p1_mpwldectrl1;
-		mmdc1->mpdgctrl0 = c->p1_mpdgctrl0;
-		mmdc1->mpdgctrl1 = c->p1_mpdgctrl1;
-		mmdc1->mprddlctl = c->p1_mprddlctl;
-		mmdc1->mpwrdlctl = c->p1_mpwrdlctl;
+	mmdc0->mpwldectrl0 = calib->p0_mpwldectrl0;
+	mmdc0->mpwldectrl1 = calib->p0_mpwldectrl1;
+	mmdc0->mpdgctrl0 = calib->p0_mpdgctrl0;
+	mmdc0->mpdgctrl1 = calib->p0_mpdgctrl1;
+	mmdc0->mprddlctl = calib->p0_mprddlctl;
+	mmdc0->mpwrdlctl = calib->p0_mpwrdlctl;
+	if (sysinfo->dsize > 1) {
+		mmdc1->mpwldectrl0 = calib->p1_mpwldectrl0;
+		mmdc1->mpwldectrl1 = calib->p1_mpwldectrl1;
+		mmdc1->mpdgctrl0 = calib->p1_mpdgctrl0;
+		mmdc1->mpdgctrl1 = calib->p1_mpdgctrl1;
+		mmdc1->mprddlctl = calib->p1_mprddlctl;
+		mmdc1->mpwrdlctl = calib->p1_mpwrdlctl;
 	}
 
 	/* Read data DQ Byte0-3 delay */
-	mmdc0->mprddqby0dl = (u32)0x33333333;
-	mmdc0->mprddqby1dl = (u32)0x33333333;
-	if (i->dsize > 0) {
-		mmdc0->mprddqby2dl = (u32)0x33333333;
-		mmdc0->mprddqby3dl = (u32)0x33333333;
+	mmdc0->mprddqby0dl = 0x33333333;
+	mmdc0->mprddqby1dl = 0x33333333;
+	if (sysinfo->dsize > 0) {
+		mmdc0->mprddqby2dl = 0x33333333;
+		mmdc0->mprddqby3dl = 0x33333333;
 	}
-	if (i->dsize > 1) {
-		mmdc1->mprddqby0dl = (u32)0x33333333;
-		mmdc1->mprddqby1dl = (u32)0x33333333;
-		mmdc1->mprddqby2dl = (u32)0x33333333;
-		mmdc1->mprddqby3dl = (u32)0x33333333;
+
+	if (sysinfo->dsize > 1) {
+		mmdc1->mprddqby0dl = 0x33333333;
+		mmdc1->mprddqby1dl = 0x33333333;
+		mmdc1->mprddqby2dl = 0x33333333;
+		mmdc1->mprddqby3dl = 0x33333333;
 	}
 
 	/* MMDC Termination: rtt_nom:2 RZQ/2(120ohm), rtt_nom:1 RZQ/4(60ohm) */
-	reg = (i->rtt_nom == 2) ? 0x00011117 : 0x00022227;
-	mmdc0->mpodtctrl = reg;
-	if (i->dsize > 1)
-		mmdc1->mpodtctrl = reg;
+	val = (sysinfo->rtt_nom == 2) ? 0x00011117 : 0x00022227;
+	mmdc0->mpodtctrl = val;
+	if (sysinfo->dsize > 1)
+		mmdc1->mpodtctrl = val;
 
 	/* complete calibration */
-	reg = (1 << 11); /* Force measurement on delay-lines */
-	mmdc0->mpmur0 = reg;
-	if (i->dsize > 1)
-		mmdc1->mpmur0 = reg;
+	val = (1 << 11); /* Force measurement on delay-lines */
+	mmdc0->mpmur0 = val;
+	if (sysinfo->dsize > 1)
+		mmdc1->mpmur0 = val;
 
 	/* Step 1: configuration request */
 	mmdc0->mdscr = (u32)(1 << 15); /* config request */
 
 	/* Step 2: Timing configuration */
-	reg = (trfc << 24) | (txs << 16) | (txp << 13) | (txpdll << 9) |
-	      (tfaw << 4) | tcl;
-	mmdc0->mdcfg0 = reg;
-	reg = (trcd << 29) | (trp << 26) | (trc << 21) | (tras << 16) |
-	      (1 << 15) |		/* trpa */
-	      (twr << 9) | (tmrd << 5) | tcwl;
-	mmdc0->mdcfg1 = reg;
-	reg = (tdllk << 16) | (trtp << 6) | (twtr << 3) | trrd;
-	mmdc0->mdcfg2 = reg;
-	reg = (taofpd << 27) | (taonpd << 24) | (tanpd << 20) | (taxpd << 16) |
-	      (todtlon << 12) | (todt_idle_off << 4);
-	mmdc0->mdotc = reg;
-	mmdc0->mdasp = CS0_END; /* CS addressing */
+	mmdc0->mdcfg0 = (trfc << 24) | (txs << 16) | (txp << 13) |
+			(txpdll << 9) | (tfaw << 4) | tcl;
+	mmdc0->mdcfg1 = (trcd << 29) | (trp << 26) | (trc << 21) |
+			(tras << 16) | (1 << 15) /* trpa */ |
+			(twr << 9) | (tmrd << 5) | tcwl;
+	mmdc0->mdcfg2 = (tdllk << 16) | (trtp << 6) | (twtr << 3) | trrd;
+	mmdc0->mdotc = (taofpd << 27) | (taonpd << 24) | (tanpd << 20) |
+		       (taxpd << 16) | (todtlon << 12) | (todt_idle_off << 4);
+	mmdc0->mdasp = cs0_end; /* CS addressing */
 
 	/* Step 3: Configure DDR type */
-	reg = (i->cs1_mirror << 19) | (i->walat << 16) | (i->bi_on << 12) |
-	      (i->mif3_mode << 9) | (i->ralat << 6);
-	mmdc0->mdmisc = reg;
+	mmdc0->mdmisc = (sysinfo->cs1_mirror << 19) | (sysinfo->walat << 16) |
+			(sysinfo->bi_on << 12) | (sysinfo->mif3_mode << 9) |
+			(sysinfo->ralat << 6);
 
 	/* Step 4: Configure delay while leaving reset */
-	reg = (txpr << 16) | (i->sde_to_rst << 8) | (i->rst_to_cke << 0);
-	mmdc0->mdor = reg;
+	mmdc0->mdor = (txpr << 16) | (sysinfo->sde_to_rst << 8) |
+		      (sysinfo->rst_to_cke << 0);
 
 	/* Step 5: Configure DDR physical parameters (density and burst len) */
-	coladdr = m->coladdr;
-	if (m->coladdr == 8)		/* 8-bit COL is 0x3 */
+	coladdr = ddr3_cfg->coladdr;
+	if (ddr3_cfg->coladdr == 8)		/* 8-bit COL is 0x3 */
 		coladdr += 4;
-	else if (m->coladdr == 12)	/* 12-bit COL is 0x4 */
+	else if (ddr3_cfg->coladdr == 12)	/* 12-bit COL is 0x4 */
 		coladdr += 1;
-	reg = (m->rowaddr - 11) << 24 |		/* ROW */
-	      (coladdr - 9) << 20 |		/* COL */
-	      (1 << 19) |			/* Burst Length = 8 for DDR3 */
-	      (i->dsize << 16);			/* DDR data bus size */
-	mmdc0->mdctl = reg;
+	mmdc0->mdctl =  (ddr3_cfg->rowaddr - 11) << 24 |	/* ROW */
+			(coladdr - 9) << 20 |			/* COL */
+			(1 << 19) |		/* Burst Length = 8 for DDR3 */
+			(sysinfo->dsize << 16);		/* DDR data bus size */
 
 	/* Step 6: Perform ZQ calibration */
-	reg = (u32)0xa1390001; /* one-time HW ZQ calib */
-	mmdc0->mpzqhwctrl = reg;
-	if (i->dsize > 1)
-		mmdc1->mpzqhwctrl = reg;
+	val = 0xa1390001; /* one-time HW ZQ calib */
+	mmdc0->mpzqhwctrl = val;
+	if (sysinfo->dsize > 1)
+		mmdc1->mpzqhwctrl = val;
 
 	/* Step 7: Enable MMDC with desired chip select */
-	reg = mmdc0->mdctl |
-	      (1 << 31) |			/* SDE_0 for CS0 */
-	      ((i->ncs == 2) ? 1 : 0) << 30;	/* SDE_1 for CS1 */
-	mmdc0->mdctl = reg;
+	mmdc0->mdctl |= (1 << 31) |			     /* SDE_0 for CS0 */
+			((sysinfo->ncs == 2) ? 1 : 0) << 30; /* SDE_1 for CS1 */
 
 	/* Step 8: Write Mode Registers to Init DDR3 devices */
-	for (cs = 0; cs < i->ncs; cs++) {
+	for (cs = 0; cs < sysinfo->ncs; cs++) {
 		/* MR2 */
-		reg = (i->rtt_wr & 3) << 9 | (m->SRT & 1) << 7 |
+		val = (sysinfo->rtt_wr & 3) << 9 | (ddr3_cfg->SRT & 1) << 7 |
 		      ((tcwl - 3) & 3) << 3;
-		mmdc0->mdscr = (u32)MR(reg, 2, 3, cs);
+		mmdc0->mdscr = MR(val, 2, 3, cs);
 		/* MR3 */
-		mmdc0->mdscr = (u32)MR(0, 3, 3, cs);
+		mmdc0->mdscr = MR(0, 3, 3, cs);
 		/* MR1 */
-		reg = ((i->rtt_nom & 1) ? 1 : 0) << 2 |
-		      ((i->rtt_nom & 2) ? 1 : 0) << 6;
-		mmdc0->mdscr = (u32)MR(reg, 1, 3, cs);
-		reg = ((tcl - 1) << 4) |	/* CAS */
+		val = ((sysinfo->rtt_nom & 1) ? 1 : 0) << 2 |
+		      ((sysinfo->rtt_nom & 2) ? 1 : 0) << 6;
+		mmdc0->mdscr = MR(val, 1, 3, cs);
+		/* MR0 */
+		val = ((tcl - 1) << 4) |	/* CAS */
 		      (1 << 8)   |		/* DLL Reset */
 		      ((twr - 3) << 9);		/* Write Recovery */
-		/* MR0 */
-		mmdc0->mdscr = (u32)MR(reg, 0, 3, cs);
+		mmdc0->mdscr = MR(val, 0, 3, cs);
 		/* ZQ calibration */
-		reg = (1 << 10);
-		mmdc0->mdscr = (u32)MR(reg, 0, 4, cs);
+		val = (1 << 10);
+		mmdc0->mdscr = MR(val, 0, 4, cs);
 	}
 
 	/* Step 10: Power down control and self-refresh */
-	reg = (tcke & 0x7) << 16 |
-	      5            << 12 |  /* PWDT_1: 256 cycles */
-	      5            <<  8 |  /* PWDT_0: 256 cycles */
-	      1            <<  6 |  /* BOTH_CS_PD */
-	      (tcksrx & 0x7) << 3 |
-	      (tcksre & 0x7);
-	mmdc0->mdpdc = reg;
-	mmdc0->mapsr = (u32)0x00011006; /* ADOPT power down enabled */
+	mmdc0->mdpdc = (tcke & 0x7) << 16 |
+			5            << 12 |  /* PWDT_1: 256 cycles */
+			5            <<  8 |  /* PWDT_0: 256 cycles */
+			1            <<  7 |  /* SLOW_PD */
+			1            <<  6 |  /* BOTH_CS_PD */
+			(tcksrx & 0x7) << 3 |
+			(tcksre & 0x7);
+	mmdc0->mapsr = 0x00001006; /* ADOPT power down enabled */
 
 	/* Step 11: Configure ZQ calibration: one-time and periodic 1ms */
-	mmdc0->mpzqhwctrl = (u32)0xa1390003;
-	if (i->dsize > 1)
-		mmdc1->mpzqhwctrl = (u32)0xa1390003;
+	val = 0xa1390003;
+	mmdc0->mpzqhwctrl = val;
+	if (sysinfo->dsize > 1)
+		mmdc1->mpzqhwctrl = val;
 
 	/* Step 12: Configure and activate periodic refresh */
-	reg = (1 << 14) |	/* REF_SEL: Periodic refresh cycles of 32kHz */
-	      (7 << 11);	/* REFR: Refresh Rate - 8 refreshes */
-	mmdc0->mdref = reg;
+	mmdc0->mdref = (1 << 14) | /* REF_SEL: Periodic refresh cycle: 32kHz */
+		       (7 << 11);  /* REFR: Refresh Rate - 8 refreshes */
 
 	/* Step 13: Deassert config request - init complete */
-	mmdc0->mdscr = (u32)0x00000000;
+	mmdc0->mdscr = 0x00000000;
 
 	/* wait for auto-ZQ calibration to complete */
 	mdelay(1);
diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c
index ac84a1f..ba21cfe 100644
--- a/arch/arm/cpu/armv7/mx6/soc.c
+++ b/arch/arm/cpu/armv7/mx6/soc.c
@@ -324,10 +324,10 @@
 	/* reserved value should start rom usb */
 	{"usb",		MAKE_CFGVAL(0x01, 0x00, 0x00, 0x00)},
 	{"sata",	MAKE_CFGVAL(0x20, 0x00, 0x00, 0x00)},
-	{"escpi1:0",	MAKE_CFGVAL(0x30, 0x00, 0x00, 0x08)},
-	{"escpi1:1",	MAKE_CFGVAL(0x30, 0x00, 0x00, 0x18)},
-	{"escpi1:2",	MAKE_CFGVAL(0x30, 0x00, 0x00, 0x28)},
-	{"escpi1:3",	MAKE_CFGVAL(0x30, 0x00, 0x00, 0x38)},
+	{"ecspi1:0",	MAKE_CFGVAL(0x30, 0x00, 0x00, 0x08)},
+	{"ecspi1:1",	MAKE_CFGVAL(0x30, 0x00, 0x00, 0x18)},
+	{"ecspi1:2",	MAKE_CFGVAL(0x30, 0x00, 0x00, 0x28)},
+	{"ecspi1:3",	MAKE_CFGVAL(0x30, 0x00, 0x00, 0x38)},
 	/* 4 bit bus width */
 	{"esdhc1",	MAKE_CFGVAL(0x40, 0x20, 0x00, 0x00)},
 	{"esdhc2",	MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)},
@@ -430,6 +430,9 @@
 	}
 #endif
 
+	/* Must disable the L2 before changing the latency parameters */
+	clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
+
 	writel(0x132, &pl310->pl310_tag_latency_ctrl);
 	writel(0x132, &pl310->pl310_data_latency_ctrl);
 
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 1ccd827..5f2b946 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -9,7 +9,6 @@
 	exynos5250-smdk5250.dtb \
 	exynos5420-smdk5420.dtb \
 	exynos5420-peach-pit.dtb
-dtb-$(CONFIG_MX6) += imx6q-sabreauto.dtb
 dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \
 	tegra20-medcom-wide.dtb \
 	tegra20-paz00.dtb \
diff --git a/arch/arm/dts/imx6q-sabreauto.dts b/arch/arm/dts/imx6q-sabreauto.dts
deleted file mode 100644
index 7af2a88..0000000
--- a/arch/arm/dts/imx6q-sabreauto.dts
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Copyright 2012 Freescale Semiconductor, Inc.
- * Copyright 2011 Linaro Ltd.
- *
- * SPDX-License-Identifier:     GPL-2.0+
- */
-
-/dts-v1/;
-
-/ {
-	model = "Freescale i.MX6 Quad SABRE Automotive Board";
-	compatible = "fsl,imx6q-sabreauto", "fsl,imx6q";
-};
diff --git a/arch/arm/include/asm/arch-mx6/clock.h b/arch/arm/include/asm/arch-mx6/clock.h
index 339c789..c11674f 100644
--- a/arch/arm/include/asm/arch-mx6/clock.h
+++ b/arch/arm/include/asm/arch-mx6/clock.h
@@ -52,12 +52,17 @@
 u32 imx_get_uartclk(void);
 u32 imx_get_fecclk(void);
 unsigned int mxc_get_clock(enum mxc_clock clk);
+void setup_gpmi_io_clk(u32 cfg);
 void enable_ocotp_clk(unsigned char enable);
 void enable_usboh3_clk(unsigned char enable);
+void enable_uart_clk(unsigned char enable);
+int enable_cspi_clock(unsigned char enable, unsigned spi_num);
+int enable_usdhc_clk(unsigned char enable, unsigned bus_num);
 int enable_sata_clock(void);
 int enable_pcie_clock(void);
 int enable_i2c_clk(unsigned char enable, unsigned i2c_num);
 int enable_spi_clk(unsigned char enable, unsigned spi_num);
 void enable_ipu_clock(void);
 int enable_fec_anatop_clock(enum enet_freq freq);
+void enable_enet_clk(unsigned char enable);
 #endif /* __ASM_ARCH_CLOCK_H */
diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h
index 2631beb..22614fc 100644
--- a/arch/arm/include/asm/arch-mx6/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx6/imx-regs.h
@@ -419,6 +419,19 @@
 	u32 gpr[14];
 };
 
+struct gpc {
+	u32	cntr;
+	u32	pgr;
+	u32	imr1;
+	u32	imr2;
+	u32	imr3;
+	u32	imr4;
+	u32	isr1;
+	u32	isr2;
+	u32	isr3;
+	u32	isr4;
+};
+
 #define IOMUXC_GPR2_COUNTER_RESET_VAL_OFFSET		20
 #define IOMUXC_GPR2_COUNTER_RESET_VAL_MASK		(3<<IOMUXC_GPR2_COUNTER_RESET_VAL_OFFSET)
 #define IOMUXC_GPR2_LVDS_CLK_SHIFT_OFFSET		16
diff --git a/arch/arm/include/asm/arch-mx6/iomux.h b/arch/arm/include/asm/arch-mx6/iomux.h
index f54db69..9b3a91f 100644
--- a/arch/arm/include/asm/arch-mx6/iomux.h
+++ b/arch/arm/include/asm/arch-mx6/iomux.h
@@ -19,6 +19,12 @@
 #define IOMUXC_GPR1_TEST_POWERDOWN		(1 << 18)
 
 /*
+ * IOMUXC_GPR5 bit fields
+ */
+#define IOMUXC_GPR5_PCIE_BTNRST			(1 << 19)
+#define IOMUXC_GPR5_PCIE_PERST			(1 << 18)
+
+/*
  * IOMUXC_GPR8 bit fields
  */
 #define IOMUXC_GPR8_PCS_TX_DEEMPH_GEN1_MASK		(0x3f << 0)
@@ -35,12 +41,15 @@
 /*
  * IOMUXC_GPR12 bit fields
  */
+#define IOMUXC_GPR12_RX_EQ_2			(0x2 << 0)
+#define IOMUXC_GPR12_RX_EQ_MASK			(0x7 << 0)
 #define IOMUXC_GPR12_LOS_LEVEL_9		(0x9 << 4)
 #define IOMUXC_GPR12_LOS_LEVEL_MASK		(0x1f << 4)
 #define IOMUXC_GPR12_APPS_LTSSM_ENABLE		(1 << 10)
 #define IOMUXC_GPR12_DEVICE_TYPE_EP		(0x0 << 12)
 #define IOMUXC_GPR12_DEVICE_TYPE_RC		(0x4 << 12)
 #define IOMUXC_GPR12_DEVICE_TYPE_MASK		(0xf << 12)
+#define IOMUXC_GPR12_TEST_POWERDOWN		(1 << 30)
 
 /*
  * IOMUXC_GPR13 bit fields
diff --git a/arch/arm/include/asm/arch-mx6/sys_proto.h b/arch/arm/include/asm/arch-mx6/sys_proto.h
index 306d699..c35a9051 100644
--- a/arch/arm/include/asm/arch-mx6/sys_proto.h
+++ b/arch/arm/include/asm/arch-mx6/sys_proto.h
@@ -20,8 +20,9 @@
 /* returns MXC_CPU_ value */
 #define cpu_type(rev) (((rev) >> 12)&0xff)
 
-/* use with MXC_CPU_ constants */
-#define is_cpu_type(cpu) (cpu_type(get_cpu_rev()) == cpu)
+/* both macros return/take MXC_CPU_ constants */
+#define get_cpu_type()	(cpu_type(get_cpu_rev()))
+#define is_cpu_type(cpu) (get_cpu_type() == cpu)
 
 const char *get_imx_type(u32 imxtype);
 unsigned imx_ddr_size(void);
diff --git a/arch/arm/include/asm/imx-common/mxc_i2c.h b/arch/arm/include/asm/imx-common/mxc_i2c.h
index 47a9edc..182c2f3 100644
--- a/arch/arm/include/asm/imx-common/mxc_i2c.h
+++ b/arch/arm/include/asm/imx-common/mxc_i2c.h
@@ -19,6 +19,39 @@
 	struct i2c_pin_ctrl sda;
 };
 
+#if defined(CONFIG_MX6QDL)
+#define I2C_PADS(name, scl_i2c, scl_gpio, scl_gp, sda_i2c, sda_gpio, sda_gp) \
+	struct i2c_pads_info mx6q_##name = {		\
+		.scl = {				\
+			.i2c_mode = MX6Q_##scl_i2c,	\
+			.gpio_mode = MX6Q_##scl_gpio,	\
+			.gp = scl_gp,			\
+		},					\
+		.sda = {				\
+			.i2c_mode = MX6Q_##sda_i2c,	\
+			.gpio_mode = MX6Q_##sda_gpio,	\
+			.gp = sda_gp,			\
+		}					\
+	};						\
+	struct i2c_pads_info mx6s_##name = {		\
+		.scl = {				\
+			.i2c_mode = MX6DL_##scl_i2c,	\
+			.gpio_mode = MX6DL_##scl_gpio,	\
+			.gp = scl_gp,			\
+		},					\
+		.sda = {				\
+			.i2c_mode = MX6DL_##sda_i2c,	\
+			.gpio_mode = MX6DL_##sda_gpio,	\
+			.gp = sda_gp,			\
+		}					\
+	};
+
+
+#define I2C_PADS_INFO(name)	\
+	(is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D)) ? \
+					&mx6q_##name : &mx6s_##name
+#endif
+
 void setup_i2c(unsigned i2c_index, int speed, int slave_addr,
 		struct i2c_pads_info *p);
 void bus_i2c_init(void *base, int speed, int slave_addr,
diff --git a/board/compulab/cm_fx6/Kconfig b/board/compulab/cm_fx6/Kconfig
new file mode 100644
index 0000000..42a8438
--- /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 0000000..5b2623a
--- /dev/null
+++ b/board/compulab/cm_fx6/MAINTAINERS
@@ -0,0 +1,6 @@
+CM_FX6 BOARD
+M:	Nikita Kiryanov <nikita@compulab.co.il>
+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 0000000..3e5c903
--- /dev/null
+++ b/board/compulab/cm_fx6/Makefile
@@ -0,0 +1,12 @@
+#
+# (C) Copyright 2014 CompuLab, Ltd. <www.compulab.co.il>
+#
+# Authors: Nikita Kiryanov <nikita@compulab.co.il>
+#
+# 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 0000000..fdb8ebf
--- /dev/null
+++ b/board/compulab/cm_fx6/cm_fx6.c
@@ -0,0 +1,483 @@
+/*
+ * Board functions for Compulab CM-FX6 board
+ *
+ * Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/
+ *
+ * Author: Nikita Kiryanov <nikita@compulab.co.il>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <fsl_esdhc.h>
+#include <miiphy.h>
+#include <netdev.h>
+#include <fdt_support.h>
+#include <sata.h>
+#include <asm/arch/crm_regs.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/iomux.h>
+#include <asm/imx-common/mxc_i2c.h>
+#include <asm/imx-common/sata.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include "common.h"
+#include "../common/eeprom.h"
+
+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 | \
+			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 |	\
+			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)
+
+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)),
+};
+
+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);
+	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)),
+	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},
+	{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
+
+#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;
+	cm_fx6_setup_gpmi_nand();
+	cm_fx6_setup_i2c();
+
+	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;
+}
+
+u32 get_board_rev(void)
+{
+	return cl_eeprom_get_board_rev();
+}
+
diff --git a/board/compulab/cm_fx6/common.c b/board/compulab/cm_fx6/common.c
new file mode 100644
index 0000000..1f39679
--- /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 <nikita@compulab.co.il>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/gpio.h>
+#include <fsl_esdhc.h>
+#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 0000000..76097f8
--- /dev/null
+++ b/board/compulab/cm_fx6/common.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/
+ *
+ * Author: Nikita Kiryanov <nikita@compulab.co.il>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <asm/arch/mx6-pins.h>
+#include <asm/arch/clock.h>
+
+#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)
+#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)
+#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);
diff --git a/board/compulab/cm_fx6/imximage.cfg b/board/compulab/cm_fx6/imximage.cfg
new file mode 100644
index 0000000..420947e
--- /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 0000000..3948ba2
--- /dev/null
+++ b/board/compulab/cm_fx6/spl.c
@@ -0,0 +1,366 @@
+/*
+ * SPL specific code for Compulab CM-FX6 board
+ *
+ * Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/
+ *
+ * Author: Nikita Kiryanov <nikita@compulab.co.il>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/arch/mx6-ddr.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/crm_regs.h>
+#include <asm/imx-common/iomux-v3.h>
+#include <fsl_esdhc.h>
+#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)
+{
+	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();
+	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
diff --git a/board/compulab/common/eeprom.c b/board/compulab/common/eeprom.c
index 20fe3e1..85442cd 100644
--- a/board/compulab/common/eeprom.c
+++ b/board/compulab/common/eeprom.c
@@ -31,8 +31,19 @@
 
 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)
diff --git a/board/freescale/mx6sabresd/mx6dlsabresd.cfg b/board/freescale/mx6sabresd/mx6dlsabresd.cfg
new file mode 100644
index 0000000..f35f22e
--- /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
diff --git a/board/gateworks/gw_ventana/eeprom.c b/board/gateworks/gw_ventana/eeprom.c
index 3edc915..ab3bab8 100644
--- a/board/gateworks/gw_ventana/eeprom.c
+++ b/board/gateworks/gw_ventana/eeprom.c
@@ -80,6 +80,9 @@
 	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 1cf38d4..a34a9a8 100644
--- a/board/gateworks/gw_ventana/gsc.c
+++ b/board/gateworks/gw_ventana/gsc.c
@@ -117,6 +117,10 @@
 		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 a222921..8d086f8 100644
--- a/board/gateworks/gw_ventana/gw_ventana.c
+++ b/board/gateworks/gw_ventana/gw_ventana.c
@@ -31,6 +31,7 @@
 #include <mmc.h>
 #include <mtd_node.h>
 #include <netdev.h>
+#include <pci.h>
 #include <power/pmic.h>
 #include <power/ltc3676_pmic.h>
 #include <power/pfuze100_pmic.h>
@@ -299,6 +300,7 @@
 	/* 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 +394,8 @@
 	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 +617,14 @@
 	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 +662,30 @@
 	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 +934,44 @@
 		.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 */
@@ -997,14 +1061,16 @@
 #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);
 	}
 
 	/* 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)
@@ -1092,6 +1158,35 @@
 	}
 	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
@@ -1283,6 +1378,7 @@
 		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
@@ -1305,7 +1401,8 @@
 				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")) {
@@ -1341,10 +1438,11 @@
 	 *  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
diff --git a/board/gateworks/gw_ventana/gw_ventana_spl.c b/board/gateworks/gw_ventana/gw_ventana_spl.c
index e943879..9fc253b 100644
--- a/board/gateworks/gw_ventana/gw_ventana_spl.c
+++ b/board/gateworks/gw_ventana/gw_ventana_spl.c
@@ -201,55 +201,79 @@
 	.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 = 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 = 0x37393C38,
-	.p1_mpwrdlctl = 0x42334538,
+	.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 @@
 	.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 @@
 	/*
 	 * 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))
diff --git a/board/gateworks/gw_ventana/ventana_eeprom.h b/board/gateworks/gw_ventana/ventana_eeprom.h
index d64b910..af12711 100644
--- a/board/gateworks/gw_ventana/ventana_eeprom.h
+++ b/board/gateworks/gw_ventana/ventana_eeprom.h
@@ -109,6 +109,7 @@
 	GW52xx,
 	GW53xx,
 	GW54xx,
+	GW552x,
 	GW_UNKNOWN,
 	GW_BADCRC,
 };
diff --git a/configs/cm_fx6_defconfig b/configs/cm_fx6_defconfig
new file mode 100644
index 0000000..50c06f7
--- /dev/null
+++ b/configs/cm_fx6_defconfig
@@ -0,0 +1,4 @@
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/compulab/cm_fx6/imximage.cfg,MX6QDL,SPL"
++S:CONFIG_ARM=y
++S:CONFIG_TARGET_CM_FX6=y
diff --git a/configs/mx6dlsabresd_defconfig b/configs/mx6dlsabresd_defconfig
index 9ce960e..7f6cdff 100644
--- a/configs/mx6dlsabresd_defconfig
+++ b/configs/mx6dlsabresd_defconfig
@@ -1,3 +1,3 @@
-CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6dl.cfg,MX6DL"
+CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6sabresd/mx6dlsabresd.cfg,MX6DL"
 CONFIG_ARM=y
 CONFIG_TARGET_MX6SABRESD=y
diff --git a/doc/README.imximage b/doc/README.imximage
index dcda200..27d3354 100644
--- a/doc/README.imximage
+++ b/doc/README.imximage
@@ -120,7 +120,7 @@
 				DATA 4 0x73FA88a0 0x200
 
 The processor support up to 60 register programming commands for IMXIMAGE_VERSION 1
-and 121 register programming commands for IMXIMAGE_VERSION 2.
+and 220 register programming commands for IMXIMAGE_VERSION 2.
 An error is generated if more commands are found in the configuration file.
 
 3. All commands are optional to program.
diff --git a/drivers/block/dwc_ahsata.c b/drivers/block/dwc_ahsata.c
index 15d65d7..29f478b 100644
--- a/drivers/block/dwc_ahsata.c
+++ b/drivers/block/dwc_ahsata.c
@@ -864,6 +864,23 @@
 	return blkcnt;
 }
 
+int sata_port_status(int dev, int port)
+{
+	struct sata_port_regs *port_mmio;
+	struct ahci_probe_ent *probe_ent = NULL;
+
+	if (dev < 0 || dev > (CONFIG_SYS_SATA_MAX_DEVICE - 1))
+		return -EINVAL;
+
+	if (sata_dev_desc[dev].priv == NULL)
+		return -ENODEV;
+
+	probe_ent = (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+	port_mmio = (struct sata_port_regs *)probe_ent->port[port].port_mmio;
+
+	return readl(&(port_mmio->ssts)) && SATA_PORT_SSTS_DET_MASK;
+}
+
 /*
  * SATA interface between low level driver and command layer
  */
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
index 4cefda4..549d648 100644
--- a/drivers/net/fec_mxc.c
+++ b/drivers/net/fec_mxc.c
@@ -28,6 +28,14 @@
  */
 #define FEC_XFER_TIMEOUT	5000
 
+/*
+ * The standard 32-byte DMA alignment does not work on mx6solox, which requires
+ * 64-byte alignment in the DMA RX FEC buffer.
+ * Introduce the FEC_DMA_RX_MINALIGN which can cover mx6solox needs and also
+ * satisfies the alignment on other SoCs (32-bytes)
+ */
+#define FEC_DMA_RX_MINALIGN	64
+
 #ifndef CONFIG_MII
 #error "CONFIG_MII has to be defined!"
 #endif
@@ -711,13 +719,37 @@
 			break;
 	}
 
-	if (!timeout)
+	if (!timeout) {
 		ret = -EINVAL;
+		goto out;
+	}
 
-	invalidate_dcache_range(addr, addr + size);
-	if (readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_READY)
+	/*
+	 * The TDAR bit is cleared when the descriptors are all out from TX
+	 * but on mx6solox we noticed that the READY bit is still not cleared
+	 * right after TDAR.
+	 * These are two distinct signals, and in IC simulation, we found that
+	 * TDAR always gets cleared prior than the READY bit of last BD becomes
+	 * cleared.
+	 * In mx6solox, we use a later version of FEC IP. It looks like that
+	 * this intrinsic behaviour of TDAR bit has changed in this newer FEC
+	 * version.
+	 *
+	 * Fix this by polling the READY bit of BD after the TDAR polling,
+	 * which covers the mx6solox case and does not harm the other SoCs.
+	 */
+	timeout = FEC_XFER_TIMEOUT;
+	while (--timeout) {
+		invalidate_dcache_range(addr, addr + size);
+		if (!(readw(&fec->tbd_base[fec->tbd_index].status) &
+		    FEC_TBD_READY))
+			break;
+	}
+
+	if (!timeout)
 		ret = -EINVAL;
 
+out:
 	debug("fec_send: status 0x%x index %d ret %i\n",
 			readw(&fec->tbd_base[fec->tbd_index].status),
 			fec->tbd_index, ret);
@@ -881,9 +913,9 @@
 	/* Allocate RX buffers. */
 
 	/* Maximum RX buffer size. */
-	size = roundup(FEC_MAX_PKT_SIZE, ARCH_DMA_MINALIGN);
+	size = roundup(FEC_MAX_PKT_SIZE, FEC_DMA_RX_MINALIGN);
 	for (i = 0; i < FEC_RBD_NUM; i++) {
-		data = memalign(ARCH_DMA_MINALIGN, size);
+		data = memalign(FEC_DMA_RX_MINALIGN, size);
 		if (!data) {
 			printf("%s: error allocating rxbuf %d\n", __func__, i);
 			goto err_ring;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 4fd9c53..28859f3 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -648,6 +648,10 @@
 		pci_hose_read_config_word(hose, dev, PCI_DEVICE_ID, &device);
 		pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);
 
+#ifdef CONFIG_PCI_FIXUP_DEV
+		board_pci_fixup_dev(hose, dev, vendor, device, class);
+#endif
+
 #ifdef CONFIG_PCI_SCAN_SHOW
 		indent++;
 
diff --git a/drivers/pci/pcie_imx.c b/drivers/pci/pcie_imx.c
index a3982c4..fd7e4d4 100644
--- a/drivers/pci/pcie_imx.c
+++ b/drivers/pci/pcie_imx.c
@@ -23,13 +23,20 @@
 #define PCI_ACCESS_READ  0
 #define PCI_ACCESS_WRITE 1
 
+#ifdef CONFIG_MX6SX
+#define MX6_DBI_ADDR	0x08ffc000
+#define MX6_IO_ADDR	0x08000000
+#define MX6_MEM_ADDR	0x08100000
+#define MX6_ROOT_ADDR	0x08f00000
+#else
 #define MX6_DBI_ADDR	0x01ffc000
-#define MX6_DBI_SIZE	0x4000
 #define MX6_IO_ADDR	0x01000000
-#define MX6_IO_SIZE	0x100000
 #define MX6_MEM_ADDR	0x01100000
-#define MX6_MEM_SIZE	0xe00000
 #define MX6_ROOT_ADDR	0x01f00000
+#endif
+#define MX6_DBI_SIZE	0x4000
+#define MX6_IO_SIZE	0x100000
+#define MX6_MEM_SIZE	0xe00000
 #define MX6_ROOT_SIZE	0xfc000
 
 /* PCIe Port Logic registers (memory-mapped) */
@@ -57,6 +64,8 @@
 #define PHY_RX_OVRD_IN_LO_RX_DATA_EN (1 << 5)
 #define PHY_RX_OVRD_IN_LO_RX_PLL_EN (1 << 3)
 
+#define PCIE_PHY_PUP_REQ		(1 << 7)
+
 /* iATU registers */
 #define PCIE_ATU_VIEWPORT		0x900
 #define PCIE_ATU_REGION_INBOUND		(0x1 << 31)
@@ -421,9 +430,19 @@
 static int imx6_pcie_assert_core_reset(void)
 {
 	struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
+#if defined(CONFIG_MX6SX)
+	struct gpc *gpc_regs = (struct gpc *)GPC_BASE_ADDR;
 
+	/* SSP_EN is not used on MX6SX anymore */
+	setbits_le32(&iomuxc_regs->gpr[12], IOMUXC_GPR12_TEST_POWERDOWN);
+	/* Force PCIe PHY reset */
+	setbits_le32(&iomuxc_regs->gpr[5], IOMUXC_GPR5_PCIE_BTNRST);
+	/* Power up PCIe PHY */
+	setbits_le32(&gpc_regs->cntr, PCIE_PHY_PUP_REQ);
+#else
 	setbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_TEST_POWERDOWN);
 	clrbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_REF_SSP_EN);
+#endif
 
 	return 0;
 }
@@ -441,6 +460,12 @@
 			IOMUXC_GPR12_LOS_LEVEL_MASK,
 			IOMUXC_GPR12_LOS_LEVEL_9);
 
+#ifdef CONFIG_MX6SX
+	clrsetbits_le32(&iomuxc_regs->gpr[12],
+			IOMUXC_GPR12_RX_EQ_MASK,
+			IOMUXC_GPR12_RX_EQ_2);
+#endif
+
 	writel((0x0 << IOMUXC_GPR8_PCS_TX_DEEMPH_GEN1_OFFSET) |
 	       (0x0 << IOMUXC_GPR8_PCS_TX_DEEMPH_GEN2_3P5DB_OFFSET) |
 	       (20 << IOMUXC_GPR8_PCS_TX_DEEMPH_GEN2_6DB_OFFSET) |
@@ -517,9 +542,16 @@
 	 */
 	mdelay(50);
 
+#if defined(CONFIG_MX6SX)
+	/* SSP_EN is not used on MX6SX anymore */
+	clrbits_le32(&iomuxc_regs->gpr[12], IOMUXC_GPR12_TEST_POWERDOWN);
+	/* Clear PCIe PHY reset bit */
+	clrbits_le32(&iomuxc_regs->gpr[5], IOMUXC_GPR5_PCIE_BTNRST);
+#else
 	/* Enable PCIe */
 	clrbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_TEST_POWERDOWN);
 	setbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_REF_SSP_EN);
+#endif
 
 	imx6_pcie_toggle_reset();
 
diff --git a/drivers/serial/serial_lpuart.c b/drivers/serial/serial_lpuart.c
index da5f9a2..0a5e159 100644
--- a/drivers/serial/serial_lpuart.c
+++ b/drivers/serial/serial_lpuart.c
@@ -14,8 +14,13 @@
 
 #define US1_TDRE        (1 << 7)
 #define US1_RDRF        (1 << 5)
+#define US1_OR          (1 << 3)
 #define UC2_TE          (1 << 3)
 #define UC2_RE          (1 << 2)
+#define CFIFO_TXFLUSH   (1 << 7)
+#define CFIFO_RXFLUSH   (1 << 6)
+#define SFIFO_RXOF      (1 << 2)
+#define SFIFO_RXUF      (1 << 0)
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -38,14 +43,10 @@
 
 static int lpuart_serial_getc(void)
 {
-	u8 status;
-
-	while (!(__raw_readb(&base->us1) & US1_RDRF))
+	while (!(__raw_readb(&base->us1) & (US1_RDRF | US1_OR)))
 		WATCHDOG_RESET();
 
-	status = __raw_readb(&base->us1);
-	status |= US1_RDRF;
-	__raw_writeb(status, &base->us1);
+	barrier();
 
 	return __raw_readb(&base->ud);
 }
@@ -88,6 +89,12 @@
 	__raw_writeb(0, &base->umodem);
 	__raw_writeb(0, &base->uc1);
 
+	/* Disable FIFO and flush buffer */
+	__raw_writeb(0x0, &base->upfifo);
+	__raw_writeb(0x0, &base->utwfifo);
+	__raw_writeb(0x1, &base->urwfifo);
+	__raw_writeb(CFIFO_TXFLUSH | CFIFO_RXFLUSH, &base->ucfifo);
+
 	/* provide data bits, parity, stop bit, etc */
 
 	serial_setbrg();
diff --git a/include/configs/cm_fx6.h b/include/configs/cm_fx6.h
new file mode 100644
index 0000000..10d02b4
--- /dev/null
+++ b/include/configs/cm_fx6.h
@@ -0,0 +1,290 @@
+/*
+ * Config file for Compulab CM-FX6 board
+ *
+ * Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/
+ *
+ * Author: Nikita Kiryanov <nikita@compulab.co.il>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __CONFIG_CM_FX6_H
+#define __CONFIG_CM_FX6_H
+
+#include <asm/arch/imx-regs.h>
+#include <config_distro_defaults.h>
+#include "mx6_common.h"
+
+/* Machine config */
+#define CONFIG_MX6
+#define CONFIG_SYS_LITTLE_ENDIAN
+#define CONFIG_MACH_TYPE		4273
+#define CONFIG_SYS_HZ			1000
+
+/* Display information on boot */
+#define CONFIG_DISPLAY_CPUINFO
+#define CONFIG_DISPLAY_BOARDINFO
+#define CONFIG_TIMESTAMP
+
+/* CMD */
+#include <config_cmd_default.h>
+#define CONFIG_CMD_GREPENV
+#undef CONFIG_CMD_FLASH
+#undef CONFIG_CMD_LOADB
+#undef CONFIG_CMD_LOADS
+#undef CONFIG_CMD_XIMG
+#undef CONFIG_CMD_FPGA
+#undef CONFIG_CMD_IMLS
+
+/* MMC */
+#define CONFIG_MMC
+#define CONFIG_CMD_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_FSL_ESDHC
+#define CONFIG_FSL_USDHC
+#define CONFIG_SYS_FSL_USDHC_NUM	3
+#define CONFIG_SYS_FSL_ESDHC_ADDR	USDHC2_BASE_ADDR
+
+/* RAM */
+#define PHYS_SDRAM_1			MMDC0_ARB_BASE_ADDR
+#define PHYS_SDRAM_2			MMDC1_ARB_BASE_ADDR
+#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
+#define CONFIG_NR_DRAM_BANKS		2
+#define CONFIG_SYS_MEMTEST_START	0x10000000
+#define CONFIG_SYS_MEMTEST_END		0x10010000
+#define CONFIG_SYS_INIT_RAM_ADDR	IRAM_BASE_ADDR
+#define CONFIG_SYS_INIT_RAM_SIZE	IRAM_SIZE
+#define CONFIG_SYS_INIT_SP_OFFSET \
+	(CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
+#define CONFIG_SYS_INIT_SP_ADDR \
+	(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)
+
+/* Serial console */
+#define CONFIG_MXC_UART
+#define CONFIG_MXC_UART_BASE		UART4_BASE
+#define CONFIG_BAUDRATE			115200
+#define CONFIG_SYS_BAUDRATE_TABLE	{9600, 19200, 38400, 57600, 115200}
+
+/* Shell */
+#define CONFIG_SYS_PROMPT	"CM-FX6 # "
+#define CONFIG_SYS_CBSIZE	1024
+#define CONFIG_SYS_MAXARGS	16
+#define CONFIG_SYS_BARGSIZE	CONFIG_SYS_CBSIZE
+#define CONFIG_SYS_PBSIZE	(CONFIG_SYS_CBSIZE + \
+					sizeof(CONFIG_SYS_PROMPT) + 16)
+
+/* SPI flash */
+#define CONFIG_SYS_NO_FLASH
+#define CONFIG_CMD_SF
+#define CONFIG_SF_DEFAULT_BUS		0
+#define CONFIG_SF_DEFAULT_CS		0
+#define CONFIG_SF_DEFAULT_SPEED		25000000
+#define CONFIG_SF_DEFAULT_MODE		(SPI_MODE_0)
+
+/* Environment */
+#define CONFIG_ENV_OVERWRITE
+#define CONFIG_ENV_IS_IN_SPI_FLASH
+#define CONFIG_ENV_SPI_MAX_HZ		CONFIG_SF_DEFAULT_SPEED
+#define CONFIG_ENV_SPI_MODE		CONFIG_SF_DEFAULT_MODE
+#define CONFIG_ENV_SPI_BUS		CONFIG_SF_DEFAULT_BUS
+#define CONFIG_ENV_SPI_CS		CONFIG_SF_DEFAULT_CS
+#define CONFIG_ENV_SECT_SIZE		(64 * 1024)
+#define CONFIG_ENV_SIZE			(8 * 1024)
+#define CONFIG_ENV_OFFSET		(768 * 1024)
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"kernel=uImage-cm-fx6\0" \
+	"autoload=no\0" \
+	"loadaddr=0x10800000\0" \
+	"fdtaddr=0x11000000\0" \
+	"console=ttymxc3,115200\0" \
+	"ethprime=FEC0\0" \
+	"bootscr=boot.scr\0" \
+	"bootm_low=18000000\0" \
+	"video_hdmi=mxcfb0:dev=hdmi,1920x1080M-32@50,if=RGB32\0" \
+	"video_dvi=mxcfb0:dev=dvi,1280x800M-32@50,if=RGB32\0" \
+	"fdtfile=cm-fx6.dtb\0" \
+	"doboot=bootm ${loadaddr}\0" \
+	"loadfdt=false\0" \
+	"setboottypez=setenv kernel zImage-cm-fx6;" \
+		"setenv doboot bootz ${loadaddr} - ${fdtaddr};" \
+		"setenv loadfdt true;\0" \
+	"setboottypem=setenv kernel uImage-cm-fx6;" \
+		"setenv doboot bootm ${loadaddr};" \
+		"setenv loadfdt false;\0"\
+	"run_eboot=echo Starting EBOOT ...; "\
+		"mmc dev ${mmcdev} && " \
+		"mmc rescan && mmc read 10042000 a 400 && go 10042000\0" \
+	"mmcdev=2\0" \
+	"mmcroot=/dev/mmcblk0p2 rw rootwait\0" \
+	"loadmmcbootscript=load mmc ${mmcdev} ${loadaddr} ${bootscr}\0" \
+	"mmcbootscript=echo Running bootscript from mmc ...; "\
+		"source ${loadaddr}\0" \
+	"mmcargs=setenv bootargs console=${console} " \
+		"root=${mmcroot} " \
+		"${video}\0" \
+	"mmcloadkernel=load mmc ${mmcdev} ${loadaddr} ${kernel}\0" \
+	"mmcloadfdt=load mmc ${mmcdev} ${fdtaddr} ${fdtfile}\0" \
+	"mmcboot=echo Booting from mmc ...; " \
+		"run mmcargs; " \
+		"run doboot\0" \
+	"satadev=0\0" \
+	"sataroot=/dev/sda2 rw rootwait\0" \
+	"sataargs=setenv bootargs console=${console} " \
+		"root=${sataroot} " \
+		"${video}\0" \
+	"loadsatabootscript=load sata ${satadev} ${loadaddr} ${bootscr}\0" \
+	"satabootscript=echo Running bootscript from sata ...; " \
+		"source ${loadaddr}\0" \
+	"sataloadkernel=load sata ${satadev} ${loadaddr} ${kernel}\0" \
+	"sataloadfdt=load sata ${satadev} ${fdtaddr} ${fdtfile}\0" \
+	"sataboot=echo Booting from sata ...; "\
+		"run sataargs; " \
+		"run doboot\0" \
+	"nandroot=/dev/mtdblock4 rw\0" \
+	"nandrootfstype=ubifs\0" \
+	"nandargs=setenv bootargs console=${console} " \
+		"root=${nandroot} " \
+		"rootfstype=${nandrootfstype} " \
+		"${video}\0" \
+	"nandloadfdt=nand read ${fdtaddr} 780000 80000;\0" \
+	"nandboot=echo Booting from nand ...; " \
+		"run nandargs; " \
+		"nand read ${loadaddr} 0 780000; " \
+		"if ${loadfdt}; then " \
+			"run nandloadfdt;" \
+		"fi; " \
+		"run doboot\0" \
+	"boot=mmc dev ${mmcdev}; " \
+		"if mmc rescan; then " \
+			"if run loadmmcbootscript; then " \
+				"run mmcbootscript;" \
+			"else " \
+				"if run mmcloadkernel; then " \
+					"if ${loadfdt}; then " \
+						"run mmcloadfdt;" \
+					"fi;" \
+					"run mmcboot;" \
+				"fi;" \
+			"fi;" \
+		"fi;" \
+		"if sata init; then " \
+			"if run loadsatabootscript; then " \
+				"run satabootscript;" \
+			"else "\
+				"if run sataloadkernel; then " \
+					"if ${loadfdt}; then " \
+						"run sataloadfdt; " \
+					"fi;" \
+					"run sataboot;" \
+				"fi;" \
+			"fi;" \
+		"fi;" \
+		"run nandboot\0"
+
+#define CONFIG_BOOTCOMMAND \
+	"run setboottypem; run boot"
+
+/* SPI */
+#define CONFIG_SPI
+#define CONFIG_MXC_SPI
+#define CONFIG_SPI_FLASH
+#define CONFIG_SPI_FLASH_ATMEL
+#define CONFIG_SPI_FLASH_EON
+#define CONFIG_SPI_FLASH_GIGADEVICE
+#define CONFIG_SPI_FLASH_MACRONIX
+#define CONFIG_SPI_FLASH_SPANSION
+#define CONFIG_SPI_FLASH_STMICRO
+#define CONFIG_SPI_FLASH_SST
+#define CONFIG_SPI_FLASH_WINBOND
+
+/* NAND */
+#ifndef CONFIG_SPL_BUILD
+#define CONFIG_CMD_NAND
+#define CONFIG_SYS_NAND_BASE		0x40000000
+#define CONFIG_SYS_NAND_MAX_CHIPS	1
+#define CONFIG_SYS_MAX_NAND_DEVICE	1
+#define CONFIG_NAND_MXS
+#define CONFIG_SYS_NAND_ONFI_DETECTION
+/* APBH DMA is required for NAND support */
+#define CONFIG_APBH_DMA
+#define CONFIG_APBH_DMA_BURST
+#define CONFIG_APBH_DMA_BURST8
+#endif
+
+/* Ethernet */
+#define CONFIG_FEC_MXC
+#define CONFIG_FEC_MXC_PHYADDR		0
+#define CONFIG_FEC_XCV_TYPE		RGMII
+#define IMX_FEC_BASE			ENET_BASE_ADDR
+#define CONFIG_PHYLIB
+#define CONFIG_PHY_ATHEROS
+#define CONFIG_MII
+#define CONFIG_ETHPRIME			"FEC0"
+#define CONFIG_ARP_TIMEOUT		200UL
+#define CONFIG_NETMASK			255.255.255.0
+#define CONFIG_NET_RETRY_COUNT		5
+
+/* USB */
+#define CONFIG_CMD_USB
+#define CONFIG_USB_EHCI
+#define CONFIG_USB_EHCI_MX6
+#define CONFIG_USB_STORAGE
+#define CONFIG_MXC_USB_PORTSC		(PORT_PTS_UTMI | PORT_PTS_PTW)
+#define CONFIG_MXC_USB_FLAGS		0
+#define CONFIG_USB_MAX_CONTROLLER_COUNT	2
+#define CONFIG_EHCI_HCD_INIT_AFTER_RESET	/* For OTG port */
+
+/* I2C */
+#define CONFIG_CMD_I2C
+#define CONFIG_SYS_I2C
+#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_SPEED		100000
+#define CONFIG_SYS_MXC_I2C3_SPEED	400000
+
+#define CONFIG_SYS_I2C_EEPROM_ADDR	0x50
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN	1
+#define CONFIG_SYS_I2C_EEPROM_BUS	2
+
+/* SATA */
+#define CONFIG_CMD_SATA
+#define CONFIG_SYS_SATA_MAX_DEVICE	1
+#define CONFIG_LIBATA
+#define CONFIG_LBA48
+#define CONFIG_DWC_AHSATA
+#define CONFIG_DWC_AHSATA_PORT_ID	0
+#define CONFIG_DWC_AHSATA_BASE_ADDR	SATA_ARB_BASE_ADDR
+
+/* GPIO */
+#define CONFIG_MXC_GPIO
+
+/* Boot */
+#define CONFIG_ZERO_BOOTDELAY_CHECK
+#define CONFIG_LOADADDR			0x10800000
+#define CONFIG_SYS_LOAD_ADDR		CONFIG_LOADADDR
+#define CONFIG_CMDLINE_TAG		/* enable passing of ATAGs */
+#define CONFIG_SYS_BOOTMAPSZ	        (8 << 20)
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_INITRD_TAG
+#define CONFIG_REVISION_TAG
+#define CONFIG_SERIAL_TAG
+
+/* misc */
+#define CONFIG_SYS_GENERIC_BOARD
+#define CONFIG_STACKSIZE			(128 * 1024)
+#define CONFIG_SYS_MALLOC_LEN			(2 * 1024 * 1024)
+#define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS	800 /* 400 KB */
+#define CONFIG_OF_BOARD_SETUP
+
+/* SPL */
+#include "imx6_spl.h"
+#define CONFIG_SPL_BOARD_INIT
+#define CONFIG_SPL_MMC_SUPPORT
+#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR	0x80 /* offset 64 kb */
+#define CONFIG_SYS_MONITOR_LEN	(CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS / 2 * 1024)
+#define CONFIG_SPL_SPI_SUPPORT
+#define CONFIG_SPL_SPI_FLASH_SUPPORT
+#define CONFIG_SYS_SPI_U_BOOT_OFFS	(64 * 1024)
+#define CONFIG_SPL_SPI_LOAD
+
+#endif	/* __CONFIG_CM_FX6_H */
diff --git a/include/configs/cm_t335.h b/include/configs/cm_t335.h
index a3e6452..767ef3a 100644
--- a/include/configs/cm_t335.h
+++ b/include/configs/cm_t335.h
@@ -107,6 +107,7 @@
 /* I2C Configuration */
 #define CONFIG_SYS_I2C_EEPROM_ADDR	0x50	/* Main EEPROM */
 #define CONFIG_SYS_I2C_EEPROM_ADDR_LEN	1
+#define CONFIG_SYS_I2C_EEPROM_BUS	0
 
 /* SPL */
 #define CONFIG_SPL_LDSCRIPT		"$(CPUDIR)/am33xx/u-boot-spl.lds"
diff --git a/include/configs/cm_t35.h b/include/configs/cm_t35.h
index 70df1eb..6f4d97f 100644
--- a/include/configs/cm_t35.h
+++ b/include/configs/cm_t35.h
@@ -135,6 +135,7 @@
 #define CONFIG_SYS_I2C_OMAP34XX
 #define CONFIG_SYS_I2C_EEPROM_ADDR	0x50
 #define CONFIG_SYS_I2C_EEPROM_ADDR_LEN	1
+#define CONFIG_SYS_I2C_EEPROM_BUS	0
 #define CONFIG_I2C_MULTI_BUS
 
 /*
diff --git a/include/configs/cm_t54.h b/include/configs/cm_t54.h
index df93a59..641ab48 100644
--- a/include/configs/cm_t54.h
+++ b/include/configs/cm_t54.h
@@ -30,6 +30,7 @@
 #define CONFIG_SYS_I2C_OMAP34XX
 #define CONFIG_SYS_I2C_EEPROM_ADDR	0x50
 #define CONFIG_SYS_I2C_EEPROM_ADDR_LEN	1
+#define CONFIG_SYS_I2C_EEPROM_BUS	0
 
 /* Enable SD/MMC CD and WP GPIOs */
 #define OMAP_HSMMC_USE_GPIO
diff --git a/include/configs/gw_ventana.h b/include/configs/gw_ventana.h
index b991b09..0e5c200 100644
--- a/include/configs/gw_ventana.h
+++ b/include/configs/gw_ventana.h
@@ -141,6 +141,7 @@
 #define CONFIG_PCI
 #define CONFIG_PCI_PNP
 #define CONFIG_PCI_SCAN_SHOW
+#define CONFIG_PCI_FIXUP_DEV
 #define CONFIG_PCIE_IMX
 #endif
 
diff --git a/include/configs/mx6qarm2.h b/include/configs/mx6qarm2.h
index fd651cf..35c0a85 100644
--- a/include/configs/mx6qarm2.h
+++ b/include/configs/mx6qarm2.h
@@ -23,6 +23,8 @@
 #define CONFIG_SETUP_MEMORY_TAGS
 #define CONFIG_INITRD_TAG
 
+#define CONFIG_SYS_GENERIC_BOARD
+
 /* Size of malloc() pool */
 #define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + 2 * 1024 * 1024)
 
diff --git a/include/configs/mx6qsabreauto.h b/include/configs/mx6qsabreauto.h
index d1639c4..0ab3127 100644
--- a/include/configs/mx6qsabreauto.h
+++ b/include/configs/mx6qsabreauto.h
@@ -45,7 +45,4 @@
 #define CONFIG_SYS_I2C_MXC
 #define CONFIG_SYS_I2C_SPEED		100000
 
-#define CONFIG_OF_SEPARATE
-#define CONFIG_DEFAULT_DEVICE_TREE   imx6q-sabreauto
-
 #endif                         /* __MX6QSABREAUTO_CONFIG_H */
diff --git a/include/configs/mx6slevk.h b/include/configs/mx6slevk.h
index 3d05a64..194d7bd 100644
--- a/include/configs/mx6slevk.h
+++ b/include/configs/mx6slevk.h
@@ -26,6 +26,8 @@
 #define CONFIG_INITRD_TAG
 #define CONFIG_REVISION_TAG
 
+#define CONFIG_SYS_GENERIC_BOARD
+
 /* Size of malloc() pool */
 #define CONFIG_SYS_MALLOC_LEN		(3 * SZ_1M)
 
diff --git a/include/configs/mx6sxsabresd.h b/include/configs/mx6sxsabresd.h
index 1eda65e..b92d944 100644
--- a/include/configs/mx6sxsabresd.h
+++ b/include/configs/mx6sxsabresd.h
@@ -198,6 +198,16 @@
 #define CONFIG_PHYLIB
 #define CONFIG_PHY_ATHEROS
 
+#define CONFIG_CMD_PCI
+#ifdef CONFIG_CMD_PCI
+#define CONFIG_PCI
+#define CONFIG_PCI_PNP
+#define CONFIG_PCI_SCAN_SHOW
+#define CONFIG_PCIE_IMX
+#define CONFIG_PCIE_IMX_PERST_GPIO	IMX_GPIO_NR(2, 1)
+#define CONFIG_PCIE_IMX_POWER_GPIO	IMX_GPIO_NR(2, 0)
+#endif
+
 /* FLASH and environment organization */
 #define CONFIG_SYS_NO_FLASH
 
diff --git a/include/configs/nitrogen6x.h b/include/configs/nitrogen6x.h
index b2b17ce..d4b0ac9 100644
--- a/include/configs/nitrogen6x.h
+++ b/include/configs/nitrogen6x.h
@@ -192,11 +192,11 @@
 	"mmcargs=setenv bootargs console=${console},${baudrate} " \
 		"root=${mmcroot}\0" \
 	"loadbootscript=" \
-		"fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \
+		"load mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \
 	"bootscript=echo Running bootscript from mmc ...; " \
 		"source\0" \
-	"loaduimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${uimage}\0" \
-	"loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \
+	"loaduimage=load mmc ${mmcdev}:${mmcpart} ${loadaddr} ${uimage}\0" \
+	"loadfdt=load mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \
 	"mmcboot=echo Booting from mmc ...; " \
 		"run mmcargs; " \
 		"if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \
diff --git a/include/pci.h b/include/pci.h
index 461f17c..2ff7365 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -659,6 +659,13 @@
 extern int pci_find_cap(struct pci_controller *hose, pci_dev_t dev, int pos,
 			int cap);
 
+#ifdef CONFIG_PCI_FIXUP_DEV
+extern void board_pci_fixup_dev(struct pci_controller *hose, pci_dev_t dev,
+				unsigned short vendor,
+				unsigned short device,
+				unsigned short class);
+#endif
+
 const char * pci_class_str(u8 class);
 int pci_last_busno(void);
 
diff --git a/include/sata.h b/include/sata.h
index c95dc56..38f4b4a 100644
--- a/include/sata.h
+++ b/include/sata.h
@@ -9,6 +9,7 @@
 
 int sata_initialize(void);
 int __sata_initialize(void);
+int sata_port_status(int dev, int port);
 
 extern block_dev_desc_t sata_dev_desc[];
 
diff --git a/tools/imximage.c b/tools/imximage.c
index 18dc051..faba238 100644
--- a/tools/imximage.c
+++ b/tools/imximage.c
@@ -568,6 +568,13 @@
 	/* Parse dcd configuration file */
 	dcd_len = parse_cfg_file(imxhdr, params->imagename);
 
+	if (imximage_version == IMXIMAGE_V2) {
+		if (imximage_init_loadsize < imximage_ivt_offset +
+			sizeof(imx_header_v2_t))
+				imximage_init_loadsize = imximage_ivt_offset +
+					sizeof(imx_header_v2_t);
+	}
+
 	/* Set the imx header */
 	(*set_imx_hdr)(imxhdr, dcd_len, params->ep, imximage_ivt_offset);
 
diff --git a/tools/imximage.h b/tools/imximage.h
index 01f861e..5b5ad0e 100644
--- a/tools/imximage.h
+++ b/tools/imximage.h
@@ -8,7 +8,7 @@
 #ifndef _IMXIMAGE_H_
 #define _IMXIMAGE_H_
 
-#define MAX_HW_CFG_SIZE_V2 121 /* Max number of registers imx can set for v2 */
+#define MAX_HW_CFG_SIZE_V2 220 /* Max number of registers imx can set for v2 */
 #define MAX_HW_CFG_SIZE_V1 60  /* Max number of registers imx can set for v1 */
 #define APP_CODE_BARKER	0xB1
 #define DCD_BARKER	0xB17219E9