Merge branch 'master' of git://git.denx.de/u-boot-ubi
diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c b/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c
index 1972de8..1ec8e2b 100644
--- a/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c
+++ b/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c
@@ -248,6 +248,39 @@
 }
 
 /**
+ * mxs_power_switch_dcdc_clocksource() - Switch PLL clock for DC-DC converters
+ * @freqsel:	One of the POWER_MISC_FREQSEL_xxx defines to select the clock
+ *
+ * This function configures and then enables an alternative PLL clock source
+ * for the DC-DC converters.
+ */
+void mxs_power_switch_dcdc_clocksource(uint32_t freqsel)
+{
+	struct mxs_power_regs *power_regs =
+		(struct mxs_power_regs *)MXS_POWER_BASE;
+
+	/* Select clocksource for DC-DC converters */
+	clrsetbits_le32(&power_regs->hw_power_misc,
+			POWER_MISC_FREQSEL_MASK,
+			freqsel);
+	setbits_le32(&power_regs->hw_power_misc,
+			POWER_MISC_SEL_PLLCLK);
+}
+
+/**
+ * mxs_power_setup_dcdc_clocksource() - Setup PLL clock source for DC-DC converters
+ *
+ * Normally, there is no need to switch DC-DC clocksource. This is the reason,
+ * why this function is a stub and does nothing. However, boards can implement
+ * this function when required and call mxs_power_switch_dcdc_clocksource() to
+ * switch to an alternative clock source.
+ */
+__weak void mxs_power_setup_dcdc_clocksource(void)
+{
+	debug("SPL: Using default DC-DC clocksource\n");
+}
+
+/**
  * mxs_src_power_init() - Preconfigure the power block
  *
  * This function configures reasonable values for the DC-DC control loop
@@ -872,6 +905,7 @@
 
 	debug("SPL: Configuring power source\n");
 
+	mxs_power_setup_dcdc_clocksource();
 	mxs_src_power_init();
 
 	if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c
index d325191..64514b1 100644
--- a/arch/arm/cpu/armv7/mx6/clock.c
+++ b/arch/arm/cpu/armv7/mx6/clock.c
@@ -727,6 +727,8 @@
 	reg = readl(&imx_ccm->CCGR2);
 	reg |= MXC_CCM_CCGR2_LCD_MASK;
 	writel(reg, &imx_ccm->CCGR2);
+
+	return 0;
 }
 #endif
 
diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c
index 6b039e4..567ddc4 100644
--- a/arch/arm/cpu/armv7/mx6/ddr.c
+++ b/arch/arm/cpu/armv7/mx6/ddr.c
@@ -796,7 +796,6 @@
 	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);
 
 	/*
diff --git a/arch/arm/imx-common/spl.c b/arch/arm/imx-common/spl.c
index ac6e40e..caa45cf 100644
--- a/arch/arm/imx-common/spl.c
+++ b/arch/arm/imx-common/spl.c
@@ -20,7 +20,15 @@
 	struct src *psrc = (struct src *)SRC_BASE_ADDR;
 	unsigned int gpr10_boot = readl(&psrc->gpr10) & (1 << 28);
 	unsigned reg = gpr10_boot ? readl(&psrc->gpr9) : readl(&psrc->sbmr1);
+	unsigned int bmode = readl(&psrc->sbmr2);
 
+	/*
+	 * Check for BMODE if serial downloader is enabled
+	 * BOOT_MODE - see IMX6DQRM Table 8-1
+	 */
+	if ((((bmode >> 24) & 0x03)  == 0x01) || /* Serial Downloader */
+		(gpr10_boot && (reg == 1)))
+		return BOOT_DEVICE_UART;
 	/* BOOT_CFG1[7:4] - see IMX6DQRM Table 8-8 */
 	switch ((reg & 0x000000FF) >> 4) {
 	 /* EIM: See 8.5.1, Table 8-9 */
diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h
index 2f068e5..f24525e 100644
--- a/arch/arm/include/asm/arch-mx6/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx6/imx-regs.h
@@ -335,10 +335,10 @@
 #include <asm/types.h>
 
 /* only for i.MX6SX/UL */
-#define WDOG3_BASE_ADDR (is_cpu_type(MXC_CPU_MX6UL) ?	\
-			 MX6UL_WDOG3_BASE_ADDR :  MX6SX_WDOG3_BASE_ADDR)
-#define LCDIF1_BASE_ADDR (is_cpu_type(MXC_CPU_MX6UL)) ?	\
-			  MX6UL_LCDIF1_BASE_ADDR : MX6SX_LCDIF1_BASE_ADDR
+#define WDOG3_BASE_ADDR ((is_cpu_type(MXC_CPU_MX6UL) ?	\
+			 MX6UL_WDOG3_BASE_ADDR :  MX6SX_WDOG3_BASE_ADDR))
+#define LCDIF1_BASE_ADDR ((is_cpu_type(MXC_CPU_MX6UL)) ?	\
+			  MX6UL_LCDIF1_BASE_ADDR : MX6SX_LCDIF1_BASE_ADDR)
 
 
 extern void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
diff --git a/arch/arm/include/asm/arch-mxs/sys_proto.h b/arch/arm/include/asm/arch-mxs/sys_proto.h
index 20ff101..f2b075e 100644
--- a/arch/arm/include/asm/arch-mxs/sys_proto.h
+++ b/arch/arm/include/asm/arch-mxs/sys_proto.h
@@ -25,6 +25,8 @@
 void mxs_common_spl_init(const uint32_t arg, const uint32_t *resptr,
 			 const iomux_cfg_t *iomux_setup,
 			 const unsigned int iomux_size);
+
+void mxs_power_switch_dcdc_clocksource(uint32_t freqsel);
 #endif
 
 struct mxs_pair {
diff --git a/board/congatec/cgtqmx6eval/MAINTAINERS b/board/congatec/cgtqmx6eval/MAINTAINERS
index c41ebf5..48c0889 100644
--- a/board/congatec/cgtqmx6eval/MAINTAINERS
+++ b/board/congatec/cgtqmx6eval/MAINTAINERS
@@ -3,4 +3,4 @@
 S:	Maintained
 F:	board/congatec/cgtqmx6eval/
 F:	include/configs/cgtqmx6eval.h
-F:	configs/cgtqmx6qeval_defconfig
+F:	configs/cgtqmx6eval_defconfig
diff --git a/board/congatec/cgtqmx6eval/cgtqmx6eval.c b/board/congatec/cgtqmx6eval/cgtqmx6eval.c
index 5fd526d..225de7c 100644
--- a/board/congatec/cgtqmx6eval/cgtqmx6eval.c
+++ b/board/congatec/cgtqmx6eval/cgtqmx6eval.c
@@ -404,7 +404,7 @@
 #ifdef CONFIG_MXC_SPI
 static void setup_spi(void)
 {
-	imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads));
+	SETUP_IOMUX_PADS(ecspi1_pads);
 	gpio_direction_output(IMX_GPIO_NR(3, 19), 0);
 }
 #endif
diff --git a/board/freescale/mx6qsabreauto/mx6qsabreauto.c b/board/freescale/mx6qsabreauto/mx6qsabreauto.c
index 7c0e90a..c2e9c57 100644
--- a/board/freescale/mx6qsabreauto/mx6qsabreauto.c
+++ b/board/freescale/mx6qsabreauto/mx6qsabreauto.c
@@ -412,14 +412,44 @@
 }
 
 #if defined(CONFIG_VIDEO_IPUV3)
+static void disable_lvds(struct display_info_t const *dev)
+{
+	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
+
+	clrbits_le32(&iomux->gpr[2],
+		     IOMUXC_GPR2_LVDS_CH0_MODE_MASK |
+		     IOMUXC_GPR2_LVDS_CH1_MODE_MASK);
+}
+
 static void do_enable_hdmi(struct display_info_t const *dev)
 {
+	disable_lvds(dev);
 	imx_enable_hdmi_phy();
 }
 
 struct display_info_t const displays[] = {{
 	.bus	= -1,
 	.addr	= 0,
+	.pixfmt	= IPU_PIX_FMT_RGB666,
+	.detect	= NULL,
+	.enable	= NULL,
+	.mode	= {
+		.name           = "Hannstar-XGA",
+		.refresh        = 60,
+		.xres           = 1024,
+		.yres           = 768,
+		.pixclock       = 15385,
+		.left_margin    = 220,
+		.right_margin   = 40,
+		.upper_margin   = 21,
+		.lower_margin   = 7,
+		.hsync_len      = 60,
+		.vsync_len      = 10,
+		.sync           = FB_SYNC_EXT,
+		.vmode          = FB_VMODE_NONINTERLACED
+} }, {
+	.bus	= -1,
+	.addr	= 0,
 	.pixfmt	= IPU_PIX_FMT_RGB24,
 	.detect	= detect_hdmi,
 	.enable	= do_enable_hdmi,
@@ -440,18 +470,69 @@
 } } };
 size_t display_count = ARRAY_SIZE(displays);
 
+iomux_v3_cfg_t const backlight_pads[] = {
+	MX6_PAD_SD4_DAT1__GPIO2_IO09 | MUX_PAD_CTRL(ENET_PAD_CTRL),
+};
+
+static void setup_iomux_backlight(void)
+{
+	gpio_direction_output(IMX_GPIO_NR(2, 9), 1);
+	imx_iomux_v3_setup_multiple_pads(backlight_pads,
+					 ARRAY_SIZE(backlight_pads));
+}
+
 static void setup_display(void)
 {
 	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
 	int reg;
 
+	setup_iomux_backlight();
 	enable_ipu_clock();
 	imx_setup_hdmi();
 
+	/* Turn on LDB_DI0 and LDB_DI1 clocks */
+	reg = readl(&mxc_ccm->CCGR3);
+	reg |= MXC_CCM_CCGR3_LDB_DI0_MASK | MXC_CCM_CCGR3_LDB_DI1_MASK;
+	writel(reg, &mxc_ccm->CCGR3);
+
+	/* Set LDB_DI0 and LDB_DI1 clk select to 3b'011 */
+	reg = readl(&mxc_ccm->cs2cdr);
+	reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK |
+		 MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
+	reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET) |
+	       (3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
+	writel(reg, &mxc_ccm->cs2cdr);
+
+	reg = readl(&mxc_ccm->cscmr2);
+	reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV | MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV;
+	writel(reg, &mxc_ccm->cscmr2);
+
 	reg = readl(&mxc_ccm->chsccdr);
 	reg |= (CHSCCDR_CLK_SEL_LDB_DI0
 		<< MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
+	reg |= (CHSCCDR_CLK_SEL_LDB_DI0 <<
+		MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET);
 	writel(reg, &mxc_ccm->chsccdr);
+
+	reg = IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW |
+	      IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW |
+	      IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG |
+	      IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT |
+	      IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG |
+	      IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT |
+	      IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0 |
+	      IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED;
+	writel(reg, &iomux->gpr[2]);
+
+	reg = readl(&iomux->gpr[3]);
+	reg &= ~(IOMUXC_GPR3_LVDS0_MUX_CTL_MASK |
+		 IOMUXC_GPR3_HDMI_MUX_CTL_MASK);
+	reg |= (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 <<
+		IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET) |
+	       (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 <<
+		IOMUXC_GPR3_HDMI_MUX_CTL_OFFSET);
+	writel(reg, &iomux->gpr[3]);
 }
 #endif /* CONFIG_VIDEO_IPUV3 */
 
@@ -467,9 +548,6 @@
 int board_early_init_f(void)
 {
 	setup_iomux_uart();
-#ifdef CONFIG_VIDEO_IPUV3
-	setup_display();
-#endif
 
 #ifdef CONFIG_NAND_MXS
 	setup_gpmi_nand();
@@ -494,6 +572,9 @@
 	gpio_direction_output(IMX_GPIO_NR(1, 15), 1);
 	imx_iomux_v3_setup_multiple_pads(port_exp, ARRAY_SIZE(port_exp));
 
+#ifdef CONFIG_VIDEO_IPUV3
+	setup_display();
+#endif
 	setup_iomux_eimnor();
 	return 0;
 }
diff --git a/board/freescale/mx6sxsabresd/mx6sxsabresd.c b/board/freescale/mx6sxsabresd/mx6sxsabresd.c
index 3ee4662..56dc020 100644
--- a/board/freescale/mx6sxsabresd/mx6sxsabresd.c
+++ b/board/freescale/mx6sxsabresd/mx6sxsabresd.c
@@ -150,11 +150,15 @@
 {
 	struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
 	struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
-	int reg;
+	int reg, ret;
 
 	/* Use 125MHz anatop loopback REF_CLK1 for ENET1 */
 	clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC1_MASK, 0);
 
+	ret = enable_fec_anatop_clock(0, ENET_125MHZ);
+	if (ret)
+		return ret;
+
 	imx_iomux_v3_setup_multiple_pads(phy_control_pads,
 					 ARRAY_SIZE(phy_control_pads));
 
@@ -163,14 +167,14 @@
 
 	/* Reset AR8031 PHY */
 	gpio_direction_output(IMX_GPIO_NR(2, 7) , 0);
-	udelay(500);
+	mdelay(10);
 	gpio_set_value(IMX_GPIO_NR(2, 7), 1);
 
 	reg = readl(&anatop->pll_enet);
 	reg |= BM_ANADIG_PLL_ENET_REF_25M_ENABLE;
 	writel(reg, &anatop->pll_enet);
 
-	return enable_fec_anatop_clock(0, ENET_125MHZ);
+	return 0;
 }
 
 int board_eth_init(bd_t *bis)
diff --git a/common/usb.c b/common/usb.c
index 700bfc3..9f67cc1 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -566,13 +566,12 @@
 }
 
 /**********************************************************************
- * gets configuration cfgno and store it in the buffer
+ * gets len of configuration cfgno
  */
-int usb_get_configuration_no(struct usb_device *dev,
-			     unsigned char *buffer, int cfgno)
+int usb_get_configuration_len(struct usb_device *dev, int cfgno)
 {
 	int result;
-	unsigned int length;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, 9);
 	struct usb_config_descriptor *config;
 
 	config = (struct usb_config_descriptor *)&buffer[0];
@@ -586,17 +585,23 @@
 				"(expected %i, got %i)\n", 9, result);
 		return -EIO;
 	}
-	length = le16_to_cpu(config->wTotalLength);
+	return le16_to_cpu(config->wTotalLength);
+}
 
-	if (length > USB_BUFSIZ) {
-		printf("%s: failed to get descriptor - too long: %d\n",
-			__func__, length);
-		return -EIO;
-	}
+/**********************************************************************
+ * gets configuration cfgno and store it in the buffer
+ */
+int usb_get_configuration_no(struct usb_device *dev, int cfgno,
+			     unsigned char *buffer, int length)
+{
+	int result;
+	struct usb_config_descriptor *config;
 
+	config = (struct usb_config_descriptor *)&buffer[0];
 	result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, length);
-	debug("get_conf_no %d Result %d, wLength %d\n", cfgno, result, length);
-	config->wTotalLength = length; /* validated, with CPU byte order */
+	debug("get_conf_no %d Result %d, wLength %d\n", cfgno, result,
+	      le16_to_cpu(config->wTotalLength));
+	config->wTotalLength = result; /* validated, with CPU byte order */
 
 	return result;
 }
@@ -1070,7 +1075,7 @@
 
 int usb_select_config(struct usb_device *dev)
 {
-	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
+	unsigned char *tmpbuf = 0;
 	int err;
 
 	err = get_descriptor_len(dev, USB_DT_DEVICE_SIZE, USB_DT_DEVICE_SIZE);
@@ -1084,14 +1089,23 @@
 	le16_to_cpus(&dev->descriptor.bcdDevice);
 
 	/* only support for one config for now */
-	err = usb_get_configuration_no(dev, tmpbuf, 0);
+	err = usb_get_configuration_len(dev, 0);
+	if (err >= 0) {
+		tmpbuf = (unsigned char *)malloc_cache_aligned(err);
+		if (!tmpbuf)
+			err = -ENOMEM;
+		else
+			err = usb_get_configuration_no(dev, 0, tmpbuf, err);
+	}
 	if (err < 0) {
 		printf("usb_new_device: Cannot read configuration, " \
 		       "skipping device %04x:%04x\n",
 		       dev->descriptor.idVendor, dev->descriptor.idProduct);
+		free(tmpbuf);
 		return err;
 	}
 	usb_parse_config(dev, tmpbuf, 0);
+	free(tmpbuf);
 	usb_set_maxpacket(dev);
 	/*
 	 * we set the default configuration here
@@ -1200,4 +1214,60 @@
 #endif
 }
 
+#ifdef CONFIG_DM_USB
+void usb_find_usb2_hub_address_port(struct usb_device *udev,
+			       uint8_t *hub_address, uint8_t *hub_port)
+{
+	struct udevice *parent;
+	struct usb_device *uparent, *ttdev;
+
+	/*
+	 * When called from usb-uclass.c: usb_scan_device() udev->dev points
+	 * to the parent udevice, not the actual udevice belonging to the
+	 * udev as the device is not instantiated yet. So when searching
+	 * for the first usb-2 parent start with udev->dev not
+	 * udev->dev->parent .
+	 */
+	ttdev = udev;
+	parent = udev->dev;
+	uparent = dev_get_parent_priv(parent);
+
+	while (uparent->speed != USB_SPEED_HIGH) {
+		struct udevice *dev = parent;
+
+		if (device_get_uclass_id(dev->parent) != UCLASS_USB_HUB) {
+			printf("Error: Cannot find high speed parent of usb-1 device\n");
+			*hub_address = 0;
+			*hub_port = 0;
+			return;
+		}
+
+		ttdev = dev_get_parent_priv(dev);
+		parent = dev->parent;
+		uparent = dev_get_parent_priv(parent);
+	}
+	*hub_address = uparent->devnum;
+	*hub_port = ttdev->portnr;
+}
+#else
+void usb_find_usb2_hub_address_port(struct usb_device *udev,
+			       uint8_t *hub_address, uint8_t *hub_port)
+{
+	/* Find out the nearest parent which is high speed */
+	while (udev->parent->parent != NULL)
+		if (udev->parent->speed != USB_SPEED_HIGH) {
+			udev = udev->parent;
+		} else {
+			*hub_address = udev->parent->devnum;
+			*hub_port = udev->portnr;
+			return;
+		}
+
+	printf("Error: Cannot find high speed parent of usb-1 device\n");
+	*hub_address = 0;
+	*hub_port = 0;
+}
+#endif
+
+
 /* EOF */
diff --git a/doc/README.imx6 b/doc/README.imx6
index 437af2f..e26ab71 100644
--- a/doc/README.imx6
+++ b/doc/README.imx6
@@ -84,3 +84,54 @@
 Reading bank 4:
 
 Word 0x00000002: 9f027772 00000004
+
+2. Using imx_usb_loader for first install with SPL
+--------------------------------------------------
+
+imx_usb_loader is a very nice tool by BoundaryDevice that
+allow to install U-Boot without a JTAG debugger, using
+the USB boot mode as described in the manual. It is
+a replacement for Freescale's MFGTOOLS.
+
+The sources can be found here:
+
+	https://github.com/boundarydevices/imx_usb_loader.git
+
+Booting in USB mode, the i.MX6 announces itself to the Linux Host as:
+
+Bus 001 Device 111: ID 15a2:0061 Freescale Semiconductor, Inc.
+
+imx_usb_loader is able to download a single file (u-boot.imx)
+to the board. For boards without SPL support, it is enough to
+issue the command:
+
+	sudo ../imx_usb_loader/imx_usb -v u-boot.imx
+
+Getting U-Boot when SPL support is active, it requires
+two downloads. imx_usb_loader downloads the SPL into
+OCRAM and starts it. SPL will check for a valid u-boot.img, and
+because it is not found, it will wait for it using the y-modem
+protocol via the console.
+
+A first install is then possible by combining imx_usb_loader with
+another tool such as kermit.
+
+sudo ../imx_usb_loader/imx_usb -v SPL
+kermit kermit_uboot
+
+and kermit_uboot contains something like this (set line should be adjusted):
+
+set line /dev/ttyUSB1
+set speed 115200
+SET CARRIER-WATCH OFF
+set flow-control none
+set handshake none
+set prefixing all
+set file type bin
+set protocol ymodem
+send u-boot.img
+c
+
+The last "c" command tells kermit (from ckermit package in most distros)
+to switch from command line mode to communication mode, and when the
+script is finished, the U-Boot prompt is shown in the same shell.
diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index fa4c82f..b2d15c9 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -581,8 +581,16 @@
 		return;
 	}
 
-	mxc_i2c_buses[index].idle_bus_fn = idle_bus_fn;
-	mxc_i2c_buses[index].idle_bus_data = idle_bus_data;
+	/*
+	 * Warning: Be careful to allow the assignment to a static
+	 * variable here. This function could be called while U-Boot is
+	 * still running in flash memory. So such assignment is equal
+	 * to write data to flash without erasing.
+	 */
+	if (idle_bus_fn)
+		mxc_i2c_buses[index].idle_bus_fn = idle_bus_fn;
+	if (idle_bus_data)
+		mxc_i2c_buses[index].idle_bus_data = idle_bus_data;
 
 	ret = enable_i2c_clk(1, index);
 	if (ret < 0) {
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index c5054d6..1ccc576 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -502,15 +502,22 @@
 
 	clk = (pre_div << 8) | (div << 4);
 
+#ifdef CONFIG_FSL_USDHC
+	esdhc_setbits32(&regs->sysctl, SYSCTL_RSTA);
+#else
 	esdhc_clrbits32(&regs->sysctl, SYSCTL_CKEN);
+#endif
 
 	esdhc_clrsetbits32(&regs->sysctl, SYSCTL_CLOCK_MASK, clk);
 
 	udelay(10000);
 
-	clk = SYSCTL_PEREN | SYSCTL_CKEN;
+#ifdef CONFIG_FSL_USDHC
+	esdhc_clrbits32(&regs->sysctl, SYSCTL_RSTA);
+#else
+	esdhc_setbits32(&regs->sysctl, SYSCTL_PEREN | SYSCTL_CKEN);
+#endif
 
-	esdhc_setbits32(&regs->sysctl, clk);
 }
 
 #ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
@@ -585,7 +592,9 @@
 	esdhc_write32(&regs->scr, 0x00000040);
 #endif
 
+#ifndef CONFIG_FSL_USDHC
 	esdhc_setbits32(&regs->sysctl, SYSCTL_HCKEN | SYSCTL_IPGEN);
+#endif
 
 	/* Set the initial clock speed */
 	mmc_set_clock(mmc, 400000);
@@ -657,8 +666,10 @@
 	/* First reset the eSDHC controller */
 	esdhc_reset(regs);
 
+#ifndef CONFIG_FSL_USDHC
 	esdhc_setbits32(&regs->sysctl, SYSCTL_PEREN | SYSCTL_HCKEN
 				| SYSCTL_IPGEN | SYSCTL_CKEN);
+#endif
 
 	writel(SDHCI_IRQ_EN_BITS, &regs->irqstaten);
 	memset(&cfg->cfg, 0, sizeof(cfg->cfg));
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
index 79f6737..3340dd2 100644
--- a/drivers/net/fec_mxc.c
+++ b/drivers/net/fec_mxc.c
@@ -131,13 +131,25 @@
 	/*
 	 * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
 	 * and do not drop the Preamble.
+	 *
+	 * The i.MX28 and i.MX6 types have another field in the MSCR (aka
+	 * MII_SPEED) register that defines the MDIO output hold time. Earlier
+	 * versions are RAZ there, so just ignore the difference and write the
+	 * register always.
+	 * The minimal hold time according to IEE802.3 (clause 22) is 10 ns.
+	 * HOLDTIME + 1 is the number of clk cycles the fec is holding the
+	 * output.
+	 * The HOLDTIME bitfield takes values between 0 and 7 (inclusive).
+	 * Given that ceil(clkrate / 5000000) <= 64, the calculation for
+	 * holdtime cannot result in a value greater than 3.
 	 */
-	register u32 speed = DIV_ROUND_UP(imx_get_fecclk(), 5000000);
+	u32 pclk = imx_get_fecclk();
+	u32 speed = DIV_ROUND_UP(pclk, 5000000);
+	u32 hold = DIV_ROUND_UP(pclk, 100000000) - 1;
 #ifdef FEC_QUIRK_ENET_MAC
 	speed--;
 #endif
-	speed <<= 1;
-	writel(speed, &eth->mii_speed);
+	writel(speed << 1 | hold << 8, &eth->mii_speed);
 	debug("%s: mii_speed %08x\n", __func__, readl(&eth->mii_speed));
 }
 
@@ -1097,6 +1109,7 @@
 #ifdef CONFIG_PHYLIB
 	phydev = phy_find_by_mask(bus, 1 << phy_id, PHY_INTERFACE_MODE_RGMII);
 	if (!phydev) {
+		mdio_unregister(bus);
 		free(bus);
 		return -ENOMEM;
 	}
@@ -1108,6 +1121,7 @@
 #ifdef CONFIG_PHYLIB
 		free(phydev);
 #endif
+		mdio_unregister(bus);
 		free(bus);
 	}
 	return ret;
diff --git a/drivers/serial/serial_mxc.c b/drivers/serial/serial_mxc.c
index d6cf1d8..51485c0 100644
--- a/drivers/serial/serial_mxc.c
+++ b/drivers/serial/serial_mxc.c
@@ -75,6 +75,7 @@
 #define  UCR4_DREN	 (1<<0)  /* Recv data ready interrupt enable */
 #define  UFCR_RXTL_SHF   0       /* Receiver trigger level shift */
 #define  UFCR_RFDIV      (7<<7)  /* Reference freq divider mask */
+#define  UFCR_RFDIV_SHF  7      /* Reference freq divider shift */
 #define  UFCR_TXTL_SHF   10      /* Transmitter trigger level shift */
 #define  USR1_PARITYERR  (1<<15) /* Parity error interrupt flag */
 #define  USR1_RTSS	 (1<<14) /* RTS pin status */
@@ -135,6 +136,10 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#define TXTL  2 /* reset default */
+#define RXTL  1 /* reset default */
+#define RFDIV 4 /* divide input clock by 2 */
+
 static void mxc_serial_setbrg(void)
 {
 	u32 clk = imx_get_uartclk();
@@ -142,7 +147,9 @@
 	if (!gd->baudrate)
 		gd->baudrate = CONFIG_BAUDRATE;
 
-	__REG(UART_PHYS + UFCR) = 4 << 7; /* divide input clock by 2 */
+	__REG(UART_PHYS + UFCR) = (RFDIV << UFCR_RFDIV_SHF)
+		| (TXTL << UFCR_TXTL_SHF)
+		| (RXTL << UFCR_RXTL_SHF);
 	__REG(UART_PHYS + UBIR) = 0xf;
 	__REG(UART_PHYS + UBMR) = clk / (2 * gd->baudrate);
 
diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c
index 541c0f9..5ef6deb 100644
--- a/drivers/usb/host/dwc2.c
+++ b/drivers/usb/host/dwc2.c
@@ -823,12 +823,13 @@
 		       (*pid << DWC2_HCTSIZ_PID_OFFSET),
 		       &hc_regs->hctsiz);
 
-		if (!in) {
-			memcpy(priv->aligned_buffer, (char *)buffer + done, len);
+		if (!in && xfer_len) {
+			memcpy(priv->aligned_buffer, (char *)buffer + done,
+			       xfer_len);
 
 			flush_dcache_range((unsigned long)priv->aligned_buffer,
 				(unsigned long)((void *)priv->aligned_buffer +
-				roundup(len, ARCH_DMA_MINALIGN)));
+				roundup(xfer_len, ARCH_DMA_MINALIGN)));
 		}
 
 		writel(phys_to_bus((unsigned long)priv->aligned_buffer),
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index c85dbce..c664b16 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -279,56 +279,16 @@
 static void ehci_update_endpt2_dev_n_port(struct usb_device *udev,
 					  struct QH *qh)
 {
-	struct usb_device *ttdev;
-	int parent_devnum;
+	uint8_t portnr = 0;
+	uint8_t hubaddr = 0;
 
 	if (udev->speed != USB_SPEED_LOW && udev->speed != USB_SPEED_FULL)
 		return;
 
-	/*
-	 * For full / low speed devices we need to get the devnum and portnr of
-	 * the tt, so of the first upstream usb-2 hub, there may be usb-1 hubs
-	 * in the tree before that one!
-	 */
-#ifdef CONFIG_DM_USB
-	/*
-	 * When called from usb-uclass.c: usb_scan_device() udev->dev points
-	 * to the parent udevice, not the actual udevice belonging to the
-	 * udev as the device is not instantiated yet. So when searching
-	 * for the first usb-2 parent start with udev->dev not
-	 * udev->dev->parent .
-	 */
-	struct udevice *parent;
-	struct usb_device *uparent;
-
-	ttdev = udev;
-	parent = udev->dev;
-	uparent = dev_get_parent_priv(parent);
-
-	while (uparent->speed != USB_SPEED_HIGH) {
-		struct udevice *dev = parent;
-
-		if (device_get_uclass_id(dev->parent) != UCLASS_USB_HUB) {
-			printf("ehci: Error cannot find high-speed parent of usb-1 device\n");
-			return;
-		}
-
-		ttdev = dev_get_parent_priv(dev);
-		parent = dev->parent;
-		uparent = dev_get_parent_priv(parent);
-	}
-	parent_devnum = uparent->devnum;
-#else
-	ttdev = udev;
-	while (ttdev->parent && ttdev->parent->speed != USB_SPEED_HIGH)
-		ttdev = ttdev->parent;
-	if (!ttdev->parent)
-		return;
-	parent_devnum = ttdev->parent->devnum;
-#endif
+	usb_find_usb2_hub_address_port(udev, &hubaddr, &portnr);
 
-	qh->qh_endpt2 |= cpu_to_hc32(QH_ENDPT2_PORTNUM(ttdev->portnr) |
-				     QH_ENDPT2_HUBADDR(parent_devnum));
+	qh->qh_endpt2 |= cpu_to_hc32(QH_ENDPT2_PORTNUM(portnr) |
+				     QH_ENDPT2_HUBADDR(hubaddr));
 }
 
 static int
diff --git a/drivers/usb/musb-new/musb_host.c b/drivers/usb/musb-new/musb_host.c
index 40b9c66..2515447 100644
--- a/drivers/usb/musb-new/musb_host.c
+++ b/drivers/usb/musb-new/musb_host.c
@@ -2092,9 +2092,13 @@
 			}
 #else
 			if (tt_needed(musb, urb->dev)) {
-				u16 hub_port = find_tt(urb->dev);
-				qh->h_addr_reg = (u8) (hub_port >> 8);
-				qh->h_port_reg = (u8) (hub_port & 0xff);
+				uint8_t portnr = 0;
+				uint8_t hubaddr = 0;
+				usb_find_usb2_hub_address_port(urb->dev,
+							       &hubaddr,
+							       &portnr);
+				qh->h_addr_reg = hubaddr;
+				qh->h_port_reg = portnr;
 			}
 #endif
 		}
diff --git a/drivers/usb/musb-new/usb-compat.h b/drivers/usb/musb-new/usb-compat.h
index 1c41e2a..760bd78 100644
--- a/drivers/usb/musb-new/usb-compat.h
+++ b/drivers/usb/musb-new/usb-compat.h
@@ -68,38 +68,6 @@
 }
 
 #ifdef CONFIG_DM_USB
-static inline u16 find_tt(struct usb_device *udev)
-{
-	struct udevice *parent;
-	struct usb_device *uparent, *ttdev;
-
-	/*
-	 * When called from usb-uclass.c: usb_scan_device() udev->dev points
-	 * to the parent udevice, not the actual udevice belonging to the
-	 * udev as the device is not instantiated yet. So when searching
-	 * for the first usb-2 parent start with udev->dev not
-	 * udev->dev->parent .
-	 */
-	ttdev = udev;
-	parent = udev->dev;
-	uparent = dev_get_parent_priv(parent);
-
-	while (uparent->speed != USB_SPEED_HIGH) {
-		struct udevice *dev = parent;
-
-		if (device_get_uclass_id(dev->parent) != UCLASS_USB_HUB) {
-			printf("musb: Error cannot find high speed parent of usb-1 device\n");
-			return 0;
-		}
-
-		ttdev = dev_get_parent_priv(dev);
-		parent = dev->parent;
-		uparent = dev_get_parent_priv(parent);
-	}
-
-	return (uparent->devnum << 8) | (ttdev->portnr - 1);
-}
-
 static inline struct usb_device *usb_dev_get_parent(struct usb_device *udev)
 {
 	struct udevice *parent = udev->dev->parent;
@@ -129,27 +97,6 @@
 	return NULL;
 }
 #else
-static inline u16 find_tt(struct usb_device *dev)
-{
-	u8 chid;
-	u8 hub;
-
-	/* Find out the nearest parent which is high speed */
-	while (dev->parent->parent != NULL)
-		if (dev->parent->speed != USB_SPEED_HIGH)
-			dev = dev->parent;
-		else
-			break;
-
-	/* determine the port address at that hub */
-	hub = dev->parent->devnum;
-	for (chid = 0; chid < USB_MAXCHILDREN; chid++)
-		if (dev->parent->children[chid] == dev)
-			break;
-
-	return (hub << 8) | chid;
-}
-
 static inline struct usb_device *usb_dev_get_parent(struct usb_device *dev)
 {
 	return dev->parent;
diff --git a/include/configs/mx7_common.h b/include/configs/mx7_common.h
index 870e12e..d507fb4 100644
--- a/include/configs/mx7_common.h
+++ b/include/configs/mx7_common.h
@@ -36,6 +36,8 @@
 #define CONFIG_DISPLAY_CPUINFO
 #define CONFIG_DISPLAY_BOARDINFO
 
+#define CONFIG_FSL_CLK
+
 #define CONFIG_LOADADDR                 0x80800000
 #define CONFIG_SYS_TEXT_BASE            0x87800000
 
diff --git a/include/configs/novena.h b/include/configs/novena.h
index 4b4f2d7..5f0a230 100644
--- a/include/configs/novena.h
+++ b/include/configs/novena.h
@@ -16,6 +16,7 @@
 #define CONFIG_FIT
 #define CONFIG_KEYBOARD
 
+#include <config_distro_defaults.h>
 #include "mx6_common.h"
 
 /* U-Boot Commands */
@@ -58,7 +59,7 @@
 /* Booting Linux */
 #define CONFIG_BOOTFILE			"fitImage"
 #define CONFIG_BOOTARGS			"console=ttymxc1,115200 "
-#define CONFIG_BOOTCOMMAND		"run net_nfs"
+#define CONFIG_BOOTCOMMAND		"run distro_bootcmd ; run net_nfs"
 #define CONFIG_HOSTNAME			novena
 
 /* Physical Memory Map */
@@ -190,6 +191,7 @@
 #endif
 
 /* Extra U-Boot environment. */
+#ifndef CONFIG_SPL_BUILD
 #define CONFIG_EXTRA_ENV_SETTINGS					\
 	"fdt_high=0xffffffff\0"						\
 	"initrd_high=0xffffffff\0"					\
@@ -199,6 +201,11 @@
 	"rootdev=/dev/mmcblk0p2\0"					\
 	"netdev=eth0\0"							\
 	"kernel_addr_r="__stringify(CONFIG_LOADADDR)"\0"		\
+	"pxefile_addr_r="__stringify(CONFIG_LOADADDR)"\0"		\
+	"scriptaddr="__stringify(CONFIG_LOADADDR)"\0"			\
+	"ramdisk_addr_r=0x28000000\0"		   			\
+	"fdt_addr_r=0x18000000\0"					\
+	"fdtfile=imx6q-novena.dtb\0"					\
 	"addcons="							\
 		"setenv bootargs ${bootargs} "				\
 		"console=${consdev},${baudrate}\0"			\
@@ -242,5 +249,19 @@
 		"fatwrite mmc 0:1 ${loadaddr} u-boot.img ${filesize} ; "\
 		"fi ; "							\
 		"fi\0"							\
+	BOOTENV
+
+#define BOOT_TARGET_DEVICES(func) \
+	func(MMC, mmc, 0) \
+	func(USB, usb, 0) \
+	func(SATA, sata, 0) \
+	func(PXE, pxe, na) \
+	func(DHCP, dhcp, na)
+
+#include <config_distro_bootcmd.h>
+
+#else
+#define CONFIG_EXTRA_ENV_SETTINGS
+#endif /* CONFIG_SPL_BUILD */
 
 #endif				/* __CONFIG_H */
diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h
index aa1b4cf..073048f 100644
--- a/include/fsl_esdhc.h
+++ b/include/fsl_esdhc.h
@@ -25,10 +25,12 @@
 #define SYSCTL_INITA		0x08000000
 #define SYSCTL_TIMEOUT_MASK	0x000f0000
 #define SYSCTL_CLOCK_MASK	0x0000fff0
+#if !defined(CONFIG_FSL_USDHC)
 #define SYSCTL_CKEN		0x00000008
 #define SYSCTL_PEREN		0x00000004
 #define SYSCTL_HCKEN		0x00000002
 #define SYSCTL_IPGEN		0x00000001
+#endif
 #define SYSCTL_RSTA		0x01000000
 #define SYSCTL_RSTC		0x02000000
 #define SYSCTL_RSTD		0x04000000
diff --git a/include/usb.h b/include/usb.h
index 55b9268..2539364 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -266,8 +266,9 @@
 			void *buffer, int transfer_len, int interval);
 int usb_disable_asynch(int disable);
 int usb_maxpacket(struct usb_device *dev, unsigned long pipe);
-int usb_get_configuration_no(struct usb_device *dev, unsigned char *buffer,
-				int cfgno);
+int usb_get_configuration_no(struct usb_device *dev, int cfgno,
+			unsigned char *buffer, int length);
+int usb_get_configuration_len(struct usb_device *dev, int cfgno);
 int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type,
 			unsigned char id, void *buf, int size);
 int usb_get_class_descriptor(struct usb_device *dev, int ifnum,
@@ -874,6 +875,18 @@
 
 int hub_port_reset(struct udevice *dev, int port, unsigned short *portstat);
 
+/*
+ * usb_find_usb2_hub_address_port() - Get hub address and port for TT setting
+ *
+ * Searches for the first HS hub above the given device. If a
+ * HS hub is found, the hub address and the port the device is
+ * connected to is return, as required for SPLIT transactions
+ *
+ * @param: udev full speed or low speed device
+ */
+void usb_find_usb2_hub_address_port(struct usb_device *udev,
+				    uint8_t *hub_address, uint8_t *hub_port);
+
 /**
  * usb_alloc_new_device() - Allocate a new device
  *