Merge branch 'master' of git://www.denx.de/git/u-boot-imx
diff --git a/MAINTAINERS b/MAINTAINERS
index bf60c67..b3a45cc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -370,7 +370,7 @@
 F:	arch/sh/
 
 SPARC
-M:	Daniel Hellstrom <daniel@gaisler.com>
+M:	Francois Retief <fgretief@spaceteq.co.za>
 S:	Maintained
 T:	git git://git.denx.de/u-boot-sparc.git
 F:	arch/sparc/
diff --git a/README b/README
index ef8d437..32c5ea6 100644
--- a/README
+++ b/README
@@ -2438,6 +2438,15 @@
 		  - CONFIG_SYS_I2C_IHS_CH3 activate hardware channel 3
 		  - CONFIG_SYS_I2C_IHS_SPEED_3 speed channel 3
 		  - CONFIG_SYS_I2C_IHS_SLAVE_3 slave addr channel 3
+		  - activate dual channel with CONFIG_SYS_I2C_IHS_DUAL
+		  - CONFIG_SYS_I2C_IHS_SPEED_0_1 speed channel 0_1
+		  - CONFIG_SYS_I2C_IHS_SLAVE_0_1 slave addr channel 0_1
+		  - CONFIG_SYS_I2C_IHS_SPEED_1_1 speed channel 1_1
+		  - CONFIG_SYS_I2C_IHS_SLAVE_1_1 slave addr channel 1_1
+		  - CONFIG_SYS_I2C_IHS_SPEED_2_1 speed channel 2_1
+		  - CONFIG_SYS_I2C_IHS_SLAVE_2_1 slave addr channel 2_1
+		  - CONFIG_SYS_I2C_IHS_SPEED_3_1 speed channel 3_1
+		  - CONFIG_SYS_I2C_IHS_SLAVE_3_1 slave addr channel 3_1
 
 		additional defines:
 
@@ -3568,6 +3577,9 @@
 
 		CONFIG_SYS_SPL_MALLOC_START
 		Starting address of the malloc pool used in SPL.
+		When this option is set the full malloc is used in SPL and
+		it is set up by spl_init() and before that, the simple malloc()
+		can be used if CONFIG_SYS_MALLOC_F is defined.
 
 		CONFIG_SYS_SPL_MALLOC_SIZE
 		The size of the malloc pool used in SPL.
diff --git a/arch/arm/dts/tegra210-p2371-2180.dts b/arch/arm/dts/tegra210-p2371-2180.dts
index 5d9adcf..bf35497 100644
--- a/arch/arm/dts/tegra210-p2371-2180.dts
+++ b/arch/arm/dts/tegra210-p2371-2180.dts
@@ -21,6 +21,56 @@
 		reg = <0x0 0x80000000 0x0 0xc0000000>;
 	};
 
+	pcie-controller@0,01003000 {
+		status = "okay";
+
+		pci@1,0 {
+			status = "okay";
+		};
+
+		pci@2,0 {
+			status = "okay";
+		};
+	};
+
+	padctl@0,7009f000 {
+		pinctrl-0 = <&padctl_default>;
+		pinctrl-names = "default";
+
+		padctl_default: pinmux {
+			xusb {
+				nvidia,lanes = "otg-1", "otg-2";
+				nvidia,function = "xusb";
+				nvidia,iddq = <0>;
+			};
+
+			usb3 {
+				nvidia,lanes = "pcie-5", "pcie-6";
+				nvidia,function = "usb3";
+				nvidia,iddq = <0>;
+			};
+
+			pcie-x1 {
+				nvidia,lanes = "pcie-0";
+				nvidia,function = "pcie-x1";
+				nvidia,iddq = <0>;
+			};
+
+			pcie-x4 {
+				nvidia,lanes = "pcie-1", "pcie-2",
+					       "pcie-3", "pcie-4";
+				nvidia,function = "pcie-x4";
+				nvidia,iddq = <0>;
+			};
+
+			sata {
+				nvidia,lanes = "sata-0";
+				nvidia,function = "sata";
+				nvidia,iddq = <0>;
+			};
+		};
+	};
+
 	sdhci@0,700b0000 {
 		status = "okay";
 		cd-gpios = <&gpio TEGRA_GPIO(Z, 1) GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/dts/tegra210.dtsi b/arch/arm/dts/tegra210.dtsi
index f3874a1..a8c2f19 100644
--- a/arch/arm/dts/tegra210.dtsi
+++ b/arch/arm/dts/tegra210.dtsi
@@ -12,6 +12,72 @@
 	#address-cells = <2>;
 	#size-cells = <2>;
 
+	pcie-controller@0,01003000 {
+		compatible = "nvidia,tegra210-pcie";
+		device_type = "pci";
+		reg = <0x0 0x01003000 0x0 0x00000800   /* PADS registers */
+		       0x0 0x01003800 0x0 0x00000800   /* AFI registers */
+		       0x0 0x02000000 0x0 0x10000000>; /* configuration space */
+		reg-names = "pads", "afi", "cs";
+		interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>, /* controller interrupt */
+			     <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; /* MSI interrupt */
+		interrupt-names = "intr", "msi";
+
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0 0 0 0 &gic GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+
+		bus-range = <0x00 0xff>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+
+		ranges = <0x82000000 0 0x01000000 0x0 0x01000000 0 0x00001000   /* port 0 configuration space */
+			  0x82000000 0 0x01001000 0x0 0x01001000 0 0x00001000   /* port 1 configuration space */
+			  0x81000000 0 0x0        0x0 0x12000000 0 0x00010000   /* downstream I/O (64 KiB) */
+			  0x82000000 0 0x13000000 0x0 0x13000000 0 0x0d000000   /* non-prefetchable memory (208 MiB) */
+			  0xc2000000 0 0x20000000 0x0 0x20000000 0 0x20000000>; /* prefetchable memory (512 MiB) */
+
+		clocks = <&tegra_car TEGRA210_CLK_PCIE>,
+			 <&tegra_car TEGRA210_CLK_AFI>,
+			 <&tegra_car TEGRA210_CLK_PLL_E>,
+			 <&tegra_car TEGRA210_CLK_CML0>;
+		clock-names = "pex", "afi", "pll_e", "cml";
+		resets = <&tegra_car 70>,
+			 <&tegra_car 72>,
+			 <&tegra_car 74>;
+		reset-names = "pex", "afi", "pcie_x";
+		status = "disabled";
+
+		phys = <&padctl TEGRA_XUSB_PADCTL_PCIE>;
+		phy-names = "pcie";
+
+		pci@1,0 {
+			device_type = "pci";
+			assigned-addresses = <0x82000800 0 0x01000000 0 0x1000>;
+			reg = <0x000800 0 0 0 0>;
+			status = "disabled";
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges;
+
+			nvidia,num-lanes = <4>;
+		};
+
+		pci@2,0 {
+			device_type = "pci";
+			assigned-addresses = <0x82001000 0 0x01001000 0 0x1000>;
+			reg = <0x001000 0 0 0 0>;
+			status = "disabled";
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges;
+
+			nvidia,num-lanes = <1>;
+		};
+	};
+
 	gic: interrupt-controller@0,50041000 {
 		compatible = "arm,gic-400";
 		#interrupt-cells = <3>;
diff --git a/arch/arm/include/asm/arch-hi6220/gpio.h b/arch/arm/include/asm/arch-hi6220/gpio.h
index 4fafaef..29ace17 100644
--- a/arch/arm/include/asm/arch-hi6220/gpio.h
+++ b/arch/arm/include/asm/arch-hi6220/gpio.h
@@ -21,7 +21,7 @@
 /* Information about a GPIO bank */
 struct hikey_gpio_platdata {
 	int bank_index;
-	unsigned int base;     /* address of registers in physical memory */
+	ulong base;     /* address of registers in physical memory */
 };
 
 #endif /* _HI6220_GPIO_H_ */
diff --git a/arch/arm/include/asm/arch-tegra/gpu.h b/arch/arm/include/asm/arch-tegra/gpu.h
index 52280f4..4423386 100644
--- a/arch/arm/include/asm/arch-tegra/gpu.h
+++ b/arch/arm/include/asm/arch-tegra/gpu.h
@@ -10,29 +10,23 @@
 
 #if defined(CONFIG_TEGRA_GPU)
 
-void config_gpu(void);
-bool gpu_configured(void);
+void tegra_gpu_config(void);
 
 #else /* CONFIG_TEGRA_GPU */
 
-static inline void config_gpu(void)
+static inline void tegra_gpu_config(void)
 {
 }
 
-static inline bool gpu_configured(void)
-{
-	return false;
-}
-
 #endif /* CONFIG_TEGRA_GPU */
 
 #if defined(CONFIG_OF_LIBFDT)
 
-int gpu_enable_node(void *blob, const char *gpupath);
+int tegra_gpu_enable_node(void *blob, const char *gpupath);
 
 #else /* CONFIG_OF_LIBFDT */
 
-static inline int gpu_enable_node(void *blob, const char *gpupath)
+static inline int tegra_gpu_enable_node(void *blob, const char *gpupath)
 {
 	return 0;
 }
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 98431a9..2be6ef4 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -23,7 +23,7 @@
 obj-y += lowlevel_init.o
 obj-y += pinmux-common.o
 obj-y += powergate.o
-obj-y += xusb-padctl.o
+obj-y += xusb-padctl-dummy.o
 obj-$(CONFIG_DISPLAY_CPUINFO) += sys_info.o
 obj-$(CONFIG_TEGRA_GPU) += gpu.o
 obj-$(CONFIG_TEGRA_CLOCK_SCALING) += emc.o
diff --git a/arch/arm/mach-tegra/board2.c b/arch/arm/mach-tegra/board2.c
index 8ecc674..8ba143d 100644
--- a/arch/arm/mach-tegra/board2.c
+++ b/arch/arm/mach-tegra/board2.c
@@ -128,7 +128,7 @@
 	clock_init();
 	clock_verify();
 
-	config_gpu();
+	tegra_gpu_config();
 
 #ifdef CONFIG_TEGRA_SPI
 	pin_mux_spi();
@@ -403,3 +403,23 @@
 {
 	return CONFIG_SYS_SDRAM_BASE + usable_ram_size_below_4g();
 }
+
+/*
+ * This function is called right before the kernel is booted. "blob" is the
+ * device tree that will be passed to the kernel.
+ */
+int ft_system_setup(void *blob, bd_t *bd)
+{
+	const char *gpu_path =
+#if defined(CONFIG_TEGRA124) || defined(CONFIG_TEGRA210)
+		"/gpu@0,57000000";
+#else
+		NULL;
+#endif
+
+	/* Enable GPU node if GPU setup has been performed */
+	if (gpu_path != NULL)
+		return tegra_gpu_enable_node(blob, gpu_path);
+
+	return 0;
+}
diff --git a/arch/arm/mach-tegra/gpu.c b/arch/arm/mach-tegra/gpu.c
index 4ea046d..c7d705d 100644
--- a/arch/arm/mach-tegra/gpu.c
+++ b/arch/arm/mach-tegra/gpu.c
@@ -25,7 +25,7 @@
 
 static bool _configured;
 
-void config_gpu(void)
+void tegra_gpu_config(void)
 {
 	struct mc_ctlr *mc = (struct mc_ctlr *)NV_PA_MC_BASE;
 
@@ -41,18 +41,13 @@
 	_configured = true;
 }
 
-bool vpr_configured(void)
-{
-	return _configured;
-}
-
 #if defined(CONFIG_OF_LIBFDT)
 
-int gpu_enable_node(void *blob, const char *gpupath)
+int tegra_gpu_enable_node(void *blob, const char *gpupath)
 {
 	int offset;
 
-	if (vpr_configured()) {
+	if (_configured) {
 		offset = fdt_path_offset(blob, gpupath);
 		if (offset > 0) {
 			fdt_status_okay(blob, offset);
diff --git a/arch/arm/mach-tegra/tegra124/Makefile b/arch/arm/mach-tegra/tegra124/Makefile
index f577f45..c00de61 100644
--- a/arch/arm/mach-tegra/tegra124/Makefile
+++ b/arch/arm/mach-tegra/tegra124/Makefile
@@ -11,6 +11,7 @@
 obj-y	+= funcmux.o
 obj-y	+= pinmux.o
 obj-y	+= xusb-padctl.o
+obj-y	+= ../xusb-padctl-common.o
 
 ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_ARMV7_NONSEC) += psci.o
diff --git a/arch/arm/mach-tegra/tegra124/xusb-padctl.c b/arch/arm/mach-tegra/tegra124/xusb-padctl.c
index 43af883..76af924 100644
--- a/arch/arm/mach-tegra/tegra124/xusb-padctl.c
+++ b/arch/arm/mach-tegra/tegra124/xusb-padctl.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (c) 2014-2015, NVIDIA CORPORATION.  All rights reserved.
  *
  * SPDX-License-Identifier: GPL-2.0
  */
@@ -8,13 +8,8 @@
 
 #include <common.h>
 #include <errno.h>
-#include <fdtdec.h>
-#include <malloc.h>
 
-#include <asm/io.h>
-
-#include <asm/arch/clock.h>
-#include <asm/arch-tegra/xusb-padctl.h>
+#include "../xusb-padctl-common.h"
 
 #include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h>
 
@@ -83,18 +78,6 @@
 	TEGRA124_FUNC_RSVD,
 };
 
-struct tegra_xusb_padctl_lane {
-	const char *name;
-
-	unsigned int offset;
-	unsigned int shift;
-	unsigned int mask;
-	unsigned int iddq;
-
-	const unsigned int *funcs;
-	unsigned int num_funcs;
-};
-
 #define TEGRA124_LANE(_name, _offset, _shift, _mask, _iddq, _funcs)	\
 	{								\
 		.name = _name,						\
@@ -121,74 +104,6 @@
 	TEGRA124_LANE("sata-0", 0x134, 26, 0x3, 6, pci),
 };
 
-struct tegra_xusb_phy_ops {
-	int (*prepare)(struct tegra_xusb_phy *phy);
-	int (*enable)(struct tegra_xusb_phy *phy);
-	int (*disable)(struct tegra_xusb_phy *phy);
-	int (*unprepare)(struct tegra_xusb_phy *phy);
-};
-
-struct tegra_xusb_phy {
-	const struct tegra_xusb_phy_ops *ops;
-
-	struct tegra_xusb_padctl *padctl;
-};
-
-struct tegra_xusb_padctl_pin {
-	const struct tegra_xusb_padctl_lane *lane;
-
-	unsigned int func;
-	int iddq;
-};
-
-#define MAX_GROUPS 3
-#define MAX_PINS 6
-
-struct tegra_xusb_padctl_group {
-	const char *name;
-
-	const char *pins[MAX_PINS];
-	unsigned int num_pins;
-
-	const char *func;
-	int iddq;
-};
-
-struct tegra_xusb_padctl_config {
-	const char *name;
-
-	struct tegra_xusb_padctl_group groups[MAX_GROUPS];
-	unsigned int num_groups;
-};
-
-struct tegra_xusb_padctl {
-	struct fdt_resource regs;
-
-	unsigned int enable;
-
-	struct tegra_xusb_phy phys[2];
-
-	const struct tegra_xusb_padctl_lane *lanes;
-	unsigned int num_lanes;
-
-	const char *const *functions;
-	unsigned int num_functions;
-
-	struct tegra_xusb_padctl_config config;
-};
-
-static inline u32 padctl_readl(struct tegra_xusb_padctl *padctl,
-			       unsigned long offset)
-{
-	return readl(padctl->regs.start + offset);
-}
-
-static inline void padctl_writel(struct tegra_xusb_padctl *padctl,
-				 u32 value, unsigned long offset)
-{
-	writel(value, padctl->regs.start + offset);
-}
-
 static int tegra_xusb_padctl_enable(struct tegra_xusb_padctl *padctl)
 {
 	u32 value;
@@ -220,7 +135,7 @@
 	u32 value;
 
 	if (padctl->enable == 0) {
-		error("tegra-xusb-padctl: unbalanced enable/disable");
+		error("unbalanced enable/disable");
 		return 0;
 	}
 
@@ -380,329 +295,27 @@
 	.unprepare = phy_unprepare,
 };
 
-static struct tegra_xusb_padctl *padctl = &(struct tegra_xusb_padctl) {
-	.phys = {
-		[0] = {
-			.ops = &pcie_phy_ops,
-		},
-		[1] = {
-			.ops = &sata_phy_ops,
-		},
+static struct tegra_xusb_phy tegra124_phys[] = {
+	{
+		.type = TEGRA_XUSB_PADCTL_PCIE,
+		.ops = &pcie_phy_ops,
+		.padctl = &padctl,
+	},
+	{
+		.type = TEGRA_XUSB_PADCTL_SATA,
+		.ops = &sata_phy_ops,
+		.padctl = &padctl,
 	},
 };
 
-static const struct tegra_xusb_padctl_lane *
-tegra_xusb_padctl_find_lane(struct tegra_xusb_padctl *padctl, const char *name)
-{
-	unsigned int i;
-
-	for (i = 0; i < padctl->num_lanes; i++)
-		if (strcmp(name, padctl->lanes[i].name) == 0)
-			return &padctl->lanes[i];
-
-	return NULL;
-}
-
-static int
-tegra_xusb_padctl_group_parse_dt(struct tegra_xusb_padctl *padctl,
-				 struct tegra_xusb_padctl_group *group,
-				 const void *fdt, int node)
-{
-	unsigned int i;
-	int len, err;
-
-	group->name = fdt_get_name(fdt, node, &len);
-
-	len = fdt_count_strings(fdt, node, "nvidia,lanes");
-	if (len < 0) {
-		error("tegra-xusb-padctl: failed to parse \"nvidia,lanes\" property");
-		return -EINVAL;
-	}
-
-	group->num_pins = len;
-
-	for (i = 0; i < group->num_pins; i++) {
-		err = fdt_get_string_index(fdt, node, "nvidia,lanes", i,
-					   &group->pins[i]);
-		if (err < 0) {
-			error("tegra-xusb-padctl: failed to read string from \"nvidia,lanes\" property");
-			return -EINVAL;
-		}
-	}
-
-	group->num_pins = len;
-
-	err = fdt_get_string(fdt, node, "nvidia,function", &group->func);
-	if (err < 0) {
-		error("tegra-xusb-padctl: failed to parse \"nvidia,func\" property");
-		return -EINVAL;
-	}
-
-	group->iddq = fdtdec_get_int(fdt, node, "nvidia,iddq", -1);
-
-	return 0;
-}
-
-static int tegra_xusb_padctl_find_function(struct tegra_xusb_padctl *padctl,
-					   const char *name)
-{
-	unsigned int i;
-
-	for (i = 0; i < padctl->num_functions; i++)
-		if (strcmp(name, padctl->functions[i]) == 0)
-			return i;
-
-	return -ENOENT;
-}
-
-static int
-tegra_xusb_padctl_lane_find_function(struct tegra_xusb_padctl *padctl,
-				     const struct tegra_xusb_padctl_lane *lane,
-				     const char *name)
-{
-	unsigned int i;
-	int func;
-
-	func = tegra_xusb_padctl_find_function(padctl, name);
-	if (func < 0)
-		return func;
-
-	for (i = 0; i < lane->num_funcs; i++)
-		if (lane->funcs[i] == func)
-			return i;
-
-	return -ENOENT;
-}
-
-static int
-tegra_xusb_padctl_group_apply(struct tegra_xusb_padctl *padctl,
-			      const struct tegra_xusb_padctl_group *group)
-{
-	unsigned int i;
-
-	for (i = 0; i < group->num_pins; i++) {
-		const struct tegra_xusb_padctl_lane *lane;
-		unsigned int func;
-		u32 value;
-
-		lane = tegra_xusb_padctl_find_lane(padctl, group->pins[i]);
-		if (!lane) {
-			error("tegra-xusb-padctl: no lane for pin %s",
-			      group->pins[i]);
-			continue;
-		}
-
-		func = tegra_xusb_padctl_lane_find_function(padctl, lane,
-							    group->func);
-		if (func < 0) {
-			error("tegra-xusb-padctl: function %s invalid for lane %s: %d",
-			      group->func, lane->name, func);
-			continue;
-		}
-
-		value = padctl_readl(padctl, lane->offset);
-
-		/* set pin function */
-		value &= ~(lane->mask << lane->shift);
-		value |= func << lane->shift;
-
-		/*
-		 * Set IDDQ if supported on the lane and specified in the
-		 * configuration.
-		 */
-		if (lane->iddq > 0 && group->iddq >= 0) {
-			if (group->iddq != 0)
-				value &= ~(1 << lane->iddq);
-			else
-				value |= 1 << lane->iddq;
-		}
-
-		padctl_writel(padctl, value, lane->offset);
-	}
-
-	return 0;
-}
-
-static int
-tegra_xusb_padctl_config_apply(struct tegra_xusb_padctl *padctl,
-			       struct tegra_xusb_padctl_config *config)
-{
-	unsigned int i;
-
-	for (i = 0; i < config->num_groups; i++) {
-		const struct tegra_xusb_padctl_group *group;
-		int err;
-
-		group = &config->groups[i];
-
-		err = tegra_xusb_padctl_group_apply(padctl, group);
-		if (err < 0) {
-			error("tegra-xusb-padctl: failed to apply group %s: %d",
-			      group->name, err);
-			continue;
-		}
-	}
-
-	return 0;
-}
-
-static int
-tegra_xusb_padctl_config_parse_dt(struct tegra_xusb_padctl *padctl,
-				  struct tegra_xusb_padctl_config *config,
-				  const void *fdt, int node)
-{
-	int subnode;
-
-	config->name = fdt_get_name(fdt, node, NULL);
-
-	fdt_for_each_subnode(fdt, subnode, node) {
-		struct tegra_xusb_padctl_group *group;
-		int err;
-
-		group = &config->groups[config->num_groups];
-
-		err = tegra_xusb_padctl_group_parse_dt(padctl, group, fdt,
-						       subnode);
-		if (err < 0) {
-			error("tegra-xusb-padctl: failed to parse group %s",
-			      group->name);
-			return err;
-		}
-
-		config->num_groups++;
-	}
-
-	return 0;
-}
-
-static int tegra_xusb_padctl_parse_dt(struct tegra_xusb_padctl *padctl,
-				      const void *fdt, int node)
-{
-	int subnode, err;
-
-	err = fdt_get_resource(fdt, node, "reg", 0, &padctl->regs);
-	if (err < 0) {
-		error("tegra-xusb-padctl: registers not found");
-		return err;
-	}
-
-	fdt_for_each_subnode(fdt, subnode, node) {
-		struct tegra_xusb_padctl_config *config = &padctl->config;
-
-		err = tegra_xusb_padctl_config_parse_dt(padctl, config, fdt,
-							subnode);
-		if (err < 0) {
-			error("tegra-xusb-padctl: failed to parse entry %s: %d",
-			      config->name, err);
-			continue;
-		}
-	}
-
-	return 0;
-}
-
-static int process_nodes(const void *fdt, int nodes[], unsigned int count)
-{
-	unsigned int i;
-
-	for (i = 0; i < count; i++) {
-		enum fdt_compat_id id;
-		int err;
-
-		if (!fdtdec_get_is_enabled(fdt, nodes[i]))
-			continue;
-
-		id = fdtdec_lookup(fdt, nodes[i]);
-		switch (id) {
-		case COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL:
-			break;
-
-		default:
-			error("tegra-xusb-padctl: unsupported compatible: %s",
-			      fdtdec_get_compatible(id));
-			continue;
-		}
-
-		padctl->num_lanes = ARRAY_SIZE(tegra124_lanes);
-		padctl->lanes = tegra124_lanes;
-
-		padctl->num_functions = ARRAY_SIZE(tegra124_functions);
-		padctl->functions = tegra124_functions;
-
-		err = tegra_xusb_padctl_parse_dt(padctl, fdt, nodes[i]);
-		if (err < 0) {
-			error("tegra-xusb-padctl: failed to parse DT: %d",
-			      err);
-			continue;
-		}
-
-		/* deassert XUSB padctl reset */
-		reset_set_enable(PERIPH_ID_XUSB_PADCTL, 0);
-
-		err = tegra_xusb_padctl_config_apply(padctl, &padctl->config);
-		if (err < 0) {
-			error("tegra-xusb-padctl: failed to apply pinmux: %d",
-			      err);
-			continue;
-		}
-
-		/* only a single instance is supported */
-		break;
-	}
-
-	return 0;
-}
-
-struct tegra_xusb_phy *tegra_xusb_phy_get(unsigned int type)
-{
-	struct tegra_xusb_phy *phy = NULL;
-
-	switch (type) {
-	case TEGRA_XUSB_PADCTL_PCIE:
-		phy = &padctl->phys[0];
-		phy->padctl = padctl;
-		break;
-
-	case TEGRA_XUSB_PADCTL_SATA:
-		phy = &padctl->phys[1];
-		phy->padctl = padctl;
-		break;
-	}
-
-	return phy;
-}
-
-int tegra_xusb_phy_prepare(struct tegra_xusb_phy *phy)
-{
-	if (phy && phy->ops && phy->ops->prepare)
-		return phy->ops->prepare(phy);
-
-	return phy ? -ENOSYS : -EINVAL;
-}
-
-int tegra_xusb_phy_enable(struct tegra_xusb_phy *phy)
-{
-	if (phy && phy->ops && phy->ops->enable)
-		return phy->ops->enable(phy);
-
-	return phy ? -ENOSYS : -EINVAL;
-}
-
-int tegra_xusb_phy_disable(struct tegra_xusb_phy *phy)
-{
-	if (phy && phy->ops && phy->ops->disable)
-		return phy->ops->disable(phy);
-
-	return phy ? -ENOSYS : -EINVAL;
-}
-
-int tegra_xusb_phy_unprepare(struct tegra_xusb_phy *phy)
-{
-	if (phy && phy->ops && phy->ops->unprepare)
-		return phy->ops->unprepare(phy);
-
-	return phy ? -ENOSYS : -EINVAL;
-}
+static const struct tegra_xusb_padctl_soc tegra124_socdata = {
+	.lanes = tegra124_lanes,
+	.num_lanes = ARRAY_SIZE(tegra124_lanes),
+	.functions = tegra124_functions,
+	.num_functions = ARRAY_SIZE(tegra124_functions),
+	.phys = tegra124_phys,
+	.num_phys = ARRAY_SIZE(tegra124_phys),
+};
 
 void tegra_xusb_padctl_init(const void *fdt)
 {
@@ -711,6 +324,6 @@
 	count = fdtdec_find_aliases_for_id(fdt, "padctl",
 					   COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL,
 					   nodes, ARRAY_SIZE(nodes));
-	if (process_nodes(fdt, nodes, count))
+	if (tegra_xusb_process_nodes(fdt, nodes, count, &tegra124_socdata))
 		return;
 }
diff --git a/arch/arm/mach-tegra/tegra210/Kconfig b/arch/arm/mach-tegra/tegra210/Kconfig
index b07363a..055fb12 100644
--- a/arch/arm/mach-tegra/tegra210/Kconfig
+++ b/arch/arm/mach-tegra/tegra210/Kconfig
@@ -19,12 +19,12 @@
 	  a GPIO expansion header, and an analog audio jack.
 
 config TARGET_P2371_2180
-	bool "NVIDIA Tegra210 P2371-2180 board"
+	bool "NVIDIA Tegra210 P2371-2180 (Jetson TX1) board"
 	help
-	  P2371-2180 is a P2180 CPU board married to a P2597 I/O board. The
-	  combination contains SoC, DRAM, eMMC, SD card slot, HDMI, USB
-	  micro-B port, Ethernet via USB3, USB3 host port, SATA, PCIe, and
-	  two GPIO expansion headers.
+	  P2371-2180 (Jetson TX1 developer kit) is a P2180 CPU board married
+	  to a P2597 I/O board. The combination contains SoC, DRAM, eMMC, SD
+	  card slot, HDMI, USB micro-B port, Ethernet via USB3, USB3 host
+	  port, SATA, PCIe, and two GPIO expansion headers.
 
 config TARGET_P2571
 	bool "NVIDIA Tegra210 P2571 base board"
diff --git a/arch/arm/mach-tegra/tegra210/Makefile b/arch/arm/mach-tegra/tegra210/Makefile
index 1fb8d1a..b6012fc 100644
--- a/arch/arm/mach-tegra/tegra210/Makefile
+++ b/arch/arm/mach-tegra/tegra210/Makefile
@@ -9,3 +9,4 @@
 obj-y	+= funcmux.o
 obj-y	+= pinmux.o
 obj-y	+= xusb-padctl.o
+obj-y	+= ../xusb-padctl-common.o
diff --git a/arch/arm/mach-tegra/tegra210/clock.c b/arch/arm/mach-tegra/tegra210/clock.c
index 6d75d37..df92bdc 100644
--- a/arch/arm/mach-tegra/tegra210/clock.c
+++ b/arch/arm/mach-tegra/tegra210/clock.c
@@ -8,6 +8,7 @@
 /* Tegra210 Clock control functions */
 
 #include <common.h>
+#include <errno.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/sysctr.h>
@@ -1030,6 +1031,59 @@
 	debug("%s: TSC CNTCR = 0x%08X\n", __func__, val);
 }
 
+#define PLLREFE_MISC			0x4c8
+#define  PLLREFE_MISC_LOCK		BIT(27)
+#define  PLLREFE_MISC_IDDQ		BIT(24)
+
+#define PLLREFE_BASE			0x4c4
+#define  PLLREFE_BASE_BYPASS		BIT(31)
+#define  PLLREFE_BASE_ENABLE		BIT(30)
+#define  PLLREFE_BASE_REF_DIS		BIT(29)
+#define  PLLREFE_BASE_KCP(kcp)		(((kcp) & 0x3) << 27)
+#define  PLLREFE_BASE_KVCO		BIT(26)
+#define  PLLREFE_BASE_DIVP(p)		(((p) & 0x1f) << 16)
+#define  PLLREFE_BASE_DIVN(n)		(((n) & 0xff) << 8)
+#define  PLLREFE_BASE_DIVM(m)		(((m) & 0xff) << 0)
+
+static int tegra_pllref_enable(void)
+{
+	u32 value;
+	unsigned long start;
+
+	/*
+	 * This sequence comes from Tegra X1 TRM section "Cold Boot, with no
+	 * Recovery Mode or Boot from USB", sub-section "PLLREFE".
+	 */
+
+	value = readl(NV_PA_CLK_RST_BASE + PLLREFE_MISC);
+	value &= ~PLLREFE_MISC_IDDQ;
+	writel(value, NV_PA_CLK_RST_BASE + PLLREFE_MISC);
+
+	udelay(5);
+
+	value = PLLREFE_BASE_ENABLE |
+		PLLREFE_BASE_KCP(0) |
+		PLLREFE_BASE_DIVP(0) |
+		PLLREFE_BASE_DIVN(0x41) |
+		PLLREFE_BASE_DIVM(4);
+	writel(value, NV_PA_CLK_RST_BASE + PLLREFE_BASE);
+
+	debug("waiting for pllrefe lock\n");
+	start = get_timer(0);
+	while (get_timer(start) < 250) {
+		value = readl(NV_PA_CLK_RST_BASE + PLLREFE_MISC);
+		if (value & PLLREFE_MISC_LOCK)
+			break;
+	}
+	if (!(value & PLLREFE_MISC_LOCK)) {
+		debug("  timeout\n");
+		return -ETIMEDOUT;
+	}
+	debug("  done\n");
+
+	return 0;
+}
+
 #define PLLE_SS_CNTL 0x68
 #define  PLLE_SS_CNTL_SSCINCINTR(x) (((x) & 0x3f) << 24)
 #define  PLLE_SS_CNTL_SSCINC(x) (((x) & 0xff) << 16)
@@ -1041,100 +1095,131 @@
 #define  PLLE_SS_CNTL_SSCMAX(x) (((x) & 0x1ff) << 0)
 
 #define PLLE_BASE 0x0e8
-#define  PLLE_BASE_ENABLE (1 << 30)
-#define  PLLE_BASE_LOCK_OVERRIDE (1 << 29)
-#define  PLLE_BASE_PLDIV_CML(x) (((x) & 0xf) << 24)
+#define  PLLE_BASE_ENABLE (1 << 31)
+#define  PLLE_BASE_PLDIV_CML(x) (((x) & 0x1f) << 24)
 #define  PLLE_BASE_NDIV(x) (((x) & 0xff) << 8)
 #define  PLLE_BASE_MDIV(x) (((x) & 0xff) << 0)
 
 #define PLLE_MISC 0x0ec
 #define  PLLE_MISC_IDDQ_SWCTL (1 << 14)
-#define  PLLE_MISC_IDDQ_OVERRIDE (1 << 13)
-#define  PLLE_MISC_LOCK_ENABLE (1 << 9)
-#define  PLLE_MISC_PTS (1 << 8)
-#define  PLLE_MISC_VREG_BG_CTRL(x) (((x) & 0x3) << 4)
+#define  PLLE_MISC_IDDQ_OVERRIDE_VALUE (1 << 13)
+#define  PLLE_MISC_LOCK (1 << 11)
+#define  PLLE_MISC_KCP(x) (((x) & 0x3) << 6)
 #define  PLLE_MISC_VREG_CTRL(x) (((x) & 0x3) << 2)
+#define  PLLE_MISC_KVCO (1 << 0)
 
 #define PLLE_AUX 0x48c
+#define  PLLE_AUX_SS_SEQ_INCLUDE (1 << 31)
+#define  PLLE_AUX_REF_SEL_PLLREFE (1 << 28)
 #define  PLLE_AUX_SEQ_ENABLE (1 << 24)
+#define  PLLE_AUX_SS_SWCTL (1 << 6)
 #define  PLLE_AUX_ENABLE_SWCTL (1 << 4)
+#define  PLLE_AUX_USE_LOCKDET (1 << 3)
 
 int tegra_plle_enable(void)
 {
-	unsigned int m = 1, n = 200, cpcon = 13;
 	u32 value;
+	unsigned long start;
 
-	value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE);
-	value &= ~PLLE_BASE_LOCK_OVERRIDE;
-	writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE);
+	/* PLLREF feeds PLLE */
+	tegra_pllref_enable();
+
+	/*
+	 * This sequence comes from Tegra X1 TRM section "Cold Boot, with no
+	 * Recovery Mode or Boot from USB", sub-section "PLLEs".
+	 */
+
+	/* 1. Select XTAL as the source */
 
 	value = readl(NV_PA_CLK_RST_BASE + PLLE_AUX);
-	value |= PLLE_AUX_ENABLE_SWCTL;
-	value &= ~PLLE_AUX_SEQ_ENABLE;
+	value &= ~PLLE_AUX_REF_SEL_PLLREFE;
 	writel(value, NV_PA_CLK_RST_BASE + PLLE_AUX);
 
-	udelay(1);
-
 	value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC);
-	value |= PLLE_MISC_IDDQ_SWCTL;
-	value &= ~PLLE_MISC_IDDQ_OVERRIDE;
-	value |= PLLE_MISC_LOCK_ENABLE;
-	value |= PLLE_MISC_PTS;
-	value |= PLLE_MISC_VREG_BG_CTRL(3);
-	value |= PLLE_MISC_VREG_CTRL(2);
+	value &= ~PLLE_MISC_IDDQ_OVERRIDE_VALUE;
 	writel(value, NV_PA_CLK_RST_BASE + PLLE_MISC);
 
+	/* 2. Wait 5 us */
 	udelay(5);
 
-	value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
-	value |= PLLE_SS_CNTL_SSCBYP | PLLE_SS_CNTL_INTERP_RESET |
-		 PLLE_SS_CNTL_BYPASS_SS;
-	writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
+	/*
+	 * 3. Program the following registers to generate a low jitter 100MHz
+	 * clock.
+	 */
 
 	value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE);
-	value &= ~PLLE_BASE_PLDIV_CML(0xf);
+	value &= ~PLLE_BASE_PLDIV_CML(0x1f);
 	value &= ~PLLE_BASE_NDIV(0xff);
 	value &= ~PLLE_BASE_MDIV(0xff);
-	value |= PLLE_BASE_PLDIV_CML(cpcon);
-	value |= PLLE_BASE_NDIV(n);
-	value |= PLLE_BASE_MDIV(m);
+	value |= PLLE_BASE_PLDIV_CML(0xe);
+	value |= PLLE_BASE_NDIV(0x7d);
+	value |= PLLE_BASE_MDIV(2);
 	writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE);
 
-	udelay(1);
+	value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC);
+	value &= ~PLLE_MISC_KCP(3);
+	value &= ~PLLE_MISC_VREG_CTRL(3);
+	value &= ~PLLE_MISC_KVCO;
+	writel(value, NV_PA_CLK_RST_BASE + PLLE_MISC);
 
 	value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE);
 	value |= PLLE_BASE_ENABLE;
 	writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE);
 
-	/* wait for lock */
-	udelay(300);
+	/* 4. Wait for LOCK */
+
+	debug("waiting for plle lock\n");
+	start = get_timer(0);
+	while (get_timer(start) < 250) {
+		value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC);
+		if (value & PLLE_MISC_LOCK)
+			break;
+	}
+	if (!(value & PLLE_MISC_LOCK)) {
+		debug("  timeout\n");
+		return -ETIMEDOUT;
+	}
+	debug("  done\n");
+
+	/* 5. Enable SSA */
 
 	value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
+	value &= ~PLLE_SS_CNTL_SSCINC(0xff);
+	value |= PLLE_SS_CNTL_SSCINC(1);
+	value &= ~PLLE_SS_CNTL_SSCINCINTR(0x3f);
+	value |= PLLE_SS_CNTL_SSCINCINTR(0x23);
+	value &= ~PLLE_SS_CNTL_SSCMAX(0x1fff);
+	value |= PLLE_SS_CNTL_SSCMAX(0x21);
 	value &= ~PLLE_SS_CNTL_SSCINVERT;
 	value &= ~PLLE_SS_CNTL_SSCCENTER;
-
-	value &= ~PLLE_SS_CNTL_SSCINCINTR(0x3f);
-	value &= ~PLLE_SS_CNTL_SSCINC(0xff);
-	value &= ~PLLE_SS_CNTL_SSCMAX(0x1ff);
-
-	value |= PLLE_SS_CNTL_SSCINCINTR(0x20);
-	value |= PLLE_SS_CNTL_SSCINC(0x01);
-	value |= PLLE_SS_CNTL_SSCMAX(0x25);
-
-	writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
-
-	value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
-	value &= ~PLLE_SS_CNTL_SSCBYP;
 	value &= ~PLLE_SS_CNTL_BYPASS_SS;
+	value &= ~PLLE_SS_CNTL_SSCBYP;
 	writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
 
+	/* 6. Wait 300 ns */
+
 	udelay(1);
-
-	value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
 	value &= ~PLLE_SS_CNTL_INTERP_RESET;
 	writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
 
+	/* 7. Enable HW power sequencer for PLLE */
+
+	value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC);
+	value &= ~PLLE_MISC_IDDQ_SWCTL;
+	writel(value, NV_PA_CLK_RST_BASE + PLLE_MISC);
+
+	value = readl(NV_PA_CLK_RST_BASE + PLLE_AUX);
+	value &= ~PLLE_AUX_SS_SWCTL;
+	value &= ~PLLE_AUX_ENABLE_SWCTL;
+	value |= PLLE_AUX_SS_SEQ_INCLUDE;
+	value |= PLLE_AUX_USE_LOCKDET;
+	writel(value, NV_PA_CLK_RST_BASE + PLLE_AUX);
+
+	/* 8. Wait 1 us */
+
 	udelay(1);
+	value |= PLLE_AUX_SEQ_ENABLE;
+	writel(value, NV_PA_CLK_RST_BASE + PLLE_AUX);
 
 	return 0;
 }
diff --git a/arch/arm/mach-tegra/tegra210/xusb-padctl.c b/arch/arm/mach-tegra/tegra210/xusb-padctl.c
index 3c10a96..9ec93e7 100644
--- a/arch/arm/mach-tegra/tegra210/xusb-padctl.c
+++ b/arch/arm/mach-tegra/tegra210/xusb-padctl.c
@@ -8,51 +8,82 @@
 
 #include <common.h>
 #include <errno.h>
-#include <fdtdec.h>
-#include <malloc.h>
 
-#include <asm/io.h>
+#include "../xusb-padctl-common.h"
 
 #include <asm/arch/clock.h>
-#include <asm/arch-tegra/xusb-padctl.h>
 
 #include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h>
 
-struct tegra_xusb_phy_ops {
-	int (*prepare)(struct tegra_xusb_phy *phy);
-	int (*enable)(struct tegra_xusb_phy *phy);
-	int (*disable)(struct tegra_xusb_phy *phy);
-	int (*unprepare)(struct tegra_xusb_phy *phy);
+enum tegra210_function {
+	TEGRA210_FUNC_SNPS,
+	TEGRA210_FUNC_XUSB,
+	TEGRA210_FUNC_UART,
+	TEGRA210_FUNC_PCIE_X1,
+	TEGRA210_FUNC_PCIE_X4,
+	TEGRA210_FUNC_USB3,
+	TEGRA210_FUNC_SATA,
+	TEGRA210_FUNC_RSVD,
 };
 
-struct tegra_xusb_phy {
-	const struct tegra_xusb_phy_ops *ops;
-
-	struct tegra_xusb_padctl *padctl;
+static const char *const tegra210_functions[] = {
+	"snps",
+	"xusb",
+	"uart",
+	"pcie-x1",
+	"pcie-x4",
+	"usb3",
+	"sata",
+	"rsvd",
 };
 
-struct tegra_xusb_padctl {
-	struct fdt_resource regs;
-
-	unsigned int enable;
-
-	struct tegra_xusb_phy phys[2];
+static const unsigned int tegra210_otg_functions[] = {
+	TEGRA210_FUNC_SNPS,
+	TEGRA210_FUNC_XUSB,
+	TEGRA210_FUNC_UART,
+	TEGRA210_FUNC_RSVD,
 };
 
-static inline u32 padctl_readl(struct tegra_xusb_padctl *padctl,
-			       unsigned long offset)
-{
-	u32 value = readl(padctl->regs.start + offset);
-	debug("padctl: %08lx > %08x\n", offset, value);
-	return value;
-}
+static const unsigned int tegra210_usb_functions[] = {
+	TEGRA210_FUNC_SNPS,
+	TEGRA210_FUNC_XUSB,
+};
 
-static inline void padctl_writel(struct tegra_xusb_padctl *padctl,
-				 u32 value, unsigned long offset)
-{
-	debug("padctl: %08lx < %08x\n", offset, value);
-	writel(value, padctl->regs.start + offset);
-}
+static const unsigned int tegra210_pci_functions[] = {
+	TEGRA210_FUNC_PCIE_X1,
+	TEGRA210_FUNC_USB3,
+	TEGRA210_FUNC_SATA,
+	TEGRA210_FUNC_PCIE_X4,
+};
+
+#define TEGRA210_LANE(_name, _offset, _shift, _mask, _iddq, _funcs)	\
+	{								\
+		.name = _name,						\
+		.offset = _offset,					\
+		.shift = _shift,					\
+		.mask = _mask,						\
+		.iddq = _iddq,						\
+		.num_funcs = ARRAY_SIZE(tegra210_##_funcs##_functions),	\
+		.funcs = tegra210_##_funcs##_functions,			\
+	}
+
+static const struct tegra_xusb_padctl_lane tegra210_lanes[] = {
+	TEGRA210_LANE("otg-0",     0x004,  0, 0x3, 0, otg),
+	TEGRA210_LANE("otg-1",     0x004,  2, 0x3, 0, otg),
+	TEGRA210_LANE("otg-2",     0x004,  4, 0x3, 0, otg),
+	TEGRA210_LANE("otg-3",     0x004,  6, 0x3, 0, otg),
+	TEGRA210_LANE("usb2-bias", 0x004, 18, 0x3, 0, otg),
+	TEGRA210_LANE("hsic-0",    0x004, 14, 0x1, 0, usb),
+	TEGRA210_LANE("hsic-1",    0x004, 15, 0x1, 0, usb),
+	TEGRA210_LANE("pcie-0",    0x028, 12, 0x3, 1, pci),
+	TEGRA210_LANE("pcie-1",    0x028, 14, 0x3, 2, pci),
+	TEGRA210_LANE("pcie-2",    0x028, 16, 0x3, 3, pci),
+	TEGRA210_LANE("pcie-3",    0x028, 18, 0x3, 4, pci),
+	TEGRA210_LANE("pcie-4",    0x028, 20, 0x3, 5, pci),
+	TEGRA210_LANE("pcie-5",    0x028, 22, 0x3, 6, pci),
+	TEGRA210_LANE("pcie-6",    0x028, 24, 0x3, 7, pci),
+	TEGRA210_LANE("sata-0",    0x028, 30, 0x3, 8, pci),
+};
 
 #define XUSB_PADCTL_ELPG_PROGRAM 0x024
 #define  XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN (1 << 31)
@@ -248,7 +279,10 @@
 		if (value & XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_DONE)
 			break;
 	}
-
+	if (!(value & XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_DONE)) {
+		debug("  timeout\n");
+		return -ETIMEDOUT;
+	}
 	debug("  done\n");
 
 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
@@ -264,7 +298,10 @@
 		if ((value & XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_DONE) == 0)
 			break;
 	}
-
+	if (value & XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_DONE) {
+		debug("  timeout\n");
+		return -ETIMEDOUT;
+	}
 	debug("  done\n");
 
 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
@@ -279,7 +316,10 @@
 		if (value & XUSB_PADCTL_UPHY_PLL_P0_CTL1_LOCKDET_STATUS)
 			break;
 	}
-
+	if (!(value & XUSB_PADCTL_UPHY_PLL_P0_CTL1_LOCKDET_STATUS)) {
+		debug("  timeout\n");
+		return -ETIMEDOUT;
+	}
 	debug("  done\n");
 
 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
@@ -295,7 +335,10 @@
 		if (value & XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_DONE)
 			break;
 	}
-
+	if (!(value & XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_DONE)) {
+		debug("  timeout\n");
+		return -ETIMEDOUT;
+	}
 	debug("  done\n");
 
 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
@@ -310,7 +353,10 @@
 		if ((value & XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_DONE) == 0)
 			break;
 	}
-
+	if (value & XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_DONE) {
+		debug("  timeout\n");
+		return -ETIMEDOUT;
+	}
 	debug("  done\n");
 
 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
@@ -358,120 +404,22 @@
 	.unprepare = phy_unprepare,
 };
 
-static struct tegra_xusb_padctl *padctl = &(struct tegra_xusb_padctl) {
-	.phys = {
-		[0] = {
-			.ops = &pcie_phy_ops,
-		},
+static struct tegra_xusb_phy tegra210_phys[] = {
+	{
+		.type = TEGRA_XUSB_PADCTL_PCIE,
+		.ops = &pcie_phy_ops,
+		.padctl = &padctl,
 	},
 };
 
-static int tegra_xusb_padctl_parse_dt(struct tegra_xusb_padctl *padctl,
-				      const void *fdt, int node)
-{
-	int err;
-
-	err = fdt_get_resource(fdt, node, "reg", 0, &padctl->regs);
-	if (err < 0) {
-		error("registers not found");
-		return err;
-	}
-
-	debug("regs: %pa-%pa\n", &padctl->regs.start,
-	      &padctl->regs.end);
-
-	return 0;
-}
-
-static int process_nodes(const void *fdt, int nodes[], unsigned int count)
-{
-	unsigned int i;
-	int err;
-
-	debug("> %s(fdt=%p, nodes=%p, count=%u)\n", __func__, fdt, nodes,
-	      count);
-
-	for (i = 0; i < count; i++) {
-		enum fdt_compat_id id;
-
-		if (!fdtdec_get_is_enabled(fdt, nodes[i]))
-			continue;
-
-		id = fdtdec_lookup(fdt, nodes[i]);
-		switch (id) {
-		case COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL:
-		case COMPAT_NVIDIA_TEGRA210_XUSB_PADCTL:
-			break;
-
-		default:
-			error("unsupported compatible: %s",
-			      fdtdec_get_compatible(id));
-			continue;
-		}
-
-		err = tegra_xusb_padctl_parse_dt(padctl, fdt, nodes[i]);
-		if (err < 0) {
-			error("failed to parse DT: %d",
-			      err);
-			continue;
-		}
-
-		/* deassert XUSB padctl reset */
-		reset_set_enable(PERIPH_ID_XUSB_PADCTL, 0);
-
-		/* only a single instance is supported */
-		break;
-	}
-
-	debug("< %s()\n", __func__);
-	return 0;
-}
-
-struct tegra_xusb_phy *tegra_xusb_phy_get(unsigned int type)
-{
-	struct tegra_xusb_phy *phy = NULL;
-
-	switch (type) {
-	case TEGRA_XUSB_PADCTL_PCIE:
-		phy = &padctl->phys[0];
-		phy->padctl = padctl;
-		break;
-	}
-
-	return phy;
-}
-
-int tegra_xusb_phy_prepare(struct tegra_xusb_phy *phy)
-{
-	if (phy && phy->ops && phy->ops->prepare)
-		return phy->ops->prepare(phy);
-
-	return phy ? -ENOSYS : -EINVAL;
-}
-
-int tegra_xusb_phy_enable(struct tegra_xusb_phy *phy)
-{
-	if (phy && phy->ops && phy->ops->enable)
-		return phy->ops->enable(phy);
-
-	return phy ? -ENOSYS : -EINVAL;
-}
-
-int tegra_xusb_phy_disable(struct tegra_xusb_phy *phy)
-{
-	if (phy && phy->ops && phy->ops->disable)
-		return phy->ops->disable(phy);
-
-	return phy ? -ENOSYS : -EINVAL;
-}
-
-int tegra_xusb_phy_unprepare(struct tegra_xusb_phy *phy)
-{
-	if (phy && phy->ops && phy->ops->unprepare)
-		return phy->ops->unprepare(phy);
-
-	return phy ? -ENOSYS : -EINVAL;
-}
+static const struct tegra_xusb_padctl_soc tegra210_socdata = {
+	.lanes = tegra210_lanes,
+	.num_lanes = ARRAY_SIZE(tegra210_lanes),
+	.functions = tegra210_functions,
+	.num_functions = ARRAY_SIZE(tegra210_functions),
+	.phys = tegra210_phys,
+	.num_phys = ARRAY_SIZE(tegra210_phys),
+};
 
 void tegra_xusb_padctl_init(const void *fdt)
 {
@@ -482,13 +430,7 @@
 	count = fdtdec_find_aliases_for_id(fdt, "padctl",
 					   COMPAT_NVIDIA_TEGRA210_XUSB_PADCTL,
 					   nodes, ARRAY_SIZE(nodes));
-	if (process_nodes(fdt, nodes, count))
-		return;
-
-	count = fdtdec_find_aliases_for_id(fdt, "padctl",
-					   COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL,
-					   nodes, ARRAY_SIZE(nodes));
-	if (process_nodes(fdt, nodes, count))
+	if (tegra_xusb_process_nodes(fdt, nodes, count, &tegra210_socdata))
 		return;
 
 	debug("< %s()\n", __func__);
diff --git a/arch/arm/mach-tegra/xusb-padctl-common.c b/arch/arm/mach-tegra/xusb-padctl-common.c
new file mode 100644
index 0000000..18ad7bf
--- /dev/null
+++ b/arch/arm/mach-tegra/xusb-padctl-common.c
@@ -0,0 +1,305 @@
+/*
+ * Copyright (c) 2014-2015, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#define pr_fmt(fmt) "tegra-xusb-padctl: " fmt
+
+#include <common.h>
+#include <errno.h>
+
+#include "xusb-padctl-common.h"
+
+#include <asm/arch/clock.h>
+
+int tegra_xusb_phy_prepare(struct tegra_xusb_phy *phy)
+{
+	if (phy && phy->ops && phy->ops->prepare)
+		return phy->ops->prepare(phy);
+
+	return phy ? -ENOSYS : -EINVAL;
+}
+
+int tegra_xusb_phy_enable(struct tegra_xusb_phy *phy)
+{
+	if (phy && phy->ops && phy->ops->enable)
+		return phy->ops->enable(phy);
+
+	return phy ? -ENOSYS : -EINVAL;
+}
+
+int tegra_xusb_phy_disable(struct tegra_xusb_phy *phy)
+{
+	if (phy && phy->ops && phy->ops->disable)
+		return phy->ops->disable(phy);
+
+	return phy ? -ENOSYS : -EINVAL;
+}
+
+int tegra_xusb_phy_unprepare(struct tegra_xusb_phy *phy)
+{
+	if (phy && phy->ops && phy->ops->unprepare)
+		return phy->ops->unprepare(phy);
+
+	return phy ? -ENOSYS : -EINVAL;
+}
+
+struct tegra_xusb_phy *tegra_xusb_phy_get(unsigned int type)
+{
+	struct tegra_xusb_phy *phy;
+	int i;
+
+	for (i = 0; i < padctl.socdata->num_phys; i++) {
+		phy = &padctl.socdata->phys[i];
+		if (phy->type != type)
+			continue;
+		return phy;
+	}
+
+	return NULL;
+}
+
+static const struct tegra_xusb_padctl_lane *
+tegra_xusb_padctl_find_lane(struct tegra_xusb_padctl *padctl, const char *name)
+{
+	unsigned int i;
+
+	for (i = 0; i < padctl->socdata->num_lanes; i++)
+		if (strcmp(name, padctl->socdata->lanes[i].name) == 0)
+			return &padctl->socdata->lanes[i];
+
+	return NULL;
+}
+
+static int
+tegra_xusb_padctl_group_parse_dt(struct tegra_xusb_padctl *padctl,
+				 struct tegra_xusb_padctl_group *group,
+				 const void *fdt, int node)
+{
+	unsigned int i;
+	int len, err;
+
+	group->name = fdt_get_name(fdt, node, &len);
+
+	len = fdt_count_strings(fdt, node, "nvidia,lanes");
+	if (len < 0) {
+		error("failed to parse \"nvidia,lanes\" property");
+		return -EINVAL;
+	}
+
+	group->num_pins = len;
+
+	for (i = 0; i < group->num_pins; i++) {
+		err = fdt_get_string_index(fdt, node, "nvidia,lanes", i,
+					   &group->pins[i]);
+		if (err < 0) {
+			error("failed to read string from \"nvidia,lanes\" property");
+			return -EINVAL;
+		}
+	}
+
+	group->num_pins = len;
+
+	err = fdt_get_string(fdt, node, "nvidia,function", &group->func);
+	if (err < 0) {
+		error("failed to parse \"nvidia,func\" property");
+		return -EINVAL;
+	}
+
+	group->iddq = fdtdec_get_int(fdt, node, "nvidia,iddq", -1);
+
+	return 0;
+}
+
+static int tegra_xusb_padctl_find_function(struct tegra_xusb_padctl *padctl,
+					   const char *name)
+{
+	unsigned int i;
+
+	for (i = 0; i < padctl->socdata->num_functions; i++)
+		if (strcmp(name, padctl->socdata->functions[i]) == 0)
+			return i;
+
+	return -ENOENT;
+}
+
+static int
+tegra_xusb_padctl_lane_find_function(struct tegra_xusb_padctl *padctl,
+				     const struct tegra_xusb_padctl_lane *lane,
+				     const char *name)
+{
+	unsigned int i;
+	int func;
+
+	func = tegra_xusb_padctl_find_function(padctl, name);
+	if (func < 0)
+		return func;
+
+	for (i = 0; i < lane->num_funcs; i++)
+		if (lane->funcs[i] == func)
+			return i;
+
+	return -ENOENT;
+}
+
+static int
+tegra_xusb_padctl_group_apply(struct tegra_xusb_padctl *padctl,
+			      const struct tegra_xusb_padctl_group *group)
+{
+	unsigned int i;
+
+	for (i = 0; i < group->num_pins; i++) {
+		const struct tegra_xusb_padctl_lane *lane;
+		unsigned int func;
+		u32 value;
+
+		lane = tegra_xusb_padctl_find_lane(padctl, group->pins[i]);
+		if (!lane) {
+			error("no lane for pin %s", group->pins[i]);
+			continue;
+		}
+
+		func = tegra_xusb_padctl_lane_find_function(padctl, lane,
+							    group->func);
+		if (func < 0) {
+			error("function %s invalid for lane %s: %d",
+			      group->func, lane->name, func);
+			continue;
+		}
+
+		value = padctl_readl(padctl, lane->offset);
+
+		/* set pin function */
+		value &= ~(lane->mask << lane->shift);
+		value |= func << lane->shift;
+
+		/*
+		 * Set IDDQ if supported on the lane and specified in the
+		 * configuration.
+		 */
+		if (lane->iddq > 0 && group->iddq >= 0) {
+			if (group->iddq != 0)
+				value &= ~(1 << lane->iddq);
+			else
+				value |= 1 << lane->iddq;
+		}
+
+		padctl_writel(padctl, value, lane->offset);
+	}
+
+	return 0;
+}
+
+static int
+tegra_xusb_padctl_config_apply(struct tegra_xusb_padctl *padctl,
+			       struct tegra_xusb_padctl_config *config)
+{
+	unsigned int i;
+
+	for (i = 0; i < config->num_groups; i++) {
+		const struct tegra_xusb_padctl_group *group;
+		int err;
+
+		group = &config->groups[i];
+
+		err = tegra_xusb_padctl_group_apply(padctl, group);
+		if (err < 0) {
+			error("failed to apply group %s: %d",
+			      group->name, err);
+			continue;
+		}
+	}
+
+	return 0;
+}
+
+static int
+tegra_xusb_padctl_config_parse_dt(struct tegra_xusb_padctl *padctl,
+				  struct tegra_xusb_padctl_config *config,
+				  const void *fdt, int node)
+{
+	int subnode;
+
+	config->name = fdt_get_name(fdt, node, NULL);
+
+	fdt_for_each_subnode(fdt, subnode, node) {
+		struct tegra_xusb_padctl_group *group;
+		int err;
+
+		group = &config->groups[config->num_groups];
+
+		err = tegra_xusb_padctl_group_parse_dt(padctl, group, fdt,
+						       subnode);
+		if (err < 0) {
+			error("failed to parse group %s", group->name);
+			return err;
+		}
+
+		config->num_groups++;
+	}
+
+	return 0;
+}
+
+static int tegra_xusb_padctl_parse_dt(struct tegra_xusb_padctl *padctl,
+				      const void *fdt, int node)
+{
+	int subnode, err;
+
+	err = fdt_get_resource(fdt, node, "reg", 0, &padctl->regs);
+	if (err < 0) {
+		error("registers not found");
+		return err;
+	}
+
+	fdt_for_each_subnode(fdt, subnode, node) {
+		struct tegra_xusb_padctl_config *config = &padctl->config;
+
+		err = tegra_xusb_padctl_config_parse_dt(padctl, config, fdt,
+							subnode);
+		if (err < 0) {
+			error("failed to parse entry %s: %d",
+			      config->name, err);
+			continue;
+		}
+	}
+
+	return 0;
+}
+
+struct tegra_xusb_padctl padctl;
+
+int tegra_xusb_process_nodes(const void *fdt, int nodes[], unsigned int count,
+	const struct tegra_xusb_padctl_soc *socdata)
+{
+	unsigned int i;
+	int err;
+
+	for (i = 0; i < count; i++) {
+		if (!fdtdec_get_is_enabled(fdt, nodes[i]))
+			continue;
+
+		padctl.socdata = socdata;
+
+		err = tegra_xusb_padctl_parse_dt(&padctl, fdt, nodes[i]);
+		if (err < 0) {
+			error("failed to parse DT: %d", err);
+			continue;
+		}
+
+		/* deassert XUSB padctl reset */
+		reset_set_enable(PERIPH_ID_XUSB_PADCTL, 0);
+
+		err = tegra_xusb_padctl_config_apply(&padctl, &padctl.config);
+		if (err < 0) {
+			error("failed to apply pinmux: %d", err);
+			continue;
+		}
+
+		/* only a single instance is supported */
+		break;
+	}
+
+	return 0;
+}
diff --git a/arch/arm/mach-tegra/xusb-padctl-common.h b/arch/arm/mach-tegra/xusb-padctl-common.h
new file mode 100644
index 0000000..f44790a
--- /dev/null
+++ b/arch/arm/mach-tegra/xusb-padctl-common.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2014-2015, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _TEGRA_XUSB_PADCTL_COMMON_H_
+#define _TEGRA_XUSB_PADCTL_COMMON_H_
+
+#include <common.h>
+#include <fdtdec.h>
+
+#include <asm/io.h>
+#include <asm/arch-tegra/xusb-padctl.h>
+
+struct tegra_xusb_padctl_lane {
+	const char *name;
+
+	unsigned int offset;
+	unsigned int shift;
+	unsigned int mask;
+	unsigned int iddq;
+
+	const unsigned int *funcs;
+	unsigned int num_funcs;
+};
+
+struct tegra_xusb_phy_ops {
+	int (*prepare)(struct tegra_xusb_phy *phy);
+	int (*enable)(struct tegra_xusb_phy *phy);
+	int (*disable)(struct tegra_xusb_phy *phy);
+	int (*unprepare)(struct tegra_xusb_phy *phy);
+};
+
+struct tegra_xusb_phy {
+	unsigned int type;
+	const struct tegra_xusb_phy_ops *ops;
+	struct tegra_xusb_padctl *padctl;
+};
+
+struct tegra_xusb_padctl_pin {
+	const struct tegra_xusb_padctl_lane *lane;
+
+	unsigned int func;
+	int iddq;
+};
+
+#define MAX_GROUPS 5
+#define MAX_PINS 7
+
+struct tegra_xusb_padctl_group {
+	const char *name;
+
+	const char *pins[MAX_PINS];
+	unsigned int num_pins;
+
+	const char *func;
+	int iddq;
+};
+
+struct tegra_xusb_padctl_soc {
+	const struct tegra_xusb_padctl_lane *lanes;
+	unsigned int num_lanes;
+	const char *const *functions;
+	unsigned int num_functions;
+	struct tegra_xusb_phy *phys;
+	unsigned int num_phys;
+};
+
+struct tegra_xusb_padctl_config {
+	const char *name;
+
+	struct tegra_xusb_padctl_group groups[MAX_GROUPS];
+	unsigned int num_groups;
+};
+
+struct tegra_xusb_padctl {
+	const struct tegra_xusb_padctl_soc *socdata;
+	struct tegra_xusb_padctl_config config;
+	struct fdt_resource regs;
+	unsigned int enable;
+
+};
+extern struct tegra_xusb_padctl padctl;
+
+static inline u32 padctl_readl(struct tegra_xusb_padctl *padctl,
+			       unsigned long offset)
+{
+	return readl(padctl->regs.start + offset);
+}
+
+static inline void padctl_writel(struct tegra_xusb_padctl *padctl,
+				 u32 value, unsigned long offset)
+{
+	writel(value, padctl->regs.start + offset);
+}
+
+int tegra_xusb_process_nodes(const void *fdt, int nodes[], unsigned int count,
+	const struct tegra_xusb_padctl_soc *socdata);
+
+#endif
diff --git a/arch/arm/mach-tegra/xusb-padctl.c b/arch/arm/mach-tegra/xusb-padctl-dummy.c
similarity index 100%
rename from arch/arm/mach-tegra/xusb-padctl.c
rename to arch/arm/mach-tegra/xusb-padctl-dummy.c
diff --git a/arch/openrisc/config.mk b/arch/openrisc/config.mk
index cd95f24..bfdb71f 100644
--- a/arch/openrisc/config.mk
+++ b/arch/openrisc/config.mk
@@ -6,7 +6,7 @@
 #
 
 ifeq ($(CROSS_COMPILE),)
-CROSS_COMPILE := or32-elf-
+CROSS_COMPILE := or1k-elf-
 endif
 
 # r10 used for global object pointer, already set in OR32 GCC but just to be
diff --git a/arch/openrisc/cpu/u-boot.lds b/arch/openrisc/cpu/u-boot.lds
index d9bb7b7..854088b 100644
--- a/arch/openrisc/cpu/u-boot.lds
+++ b/arch/openrisc/cpu/u-boot.lds
@@ -1,5 +1,5 @@
 #include <config.h>
-OUTPUT_ARCH(or32)
+OUTPUT_ARCH(or1k)
 __DYNAMIC  =  0;
 
 MEMORY
diff --git a/arch/powerpc/cpu/mpc83xx/Kconfig b/arch/powerpc/cpu/mpc83xx/Kconfig
index 3fb901f..3ea62ca 100644
--- a/arch/powerpc/cpu/mpc83xx/Kconfig
+++ b/arch/powerpc/cpu/mpc83xx/Kconfig
@@ -67,6 +67,9 @@
 config TARGET_HRCON
 	bool "Support hrcon"
 
+config TARGET_STRIDER
+	bool "Support strider"
+
 endchoice
 
 source "board/esd/vme8349/Kconfig"
diff --git a/arch/sparc/config.mk b/arch/sparc/config.mk
index d615f29..43faad4 100644
--- a/arch/sparc/config.mk
+++ b/arch/sparc/config.mk
@@ -1,19 +1,25 @@
 #
-# (C) Copyright 2007
-# Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
+# (C) Copyright 2015
+# Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
 #
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
 ifeq ($(CROSS_COMPILE),)
-CROSS_COMPILE := sparc-elf-
+CROSS_COMPILE := sparc-linux-
 endif
 
+# This GCC compiler is known to work:
+#  https://www.kernel.org/pub/tools/crosstool/files/bin/x86_64/4.9.0/
+
 gcclibdir := $(shell dirname `$(CC) -print-libgcc-file-name`)
 
 CONFIG_STANDALONE_LOAD_ADDR ?= 0x00000000 -L $(gcclibdir) \
 			       -T $(srctree)/examples/standalone/sparc.lds
 
-PLATFORM_CPPFLAGS += -D__sparc__
+cpuflags-$(CONFIG_LEON2) := -mcpu=leon
+cpuflags-$(CONFIG_LEON3) := -mcpu=leon3
+
+PLATFORM_CPPFLAGS += $(cpuflags-y)
 
 PLATFORM_RELFLAGS += -fPIC
diff --git a/arch/sparc/cpu/leon2/serial.c b/arch/sparc/cpu/leon2/serial.c
index 5cfbb9e..603364e 100644
--- a/arch/sparc/cpu/leon2/serial.c
+++ b/arch/sparc/cpu/leon2/serial.c
@@ -1,72 +1,78 @@
 /* GRLIB APBUART Serial controller driver
  *
- * (C) Copyright 2008
- * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ * (C) Copyright 2008, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
 #include <common.h>
-#include <asm/processor.h>
-#include <asm/leon.h>
+#include <asm/io.h>
 #include <serial.h>
-#include <linux/compiler.h>
+#include <watchdog.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+static unsigned leon2_serial_calc_scaler(unsigned freq, unsigned baud)
+{
+	return (((freq*10) / (baud*8)) - 5) / 10;
+}
+
 static int leon2_serial_init(void)
 {
-	LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
+	LEON2_regs *leon2 = (LEON2_regs *)LEON2_PREGS;
 	LEON2_Uart_regs *regs;
 	unsigned int tmp;
 
-	/* Init LEON2 UART
-	 *
-	 * Set scaler / baud rate
-	 *
-	 * Receiver & transmitter enable
-	 */
 #if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
-	regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1;
+	regs = (LEON2_Uart_regs *)&leon2->UART_Channel_1;
 #else
-	regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2;
+	regs = (LEON2_Uart_regs *)&leon2->UART_Channel_2;
 #endif
 
-	regs->UART_Scaler = CONFIG_SYS_LEON2_UART1_SCALER;
+	/* Set scaler / baud rate */
+	tmp = leon2_serial_calc_scaler(CONFIG_SYS_CLK_FREQ, CONFIG_BAUDRATE);
+	writel(tmp, &regs->UART_Scaler);
 
 	/* Let bit 11 be unchanged (debug bit for GRMON) */
-	tmp = READ_WORD(regs->UART_Control);
+	tmp = readl(&regs->UART_Control) & LEON2_UART_CTRL_DBG;
+	tmp |= (LEON2_UART1_LOOPBACK_ENABLE << 7);
+	tmp |= (LEON2_UART1_FLOWCTRL_ENABLE << 6);
+	tmp |= (LEON2_UART1_PARITY_ENABLE << 5);
+	tmp |= (LEON2_UART1_ODDPAR_ENABLE << 4);
+	/* Receiver & transmitter enable */
+	tmp |= (LEON2_UART_CTRL_RE | LEON2_UART_CTRL_TE);
+	writel(tmp, &regs->UART_Control);
 
-	regs->UART_Control = ((tmp & LEON2_UART_CTRL_DBG) |
-			      (LEON2_UART1_LOOPBACK_ENABLE << 7) |
-			      (LEON2_UART1_FLOWCTRL_ENABLE << 6) |
-			      (LEON2_UART1_PARITY_ENABLE << 5) |
-			      (LEON2_UART1_ODDPAR_ENABLE << 4) |
-			      LEON2_UART_CTRL_RE | LEON2_UART_CTRL_TE);
-
+	gd->arch.uart = regs;
 	return 0;
 }
 
+static inline LEON2_Uart_regs *leon2_get_uart_regs(void)
+{
+	LEON2_Uart_regs *uart = gd->arch.uart;
+
+	return uart;
+}
+
 static void leon2_serial_putc_raw(const char c)
 {
-	LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
-	LEON2_Uart_regs *regs;
+	LEON2_Uart_regs *uart = leon2_get_uart_regs();
 
-#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
-	regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1;
-#else
-	regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2;
-#endif
+	if (!uart)
+		return;
 
 	/* Wait for last character to go. */
-	while (!(READ_WORD(regs->UART_Status) & LEON2_UART_STAT_THE)) ;
+	while (!(readl(&uart->UART_Status) & LEON2_UART_STAT_THE))
+		WATCHDOG_RESET();
 
 	/* Send data */
-	regs->UART_Channel = c;
+	writel(c, &uart->UART_Channel);
 
 #ifdef LEON_DEBUG
 	/* Wait for data to be sent */
-	while (!(READ_WORD(regs->UART_Status) & LEON2_UART_STAT_TSE)) ;
+	while (!(readl(&uart->UART_Status) & LEON2_UART_STAT_TSE))
+		WATCHDOG_RESET();
 #endif
 }
 
@@ -80,56 +86,43 @@
 
 static int leon2_serial_getc(void)
 {
-	LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
-	LEON2_Uart_regs *regs;
+	LEON2_Uart_regs *uart = leon2_get_uart_regs();
 
-#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
-	regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1;
-#else
-	regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2;
-#endif
+	if (!uart)
+		return 0;
 
 	/* Wait for a character to arrive. */
-	while (!(READ_WORD(regs->UART_Status) & LEON2_UART_STAT_DR)) ;
+	while (!(readl(&uart->UART_Status) & LEON2_UART_STAT_DR))
+		WATCHDOG_RESET();
 
-	/* read data */
-	return READ_WORD(regs->UART_Channel);
+	/* Read character data */
+	return readl(&uart->UART_Channel);
 }
 
 static int leon2_serial_tstc(void)
 {
-	LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
-	LEON2_Uart_regs *regs;
+	LEON2_Uart_regs *uart = leon2_get_uart_regs();
 
-#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
-	regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1;
-#else
-	regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2;
-#endif
+	if (!uart)
+		return 0;
 
-	return (READ_WORD(regs->UART_Status) & LEON2_UART_STAT_DR);
+	return readl(&uart->UART_Status) & LEON2_UART_STAT_DR;
 }
 
-/* set baud rate for uart */
 static void leon2_serial_setbrg(void)
 {
-	/* update baud rate settings, read it from gd->baudrate */
+	LEON2_Uart_regs *uart = leon2_get_uart_regs();
 	unsigned int scaler;
-	LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
-	LEON2_Uart_regs *regs;
 
-#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
-	regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1;
-#else
-	regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2;
-#endif
+	if (!uart)
+		return;
 
-	if (gd->baudrate > 0) {
-		scaler =
-		    (((CONFIG_SYS_CLK_FREQ * 10) / (gd->baudrate * 8)) -
-		     5) / 10;
-		regs->UART_Scaler = scaler;
-	}
+	if (!gd->baudrate)
+		gd->baudrate = CONFIG_BAUDRATE;
+
+	scaler = leon2_serial_calc_scaler(CONFIG_SYS_CLK_FREQ, CONFIG_BAUDRATE);
+
+	writel(scaler, &uart->UART_Scaler);
 }
 
 static struct serial_device leon2_serial_drv = {
diff --git a/arch/sparc/cpu/leon2/start.S b/arch/sparc/cpu/leon2/start.S
index e43097c..974de76 100644
--- a/arch/sparc/cpu/leon2/start.S
+++ b/arch/sparc/cpu/leon2/start.S
@@ -57,6 +57,27 @@
 #error Must define number of SPARC register windows, default is 8
 #endif
 
+/* Macros to load address into a register. Uses GOT table for PIC */
+#ifdef __PIC__
+
+#define SPARC_PIC_THUNK_CALL(reg) \
+	sethi	%pc22(_GLOBAL_OFFSET_TABLE_-4), %##reg; \
+	call	__sparc_get_pc_thunk.reg; \
+	 add	%##reg, %pc10(_GLOBAL_OFFSET_TABLE_+4), %##reg;
+
+#define SPARC_LOAD_ADDRESS(sym, got, reg) \
+	sethi	%gdop_hix22(sym), %##reg; \
+	xor	%##reg, %gdop_lox10(sym), %##reg; \
+	ld	[%##got + %##reg], %##reg, %gdop(sym);
+
+#else
+
+#define SPARC_PIC_THUNK_CALL(reg)
+#define SPARC_LOAD_ADDRESS(sym, got, tmp) \
+	set	sym, %##reg;
+
+#endif
+
 #define STACK_ALIGN	8
 #define SA(X)	(((X)+(STACK_ALIGN-1)) & ~(STACK_ALIGN-1))
 
@@ -278,7 +299,7 @@
 	srl	%g2, 30, %g2
 	andcc	%g2, 3, %g6
 	bne,a	leon2_init_wim
-	mov	%g0, %asr16		! clear err_reg
+	 mov	%g0, %asr16		! clear err_reg
 
 leon2_init_wim:
 	set	WIM_INIT, %g3
@@ -299,7 +320,7 @@
 
 cpu_init_unreloc:
 	call	cpu_init_f
-	nop
+	 nop
 
 /* un relocated start address of monitor */
 #define TEXT_START _text
@@ -307,9 +328,10 @@
 /* un relocated end address of monitor */
 #define DATA_END __init_end
 
+	SPARC_PIC_THUNK_CALL(l7)
 reloc:
-	set	TEXT_START,%g2
-	set	DATA_END,%g3
+	SPARC_LOAD_ADDRESS(TEXT_START, l7, g2)
+	SPARC_LOAD_ADDRESS(DATA_END, l7, g3)
 	set	CONFIG_SYS_RELOC_MONITOR_BASE,%g4
 reloc_loop:
 	ldd	[%g2],%l0
@@ -319,7 +341,7 @@
 	inc	16,%g2
 	subcc	%g3,%g2,%g0
 	bne	reloc_loop
-	inc	16,%g4
+	 inc	16,%g4
 
 	clr	%l0
 	clr	%l1
@@ -336,8 +358,8 @@
 
 clr_bss:
 /* clear bss area (the relocated) */
-	set	__bss_start,%g2
-	set	__bss_end,%g3
+	SPARC_LOAD_ADDRESS(__bss_start, l7, g2)
+	SPARC_LOAD_ADDRESS(__bss_end, l7, g3)
 	sub	%g3,%g2,%g3
 	add	%g3,%g4,%g3
 	clr	%g1	/* std %g0 uses g0 and g1 */
@@ -348,19 +370,19 @@
 	inc	16,%g4
 	cmp	%g3,%g4
 	bne	clr_bss_16
-	nop
+	 nop
 
 /* add offsets to GOT table */
 fixup_got:
-	set	__got_start,%g4
-	set	__got_end,%g3
+	SPARC_LOAD_ADDRESS(__got_start, l7, g4)
+	SPARC_LOAD_ADDRESS(__got_end, l7, g3)
 /*
  * new got offset = (old GOT-PTR (read with ld) -
  *   CONFIG_SYS_RELOC_MONITOR_BASE(from define) ) +
  *   Destination Address (from define)
  */
 	set	CONFIG_SYS_RELOC_MONITOR_BASE,%g2
-	set	TEXT_START, %g1
+	SPARC_LOAD_ADDRESS(TEXT_START, l7, g1)
 	add	%g4,%g2,%g4
 	sub	%g4,%g1,%g4
 	add	%g3,%g2,%g3
@@ -375,11 +397,11 @@
 	inc	4,%g4
 	cmp	%g3,%g4
 	bne	got_loop
-	nop
+	 nop
 
 prom_relocate:
-	set	__prom_start, %g2
-	set	__prom_end, %g3
+	SPARC_LOAD_ADDRESS(__prom_start, l7, g2)
+	SPARC_LOAD_ADDRESS(__prom_end, l7, g3)
 	set	CONFIG_SYS_PROM_OFFSET, %g4
 
 prom_relocate_loop:
@@ -390,7 +412,7 @@
 	inc	16,%g2
 	subcc	%g3,%g2,%g0
 	bne	prom_relocate_loop
-	inc	16,%g4
+	 inc	16,%g4
 
 /* Trap table has been moved, lets tell CPU about
  * the new trap table address
@@ -403,19 +425,19 @@
 	nop
 /* Call relocated init functions */
 jump:
-	set	cpu_init_f2,%o1
+	SPARC_LOAD_ADDRESS(cpu_init_f2, l7, o1)
 	set	CONFIG_SYS_RELOC_MONITOR_BASE,%o2
 	add	%o1,%o2,%o1
 	sub	%o1,%g1,%o1
 	call	%o1
-	clr	%o0
+	 clr	%o0
 
-	set	board_init_f,%o1
+	SPARC_LOAD_ADDRESS(board_init_f, l7, o1)
 	set	CONFIG_SYS_RELOC_MONITOR_BASE,%o2
 	add	%o1,%o2,%o1
 	sub	%o1,%g1,%o1
 	call	%o1
-	clr	%o0
+	 clr	%o0
 
 dead:	ta 0				! if call returns...
 	nop
diff --git a/arch/sparc/cpu/leon3/Makefile b/arch/sparc/cpu/leon3/Makefile
index 4f13ec3..f4cf43c 100644
--- a/arch/sparc/cpu/leon3/Makefile
+++ b/arch/sparc/cpu/leon3/Makefile
@@ -6,4 +6,5 @@
 #
 
 extra-y	= start.o
-obj-y	= cpu_init.o serial.o cpu.o ambapp.o interrupts.o prom.o usb_uhci.o
+obj-y	= cpu_init.o serial.o cpu.o ambapp.o ambapp_low.o ambapp_low_c.o \
+	interrupts.o prom.o usb_uhci.o memcfg.o memcfg_low.o
diff --git a/arch/sparc/cpu/leon3/ambapp.c b/arch/sparc/cpu/leon3/ambapp.c
index a30d1f2..b8ac05f 100644
--- a/arch/sparc/cpu/leon3/ambapp.c
+++ b/arch/sparc/cpu/leon3/ambapp.c
@@ -1,343 +1,316 @@
-/* Gaisler AMBA Plug&Play bus scanning. Functions
- * ending on _nomem is inteded to be used only during
- * initialization, only registers are used (no ram).
+/* GRLIB AMBA Plug&Play information scanning, relies on assembler
+ * routines.
  *
- * (C) Copyright 2007
- * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
+ * (C) Copyright 2010, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
+/* #define DEBUG */
+
 #include <common.h>
-#include <command.h>
+#include <malloc.h>
 #include <ambapp.h>
+#include <config.h>
 
-#if defined(CONFIG_CMD_AMBAPP)
-extern void ambapp_print_apb(apbctrl_pp_dev * apb,
-			     ambapp_ahbdev * apbmst, int index);
-extern void ambapp_print_ahb(ahbctrl_pp_dev * ahb, int index);
-extern int ambapp_apb_print;
-extern int ambapp_ahb_print;
-#endif
-
-static int ambapp_apb_scan(unsigned int vendor,	/* Plug&Play Vendor ID */
-			   unsigned int driver,	/* Plug&Play Device ID */
-			   ambapp_apbdev * dev,	/* Result(s) is placed here */
-			   int index,	/* Index of device to start copying Plug&Play
-					 * info into dev
-					 */
-			   int max_cnt	/* Maximal count that dev can hold, if dev
-					 * is NULL function will stop scanning after
-					 * max_cnt devices are found.
-					 */
-    )
-{
-	int i, cnt = 0;
-	unsigned int apbmst_base;
-	ambapp_ahbdev apbmst;
-	apbctrl_pp_dev *apb;
-
-	if (max_cnt == 0)
-		return 0;
-
-	/* Get AMBA APB Master */
-	if (ambapp_ahbslv_first(VENDOR_GAISLER, GAISLER_APBMST, &apbmst) != 1) {
-		return 0;
-	}
-
-	/* Get APB CTRL Plug&Play info area */
-	apbmst_base = apbmst.address[0] & LEON3_IO_AREA;
-	apb = (apbctrl_pp_dev *) (apbmst_base | LEON3_CONF_AREA);
-
-	for (i = 0; i < LEON3_APB_SLAVES; i++) {
-#if defined(CONFIG_CMD_AMBAPP)
-		if (ambapp_apb_print && amba_vendor(apb->conf)
-		    && amba_device(apb->conf)) {
-			ambapp_print_apb(apb, &apbmst, i);
-		}
-#endif
-		if ((amba_vendor(apb->conf) == vendor) &&
-		    (amba_device(apb->conf) == driver) && ((index < 0)
-							   || (index-- == 0))) {
-			/* Convert Plug&Play info into a more readable format */
-			cnt++;
-			if (dev) {
-				dev->irq = amba_irq(apb->conf);
-				dev->ver = amba_ver(apb->conf);
-				dev->address =
-				    (apbmst_base |
-				     (((apb->
-					bar & 0xfff00000) >> 12))) & (((apb->
-									bar &
-									0x0000fff0)
-								       << 4) |
-								      0xfff00000);
-				dev++;
-			}
-			/* found max devices? */
-			if (cnt >= max_cnt)
-				return cnt;
-		}
-		/* Get next Plug&Play entry */
-		apb++;
-	}
-	return cnt;
-}
-
-unsigned int ambapp_apb_next_nomem(register unsigned int vendor,	/* Plug&Play Vendor ID */
-				   register unsigned int driver,	/* Plug&Play Device ID */
-				   register int index)
-{
-	register int i;
-	register ahbctrl_pp_dev *apbmst;
-	register apbctrl_pp_dev *apb;
-	register unsigned int apbmst_base;
-
-	/* APBMST is a AHB Slave */
-	apbmst = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_APBMST, 1, 0);
-	if (!apbmst)
-		return 0;
-
-	apbmst_base = amba_membar_start(apbmst->bars[0]);
-	if (amba_membar_type(apbmst->bars[0]) == AMBA_TYPE_AHBIO)
-		apbmst_base = AMBA_TYPE_AHBIO_ADDR(apbmst_base);
-	apbmst_base &= LEON3_IO_AREA;
-
-	/* Find the vendor/driver device on the first APB bus */
-	apb = (apbctrl_pp_dev *) (apbmst_base | LEON3_CONF_AREA);
-
-	for (i = 0; i < LEON3_APB_SLAVES; i++) {
-		if ((amba_vendor(apb->conf) == vendor) &&
-		    (amba_device(apb->conf) == driver) && ((index < 0)
-							   || (index-- == 0))) {
-			/* Convert Plug&Play info info a more readable format */
-			return (apbmst_base | (((apb->bar & 0xfff00000) >> 12)))
-			    & (((apb->bar & 0x0000fff0) << 4) | 0xfff00000);
-		}
-		/* Get next Plug&Play entry */
-		apb++;
-	}
-	return 0;
-}
-
-/****************************** APB SLAVES ******************************/
-
-int ambapp_apb_count(unsigned int vendor, unsigned int driver)
-{
-	return ambapp_apb_scan(vendor, driver, NULL, 0, LEON3_APB_SLAVES);
-}
-
-int ambapp_apb_first(unsigned int vendor,
-		     unsigned int driver, ambapp_apbdev * dev)
-{
-	return ambapp_apb_scan(vendor, driver, dev, 0, 1);
-}
-
-int ambapp_apb_next(unsigned int vendor,
-		    unsigned int driver, ambapp_apbdev * dev, int index)
-{
-	return ambapp_apb_scan(vendor, driver, dev, index, 1);
-}
-
-int ambapp_apbs_first(unsigned int vendor,
-		      unsigned int driver, ambapp_apbdev * dev, int max_cnt)
-{
-	return ambapp_apb_scan(vendor, driver, dev, 0, max_cnt);
-}
-
-enum {
-	AHB_SCAN_MASTER = 0,
-	AHB_SCAN_SLAVE = 1
+/************ C INTERFACE OF ASSEMBLER SCAN ROUTINES ************/
+struct ambapp_find_apb_info {
+	/* Address of APB device Plug&Play information */
+	struct ambapp_pnp_apb	*pnp;
+	/* AHB Bus index of where the APB-Master Bridge device was found */
+	int			ahb_bus_index;
+	int			dec_index;
 };
 
-/* Scan AMBA Plug&Play bus for AMBA AHB Masters or AHB Slaves
- * for a certain matching Vendor and Device ID.
+struct ambapp_find_ahb_info {
+	/* Address of AHB device Plug&Play information */
+	struct ambapp_pnp_ahb	*pnp;
+	/* AHB Bus index of where the AHB device was found */
+	int			ahb_bus_index;
+	int			dec_index;
+};
+
+extern void ambapp_find_buses(unsigned int ioarea, struct ambapp_bus *abus);
+
+extern int ambapp_find_apb(struct ambapp_bus *abus, unsigned int dev_vend,
+	int index, struct ambapp_find_apb_info *result);
+
+extern int ambapp_find_ahb(struct ambapp_bus *abus, unsigned int dev_vend,
+	int index, int type, struct ambapp_find_ahb_info *result);
+
+/************ C ROUTINES USED BY U-BOOT AMBA CORE DRIVERS ************/
+struct ambapp_bus ambapp_plb;
+
+void ambapp_bus_init(
+	unsigned int ioarea,
+	unsigned int freq,
+	struct ambapp_bus *abus)
+{
+	int i;
+
+	ambapp_find_buses(ioarea, abus);
+	for (i = 0; i < 6; i++)
+		if (abus->ioareas[i] == 0)
+			break;
+	abus->buses = i;
+	abus->freq = freq;
+}
+
+/* Parse APB PnP Information */
+void ambapp_apb_parse(struct ambapp_find_apb_info *info, ambapp_apbdev *dev)
+{
+	struct ambapp_pnp_apb *apb = info->pnp;
+	unsigned int apbbase = (unsigned int)apb & 0xfff00000;
+
+	dev->vendor = amba_vendor(apb->id);
+	dev->device = amba_device(apb->id);
+	dev->irq = amba_irq(apb->id);
+	dev->ver = amba_ver(apb->id);
+	dev->address = (apbbase | (((apb->iobar & 0xfff00000) >> 12))) &
+			(((apb->iobar &	0x0000fff0) << 4) | 0xfff00000);
+	dev->mask = amba_apb_mask(apb->iobar);
+	dev->ahb_bus_index = info->ahb_bus_index - 1;
+}
+
+/* Parse AHB PnP information */
+void ambapp_ahb_parse(struct ambapp_find_ahb_info *info, ambapp_ahbdev *dev)
+{
+	struct ambapp_pnp_ahb *ahb = info->pnp;
+	unsigned int ahbbase = (unsigned int)ahb & 0xfff00000;
+	int i, type;
+	unsigned int addr, mask, mbar;
+
+	dev->vendor = amba_vendor(ahb->id);
+	dev->device = amba_device(ahb->id);
+	dev->irq = amba_irq(ahb->id);
+	dev->ver = amba_ver(ahb->id);
+	dev->userdef[0] = ahb->custom[0];
+	dev->userdef[1] = ahb->custom[1];
+	dev->userdef[2] = ahb->custom[2];
+	dev->ahb_bus_index = info->ahb_bus_index - 1;
+	for (i = 0; i < 4; i++) {
+		mbar = ahb->mbar[i];
+		addr = amba_membar_start(mbar);
+		type = amba_membar_type(mbar);
+		if (type == AMBA_TYPE_AHBIO) {
+			addr = amba_ahbio_adr(addr, ahbbase);
+			mask = (((unsigned int)
+				(amba_membar_mask((~mbar))<<8)|0xff))+1;
+		} else {
+			/* AHB memory area, absolute address */
+			mask = (~((unsigned int)
+				(amba_membar_mask(mbar)<<20)))+1;
+		}
+		dev->address[i] = addr;
+		dev->mask[i] = mask;
+		dev->type[i] = type;
+	}
+}
+
+int ambapp_apb_find(struct ambapp_bus *abus, int vendor, int device,
+	int index, ambapp_apbdev *dev)
+{
+	unsigned int devid = AMBA_PNP_ID(vendor, device);
+	int found;
+	struct ambapp_find_apb_info apbdev;
+
+	found = ambapp_find_apb(abus, devid, index, &apbdev);
+	if (found == 1)
+		ambapp_apb_parse(&apbdev, dev);
+
+	return found;
+}
+
+int ambapp_apb_count(struct ambapp_bus *abus, int vendor, int device)
+{
+	unsigned int devid = AMBA_PNP_ID(vendor, device);
+	int found;
+	struct ambapp_find_apb_info apbdev;
+
+	found = ambapp_find_apb(abus, devid, 63, &apbdev);
+	if (found == 1)
+		return 64;
+	else
+		return 63 - apbdev.dec_index;
+}
+
+int ambapp_ahb_find(struct ambapp_bus *abus, int vendor, int device,
+	int index, ambapp_ahbdev *dev, int type)
+{
+	int found;
+	struct ambapp_find_ahb_info ahbdev;
+	unsigned int devid = AMBA_PNP_ID(vendor, device);
+
+	found = ambapp_find_ahb(abus, devid, index, type, &ahbdev);
+	if (found == 1)
+		ambapp_ahb_parse(&ahbdev, dev);
+
+	return found;
+}
+
+int ambapp_ahbmst_find(struct ambapp_bus *abus, int vendor, int device,
+	int index, ambapp_ahbdev *dev)
+{
+	return ambapp_ahb_find(abus, vendor, device, index, dev, DEV_AHB_MST);
+}
+
+int ambapp_ahbslv_find(struct ambapp_bus *abus, int vendor, int device,
+	int index, ambapp_ahbdev *dev)
+{
+	return ambapp_ahb_find(abus, vendor, device, index, dev, DEV_AHB_SLV);
+}
+
+int ambapp_ahb_count(struct ambapp_bus *abus, int vendor, int device, int type)
+{
+	int found;
+	struct ambapp_find_ahb_info ahbdev;
+	unsigned int devid = AMBA_PNP_ID(vendor, device);
+
+	found = ambapp_find_ahb(abus, devid, 63, type, &ahbdev);
+	if (found == 1)
+		return 64;
+	else
+		return 63 - ahbdev.dec_index;
+}
+
+int ambapp_ahbmst_count(struct ambapp_bus *abus, int vendor, int device)
+{
+	return ambapp_ahb_count(abus, vendor, device, DEV_AHB_MST);
+}
+
+int ambapp_ahbslv_count(struct ambapp_bus *abus, int vendor, int device)
+{
+	return ambapp_ahb_count(abus, vendor, device, DEV_AHB_SLV);
+}
+
+/* The define CONFIG_SYS_GRLIB_SINGLE_BUS may be defined on GRLIB systems
+ * where only one AHB Bus is available - no bridges are present. This option
+ * is available only to reduce the footprint.
  *
- * Return number of devices found.
- *
- * Compact edition...
+ * Defining this on a multi-bus GRLIB system may also work depending on the
+ * design.
  */
-static int ambapp_ahb_scan(unsigned int vendor,	/* Plug&Play Vendor ID */
-			   unsigned int driver,	/* Plug&Play Device ID */
-			   ambapp_ahbdev * dev,	/* Result(s) is placed here */
-			   int index,	/* Index of device to start copying Plug&Play
-					 * info into dev
-					 */
-			   int max_cnt,	/* Maximal count that dev can hold, if dev
-					 * is NULL function will stop scanning after
-					 * max_cnt devices are found.
-					 */
-			   int type	/* Selectes what type of devices to scan.
-					 * 0=AHB Masters
-					 * 1=AHB Slaves
-					 */
-    )
+
+#ifndef CONFIG_SYS_GRLIB_SINGLE_BUS
+
+/* GAISLER AHB2AHB Version 1 Bridge Definitions */
+#define AHB2AHB_V1_FLAG_FFACT     0x0f0	/* Frequency factor against top bus */
+#define AHB2AHB_V1_FLAG_FFACT_DIR 0x100	/* Factor direction, 0=down, 1=up */
+#define AHB2AHB_V1_FLAG_MBUS      0x00c	/* Master bus number mask */
+#define AHB2AHB_V1_FLAG_SBUS      0x003	/* Slave bus number mask */
+
+/* Get Parent bus frequency. Note that since we go from a "child" bus
+ * to a parent bus, the frequency factor direction is inverted.
+ */
+unsigned int gaisler_ahb2ahb_v1_freq(ambapp_ahbdev *ahb, unsigned int freq)
 {
-	int i, j, cnt = 0, max_pp_devs;
-	unsigned int addr;
-	ahbctrl_info *info = (ahbctrl_info *) (LEON3_IO_AREA | LEON3_CONF_AREA);
-	ahbctrl_pp_dev *ahb;
+	int dir;
+	unsigned char ffact;
 
-	if (max_cnt == 0)
-		return 0;
+	/* Get division/multiple factor */
+	ffact = (ahb->userdef[0] & AHB2AHB_V1_FLAG_FFACT) >> 4;
+	if (ffact != 0) {
+		dir = ahb->userdef[0] & AHB2AHB_V1_FLAG_FFACT_DIR;
 
-	if (type == 0) {
-		max_pp_devs = LEON3_AHB_MASTERS;
-		ahb = info->masters;
-	} else {
-		max_pp_devs = LEON3_AHB_SLAVES;
-		ahb = info->slaves;
+		/* Calculate frequency by dividing or
+		 * multiplying system frequency
+		 */
+		if (dir)
+			freq = freq * ffact;
+		else
+			freq = freq / ffact;
 	}
 
-	for (i = 0; i < max_pp_devs; i++) {
-#if defined(CONFIG_CMD_AMBAPP)
-		if (ambapp_ahb_print && amba_vendor(ahb->conf) &&
-		    amba_device(ahb->conf)) {
-			ambapp_print_ahb(ahb, i);
-		}
+	return freq;
+}
+
+/* AHB2AHB and L2CACHE ver 2 is not supported yet. */
+unsigned int gaisler_ahb2ahb_v2_freq(ambapp_ahbdev *ahb, unsigned int freq)
+{
+	panic("gaisler_ahb2ahb_v2_freq: AHB2AHB ver 2 not supported\n");
+	return -1;
+}
 #endif
-		if ((amba_vendor(ahb->conf) == vendor) &&
-		    (amba_device(ahb->conf) == driver) &&
-		    ((index < 0) || (index-- == 0))) {
-			/* Convert Plug&Play info info a more readable format */
-			cnt++;
-			if (dev) {
-				dev->irq = amba_irq(ahb->conf);
-				dev->ver = amba_ver(ahb->conf);
-				dev->userdef[0] = ahb->userdef[0];
-				dev->userdef[1] = ahb->userdef[1];
-				dev->userdef[2] = ahb->userdef[2];
-				for (j = 0; j < 4; j++) {
-					addr = amba_membar_start(ahb->bars[j]);
-					if (amba_membar_type(ahb->bars[j]) ==
-					    AMBA_TYPE_AHBIO)
-						addr =
-						    AMBA_TYPE_AHBIO_ADDR(addr);
-					dev->address[j] = addr;
-				}
-				dev++;
-			}
-			/* found max devices? */
-			if (cnt >= max_cnt)
-				return cnt;
+
+/* Return the frequency of a AHB bus identified by index found
+ * note that this is not the AHB Bus number.
+ */
+unsigned int ambapp_bus_freq(struct ambapp_bus *abus, int ahb_bus_index)
+{
+	unsigned int freq = abus->freq;
+#ifndef CONFIG_SYS_GRLIB_SINGLE_BUS
+	unsigned int ioarea, ioarea_parent, bridge_pnp_ofs;
+	struct ambapp_find_ahb_info ahbinfo;
+	ambapp_ahbdev ahb;
+	int parent;
+
+	debug("ambapp_bus_freq: get freq on bus %d\n", ahb_bus_index);
+
+	while (ahb_bus_index != 0) {
+		debug("  BUS[0]: 0x%08x\n", abus->ioareas[0]);
+		debug("  BUS[1]: 0x%08x\n", abus->ioareas[1]);
+		debug("  BUS[2]: 0x%08x\n", abus->ioareas[2]);
+		debug("  BUS[3]: 0x%08x\n", abus->ioareas[3]);
+		debug("  BUS[4]: 0x%08x\n", abus->ioareas[4]);
+		debug("  BUS[5]: 0x%08x\n", abus->ioareas[5]);
+
+		/* Get I/O area of AHB bus */
+		ioarea = abus->ioareas[ahb_bus_index];
+
+		debug("  IOAREA: 0x%08x\n", ioarea);
+
+		/* Get parent bus */
+		parent = (ioarea & 0x7);
+		if (parent == 0) {
+			panic("%s: parent=0 indicates no parent! Stopping.\n",
+				__func__);
+			return -1;
 		}
-		/* Get next Plug&Play entry */
-		ahb++;
-	}
-	return cnt;
-}
+		parent = parent - 1;
+		bridge_pnp_ofs = ioarea & 0x7e0;
 
-unsigned int ambapp_ahb_get_info(ahbctrl_pp_dev * ahb, int info)
-{
-	register unsigned int ret;
+		debug("  PARENT: %d\n", parent);
+		debug("  BRIDGE_OFS: 0x%08x\n", bridge_pnp_ofs);
 
-	if (!ahb)
-		return 0;
+		/* Get AHB/AHB bridge PnP address */
+		ioarea_parent = (abus->ioareas[parent] & 0xfff00000) |
+				AMBA_CONF_AREA | AMBA_AHB_SLAVE_CONF_AREA;
+		ahbinfo.pnp = (struct ambapp_pnp_ahb *)
+				(ioarea_parent | bridge_pnp_ofs);
 
-	switch (info) {
-	default:
-		info = 0;
-	case 0:
-	case 1:
-	case 2:
-	case 3:
-		/* Get Address from PnP Info */
-		ret = amba_membar_start(ahb->bars[info]);
-		if (amba_membar_type(ahb->bars[info]) == AMBA_TYPE_AHBIO)
-			ret = AMBA_TYPE_AHBIO_ADDR(ret);
-		return ret;
-	}
-	return 0;
+		debug("  IOAREA PARENT: 0x%08x\n", ioarea_parent);
+		debug("  BRIDGE PNP: 0x%p\n", ahbinfo.pnp);
 
-}
+		/* Parse the AHB information */
+		ahbinfo.ahb_bus_index = parent;
+		ambapp_ahb_parse(&ahbinfo, &ahb);
 
-ahbctrl_pp_dev *ambapp_ahb_next_nomem(register unsigned int vendor,	/* Plug&Play Vendor ID */
-				      register unsigned int driver,	/* Plug&Play Device ID */
-				      register unsigned int opts,	/* 1=slave, 0=master */
-				      register int index)
-{
-	register ahbctrl_pp_dev *ahb;
-	register ahbctrl_info *info =
-	    (ahbctrl_info *) (LEON3_IO_AREA | LEON3_CONF_AREA);
-	register int i;
-	register int max_pp_devs;
+		debug("  BRIDGE ID: VENDOR=%d(0x%x), DEVICE=%d(0x%x)\n",
+			ahb.vendor, ahb.vendor, ahb.device, ahb.device);
 
-	if (opts == 0) {
-		max_pp_devs = LEON3_AHB_MASTERS;
-		ahb = info->masters;
-	} else {
-		max_pp_devs = LEON3_AHB_SLAVES;
-		ahb = info->slaves;
-	}
+		/* Different bridges may convert frequency differently */
+		if ((ahb.vendor == VENDOR_GAISLER) &&
+			((ahb.device == GAISLER_AHB2AHB) ||
+			(ahb.device == GAISLER_L2CACHE))) {
+			/* Get new frequency */
+			if (ahb.ver > 1)
+				freq = gaisler_ahb2ahb_v2_freq(&ahb, freq);
+			else
+				freq = gaisler_ahb2ahb_v1_freq(&ahb, freq);
 
-	for (i = 0; i < max_pp_devs; i++) {
-		if ((amba_vendor(ahb->conf) == vendor) &&
-		    (amba_device(ahb->conf) == driver) &&
-		    ((index < 0) || (index-- == 0))) {
-			/* Convert Plug&Play info info a more readable format */
-			return ahb;
+			debug("  NEW FREQ: %dHz\n", freq);
+		} else {
+			panic("%s: unsupported AMBA bridge\n", __func__);
+			return -1;
 		}
-		/* Get next Plug&Play entry */
-		ahb++;
+
+		/* Step upwards towards system top bus */
+		ahb_bus_index = parent;
 	}
-	return 0;
-}
+#endif
 
-/****************************** AHB MASTERS ******************************/
-int ambapp_ahbmst_count(unsigned int vendor, unsigned int driver)
-{
-	/* Get number of devices of this vendor&device ID */
-	return ambapp_ahb_scan(vendor, driver, NULL, 0, LEON3_AHB_MASTERS,
-			       AHB_SCAN_MASTER);
-}
+	debug("ambapp_bus_freq: %dHz\n", freq);
 
-int ambapp_ahbmst_first(unsigned int vendor, unsigned int driver,
-			ambapp_ahbdev * dev)
-{
-	/* find first device of this */
-	return ambapp_ahb_scan(vendor, driver, dev, 0, 1, AHB_SCAN_MASTER);
-}
-
-int ambapp_ahbmst_next(unsigned int vendor,
-		       unsigned int driver, ambapp_ahbdev * dev, int index)
-{
-	/* find first device of this */
-	return ambapp_ahb_scan(vendor, driver, dev, index, 1, AHB_SCAN_MASTER);
-}
-
-int ambapp_ahbmsts_first(unsigned int vendor,
-			 unsigned int driver, ambapp_ahbdev * dev, int max_cnt)
-{
-	/* find first device of this */
-	return ambapp_ahb_scan(vendor, driver, dev, 0, max_cnt,
-			       AHB_SCAN_MASTER);
-}
-
-/****************************** AHB SLAVES ******************************/
-int ambapp_ahbslv_count(unsigned int vendor, unsigned int driver)
-{
-	/* Get number of devices of this vendor&device ID */
-	return ambapp_ahb_scan(vendor, driver, NULL, 0, LEON3_AHB_SLAVES,
-			       AHB_SCAN_SLAVE);
-}
-
-int ambapp_ahbslv_first(unsigned int vendor, unsigned int driver,
-			ambapp_ahbdev * dev)
-{
-	/* find first device of this */
-	return ambapp_ahb_scan(vendor, driver, dev, 0, 1, AHB_SCAN_SLAVE);
-}
-
-int ambapp_ahbslv_next(unsigned int vendor,
-		       unsigned int driver, ambapp_ahbdev * dev, int index)
-{
-	/* find first device of this */
-	return ambapp_ahb_scan(vendor, driver, dev, index, 1, AHB_SCAN_SLAVE);
-}
-
-int ambapp_ahbslvs_first(unsigned int vendor,
-			 unsigned int driver, ambapp_ahbdev * dev, int max_cnt)
-{
-	/* find first device of this */
-	return ambapp_ahb_scan(vendor, driver, dev, 0, max_cnt, AHB_SCAN_SLAVE);
+	return freq;
 }
diff --git a/arch/sparc/cpu/leon3/ambapp_low.S b/arch/sparc/cpu/leon3/ambapp_low.S
new file mode 100644
index 0000000..2863586
--- /dev/null
+++ b/arch/sparc/cpu/leon3/ambapp_low.S
@@ -0,0 +1,784 @@
+/* GRLIB AMBA Plug&Play information scanning implemented without
+ * using memory (stack) and one register window. The code scan
+ * the PnP info and inserts the AHB bridges/buses into register
+ * i0-i5.
+ * The code support
+ *  - up to 6 AHB buses
+ *  - multiple APB buses
+ *  - support for AHB2AHB & L2CACHE bridges
+ *
+ * (C) Copyright 2010, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <ambapp.h>
+
+	.seg	"text"
+	.globl	_nomem_amba_init
+	.globl	_nomem_ambapp_find_buses
+	.globl	_nomem_find_apb
+	.globl	_nomem_find_ahb
+
+/* Overview
+ * ========
+ *
+ * _nomem_amba_init         - Init AMBA bus and calls _nomem_ambapp_find_buses
+ * _nomem_ambapp_find_buses - Scan AMBA PnP info for AHB buses/bridges and
+ *                            place them in i0-i5, see below
+ * _nomem_find_apb          - Find one APB device identified by VENDOR:DEVICE
+ *                            ID and an index.
+ * _nomem_find_ahb          - Find one AHB Master or Slave device identified
+ *                            by VENDOR:DEVICE ID and an index.
+ * init_ahb_bridges         - Local function. Clears i0-i5
+ * insert_ahb_bridge        - Local function. Insert a new AHB bus into first
+ *                            free register in i0-i5. It also checks that the
+ *                            bus has not already been added.
+ * get_ahb_bridge           - Local function. Get AHB bus from registers,
+ *                            return register iN, where N is defined by o0.
+ *
+ * The _nomem_find_apb and _nomem_find_ahb function requires that i0-i5
+ * are populated with the AHB buses of the system. The registers are
+ * initialized by _nomem_ambapp_find_buses.
+ *
+ * AHB Bus result and requirements of i0-i5
+ * ========================================
+ *
+ * i0: AHB BUS0 IOAREA, no parent bus
+ * i1: AHB BUS1 IOAREA, parent bus is always i0 (AHB BUS0) and bridge address
+ * i2: AHB BUS2 IOAREA, 3-bit parent bus number and bridge address
+ * i3: AHB BUS3 IOAREA, 3-bit parent bus number and bridge address
+ * i4: AHB BUS4 IOAREA, 3-bit parent bus number and bridge address
+ * i5: AHB BUS5 IOAREA, 3-bit parent bus number and bridge address
+ *
+ * AHB BUS
+ * -------
+ * Bits 31-20 (0xfff00000) contain the found bus I/O Area (AHB PnP area).
+ *
+ * 3-bit Parent bus
+ * ----------------
+ * Bits 2-0 (0x00000007) contain parent bus number. Zero if no parent
+ * bus, 1 = parent is AHB BUS 0 (i0), 2 = parent is AHB BUS 1 (i1)..
+ *
+ * Bridge Address
+ * --------------
+ * Bits 10-5 (0x000007e0) contain the index of the Bridge's PnP
+ * information on the parent. Since all bridges are found in the
+ * PnP information they all have a PnP entry. Together with the
+ * parent bus number the PnP entry can be found:
+ *  PnPEntry = (BRIDGE_ADDRESS + (iN & 0xfff00000)) | 0x000ff800
+ *  where N is the parent bus minus one.
+ *
+ */
+
+/* Function initializes the AHB Bridge I/O AREA storage. (Clears i0-i5)
+ *
+ * Arguments
+ *  none
+ *
+ * Results
+ *  none
+ *
+ * Clobbered
+ *  none
+ */
+
+init_ahb_bridges:
+	mov	%g0, %i0
+	mov	%g0, %i1
+	mov	%g0, %i2
+	mov	%g0, %i3
+	mov	%g0, %i4
+	retl
+	 mov	%g0, %i5
+
+/* Function returns AHB Bridge I/O AREA for specified bus.
+ *
+ * Arguments
+ *  - o0 = bus number
+ *
+ * Results
+ *  - o0 = I/O AREA
+ *
+ * Clobbered
+ *  none
+ */
+get_ahb_bridge:
+	cmp	%o0, 1
+	be,a	L1
+	 mov	%i0, %o0
+
+	cmp	%o0, 2
+	be,a	L1
+	 mov	%i1, %o0
+
+	cmp	%o0, 3
+	be,a	L1
+	 mov	%i2, %o0
+
+	cmp	%o0, 4
+	be,a	L1
+	 mov	%i3, %o0
+
+	cmp	%o0, 5
+	be,a	L1
+	 mov	%i4, %o0
+
+	cmp	%o0, 6
+	be,a	L1
+	 mov	%i5, %o0
+
+	/* o0 > 6: only 6 buses supported */
+	mov	%g0, %o0
+L1:
+	retl
+	 nop
+
+/* Function adds a AHB Bridge I/O AREA to the i0-i5 registers if
+ * not already added. It stores the bus PnP start information.
+ *
+ * Arguments
+ *  - o0 = AHB Bridge I/O area
+ *
+ * Results
+ *  none
+ *
+ * Clobbered
+ *  o2, o3
+ */
+insert_ahb_bridge:
+	/* Check that bridge hasn't already been added */
+	andn	%o0, 0x7ff, %o2
+	andn	%i0, 0x7ff, %o3
+	cmp	%o3, %o2
+	be	L2
+	 andn	%i1, 0x7ff, %o3
+	cmp	%o3, %o2
+	be	L2
+	 andn	%i2, 0x7ff, %o3
+	cmp	%o3, %o2
+	be	L2
+	 andn	%i3, 0x7ff, %o3
+	cmp	%o3, %o2
+	be	L2
+	 andn	%i4, 0x7ff, %o3
+	cmp	%o3, %o2
+	be	L2
+	 andn	%i5, 0x7ff, %o3
+	cmp	%o3, %o2
+	be	L2
+
+	/* Insert into first free posistion */
+	 cmp	%i0, %g0
+	be,a	L2
+	 mov	%o0, %i0
+
+	cmp	%i1, %g0
+	be,a	L2
+	 mov	%o0, %i1
+
+	cmp	%i2, %g0
+	be,a	L2
+	 mov	%o0, %i2
+
+	cmp	%i3, %g0
+	be,a	L2
+	 mov	%o0, %i3
+
+	cmp	%i4, %g0
+	be,a	L2
+	 mov	%o0, %i4
+
+	cmp	%i5, %g0
+	be,a	L2
+	 mov	%o0, %i5
+L2:
+	retl
+	 nop
+
+/* FUNCTION int _nomem_find_ahb_bus(
+ *	unsigned int bridge,
+ *	int vendor_device,
+ *	int index,
+ *	void **pconf,
+ *	int not_used,
+ *	int option
+ *	)
+ *
+ * Scans the AHB Master or Slave area for a matching VENDOR:DEVICE, the
+ * index is decremented when a matching device is found but index is
+ * greater than zero. When index is zero and a matching DEVICE:VENDOR
+ * is found the AHB configuration address and AHB I/O area is returned.
+ *
+ * i0-i7,l0,l1,l2,l3,l4,g2,o6 is not available for use.
+ * o1,o5 Must be left untouched
+ *
+ * Results
+ *  - o0 Number of found devices (1 or 0)
+ *  - o2 is decremented for each matching VENDOR:DEVICE found, zero if found
+ *  - o3 Address of the AHB PnP configuration entry (Only valid if o0=1)
+ *
+ * Clobbered
+ *  - o3 (Clobbered when no device was found)
+ *  - o4 (Number of Devices left to search)
+ *  - o0 (Bus ID, PnP ID, Device)
+ */
+_nomem_find_ahb_bus:
+
+	/* Get the number of Slaves/Masters.
+	 * Only AHB Bus 0 has 64 AHB Masters/Slaves the
+	 * other AHB buses has 16 slaves and 16 masters.
+	 */
+	add	%g0, 16, %o4		/* Defaulting to 16 */
+	andcc	%o0, 0x7, %g0		/* 3-bit bus id */
+	be,a	.L_maxloops_detected
+	 add	%g0, 64, %o4		/* AHB Bus 0 has 64 AHB Masters/Slaves */
+.L_maxloops_detected:
+
+	/* Get start address of AHB Slave or AHB Master area depending on what
+	 * we are searching for.
+	 */
+	andn	%o0, 0x7ff, %o0		/* Remove Bus ID and 5-bit AHB/AHB
+					 * Bridge PnP Address to get I/O Area */
+	set	AMBA_CONF_AREA,	%o3
+	or	%o3, %o0, %o3		/* Master area address */
+
+	cmp	%o5, DEV_AHB_SLV
+	be,a	.L_conf_area_calculated
+	 or	%o3, AMBA_AHB_SLAVE_CONF_AREA, %o3	/* Add 0x800 to get to slave area */
+.L_conf_area_calculated:
+
+	/* Iterate over all AHB device and try to find matching DEVICE:VENDOR
+	 * o1 - VENDOR|DEVICE
+	 * o2 - Index
+	 * o3 - Current AHB Device Configuration address
+	 * o5 - Type (leave untouched)
+	 *
+	 * o4 - Number of AHB device left to process
+	 * o0 - tmp
+	 */
+.L_process_one_conf:
+	ld	[%o3], %o0
+	andn	%o0, 0xfff, %o0
+	cmp	%o0, 0			/* No device if zero */
+	beq	.L_next_conf
+	 cmp	%o1, 0			/* If VENDOR:DEVICE==0, consider all matching */
+	beq	.L_process_ahb_dev_found
+	 cmp	%o0, %o1		/* Does VENDOR and DEVICE Match? */
+	bne	.L_next_conf
+	 nop
+.L_process_ahb_dev_found:
+	/* Found a Matching VENDOR:DEVICE, index must also match */
+	cmp	%o2, %g0
+	bne	.L_next_conf
+	 dec	%o2
+	/* Index matches also, return happy with o3 set to AHB Conf Address */
+	mov	%g0, %o2
+	retl
+	 add	%g0, 1, %o0
+
+.L_next_conf:
+	subcc	%o4, 1, %o4		/* One device has been processed,
+					 * Are there more devices to process? */
+	bne	.L_process_one_conf
+	 add	%o3, AMBA_AHB_CONF_LENGH, %o3	/* Next Configuration entry */
+	/* No Matching device found */
+	retl
+	 mov	%g0, %o0
+
+/* FUNCTION int _nomem_find_ahb(
+ *      int unused,
+ *	int vendor_device,
+ *	int index,
+ *	void **pconf,
+ *	int *ahb_bus_index,
+ *	int option,
+ *	)
+ *
+ * Find a AHB Master or AHB Slave device, it puts the address of the AHB PnP
+ * configuration in o3 (pconf), the I/O Area base address in o4 (pioarea).
+ *
+ * Calls _nomem_find_ahb_bus for every AHB bus.
+ *
+ * i0-i7, l0, l1, o6, g1, g4-g7 is not available for use.
+ *
+ * Arguments
+ *  - o0 Unused
+ *
+ * Results
+ *  - o0 Number of found devices (1 or 0)
+ *  - o2 Decremented Index (Zero if found)
+ *  - o3 Address of the AHB PnP configuration entry
+ *  - o4 AHB Bus index the device was found on (if o0=1)
+ *  - o5 Left untouched
+ *
+ * Clobbered
+ *  - o0 (AHB Bridge and used by _nomem_find_ahb_bus)
+ *  - o2 (index is decremented)
+ *  - l2 (Current AHB Bus index)
+ *  - g2 (return address)
+ */
+_nomem_find_ahb:
+	mov	%o7, %g2		/* Save return address */
+	/* Scan all AHB Buses found for the AHB Master/Slave matching VENDOR:DEVICE */
+	clr	%l2
+.L_search_next_ahb_bus:
+	add	%l2, 1, %l2
+	call	get_ahb_bridge			/* Get bus %l0 I/O Area */
+	 mov	%l2, %o0
+	cmp	%o0, %g0
+	be	.L_no_device_found		/* If no more AHB bus is left to be scanned, proceed */
+	 nop
+	call	_nomem_find_ahb_bus		/* Scan AHB bus %o0 for VENDOR:DEVICE. Index in o3 is decremented  */
+	 nop
+	cmp	%o0, %g0			/* If VENDOR:DEVICE was not found scan next AHB Bus */
+	be	.L_search_next_ahb_bus		/* Do next bus is o0=0 (not found) */
+	 nop
+	/* The device was found, o0 is 1 */
+	mov	%g2, %o7		/* Restore return address */
+	retl
+	 mov	%l2, %o4		/* The AHB bus index the device was found on */
+
+	/* No device found matching */
+.L_no_device_found:
+	mov	%g2, %o7		/* Restore return address */
+	retl
+	 mov	%g0, %o0
+
+
+/* FUNCTION int _nomem_find_apb_bus(
+ *      int apbmst,
+ *	int vendor_device,
+ *	int index,
+ *	void **pconf
+ *	)
+ *
+ * Find a APB Slave device, it puts the address of the APB PnP configuration
+ * in o3 (pconf).
+ *
+ * Calls _nomem_find_ahb_bus for every AHB bus searching for AHB/APB Bridges.
+ * The AHB/APB bridges are AHB Slaves with ID GAISLER_APBMST.
+ *
+ * Results
+ *  - o0 Number of found devices (1 or 0)
+ *  - o2 Decremented Index
+ *  - o3 Address of the found APB device PnP configuration entry
+ *
+ * Clobbered
+ *  - o5 PnP VENDOR:DEVICE ID
+ */
+
+_nomem_find_apb_bus:
+	set	AMBA_CONF_AREA, %o3
+	or	%o0, %o3, %o3		/* Calc start of APB device PnP info */
+	add	%g0, 16, %o0		/* o0, number of APB Slaves left to scan */
+.L_process_one_apb_conf:
+	ld	[%o3], %o5
+	andn	%o5, 0xfff, %o5
+	cmp	%o5, 0			/* No device if zero */
+	beq	.L_process_apb_dev_not_found
+	 cmp	%o1, 0			/* If VENDOR:DEVICE == -1, consider all matching */
+	beq	.L_process_apb_dev_found
+	 cmp	%o1, %o5		/* Found VENDOR:DEVICE */
+	bne	.L_process_apb_dev_not_found
+	 nop
+
+.L_process_apb_dev_found:
+	/* Found matching device, compare index */
+	cmp	%o2, %g0
+	bne	.L_process_apb_dev_not_found
+	 dec	%o2
+	/* Matching index and VENDOR:DEVICE */
+	retl
+	 add	%g0, 1, %o0
+
+.L_process_apb_dev_not_found:
+	subcc	%o0, 1, %o0
+	bne	.L_process_one_apb_conf
+	 add	%o3, 8, %o3
+	retl
+	 mov	%g0, %o0
+
+/* FUNCTION int _nomem_find_apb(
+ *      int unused,
+ *	int vendor_device,
+ *	int index,
+ *	void **pconf,
+ *	int *ahb_bus_index
+ *	)
+ *
+ * Find a APB Slave device, it puts the address of the APB PnP configuration
+ * in o3 (pconf), the APB Master I/O Area base address in o4 (papbarea).
+ *
+ * Calls _nomem_find_ahb_bus for every AHB bus searching for AHB/APB Bridges.
+ * The AHB/APB bridges are AHB Slaves with ID GAISLER_APBMST.
+ *
+ * i0-i7, l0, l1, o6 is not available for use.
+ *
+ * Arguments
+ *  - o0 Unused
+ *
+ * Results
+ *  - o0 Number of found devices (1 or 0)
+ *  - o2 Decremented Index if not found
+ *  - o3 Address of the APB PnP configuration entry
+ *  - o4 AHB Bus index of APB Bridge/APB Device
+ *
+ * Clobbered
+ *  - o0 (AHB Bridge)
+ *  - o2 (index is decremented)
+ *  - l2 (APB DEV Index [7..4] : APBMST AHB Index [3..0])
+ *  - l3 (Current AHB Bus index)
+ *  - l4 (temporary storage for APB VENDOR:DEVICE)
+ *  - o5 (AHB Slave ID)
+ *  - o0 (clobbered by _nomem_find_ahb_bus)
+ *  - g2 (Return address)
+ */
+_nomem_find_apb:
+	/* Scan all AHB Buses found for AHB/APB Bridges */
+	mov	%o7, %g2		/* Save return address */
+	mov	%o1, %l4		/* Save APB VENDOR:DEVICE */
+	sll	%o2, 4, %l2		/* APB MST index = 0 */
+	add	%g0, 1, %l3		/* AHB Bus index = 0 */
+.L2_search_next_ahb_bus:
+	call	get_ahb_bridge		/* Get bus %l3 I/O Area */
+	 mov	%l3, %o0
+	cmp	%o0, %g0
+	be	.L2_no_device_found	/* If no more AHB bus is left to be scanned, proceed */
+	 add	%g0, DEV_AHB_SLV, %o5	/* Search for AHB Slave */
+	sethi	%hi(AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_APBMST)), %o1
+	call	_nomem_find_ahb_bus	/* Scan AHB bus %o0 for VENDOR:DEVICE. Index in o3 is decremented */
+	 and	%l2, 0xf, %o2		/* Set APBMST index */
+	cmp	%o0, %g0		/* If no AHB/APB Bridge was not found, scan next AHB Bus */
+	be	.L_no_apb_bridge_found	/* Do next bus */
+	 nop
+
+	/* The AHB/APB Bridge was found.
+         * Search for the requested APB Device on the APB bus using
+	 * find_apb_bus, it will decrement the index.
+         */
+	ld	[%o3 + AMBA_AHB_MBAR0_OFS], %o3
+	sll	%o3, 16, %o0
+	and	%o0, %o3, %o0		/* Address AND Address Mask */
+	sethi	%hi(0xfff00000), %o3
+	and	%o0, %o3, %o0		/* AHB/APB Bridge address */
+
+	srl	%l2, 4, %o2		/* APB DEV Index */
+	call	_nomem_find_apb_bus
+	 mov	%l4, %o1		/* APB VENDOR:DEVICE */
+	cmp	%o0, %g0
+	be	.L_apb_dev_not_found
+	 mov	%g2, %o7		/* Restore return address */
+	/* APB Device found
+	 * o0 1
+	 * o2 Index is decremented to zero
+	 * o3 APB configuration address,
+	 * o4 APB Bridge Configuration address.
+	 */
+	mov	%g0, %o2
+	retl
+	 mov	%l3, %o4
+
+.L_apb_dev_not_found:
+	/* Update APB DEV Index by saving output from find_apb_bus
+	 * (index parameter) into bits [31..4] in L2.
+	 */
+	sll	%o2, 4, %o2
+	and	%l2, 0xf, %l2
+	or	%o2, %l2, %l2
+	/* Try finding the next AHB/APB Bridge on the same AHB bus
+	 * to find more APB devices
+	 */
+	ba	.L2_search_next_ahb_bus	/* Find next AHB/APB bridge */
+	 inc	%l2
+
+.L_no_apb_bridge_found:
+	inc	%l3			/* Next AHB Bus */
+	ba	.L2_search_next_ahb_bus	/* Process next AHB bus */
+	 andn	%l2, 0xf, %l2		/* Start at APB Bridge index 0 at every AHB Bus */
+	/* No device found matching */
+.L2_no_device_found:
+	mov	%g2, %o7		/* Restore return address */
+	srl	%l2, 4, %o2		/* APB DEV Index */
+	retl
+	 mov	%g0, %o0
+
+
+
+/* FUNCTION _nomem_amba_scan_gaisler_ahb2ahb_bridge(unsigned int bridge, int bus)
+ *
+ * Constraints:
+ *   - o1 may not be used
+ *   - o0, o2, o3 may be used.
+ *
+ * Arguments
+ *  - o0 PnP Address of Bridge AHB device
+ *  - o2 PnP ID of AHB device
+ *
+ * Results
+ *  - o0 Address of new bus PnP area or a 1 if AHB device is no bridge
+ *
+ * Clobbered
+ *   - o0, o2
+ *
+ */
+_nomem_amba_scan_gaisler_ahb2ahb_bridge:
+	andn	%o2, 0xfff, %o2
+	sethi	%hi(AMBA_PNP_ID(VENDOR_GAISLER,GAISLER_AHB2AHB)), %o3
+	cmp	%o2, %o3
+	beq	.L_is_ahb2ahb_bridge
+	 nop
+
+	retl
+	 add	%g0, 1, %o0
+
+.L_is_ahb2ahb_bridge:
+	/* Found a GAISLER AHB2AHB bridge */
+	retl
+	 ld	[%o0 + AMBA_AHB_CUSTOM1_OFS], %o0 /* Get address of bridge PnP area */
+
+
+/* FUNCTION _nomem_amba_scan_gaisler_l2cache_bridge(unsigned int bridge, int bus)
+ *
+ * Constraints:
+ *   - o1 may not be used
+ *   - o0, o2, o3 may be used.
+ *
+ * Arguments
+ *  - o0 PnP Address of Bridge AHB device
+ *  - o2 PnP ID of AHB device
+ *
+ * Results
+ *  - o0 Address of new bus PnP area or a 1 if AHB device is no bridge
+ *
+ * Clobbered
+ *   - o0, o2
+ *
+ */
+_nomem_amba_scan_gaisler_l2cache_bridge:
+	andn	%o2, 0xfff, %o2
+	sethi	%hi(AMBA_PNP_ID(VENDOR_GAISLER,GAISLER_L2CACHE)), %o3
+	cmp	%o2, %o3
+	beq	.L_is_l2cache_bridge
+	 nop
+
+	retl
+	 add	%g0, 1, %o0
+
+.L_is_l2cache_bridge:
+	/* Found a GAISLER l2cache bridge */
+	retl
+	 ld	[%o0 + AMBA_AHB_CUSTOM1_OFS], %o0 /* Get address of bridge PnP area */
+
+
+/* FUNCTION _nomem_amba_scan(unsigned int bridge, int bus)
+ *
+ * Constraints:
+ *  i0-i7, l0 is used by caller
+ *  o5-o7 may not be used.
+ *
+ * Arguments
+ *  - o0 Bridge Information: I/O AREA and parent bus
+ *  - o1 Bus
+ *
+ * Results
+ *  - o0 Number of AHB bridges found
+ *
+ * Clobbered
+ *  - o0 (Current AHB slave conf address)
+ *  - o2 (Used by insert_bridge)
+ *  - o3 (Used by insert_bridge)
+ *  - l1 (Number of AHB Slaves left to process)
+ *  - l2 (Current AHB slave conf address)
+ *  - g2 (Return address)
+ */
+_nomem_amba_scan:
+	mov	%o7, %g2	/* Save return address */
+	set	16, %l1
+	cmp	%o1, 1
+	be,a	.L2_maxloops_detected
+	 add	%g0, 64, %l1
+.L2_maxloops_detected:
+
+	/* Clear 3-bit parent bus from bridge to get I/O AREA, then or
+	 * (AMBA_CONF_AREA | AMBA_AHB_SLAVE_CONF_AREA) to get first AHB slave
+	 * conf address.
+	 */
+	andn	%o0, 0x7ff, %o0
+	set	(AMBA_CONF_AREA | AMBA_AHB_SLAVE_CONF_AREA), %l2
+	or	%o0, %l2, %l2
+
+	/* Scan AHB Slave area for AHB<->AHB bridges. For each AHB device
+	 * all "bridge drivers" are called, the driver function interface:
+	 *
+	 * Input:
+	 *   - o0 PnP Address of Bridge AHB device
+	 *   - o2 PnP ID of AHB device
+	 * Return values:
+	 *   - o0 Address of new bus PnP area, returning a 1 in o2 means not found
+	 *
+	 * Constraints:
+	 *   - o1 may not be used
+	 *   - o0, o2, o3 may be used.
+	 *
+	 */
+.L_scan_one_ahb_slave:
+	ld	[%l2], %o2
+
+	cmp	%o2, %g0
+	beq	.L_scan_next_ahb_slave
+	 nop
+
+	/* Call the GAISLER AHB2AHB bridge driver */
+	call	_nomem_amba_scan_gaisler_ahb2ahb_bridge
+	 mov	%l2, %o0
+	cmp	%o0, 1
+	bne	.L_found_bridge
+	 ld	[%l2], %o2
+
+	/* Call the GAISLER L2CACHE bridge driver */
+	call	_nomem_amba_scan_gaisler_l2cache_bridge
+	 mov	%l2, %o0
+	cmp	%o0, 1
+	bne	.L_found_bridge
+	 ld	[%l2], %o2
+
+	/* Insert next bridge "driver" function here */
+
+
+	/* The PnP ID did not match a bridge - a new bus was not found ==>
+	 * step to next AHB device */
+	ba	.L_scan_next_ahb_slave
+	 nop
+
+	/* Add Found bus */
+.L_found_bridge:
+	and	%l2, 0x7e0, %o2
+	or	%o2, %o0, %o0		/* Add AHB/AHB Bridge PnP address */
+	call	insert_ahb_bridge	/* Insert Bridge into found buses storage */
+	 or	%o1, %o0, %o0		/* Add parent bus LSB 3-bits */
+
+.L_scan_next_ahb_slave:
+	/* More Slaves to process? */
+	subcc	%l1, 1, %l1
+	bne	.L_scan_one_ahb_slave
+	 add	%l2, AMBA_AHB_CONF_LENGH, %l2
+
+	/* No more AHB devices to process */
+	mov	%g2, %o7	/* Restore return address */
+	retl
+	 nop
+
+/* FUNCTION _nomem_ambapp_find_buses(unsigned int ioarea)
+ *
+ * Find AMBA AHB buses.
+ *
+ * Constraints:
+ *  i6-i7, l7 is used by caller
+ *
+ * Arguments
+ *  - o0 Bridge Information: I/O AREA and parent bus
+ *
+ * Results
+ *  - o0 Number of AHB bridges found
+ *  - i0-i5 initialized
+ *
+ * Clobbered
+ *  - o0 (Current AHB slave conf address)
+ *  - o2 (Used by insert_bridge)
+ *  - o3 (Used by insert_bridge)
+ *  - l0 (Current AHB Bus)
+ *  - l1 (Used by nomem_amba_scan)
+ *  - l2 (Used by nomem_amba_scan)
+ *  - l3 (Used by nomem_amba_scan)
+ *  - l4 (Used by nomem_amba_scan)
+ *
+ *  - g1 (level 1 return address)
+ *  - g2 (Used by nomem_amba_scan)
+ */
+_nomem_ambapp_find_buses:
+	mov	%o7, %g1	/* Save return address */
+
+	/* Initialize AHB Bus storage */
+	call	init_ahb_bridges
+	 nop
+
+	/* Insert AHB Bus 0 */
+	call	insert_ahb_bridge
+	 nop			/* Argument already prepared by caller */
+
+	/* Scan AHB Bus 0 for AHB Bridges */
+	call	_nomem_amba_scan
+	 add	%g0, 1, %o1
+
+	/* Scan all AHB Buses found for more AHB Bridges */
+	add	%g0, 2, %l0
+.L100_search_next_ahb_bus:
+	call	get_ahb_bridge			/* Get bus %l0 I/O Area */
+	 mov	%l0, %o0
+	cmp	%o0, %g0
+	be	.L100_return			/* If no more AHB bus is left to be scanned, proceed */
+	 nop
+	call	_nomem_amba_scan		/* Scan bus %l0 for AHB Bridges. i0-i7,l0 is used */
+	 mov	%l0, %o1			/* I/O AREA untouched in o0 */
+	ba	.L100_search_next_ahb_bus	/* Do next bus */
+	 add	%l0, 1, %l0
+
+.L100_return:
+	mov	%g1, %o7
+	retl
+	 nop
+
+
+/* FUNCTION _nomem_amba_init(unsigned int ioarea)
+ *
+ *  Find all AHB buses
+ *
+ * Constraints:
+ *  i6, i7, o6, o7, l7, l6, g3, g4, g5, g6, g7 is used by caller
+ *
+ * Arguments
+ *  - o0 Bridge Information: I/O AREA and parent bus
+ *
+ * Results
+ *  - o0 Number of AHB bridges found
+ *
+ * Clobbered
+ *  - l0, l1, l2, l3, l4, g1, g2 (used by _nomem_ambapp_find_buses)
+ *  - o0, o1, o2, o3 (Used as arguments)
+ *  - o5 (return address)
+ *  - g1 (level 1 return address)
+ *  - g2 (level 2 return address)
+ */
+_nomem_amba_init:
+	mov	%o7, %o5	/* Save return address, o5 not used */
+
+	/* Scan for buses, it will init i0-i5 */
+	call	_nomem_ambapp_find_buses
+	 nop
+
+	mov	%o5, %o7
+	retl
+	 nop
+
+/* Call tree and their return address register
+ *
+ *_nomem_amba_scan           (g1)
+ * -> init_ahb_bridges       (o7)
+ * -> insert_ahb_bridge      (o7)
+ * -> _nomem_amba_scan       (g2)
+ *    -> insert_ahb_bridge   (o7)
+ * -> get_ahb_bridge         (o7)
+ *
+ *
+ * -> _nomem_find_apb        (g2)
+ *    -> get_ahb_bridge      (o7)
+ *    -> _nomem_find_ahb_bus (o7)
+ *    -> _nomem_find_apb_bus (o7)
+ * -> _nomem_find_ahb        (g2)
+ *    -> get_ahb_bridge      (o7)
+ *    -> _nomem_find_ahb_bus (o7)
+ * -> mem_handler.func()     (o7)
+ *
+ */
diff --git a/arch/sparc/cpu/leon3/ambapp_low_c.S b/arch/sparc/cpu/leon3/ambapp_low_c.S
new file mode 100644
index 0000000..42288fa
--- /dev/null
+++ b/arch/sparc/cpu/leon3/ambapp_low_c.S
@@ -0,0 +1,113 @@
+/* C-interface for AMBA PnP scanning functions implemented in
+ * ambapp_low.S. At the point the memory and stack can be
+ * used.
+ *
+ * (C) Copyright 2010, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+
+	.seg	"text"
+	.extern	_nomem_ambapp_find_buses
+	.extern	_nomem_find_apb
+	.extern	_nomem_find_ahb
+
+	.globl	ambapp_find_buses
+	.globl	ambapp_find_apb
+	.globl	ambapp_find_ahb
+
+
+/* C-interface for _nomem_ambapp_find_buses used when memory is available.
+ */
+ambapp_find_buses:
+	save	%sp, -104, %sp
+	mov	%i1, %l7	/* Save second argument */
+	call _nomem_ambapp_find_buses
+	 mov	%i0, %o0
+
+	/* Store result */
+	st	%g0, [%l7+0x00]
+	st	%i0, [%l7+0x04]
+	st	%i1, [%l7+0x08]
+	st	%i2, [%l7+0x0c]
+	st	%i3, [%l7+0x10]
+	st	%i4, [%l7+0x14]
+	st	%i5, [%l7+0x18]
+
+	ret
+	 restore
+
+/* C-interface for _nomem_find_apb used when memory is available.
+ *
+ * void ambapp_find_apb(
+ *	struct ambapp_bus *abus,
+ *	unsigned int dev_vend,
+ *	int index,
+ *	struct ambapp_find_apb_info *result
+ *	);
+ *
+ */
+ambapp_find_apb:
+	save	%sp, -104, %sp
+
+	mov	%i3, %l7	/* Save second argument */
+	mov	%i1, %o1
+	mov	%i2, %o2
+
+	/* Initialize buses available in system */
+	ld	[%i0+0x08], %i1
+	ld	[%i0+0x0c], %i2
+	ld	[%i0+0x10], %i3
+	ld	[%i0+0x14], %i4
+	ld	[%i0+0x18], %i5
+
+	call _nomem_find_apb
+	 ld	[%i0+0x04], %i0
+
+	st	%o2, [%l7+0x08]	/* Decremented Index */
+	st	%o3, [%l7]	/* PnP configuration address of APB Device */
+	st	%o4, [%l7+0x04]	/* AHB Bus Index of AHB/APB bridge and APB Device */
+	mov	%o0, %i0
+	ret
+	 restore
+
+/* C-interface for _nomem_find_ahb used when memory is available.
+ *
+ * void ambapp_find_ahb(
+ *	struct ambapp_bus *abus,
+ *	unsigned int dev_vend,
+ *	int index,
+ *	int type,
+ *	struct ambapp_find_ahb_info *result
+ *	);
+ *
+ */
+ambapp_find_ahb:
+	save	%sp, -104, %sp
+
+	mov	%i4, %l7	/* Save second argument */
+	clr	%o0
+	mov	%i1, %o1
+	mov	%i2, %o2
+	clr	%o3
+	clr	%o4
+	mov	%i3, %o5
+
+	/* Initialize buses available in system */
+	ld	[%i0+0x08], %i1
+	ld	[%i0+0x0c], %i2
+	ld	[%i0+0x10], %i3
+	ld	[%i0+0x14], %i4
+	ld	[%i0+0x18], %i5
+
+	call _nomem_find_ahb
+	 ld	[%i0+0x04], %i0
+
+	st	%o2, [%l7+0x08]	/* Decremented Index */
+	st	%o3, [%l7]	/* PnP configuration address of AHB Device */
+	st	%o4, [%l7+0x04]	/* AHB Bus Index of AHB Device */
+	mov	%o0, %i0
+	ret
+	 restore
diff --git a/arch/sparc/cpu/leon3/cpu_init.c b/arch/sparc/cpu/leon3/cpu_init.c
index 2f41d88..b140da3 100644
--- a/arch/sparc/cpu/leon3/cpu_init.c
+++ b/arch/sparc/cpu/leon3/cpu_init.c
@@ -1,8 +1,8 @@
 /* Initializes CPU and basic hardware such as memory
  * controllers, IRQ controller and system timer 0.
  *
- * (C) Copyright 2007
- * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
+ * (C) Copyright 2007, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
@@ -11,9 +11,17 @@
 #include <asm/asi.h>
 #include <asm/leon.h>
 #include <ambapp.h>
+#include <grlib/irqmp.h>
+#include <grlib/gptimer.h>
+#include <debug_uart.h>
 
 #include <config.h>
 
+/* Default Plug&Play I/O area */
+#ifndef CONFIG_AMBAPP_IOAREA
+#define CONFIG_AMBAPP_IOAREA AMBA_DEFAULT_IOAREA
+#endif
+
 #define TIMER_BASE_CLK 1000000
 #define US_PER_TICK (1000000 / CONFIG_SYS_HZ)
 
@@ -22,11 +30,7 @@
 /* reset CPU (jump to 0, without reset) */
 void start(void);
 
-/* find & initialize the memory controller */
-int init_memory_ctrl(void);
-
 ambapp_dev_irqmp *irqmp = NULL;
-ambapp_dev_mctrl memctrl;
 ambapp_dev_gptimer *gptimer = NULL;
 unsigned int gptimer_irq = 0;
 int leon3_snooping_avail = 0;
@@ -39,64 +43,32 @@
 /*
  * Breath some life into the CPU...
  *
- * Set up the memory map,
- * initialize a bunch of registers.
- *
  * Run from FLASH/PROM:
  *  - until memory controller is set up, only registers available
+ *  - memory controller has already been setup up, stack can be used
  *  - no global variables available for writing
  *  - constants available
  */
-
 void cpu_init_f(void)
 {
-	/* these varaiable must not be initialized */
-	ambapp_dev_irqmp *irqmp;
-	ambapp_apbdev apbdev;
-	register unsigned int apbmst;
-
-	/* find AMBA APB Master */
-	apbmst = (unsigned int)
-	    ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_APBMST, 1, 0);
-	if (!apbmst) {
-		/*
-		 * no AHB/APB bridge, something is wrong
-		 * ==> jump to start (or hang)
-		 */
-		while (1) ;
-	}
-	/* Init memory controller */
-	if (init_memory_ctrl()) {
-		while (1) ;
-	}
-
-	/****************************************************
-	 * From here we can use the main memory and the stack.
-	 */
-
-	/* Find AMBA APB IRQMP Controller */
-	if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_IRQMP, &apbdev) != 1) {
-		/* no IRQ controller, something is wrong
-		 * ==> jump to start (or hang)
-		 */
-		while (1) ;
-	}
-	irqmp = (ambapp_dev_irqmp *) apbdev.address;
-
-	/* initialize the IRQMP */
-	irqmp->ilevel = 0xf;	/* all IRQ off */
-	irqmp->iforce = 0;
-	irqmp->ipend = 0;
-	irqmp->iclear = 0xfffe;	/* clear all old pending interrupts */
-	irqmp->cpu_mask[0] = 0;	/* mask all IRQs on CPU 0 */
-	irqmp->cpu_force[0] = 0;	/* no force IRQ on CPU 0 */
-
-	/* cache */
+#ifdef CONFIG_DEBUG_UART
+	debug_uart_init();
+#endif
 }
 
+/* Routine called from start.S,
+ *
+ * Run from FLASH/PROM:
+ *  - memory controller has already been setup up, stack can be used
+ *  - global variables available for read/writing
+ *  - constants avaiable
+	 */
 void cpu_init_f2(void)
 {
-
+	/* Initialize the AMBA Plug & Play bus structure, the bus
+	 * structure represents the AMBA bus that the CPU is located at.
+	 */
+	ambapp_bus_init(CONFIG_AMBAPP_IOAREA, CONFIG_SYS_CLK_FREQ, &ambapp_plb);
 }
 
 /*
@@ -105,95 +77,58 @@
 int cpu_init_r(void)
 {
 	ambapp_apbdev apbdev;
+	int index, cpu;
+	ambapp_dev_gptimer *timer = NULL;
+	unsigned int bus_freq;
 
 	/*
 	 * Find AMBA APB IRQMP Controller,
-	 * When we come so far we know there is a IRQMP available
 	 */
-	ambapp_apb_first(VENDOR_GAISLER, GAISLER_IRQMP, &apbdev);
-	irqmp = (ambapp_dev_irqmp *) apbdev.address;
+	if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER,
+		GAISLER_IRQMP, 0, &apbdev) != 1) {
+		panic("%s: IRQ controller not found\n", __func__);
+		return -1;
+	}
+	irqmp = (ambapp_dev_irqmp *)apbdev.address;
+
+	/* initialize the IRQMP */
+	irqmp->ilevel = 0xf;	/* all IRQ off */
+	irqmp->iforce = 0;
+	irqmp->ipend = 0;
+	irqmp->iclear = 0xfffe;	/* clear all old pending interrupts */
+	for (cpu = 0; cpu < 16; cpu++) {
+		/* mask and clear force for all IRQs on CPU[N] */
+		irqmp->cpu_mask[cpu] = 0;
+		irqmp->cpu_force[cpu] = 0;
+	}
 
 	/* timer */
-	if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_GPTIMER, &apbdev) != 1) {
-		printf("cpu_init_r: gptimer not found!\n");
+	index = 0;
+	while (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_GPTIMER,
+		index, &apbdev) == 1) {
+		timer = (ambapp_dev_gptimer *)apbdev.address;
+		if (gptimer == NULL) {
+			gptimer = timer;
+			gptimer_irq = apbdev.irq;
+		}
+
+		/* Different buses may have different frequency, the
+		 * frequency of the bus tell in which frequency the timer
+		 * prescaler operates.
+		 */
+		bus_freq = ambapp_bus_freq(&ambapp_plb, apbdev.ahb_bus_index);
+
+		/* initialize prescaler common to all timers to 1MHz */
+		timer->scalar = timer->scalar_reload =
+		    (((bus_freq / 1000) + 500) / 1000) - 1;
+
+		index++;
+	}
+	if (!gptimer) {
+		printf("%s: gptimer not found!\n", __func__);
 		return 1;
 	}
-	gptimer = (ambapp_dev_gptimer *) apbdev.address;
-	gptimer_irq = apbdev.irq;
-
-	/* initialize prescaler common to all timers to 1MHz */
-	gptimer->scalar = gptimer->scalar_reload =
-	    (((CONFIG_SYS_CLK_FREQ / 1000) + 500) / 1000) - 1;
-
-	return (0);
-}
-
-/* find & setup memory controller */
-int init_memory_ctrl()
-{
-	register ambapp_dev_mctrl *mctrl;
-	register ambapp_dev_sdctrl *sdctrl;
-	register ambapp_dev_ddrspa *ddrspa;
-	register ambapp_dev_ddr2spa *ddr2spa;
-	register ahbctrl_pp_dev *ahb;
-	register unsigned int base;
-	register int not_found_mctrl = -1;
-
-	/* find ESA Memory controller */
-	base = ambapp_apb_next_nomem(VENDOR_ESA, ESA_MCTRL, 0);
-	if (base) {
-		mctrl = (ambapp_dev_mctrl *) base;
-
-		/* config MCTRL memory controller */
-		mctrl->mcfg1 = CONFIG_SYS_GRLIB_MEMCFG1 | (mctrl->mcfg1 & 0x300);
-		mctrl->mcfg2 = CONFIG_SYS_GRLIB_MEMCFG2;
-		mctrl->mcfg3 = CONFIG_SYS_GRLIB_MEMCFG3;
-		not_found_mctrl = 0;
-	}
-
-	/* find Gaisler Fault Tolerant Memory controller */
-	base = ambapp_apb_next_nomem(VENDOR_GAISLER, GAISLER_FTMCTRL, 0);
-	if (base) {
-		mctrl = (ambapp_dev_mctrl *) base;
-
-		/* config MCTRL memory controller */
-		mctrl->mcfg1 = CONFIG_SYS_GRLIB_FT_MEMCFG1 | (mctrl->mcfg1 & 0x300);
-		mctrl->mcfg2 = CONFIG_SYS_GRLIB_FT_MEMCFG2;
-		mctrl->mcfg3 = CONFIG_SYS_GRLIB_FT_MEMCFG3;
-		not_found_mctrl = 0;
-	}
-
-	/* find SDRAM controller */
-	base = ambapp_apb_next_nomem(VENDOR_GAISLER, GAISLER_SDCTRL, 0);
-	if (base) {
-		sdctrl = (ambapp_dev_sdctrl *) base;
-
-		/* config memory controller */
-		sdctrl->sdcfg = CONFIG_SYS_GRLIB_SDRAM;
-		not_found_mctrl = 0;
-	}
-
-	ahb = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_DDR2SPA, 1, 0);
-	if (ahb) {
-		ddr2spa = (ambapp_dev_ddr2spa *) ambapp_ahb_get_info(ahb, 1);
-
-		/* Config DDR2 memory controller */
-		ddr2spa->cfg1 = CONFIG_SYS_GRLIB_DDR2_CFG1;
-		ddr2spa->cfg3 = CONFIG_SYS_GRLIB_DDR2_CFG3;
-		not_found_mctrl = 0;
-	}
-
-	ahb = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_DDRSPA, 1, 0);
-	if (ahb) {
-		ddrspa = (ambapp_dev_ddrspa *) ambapp_ahb_get_info(ahb, 1);
-
-		/* Config DDR memory controller */
-		ddrspa->ctrl = CONFIG_SYS_GRLIB_DDR_CFG;
-		not_found_mctrl = 0;
-	}
-
-	/* failed to find any memory controller */
-	return not_found_mctrl;
+	return 0;
 }
 
 /* Uses Timer 0 to get accurate
@@ -216,8 +151,8 @@
 	gptimer->e[0].val = 0;
 	gptimer->e[0].rld = (TIMER_BASE_CLK / CONFIG_SYS_HZ) - 1;
 	gptimer->e[0].ctrl =
-	    (LEON3_GPTIMER_EN |
-	     LEON3_GPTIMER_RL | LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN);
+	    (GPTIMER_CTRL_EN | GPTIMER_CTRL_RS |
+	     GPTIMER_CTRL_LD | GPTIMER_CTRL_IE);
 
 	return gptimer_irq;
 }
diff --git a/arch/sparc/cpu/leon3/interrupts.c b/arch/sparc/cpu/leon3/interrupts.c
index a834aa0..2312b58 100644
--- a/arch/sparc/cpu/leon3/interrupts.c
+++ b/arch/sparc/cpu/leon3/interrupts.c
@@ -23,6 +23,8 @@
 
 #include <asm/leon.h>
 #include <ambapp.h>
+#include <grlib/irqmp.h>
+#include <grlib/gptimer.h>
 
 /* 15 normal irqs and a non maskable interrupt */
 #define NR_IRQS 15
@@ -125,9 +127,8 @@
 /* Handle Timer 0 IRQ */
 void timer_interrupt_cpu(void *arg)
 {
-	gptimer->e[0].ctrl = (LEON3_GPTIMER_EN |
-			      LEON3_GPTIMER_RL |
-			      LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN);
+	gptimer->e[0].ctrl = (GPTIMER_CTRL_EN | GPTIMER_CTRL_RS |
+			      GPTIMER_CTRL_LD | GPTIMER_CTRL_IE);
 	/* nothing to do here */
 	return;
 }
diff --git a/arch/sparc/cpu/leon3/memcfg.c b/arch/sparc/cpu/leon3/memcfg.c
new file mode 100644
index 0000000..b9eda44
--- /dev/null
+++ b/arch/sparc/cpu/leon3/memcfg.c
@@ -0,0 +1,237 @@
+/* GRLIB Memory controller setup. The register values are used
+ * from the associated low level assembler routine implemented
+ * in memcfg_low.S.
+ *
+ * (C) Copyright 2010, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <ambapp.h>
+#include "memcfg.h"
+#include <config.h>
+
+#ifdef CONFIG_SYS_GRLIB_ESA_MCTRL1
+struct mctrl_setup esa_mctrl1_cfg = {
+	.reg_mask = 0x7,
+	.regs = {
+		{
+			.mask = 0x00000300,
+			.value = CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG1,
+		},
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2,
+		},
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG3,
+		},
+	}
+};
+#ifdef CONFIG_SYS_GRLIB_ESA_MCTRL2
+struct mctrl_setup esa_mctrl2_cfg = {
+	.reg_mask = 0x7,
+	.regs = {
+		{
+			.mask = 0x00000300,
+			.value = CONFIG_SYS_GRLIB_ESA_MCTRL2_CFG1,
+		},
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_ESA_MCTRL2_CFG2,
+		},
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_ESA_MCTRL2_CFG3,
+		},
+	}
+};
+#endif
+#endif
+
+#ifdef CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1
+struct mctrl_setup gaisler_ftmctrl1_cfg = {
+	.reg_mask = 0x7,
+	.regs = {
+		{
+			.mask = 0x00000300,
+			.value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG1,
+		},
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2,
+		},
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG3,
+		},
+	}
+};
+#ifdef CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2
+struct mctrl_setup gaisler_ftmctrl2_cfg = {
+	.reg_mask = 0x7,
+	.regs = {
+		{
+			.mask = 0x00000300,
+			.value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2_CFG1,
+		},
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2_CFG2,
+		},
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2_CFG3,
+		},
+	}
+};
+#endif
+#endif
+
+#ifdef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1
+struct mctrl_setup gaisler_sdctrl1_cfg = {
+	.reg_mask = 0x1,
+	.regs = {
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_SDCTRL1_CTRL,
+		},
+	}
+};
+#ifdef CONFIG_SYS_GRLIB_GAISLER_SDCTRL2
+struct mctrl_setup gaisler_sdctrl2_cfg = {
+	.reg_mask = 0x1,
+	.regs = {
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_SDCTRL2_CTRL,
+		},
+	}
+};
+#endif
+#endif
+
+#ifdef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1
+struct ahbmctrl_setup gaisler_ddr2spa1_cfg = {
+	.ahb_mbar_no = 1,
+	.reg_mask = 0xd,
+	.regs = {
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1_CFG1,
+		},
+		{ 0x00000000, 0},
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1_CFG3,
+		},
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1_CFG4,
+		},
+	}
+};
+#ifdef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2
+struct ahbmctrl_setup gaisler_ddr2spa2_cfg = {
+	.ahb_mbar_no = 1,
+	.reg_mask = 0xd,
+	.regs = {
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2_CFG1,
+		},
+		{ 0x00000000, 0},
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2_CFG3,
+		},
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2_CFG4,
+		},
+	}
+};
+#endif
+#endif
+
+#ifdef CONFIG_SYS_GRLIB_GAISLER_DDRSPA1
+struct ahbmctrl_setup gaisler_ddrspa1_cfg = {
+	.ahb_mbar_no = 1,
+	.reg_mask = 0x1,
+	.regs = {
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_DDRSPA1_CTRL,
+		},
+	}
+};
+#ifdef CONFIG_SYS_GRLIB_GAISLER_DDRSPA2
+struct ahbmctrl_setup gaisler_ddrspa2_cfg = {
+	.ahb_mbar_no = 1,
+	.reg_mask = 0x1,
+	.regs = {
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_DDRSPA2_CTRL,
+		},
+	}
+};
+#endif
+#endif
+
+struct grlib_mctrl_handler grlib_mctrl_handlers[] = {
+/* ESA MCTRL (PROM/FLASH/IO/SRAM/SDRAM) */
+#ifdef CONFIG_SYS_GRLIB_ESA_MCTRL1
+	{DEV_APB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_ESA, ESA_MCTRL),
+	_nomem_mctrl_init, (void *)&esa_mctrl1_cfg},
+#ifdef CONFIG_SYS_GRLIB_ESA_MCTRL2
+	{DEV_APB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_ESA, ESA_MCTRL),
+	_nomem_mctrl_init, (void *)&esa_mctrl2_cfg},
+#endif
+#endif
+
+/* GAISLER Fault Tolerant Memory controller (PROM/FLASH/IO/SRAM/SDRAM) */
+#ifdef CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1
+	{DEV_APB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_FTMCTRL),
+	_nomem_mctrl_init, (void *)&gaisler_ftmctrl1_cfg},
+#ifdef CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2
+	{DEV_APB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_FTMCTRL),
+	_nomem_mctrl_init, (void *)&gaisler_ftmctrl2_cfg},
+#endif
+#endif
+
+/* GAISLER SDRAM-only Memory controller (SDRAM) */
+#ifdef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1
+	{DEV_APB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_SDCTRL),
+	_nomem_mctrl_init, (void *)&gaisler_sdctrl1_cfg},
+#ifdef CONFIG_SYS_GRLIB_GAISLER_SDCTRL2
+	{DEV_APB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_SDCTRL),
+	_nomem_mctrl_init, (void *)&gaisler_sdctrl2_cfg},
+#endif
+#endif
+
+/* GAISLER DDR Memory controller (DDR) */
+#ifdef CONFIG_SYS_GRLIB_GAISLER_DDRSPA1
+	{DEV_AHB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_DDRSP),
+	_nomem_ahbmctrl_init, (void *)&gaisler_ddrspa1_cfg},
+#ifdef CONFIG_SYS_GRLIB_GAISLER_DDRSPA2
+	{DEV_AHB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_DDRSP),
+	_nomem_ahbmctrl_init, (void *)&gaisler_ddrspa2_cfg},
+#endif
+#endif
+
+/* GAISLER DDR2 Memory controller (DDR2) */
+#ifdef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1
+	{DEV_AHB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_DDR2SP),
+	_nomem_ahbmctrl_init, (void *)&gaisler_ddr2spa1_cfg},
+#ifdef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2
+	{DEV_AHB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_DDR2SP),
+	_nomem_ahbmctrl_init, (void *)&gaisler_ddr2spa2_cfg},
+#endif
+#endif
+
+	/* Mark end */
+	MH_END
+};
diff --git a/arch/sparc/cpu/leon3/memcfg.h b/arch/sparc/cpu/leon3/memcfg.h
new file mode 100644
index 0000000..a524896
--- /dev/null
+++ b/arch/sparc/cpu/leon3/memcfg.h
@@ -0,0 +1,90 @@
+/* GRLIB Memory controller setup structures
+ *
+ * (C) Copyright 2010, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __MEMCFG_H__
+#define __MEMCFG_H__
+
+/*********** Low Level Memory Controller Initalization ***********/
+
+#ifndef __ASSEMBLER__
+
+struct grlib_mctrl_handler;
+
+typedef void (*mctrl_handler_t)(
+	struct grlib_mctrl_handler *dev,
+	void *conf,
+	unsigned int ioarea
+	);
+
+/* Memory Controller Handler Structure */
+struct grlib_mctrl_handler {
+	unsigned char	type;		/* 0x00. MASK: AHB MST&SLV, APB SLV */
+	char		index;		/* 0x01. Unit number, 0, 1, 2... */
+	char		unused[2];	/* 0x02 */
+	unsigned int	ven_dev;	/* 0x04. Device and Vendor */
+	mctrl_handler_t	func;		/* 0x08. Memory Controller Handler */
+	void		*priv;		/* 0x0c. Optional private data, ptr to
+					 * info how to set up controller */
+};
+
+extern struct grlib_mctrl_handler grlib_mctrl_handlers[];
+
+#endif
+
+#define MH_STRUCT_SIZE		(4*4)
+#define MH_TYPE			0x00
+#define MH_INDEX		0x01
+#define MH_VENDOR_DEVICE	0x04
+#define MH_FUNC			0x08
+#define MH_PRIV			0x0c
+
+#define MH_TYPE_NONE	DEV_NONE
+#define MH_TYPE_AHB_MST	DEV_AHB_MST
+#define MH_TYPE_AHB_SLV	DEV_AHB_SLV
+#define MH_TYPE_APB_SLV	DEV_APB_SLV
+
+#define MH_UNUSED	{0, 0}
+#define MH_END		{DEV_NONE, 0, MH_UNUSED, AMBA_PNP_ID(0, 0), 0, 0}
+
+/*********** Low Level Memory Controller Initalization Handlers ***********/
+
+#ifndef __ASSEMBLER__
+extern void _nomem_mctrl_init(
+	struct grlib_mctrl_handler *dev,
+	void *conf,
+	unsigned int ioarea_apbmst);
+
+struct mctrl_setup {
+	unsigned int reg_mask;		/* Which registers to write */
+	struct {
+		unsigned int mask;	/* Mask used keep reg bits unchanged */
+		unsigned int value;	/* Value written to register */
+	} regs[8];
+};
+
+extern void _nomem_ahbmctrl_init(
+	struct grlib_mctrl_handler *dev,
+	void *conf,
+	unsigned int ioarea_apbmst);
+
+struct ahbmctrl_setup {
+	int ahb_mbar_no;		/* MBAR to get register address from */
+	unsigned int reg_mask;		/* Which registers to write */
+	struct {
+		unsigned int mask;	/* Mask used keep reg bits unchanged */
+		unsigned int value;	/* Value written to register */
+	} regs[8];
+};
+#endif
+
+/* mctrl_setup data structure defines */
+#define NREGS_OFS 0
+#define REGS_OFS 0x4
+#define REGS_SIZE 8
+
+#endif
diff --git a/arch/sparc/cpu/leon3/memcfg_low.S b/arch/sparc/cpu/leon3/memcfg_low.S
new file mode 100644
index 0000000..84a81a9
--- /dev/null
+++ b/arch/sparc/cpu/leon3/memcfg_low.S
@@ -0,0 +1,253 @@
+/* This is the memory initialization functions, the function
+ * implemented below initializes each memory controller
+ * found and specified by the input grlib_mctrl_handler structure.
+ *
+ * After the memory controllers have been initialized the stack
+ * can be used.
+ *
+ * (C) Copyright 2010, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <ambapp.h>
+#include "memcfg.h"
+#include <config.h>
+
+	.seg	"text"
+	.globl	_nomem_memory_ctrl_init
+	.globl	_nomem_mctrl_init, _nomem_ahbmctrl_init
+	.extern	_nomem_find_apb
+	.extern	_nomem_find_ahb
+
+
+/* FUNCTION
+ *   _nomem_memory_controller_init(struct grlib_mctrl_handler *mem_handlers)
+ *
+ * Initialize AMBA devices, _nomem_amba_init() has prepared i0-i5
+ * with the AHB buses on the system.
+ *
+ * For each entry in mem_handlers find the VENDOR:DEVICE and handle it
+ * by calling the handler function pointer.
+ *
+ * Constraints:
+ *  i6, i7, o6, l7, l6, g3, g4, g5, g6, g7 is used by caller
+ *  o7 is return address
+ *  l5 reserved for this function for future use.
+ *
+ * Arguments
+ *  - o0 Pointer to memory handler array
+ *
+ * Results
+ *  - o0 Number of memory controllers found
+ *
+ * Clobbered
+ *  - o0 (Current AHB slave conf address)
+ *  - l0 (mem handler entry address)
+ *  - l1 (Return value, number of memory controllers found)
+ *  - o7 (function pointer)
+ *  - l0, l1, l2, l3, l4, g1, g2 (used by _nomem_ambapp_find_buses)
+ *  - o0, o1, o2, o3, o4, o5 (Used as arguments)
+ *
+ *  - g1 ( level 1 return address)
+ *  - g2 ( level 2 return address)
+ */
+
+_nomem_memory_ctrl_init:
+	/* At this point all AHB buses has been found and the I/O Areas of
+	 * all AHB buses is stored in the i0-i5 registers. Max 6 buses. Next,
+	 * memory controllers are found by searching all buses for matching
+	 * VENDOR:DEVICE. The VENDOR:DEVICE to search for are taken from the
+	 * mem_handlers array. For each match the function pointer stored in
+	 * the mem_handler entry is called to handle the hardware setup.
+	 */
+	mov	%o7, %g1	/* Save return address */
+	mov	%o0, %l0
+	mov	%g0, %l1	/* The return value */
+
+.L_do_one_mem_handler:
+	ld	[%l0 + MH_FUNC], %o7
+	cmp	%o7, %g0
+	be	.L_all_mctrl_handled
+	 nop
+
+	/*** Scan for memory controller ***/
+
+	/* Set up argments, o5 not used by _nomem_find_apb */
+	ldub	[%l0 + MH_TYPE], %o5
+	clr	%o4
+	clr	%o3
+	ldub	[%l0 + MH_INDEX], %o2
+	ld	[%l0 + MH_VENDOR_DEVICE], %o1
+
+	/* An empty config? */
+	cmp	%o5, DEV_NONE
+	beq	.L_all_mctrl_next
+
+	/* Select function (APB or AHB) */
+	 cmp	%o5, DEV_APB_SLV
+	bne	.L_find_ahb_memctrl
+	 clr	%o0
+.L_find_apb_memctrl:
+	call	_nomem_find_apb			/* Scan for APB slave device */
+	 nop
+
+	/* o3 = iobar address
+	 * o4 = AHB Bus index
+	 *
+	 * REG ADR = ((iobar >> 12) & (iobar << 4) & 0xfff00) | "APB Base"
+	 */
+	ld	[%o3 + AMBA_APB_IOBAR_OFS], %o5
+	srl	%o5, 12, %o2
+	sll	%o5, 4, %o5
+	and	%o2, %o5, %o5
+	set	0xfff00, %o2
+	and	%o2, %o5, %o5
+	sethi	%hi(0xfff00000), %o2
+	and	%o3, %o2, %o2
+	or	%o5, %o2, %o5	/* Register base address */
+
+	ba	.L_call_one_mem_handler
+	 nop
+
+.L_find_ahb_memctrl:
+	call	_nomem_find_ahb		/* Scan for AHB Slave or Master.
+					 * o5 determine type. */
+	 nop
+	clr	%o5
+
+	/* Call the handler function if the hardware was found
+	 *
+	 * o0 = mem_handler
+	 * o1 = Configuration address
+	 * o2 = AHB Bus index
+	 * o3 = APB Base register (if APB Slave)
+	 *
+	 * Constraints:
+	 * i0-i7, l0, l1, l5, g1, g3-g7 may no be used.
+	 */
+.L_call_one_mem_handler:
+	cmp	%o0, %g0
+	be	.L_all_mctrl_next
+	 mov	%l0, %o0			/* Mem handler pointer */
+	mov	%o3, %o1			/* AMBA PnP Configuration address */
+	mov	%o4, %o2			/* AHB Bus index */
+	ld	[%l0 + MH_FUNC], %o7	/* Get Function pointer */
+	call	%o7
+	 mov	%o5, %o3			/* APB Register Base Address */
+
+	inc	%l1				/* Number of Memory controllers
+						 * handled. */
+
+	/* Do next entry in mem_handlers */
+.L_all_mctrl_next:
+	ba	.L_do_one_mem_handler
+	 add	%l0, MH_STRUCT_SIZE, %l0
+
+.L_all_mctrl_handled:
+	mov	%g1, %o7	/* Restore return address */
+	retl
+	 mov	%l1, %o0
+
+
+
+/* Generic Memory controller initialization routine (APB Registers)
+ *
+ * o0 = mem_handler structure pointer
+ * o1 = Configuration address
+ * o2 = AHB Bus index
+ * o3 = APB Base register
+ *
+ * Clobbered
+ *  o0-o4
+ */
+_nomem_mctrl_init:
+	ld	[%o0 + MH_PRIV], %o0	/* Get Private structure */
+	ld	[%o0], %o1		/* Get Reg Mask */
+	and	%o1, 0xff, %o1
+	add	%o0, REGS_OFS, %o0	/* Point to first reg */
+.L_do_one_reg:
+	andcc	%o1, 0x1, %g0
+	beq	.L_do_next_reg
+	 ld	[%o0], %o2
+	ld	[%o3], %o4
+	and	%o4, %o2, %o4
+	ld	[%o0 + 4], %o2
+	or	%o4, %o2, %o4
+	st	%o4, [%o3]
+
+.L_do_next_reg:
+	add	%o0, REGS_SIZE, %o0
+	add	%o3, 4, %o3
+	srl	%o1, 1, %o1
+	cmp	%o1, 0
+	bne	.L_do_one_reg
+	 nop
+
+	/* No more registers to write */
+	retl
+	 nop
+
+
+
+/* Generic Memory controller initialization routine (AHB Registers)
+ *
+ * o0 = mem_handler structure pointer
+ * o1 = Configuration address of memory controller
+ * o2 = AHB Bus index
+ *
+ * Clobbered
+ *  o0-o5
+ */
+_nomem_ahbmctrl_init:
+	ld	[%o0 + MH_PRIV], %o0		/* Get Private structure */
+
+	/* Get index of AHB MBAR to get registers from */
+	ld	[%o0], %o5
+	add	%o0, 4, %o0
+
+	/* Get Address of MBAR in PnP info */
+	add	%o5, 4, %o5
+	sll	%o5, 2, %o5
+	add	%o5, %o1, %o5			/* Address of MBAR */
+
+	/* Get Address of registers from PnP information
+	 * Address is in AHB I/O format, i.e. relative to bus
+	 *
+	 * ADR = (iobar & (iobar << 16) & 0xfff00000)
+	 * IOADR = (ADR >> 12) | "APB Base"
+	 */
+	ld	[%o5], %o5
+	sll	%o5, 16, %o4
+	and	%o5, %o4, %o5
+	sethi	%hi(0xfff00000), %o4
+	and	%o5, %o4, %o5			/* ADR */
+	and	%o4, %o1, %o4
+	srl	%o5, 12, %o5
+	or	%o5, %o4, %o3			/* IOADR in o3 */
+
+	ld	[%o0], %o1			/* Get Reg Mask */
+	and	%o1, 0xff, %o1
+	add	%o0, REGS_OFS, %o0		/* Point to first reg */
+.L_do_one_ahbreg:
+	andcc	%o1, 0x1, %g0
+	beq	.L_do_next_reg
+	 ld	[%o0], %o2
+	ld	[%o3], %o4
+	and	%o4, %o2, %o4
+	ld	[%o0 + 4], %o2
+	or	%o4, %o2, %o4
+	st	%o4, [%o3]
+
+.L_do_next_ahbreg:
+	add	%o0, REGS_SIZE, %o0
+	add	%o3, 4, %o3
+	srl	%o1, 1, %o1
+	cmp	%o1, 0
+	bne	.L_do_one_reg
+	 nop
+
+	/* No more registers to write */
+	retl
+	 nop
diff --git a/arch/sparc/cpu/leon3/prom.c b/arch/sparc/cpu/leon3/prom.c
index b83776b..c391be7 100644
--- a/arch/sparc/cpu/leon3/prom.c
+++ b/arch/sparc/cpu/leon3/prom.c
@@ -15,13 +15,17 @@
 #include <asm/irq.h>
 #include <asm/leon.h>
 #include <ambapp.h>
+#include <grlib/apbuart.h>
+#include <grlib/irqmp.h>
+#include <grlib/gptimer.h>
 
 #include <config.h>
 /*
 #define PRINT_ROM_VEC
 */
 extern struct linux_romvec *kernel_arg_promvec;
-extern ambapp_dev_apbuart *leon3_apbuart;
+
+DECLARE_GLOBAL_DATA_PTR;
 
 #define PROM_PGT __attribute__ ((__section__ (".prom.pgt")))
 #define PROM_TEXT __attribute__ ((__section__ (".prom.text")))
@@ -740,14 +744,14 @@
 
 	/* Wait for last character to go. */
 	while (!(SPARC_BYPASS_READ(&uart->status)
-		 & LEON_REG_UART_STATUS_THE)) ;
+		 & APBUART_STATUS_THE));
 
 	/* Send data */
 	SPARC_BYPASS_WRITE(&uart->data, c);
 
 	/* Wait for data to be sent */
 	while (!(SPARC_BYPASS_READ(&uart->status)
-		 & LEON_REG_UART_STATUS_TSE)) ;
+		 & APBUART_STATUS_TSE));
 
 	return 0;
 }
@@ -909,7 +913,7 @@
 	pspi->avail.num_bytes = pspi->totphys.num_bytes;
 
 	/* Set the pointer to the Console UART in romvec */
-	pspi->reloc_funcs.leon3_apbuart = leon3_apbuart;
+	pspi->reloc_funcs.leon3_apbuart = gd->arch.uart;
 
 	{
 		int j = 1;
diff --git a/arch/sparc/cpu/leon3/serial.c b/arch/sparc/cpu/leon3/serial.c
index bca6b65..66b3773 100644
--- a/arch/sparc/cpu/leon3/serial.c
+++ b/arch/sparc/cpu/leon3/serial.c
@@ -1,66 +1,79 @@
 /* GRLIB APBUART Serial controller driver
  *
- * (C) Copyright 2007
- * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ * (C) Copyright 2007, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
 #include <common.h>
-#include <asm/processor.h>
-#include <asm/leon.h>
+#include <asm/io.h>
 #include <ambapp.h>
+#include <grlib/apbuart.h>
 #include <serial.h>
-#include <linux/compiler.h>
+#include <watchdog.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-ambapp_dev_apbuart *leon3_apbuart = NULL;
+/* Select which UART that will become u-boot console */
+#ifndef CONFIG_SYS_GRLIB_APBUART_INDEX
+#define CONFIG_SYS_GRLIB_APBUART_INDEX 0
+#endif
 
 static int leon3_serial_init(void)
 {
+	ambapp_dev_apbuart *uart;
 	ambapp_apbdev apbdev;
 	unsigned int tmp;
 
 	/* find UART */
-	if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_APBUART, &apbdev) == 1) {
-
-		leon3_apbuart = (ambapp_dev_apbuart *) apbdev.address;
-
-		/* found apbuart, let's init...
-		 *
-		 * Set scaler / baud rate
-		 *
-		 * Receiver & transmitter enable
-		 */
-		leon3_apbuart->scaler = CONFIG_SYS_GRLIB_APBUART_SCALER;
-
-		/* Let bit 11 be unchanged (debug bit for GRMON) */
-		tmp = READ_WORD(leon3_apbuart->ctrl);
-
-		leon3_apbuart->ctrl = ((tmp & LEON_REG_UART_CTRL_DBG) |
-				       LEON_REG_UART_CTRL_RE |
-				       LEON_REG_UART_CTRL_TE);
-
-		return 0;
+	if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_APBUART,
+		CONFIG_SYS_GRLIB_APBUART_INDEX, &apbdev) != 1) {
+		panic("%s: apbuart not found!\n", __func__);
+		return -1; /* didn't find hardware */
 	}
-	return -1;		/* didn't find hardware */
+
+	/* found apbuart, let's init .. */
+	uart = (ambapp_dev_apbuart *) apbdev.address;
+
+	/* Set scaler / baud rate */
+	tmp = (((CONFIG_SYS_CLK_FREQ*10) / (CONFIG_BAUDRATE*8)) - 5)/10;
+	writel(tmp, &uart->scaler);
+
+	/* Let bit 11 be unchanged (debug bit for GRMON) */
+	tmp = readl(&uart->ctrl) & APBUART_CTRL_DBG;
+	/* Receiver & transmitter enable */
+	tmp |= APBUART_CTRL_RE | APBUART_CTRL_TE;
+	writel(tmp, &uart->ctrl);
+
+	gd->arch.uart = uart;
+	return 0;
+}
+
+static inline ambapp_dev_apbuart *leon3_get_uart_regs(void)
+{
+	ambapp_dev_apbuart *uart = gd->arch.uart;
+	return uart;
 }
 
 static void leon3_serial_putc_raw(const char c)
 {
-	if (!leon3_apbuart)
+	ambapp_dev_apbuart * const uart = leon3_get_uart_regs();
+
+	if (!uart)
 		return;
 
 	/* Wait for last character to go. */
-	while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_THE)) ;
+	while (!(readl(&uart->status) & APBUART_STATUS_THE))
+		WATCHDOG_RESET();
 
 	/* Send data */
-	leon3_apbuart->data = c;
+	writel(c, &uart->data);
 
 #ifdef LEON_DEBUG
 	/* Wait for data to be sent */
-	while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_TSE)) ;
+	while (!(readl(&uart->status) & APBUART_STATUS_TSE))
+		WATCHDOG_RESET();
 #endif
 }
 
@@ -74,36 +87,44 @@
 
 static int leon3_serial_getc(void)
 {
-	if (!leon3_apbuart)
+	ambapp_dev_apbuart * const uart = leon3_get_uart_regs();
+
+	if (!uart)
 		return 0;
 
 	/* Wait for a character to arrive. */
-	while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_DR)) ;
+	while (!(readl(&uart->status) & APBUART_STATUS_DR))
+		WATCHDOG_RESET();
 
-	/* read data */
-	return READ_WORD(leon3_apbuart->data);
+	/* Read character data */
+	return readl(&uart->data);
 }
 
 static int leon3_serial_tstc(void)
 {
-	if (leon3_apbuart)
-		return (READ_WORD(leon3_apbuart->status) &
-			LEON_REG_UART_STATUS_DR);
-	return 0;
+	ambapp_dev_apbuart * const uart = leon3_get_uart_regs();
+
+	if (!uart)
+		return 0;
+
+	return readl(&uart->status) & APBUART_STATUS_DR;
 }
 
 /* set baud rate for uart */
 static void leon3_serial_setbrg(void)
 {
-	/* update baud rate settings, read it from gd->baudrate */
+	ambapp_dev_apbuart * const uart = leon3_get_uart_regs();
 	unsigned int scaler;
-	if (leon3_apbuart && (gd->baudrate > 0)) {
-		scaler =
-		    (((CONFIG_SYS_CLK_FREQ * 10) / (gd->baudrate * 8)) -
-		     5) / 10;
-		leon3_apbuart->scaler = scaler;
-	}
-	return;
+
+	if (!uart)
+		return;
+
+	if (!gd->baudrate)
+		gd->baudrate = CONFIG_BAUDRATE;
+
+	scaler = (((CONFIG_SYS_CLK_FREQ*10) / (gd->baudrate*8)) - 5)/10;
+
+	writel(scaler, &uart->scaler);
 }
 
 static struct serial_device leon3_serial_drv = {
@@ -126,3 +147,26 @@
 {
 	return &leon3_serial_drv;
 }
+
+#ifdef CONFIG_DEBUG_UART_APBUART
+
+#include <debug_uart.h>
+
+static inline void _debug_uart_init(void)
+{
+	ambapp_dev_apbuart *uart = (ambapp_dev_apbuart *)CONFIG_DEBUG_UART_BASE;
+	uart->scaler = (((CONFIG_DEBUG_UART_CLOCK*10) / (CONFIG_BAUDRATE*8)) - 5)/10;
+	uart->ctrl = APBUART_CTRL_RE | APBUART_CTRL_TE;
+}
+
+static inline void _debug_uart_putc(int ch)
+{
+	ambapp_dev_apbuart *uart = (ambapp_dev_apbuart *)CONFIG_DEBUG_UART_BASE;
+	while (!(readl(&uart->status) & APBUART_STATUS_THE))
+		WATCHDOG_RESET();
+	writel(ch, &uart->data);
+}
+
+DEBUG_UART_FUNCS
+
+#endif
diff --git a/arch/sparc/cpu/leon3/start.S b/arch/sparc/cpu/leon3/start.S
index cf897f6..2031149 100644
--- a/arch/sparc/cpu/leon3/start.S
+++ b/arch/sparc/cpu/leon3/start.S
@@ -2,9 +2,6 @@
  * Copyright (C) 2007,
  * Daniel Hellstrom, daniel@gaisler.com
  *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
@@ -16,6 +13,12 @@
 #include <asm/stack.h>
 #include <asm/leon.h>
 #include <version.h>
+#include <ambapp.h>
+
+/* Default Plug&Play I/O area */
+#ifndef CONFIG_AMBAPP_IOAREA
+#define CONFIG_AMBAPP_IOAREA AMBA_DEFAULT_IOAREA
+#endif
 
 /* Entry for traps which jump to a programmer-specified trap handler.  */
 #define TRAPR(H)  \
@@ -60,6 +63,27 @@
 #error Must define number of SPARC register windows, default is 8
 #endif
 
+/* Macros to load address into a register. Uses GOT table for PIC */
+#ifdef __PIC__
+
+#define SPARC_PIC_THUNK_CALL(reg) \
+	sethi	%pc22(_GLOBAL_OFFSET_TABLE_-4), %##reg; \
+	call	__sparc_get_pc_thunk.reg; \
+	 add	%##reg, %pc10(_GLOBAL_OFFSET_TABLE_+4), %##reg;
+
+#define SPARC_LOAD_ADDRESS(sym, got, reg) \
+	sethi	%gdop_hix22(sym), %##reg; \
+	xor	%##reg, %gdop_lox10(sym), %##reg; \
+	ld	[%##got + %##reg], %##reg, %gdop(sym);
+
+#else
+
+#define SPARC_PIC_THUNK_CALL(reg)
+#define SPARC_LOAD_ADDRESS(sym, got, tmp) \
+	set	sym, %##reg;
+
+#endif
+
 #define STACK_ALIGN	8
 #define SA(X)	(((X)+(STACK_ALIGN-1)) & ~(STACK_ALIGN-1))
 
@@ -190,6 +214,7 @@
 	.ascii U_BOOT_VERSION_STRING, "\0"
 
 	.section	".text"
+	.extern	_nomem_amba_init, _nomem_memory_ctrl_init
 	.align 4
 
 _hardreset:
@@ -232,7 +257,7 @@
 	bge	clear_window
 	save
 
-wininit:
+wiminit:
 	set	WIM_INIT, %g3
 	mov	%g3, %wim
 
@@ -241,9 +266,41 @@
 	andn	%fp, 0x0f, %fp
 	sub	%fp, 64, %sp
 
+/* Obtain the address of _GLOBAL_OFFSET_TABLE_ */
+	SPARC_PIC_THUNK_CALL(l7)
+
+/* Scan AMBA Bus for AMBA buses using PnP information. All found
+ * AMBA buses I/O area will be located in i0-i5 upon return.
+ * The i0-i5 registers are later used by _nomem_amba_init2
+ */
+ambainit:
+	call	_nomem_amba_init
+	 sethi	%hi(CONFIG_AMBAPP_IOAREA), %o0
+
+/* Scan AMBA Buses for memory controllers, then initialize the
+ * memory controllers. Note that before setting up the memory controller
+ * the stack can not be used.
+ */
+memory_ctrl_init:
+	SPARC_LOAD_ADDRESS(grlib_mctrl_handlers, l7, o0)
+
+	call	_nomem_memory_ctrl_init
+	 nop
+
+/* The return valu indicate how many memory controllers where found and
+ * initialized, if no memory controller was initialized, we can not continue
+ * because from here on we expect memory to be working.
+ */
+	cmp	%o0, 0
+memory_ctrl_init_failed:
+	beq	memory_ctrl_init_failed
+	 nop
+
+/*** From now on the stack can be used. ***/
+
 cpu_init_unreloc:
 	call	cpu_init_f
-	nop
+	 nop
 
 /* un relocated start address of monitor */
 #define TEXT_START _text
@@ -252,8 +309,8 @@
 #define DATA_END __init_end
 
 reloc:
-	set	TEXT_START,%g2
-	set	DATA_END,%g3
+	SPARC_LOAD_ADDRESS(TEXT_START, l7, g2)
+	SPARC_LOAD_ADDRESS(DATA_END, l7, g3)
 	set	CONFIG_SYS_RELOC_MONITOR_BASE,%g4
 reloc_loop:
 	ldd	[%g2],%l0
@@ -263,7 +320,7 @@
 	inc	16,%g2
 	subcc	%g3,%g2,%g0
 	bne	reloc_loop
-	inc	16,%g4
+	 inc	16,%g4
 
 	clr	%l0
 	clr	%l1
@@ -280,8 +337,8 @@
 
 clr_bss:
 /* clear bss area (the relocated) */
-	set	__bss_start,%g2
-	set	__bss_end,%g3
+	SPARC_LOAD_ADDRESS(__bss_start, l7, g2)
+	SPARC_LOAD_ADDRESS(__bss_end, l7, g3)
 	sub	%g3,%g2,%g3
 	add	%g3,%g4,%g3
 	clr	%g1	/* std %g0 uses g0 and g1 */
@@ -292,19 +349,19 @@
 	inc	16,%g4
 	cmp	%g3,%g4
 	bne	clr_bss_16
-	nop
+	 nop
 
 /* add offsets to GOT table */
 fixup_got:
-	set	__got_start,%g4
-	set	__got_end,%g3
+	SPARC_LOAD_ADDRESS(__got_start, l7, g4)
+	SPARC_LOAD_ADDRESS(__got_end, l7, g3)
 /*
  * new got offset = (old GOT-PTR (read with ld) -
  *   CONFIG_SYS_RELOC_MONITOR_BASE(from define) ) +
  *   Destination Address (from define)
  */
 	set	CONFIG_SYS_RELOC_MONITOR_BASE,%g2
-	set	TEXT_START, %g1
+	SPARC_LOAD_ADDRESS(TEXT_START, l7, g1)
 	add	%g4,%g2,%g4
 	sub	%g4,%g1,%g4
 	add	%g3,%g2,%g3
@@ -319,11 +376,11 @@
 	inc	4,%g4
 	cmp	%g3,%g4
 	bne	got_loop
-	nop
+	 nop
 
 prom_relocate:
-	set	__prom_start, %g2
-	set	__prom_end, %g3
+	SPARC_LOAD_ADDRESS(__prom_start, l7, g2)
+	SPARC_LOAD_ADDRESS(__prom_end, l7, g3)
 	set	CONFIG_SYS_PROM_OFFSET, %g4
 
 prom_relocate_loop:
@@ -334,7 +391,7 @@
 	inc	16,%g2
 	subcc	%g3,%g2,%g0
 	bne	prom_relocate_loop
-	inc	16,%g4
+	 inc	16,%g4
 
 /* Trap table has been moved, lets tell CPU about
  * the new trap table address
@@ -361,19 +418,20 @@
 	nop
 /* Call relocated init functions */
 jump:
-	set	cpu_init_f2,%o1
+	SPARC_LOAD_ADDRESS(cpu_init_f2, l7, o1)
 	set	CONFIG_SYS_RELOC_MONITOR_BASE,%o2
 	add	%o1,%o2,%o1
 	sub	%o1,%g1,%o1
 	call	%o1
-	clr	%o0
+	 clr	%o0
 
-	set	board_init_f,%o1
+	SPARC_LOAD_ADDRESS(board_init_f, l7, o1)
 	set	CONFIG_SYS_RELOC_MONITOR_BASE,%o2
+	SPARC_LOAD_ADDRESS(TEXT_START, l7, g1)
 	add	%o1,%o2,%o1
 	sub	%o1,%g1,%o1
 	call	%o1
-	clr	%o0
+	 clr	%o0
 
 dead:	ta 0				! if call returns...
 	nop
diff --git a/arch/sparc/cpu/leon3/usb_uhci.c b/arch/sparc/cpu/leon3/usb_uhci.c
index ca7d6e8..1be84c6 100644
--- a/arch/sparc/cpu/leon3/usb_uhci.c
+++ b/arch/sparc/cpu/leon3/usb_uhci.c
@@ -690,11 +690,11 @@
  */
 int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
 {
-	unsigned char temp;
 	ambapp_ahbdev ahbdev;
 
 	/* Find GRUSB core using AMBA Plug&Play information */
-	if (ambapp_ahbslv_first(VENDOR_GAISLER, GAISLER_UHCI, &ahbdev) != 1) {
+	if (ambapp_ahbslv_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_UHCI,
+		CONFIG_SYS_GRLIB_GRUSB_INDEX, &ahbdev) != 1) {
 		printf("USB UHCI: Failed to find GRUSB controller\n");
 		return -1;
 	}
diff --git a/arch/sparc/include/asm/global_data.h b/arch/sparc/include/asm/global_data.h
index 667e7d6..0680a56 100644
--- a/arch/sparc/include/asm/global_data.h
+++ b/arch/sparc/include/asm/global_data.h
@@ -15,6 +15,7 @@
 
 /* Architecture-specific global data */
 struct arch_global_data {
+	void *uart;
 };
 
 #include <asm-generic/global_data.h>
diff --git a/arch/sparc/include/asm/io.h b/arch/sparc/include/asm/io.h
index f7b89c8..a317d13 100644
--- a/arch/sparc/include/asm/io.h
+++ b/arch/sparc/include/asm/io.h
@@ -1,7 +1,7 @@
 /* SPARC I/O definitions
  *
- * (C) Copyright 2007
- * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ * (C) Copyright 2007, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
@@ -12,45 +12,57 @@
 /* Nothing to sync, total store ordering (TSO)... */
 #define sync()
 
+/*
+ * Generic virtual read/write.
+ */
+
+#ifndef CONFIG_SYS_HAS_NO_CACHE
+
 /* Forces a cache miss on read/load.
  * On some architectures we need to bypass the cache when reading
  * I/O registers so that we are not reading the same status word
  * over and over again resulting in a hang (until an IRQ if lucky)
- *
  */
-#ifndef CONFIG_SYS_HAS_NO_CACHE
-#define READ_BYTE(var)  SPARC_NOCACHE_READ_BYTE((unsigned int)(var))
-#define READ_HWORD(var) SPARC_NOCACHE_READ_HWORD((unsigned int)(var))
-#define READ_WORD(var)  SPARC_NOCACHE_READ((unsigned int)(var))
-#define READ_DWORD(var) SPARC_NOCACHE_READ_DWORD((unsigned int)(var))
+
+#define __arch_getb(a)		SPARC_NOCACHE_READ_BYTE((unsigned int)(a))
+#define __arch_getw(a)		SPARC_NOCACHE_READ_HWORD((unsigned int)(a))
+#define __arch_getl(a)		SPARC_NOCACHE_READ((unsigned int)(a))
+#define __arch_getq(a)		SPARC_NOCACHE_READ_DWORD((unsigned int)(a))
+
 #else
-#define READ_BYTE(var)  (var)
-#define READ_HWORD(var) (var)
-#define READ_WORD(var)  (var)
-#define READ_DWORD(var) (var)
-#endif
 
-/*
- * Generic virtual read/write.
- */
-#define __arch_getb(a)			(READ_BYTE(a))
-#define __arch_getw(a)			(READ_HWORD(a))
-#define __arch_getl(a)			(READ_WORD(a))
-#define __arch_getq(a)			(READ_DWORD(a))
+#define __arch_getb(a)		(*(volatile unsigned char *)(a))
+#define __arch_getw(a)		(*(volatile unsigned short *)(a))
+#define __arch_getl(a)		(*(volatile unsigned int *)(a))
+#define __arch_getq(a)		(*(volatile unsigned long long *)(a))
 
-#define __arch_putb(v,a)		(*(volatile unsigned char *)(a) = (v))
-#define __arch_putw(v,a)		(*(volatile unsigned short *)(a) = (v))
-#define __arch_putl(v,a)		(*(volatile unsigned int *)(a) = (v))
+#endif /* CONFIG_SYS_HAS_NO_CACHE */
 
-#define __raw_writeb(v,a)		__arch_putb(v,a)
-#define __raw_writew(v,a)		__arch_putw(v,a)
-#define __raw_writel(v,a)		__arch_putl(v,a)
+#define __arch_putb(v, a)	(*(volatile unsigned char *)(a) = (v))
+#define __arch_putw(v, a)	(*(volatile unsigned short *)(a) = (v))
+#define __arch_putl(v, a)	(*(volatile unsigned int *)(a) = (v))
+#define __arch_putq(v, a)	(*(volatile unsigned long long *)(a) = (v))
+
+#define __raw_writeb(v, a)		__arch_putb(v, a)
+#define __raw_writew(v, a)		__arch_putw(v, a)
+#define __raw_writel(v, a)		__arch_putl(v, a)
+#define __raw_writeq(v, a)		__arch_putq(v, a)
 
 #define __raw_readb(a)			__arch_getb(a)
 #define __raw_readw(a)			__arch_getw(a)
 #define __raw_readl(a)			__arch_getl(a)
 #define __raw_readq(a)			__arch_getq(a)
 
+#define writeb				__raw_writeb
+#define writew				__raw_writew
+#define writel				__raw_writel
+#define writeq				__raw_writeq
+
+#define readb				__raw_readb
+#define readw				__raw_readw
+#define readl				__raw_readl
+#define readq				__raw_readq
+
 /*
  * Given a physical address and a length, return a virtual address
  * that can be used to access the memory range with the caching
diff --git a/arch/sparc/include/asm/winmacro.h b/arch/sparc/include/asm/winmacro.h
index 65e4561..4f68fbd 100644
--- a/arch/sparc/include/asm/winmacro.h
+++ b/arch/sparc/include/asm/winmacro.h
@@ -136,130 +136,3 @@
 	ld	[reg + FW_FSR], %fsr;
 
 #endif
-
-#ifndef __SPARC_WINMACRO_H__
-#define __SPARC_WINMACRO_H__
-
-#include <asm/asmmacro.h>
-#include <asm/stack.h>
-
-/* Store the register window onto the 8-byte aligned area starting
- * at %reg.  It might be %sp, it might not, we don't care.
- */
-#define RW_STORE(reg) \
-	std	%l0, [%reg + RW_L0]; \
-	std	%l2, [%reg + RW_L2]; \
-	std	%l4, [%reg + RW_L4]; \
-	std	%l6, [%reg + RW_L6]; \
-	std	%i0, [%reg + RW_I0]; \
-	std	%i2, [%reg + RW_I2]; \
-	std	%i4, [%reg + RW_I4]; \
-	std	%i6, [%reg + RW_I6];
-
-/* Load a register window from the area beginning at %reg. */
-#define RW_LOAD(reg) \
-	ldd	[%reg + RW_L0], %l0; \
-	ldd	[%reg + RW_L2], %l2; \
-	ldd	[%reg + RW_L4], %l4; \
-	ldd	[%reg + RW_L6], %l6; \
-	ldd	[%reg + RW_I0], %i0; \
-	ldd	[%reg + RW_I2], %i2; \
-	ldd	[%reg + RW_I4], %i4; \
-	ldd	[%reg + RW_I6], %i6;
-
-/* Loading and storing struct pt_reg trap frames. */
-#define PT_LOAD_INS(base_reg) \
-	ldd	[%base_reg + SF_REGS_SZ + PT_I0], %i0; \
-	ldd	[%base_reg + SF_REGS_SZ + PT_I2], %i2; \
-	ldd	[%base_reg + SF_REGS_SZ + PT_I4], %i4; \
-	ldd	[%base_reg + SF_REGS_SZ + PT_I6], %i6;
-
-#define PT_LOAD_GLOBALS(base_reg) \
-	ld	[%base_reg + SF_REGS_SZ + PT_G1], %g1; \
-	ldd	[%base_reg + SF_REGS_SZ + PT_G2], %g2; \
-	ldd	[%base_reg + SF_REGS_SZ + PT_G4], %g4; \
-	ldd	[%base_reg + SF_REGS_SZ + PT_G6], %g6;
-
-#define PT_LOAD_YREG(base_reg, scratch) \
-	ld	[%base_reg + SF_REGS_SZ + PT_Y], %scratch; \
-	wr	%scratch, 0x0, %y;
-
-#define PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
-	ld	[%base_reg + SF_REGS_SZ + PT_PSR], %pt_psr; \
-	ld	[%base_reg + SF_REGS_SZ + PT_PC], %pt_pc; \
-	ld	[%base_reg + SF_REGS_SZ + PT_NPC], %pt_npc;
-
-#define PT_LOAD_ALL(base_reg, pt_psr, pt_pc, pt_npc, scratch) \
-	PT_LOAD_YREG(base_reg, scratch) \
-	PT_LOAD_INS(base_reg) \
-	PT_LOAD_GLOBALS(base_reg) \
-	PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc)
-
-#define PT_STORE_INS(base_reg) \
-	std	%i0, [%base_reg + SF_REGS_SZ + PT_I0]; \
-	std	%i2, [%base_reg + SF_REGS_SZ + PT_I2]; \
-	std	%i4, [%base_reg + SF_REGS_SZ + PT_I4]; \
-	std	%i6, [%base_reg + SF_REGS_SZ + PT_I6];
-
-#define PT_STORE_GLOBALS(base_reg) \
-	st	%g1, [%base_reg + SF_REGS_SZ + PT_G1]; \
-	std	%g2, [%base_reg + SF_REGS_SZ + PT_G2]; \
-	std	%g4, [%base_reg + SF_REGS_SZ + PT_G4]; \
-	std	%g6, [%base_reg + SF_REGS_SZ + PT_G6];
-
-#define PT_STORE_YREG(base_reg, scratch) \
-	rd	%y, %scratch; \
-	st	%scratch, [%base_reg + SF_REGS_SZ + PT_Y];
-
-#define PT_STORE_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
-	st	%pt_psr, [%base_reg + SF_REGS_SZ + PT_PSR]; \
-	st	%pt_pc,  [%base_reg + SF_REGS_SZ + PT_PC]; \
-	st	%pt_npc, [%base_reg + SF_REGS_SZ + PT_NPC];
-
-#define PT_STORE_ALL(base_reg, reg_psr, reg_pc, reg_npc, g_scratch) \
-	PT_STORE_PRIV(base_reg, reg_psr, reg_pc, reg_npc) \
-	PT_STORE_GLOBALS(base_reg) \
-	PT_STORE_YREG(base_reg, g_scratch) \
-	PT_STORE_INS(base_reg)
-
-/* Store the fpu register window*/
-#define FW_STORE(reg) \
-	std	%f0, [reg + FW_F0]; \
-	std	%f2, [reg + FW_F2]; \
-	std	%f4, [reg + FW_F4]; \
-	std	%f6, [reg + FW_F6]; \
-	std	%f8, [reg + FW_F8]; \
-	std	%f10, [reg + FW_F10]; \
-	std	%f12, [reg + FW_F12]; \
-	std	%f14, [reg + FW_F14]; \
-	std	%f16, [reg + FW_F16]; \
-	std	%f18, [reg + FW_F18]; \
-	std	%f20, [reg + FW_F20]; \
-	std	%f22, [reg + FW_F22]; \
-	std	%f24, [reg + FW_F24]; \
-	std	%f26, [reg + FW_F26]; \
-	std	%f28, [reg + FW_F28]; \
-	std	%f30, [reg + FW_F30]; \
-	st	%fsr, [reg + FW_FSR];
-
-/* Load a fpu register window from the area beginning at reg. */
-#define FW_LOAD(reg) \
-	ldd	[reg + FW_F0], %f0; \
-	ldd	[reg + FW_F2], %f2; \
-	ldd	[reg + FW_F4], %f4; \
-	ldd	[reg + FW_F6], %f6; \
-	ldd	[reg + FW_F8], %f8; \
-	ldd	[reg + FW_F10], %f10; \
-	ldd	[reg + FW_F12], %f12; \
-	ldd	[reg + FW_F14], %f14; \
-	ldd	[reg + FW_F16], %f16; \
-	ldd	[reg + FW_F18], %f18; \
-	ldd	[reg + FW_F20], %f20; \
-	ldd	[reg + FW_F22], %f22; \
-	ldd	[reg + FW_F24], %f24; \
-	ldd	[reg + FW_F26], %f26; \
-	ldd	[reg + FW_F28], %f28; \
-	ldd	[reg + FW_F30], %f30; \
-	ld	[reg + FW_FSR], %fsr;
-
-#endif
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index f92082d..8914be3 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -420,6 +420,21 @@
 	  so a default 0x10000000 size covers all of the 256 buses which is the
 	  maximum number of PCI buses as defined by the PCI specification.
 
+config I8259_PIC
+	bool
+	default y
+	help
+	  Intel 8259 ISA compatible chipset incorporates two 8259 (master and
+	  slave) interrupt controllers. Include this to have U-Boot set up
+	  the interrupt correctly.
+
+config I8254_TIMER
+	bool
+	default y
+	help
+	  Intel 8254 timer contains three counters which have fixed uses.
+	  Include this to have U-Boot set up the timer correctly.
+
 source "arch/x86/lib/efi/Kconfig"
 
 endmenu
diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c
index addd26e..b00ddc0 100644
--- a/arch/x86/cpu/interrupts.c
+++ b/arch/x86/cpu/interrupts.c
@@ -252,7 +252,7 @@
 	/* Just in case... */
 	disable_interrupts();
 
-#ifdef CONFIG_SYS_PCAT_INTERRUPTS
+#ifdef CONFIG_I8259_PIC
 	/* Initialize the master/slave i8259 pic */
 	i8259_init();
 #endif
diff --git a/arch/x86/cpu/pci.c b/arch/x86/cpu/pci.c
index d2ec45a..7a31260 100644
--- a/arch/x86/cpu/pci.c
+++ b/arch/x86/cpu/pci.c
@@ -19,51 +19,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-static struct pci_controller x86_hose;
-
-int pci_early_init_hose(struct pci_controller **hosep)
-{
-	struct pci_controller *hose;
-
-	hose = calloc(1, sizeof(struct pci_controller));
-	if (!hose)
-		return -ENOMEM;
-
-	board_pci_setup_hose(hose);
-	pci_setup_type1(hose);
-	hose->last_busno = pci_hose_scan(hose);
-	gd->hose = hose;
-	*hosep = hose;
-
-	return 0;
-}
-
-__weak int board_pci_pre_scan(struct pci_controller *hose)
-{
-	return 0;
-}
-
-__weak int board_pci_post_scan(struct pci_controller *hose)
-{
-	return 0;
-}
-
-void pci_init_board(void)
-{
-	struct pci_controller *hose = &x86_hose;
-
-	/* Stop using the early hose */
-	gd->hose = NULL;
-
-	board_pci_setup_hose(hose);
-	pci_setup_type1(hose);
-	pci_register_hose(hose);
-
-	board_pci_pre_scan(hose);
-	hose->last_busno = pci_hose_scan(hose);
-	board_pci_post_scan(hose);
-}
-
 static struct pci_controller *get_hose(void)
 {
 	if (gd->hose)
diff --git a/arch/x86/cpu/qemu/Makefile b/arch/x86/cpu/qemu/Makefile
index 1c00d1d..3f3958a 100644
--- a/arch/x86/cpu/qemu/Makefile
+++ b/arch/x86/cpu/qemu/Makefile
@@ -9,4 +9,3 @@
 endif
 obj-y += qemu.o
 obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi.o dsdt.o
-obj-$(CONFIG_PCI) += pci.o
diff --git a/arch/x86/cpu/qemu/pci.c b/arch/x86/cpu/qemu/pci.c
deleted file mode 100644
index 2e94456..0000000
--- a/arch/x86/cpu/qemu/pci.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#include <common.h>
-#include <pci.h>
-#include <pci_rom.h>
-#include <asm/pci.h>
-#include <asm/arch/device.h>
-#include <asm/arch/qemu.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-static bool i440fx;
-
-void board_pci_setup_hose(struct pci_controller *hose)
-{
-	hose->first_busno = 0;
-	hose->last_busno = 0;
-
-	/* PCI memory space */
-	pci_set_region(hose->regions + 0,
-		       CONFIG_PCI_MEM_BUS,
-		       CONFIG_PCI_MEM_PHYS,
-		       CONFIG_PCI_MEM_SIZE,
-		       PCI_REGION_MEM);
-
-	/* PCI IO space */
-	pci_set_region(hose->regions + 1,
-		       CONFIG_PCI_IO_BUS,
-		       CONFIG_PCI_IO_PHYS,
-		       CONFIG_PCI_IO_SIZE,
-		       PCI_REGION_IO);
-
-	pci_set_region(hose->regions + 2,
-		       CONFIG_PCI_PREF_BUS,
-		       CONFIG_PCI_PREF_PHYS,
-		       CONFIG_PCI_PREF_SIZE,
-		       PCI_REGION_PREFETCH);
-
-	pci_set_region(hose->regions + 3,
-		       0,
-		       0,
-		       gd->ram_size,
-		       PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
-
-	hose->region_count = 4;
-}
-
-int board_pci_post_scan(struct pci_controller *hose)
-{
-	int ret = 0;
-	u16 device, xbcs;
-	int pam, i;
-	pci_dev_t vga;
-	ulong start;
-
-	/*
-	 * i440FX and Q35 chipset have different PAM register offset, but with
-	 * the same bitfield layout. Here we determine the offset based on its
-	 * PCI device ID.
-	 */
-	device = x86_pci_read_config16(PCI_BDF(0, 0, 0), PCI_DEVICE_ID);
-	i440fx = (device == PCI_DEVICE_ID_INTEL_82441);
-	pam = i440fx ? I440FX_PAM : Q35_PAM;
-
-	/*
-	 * Initialize Programmable Attribute Map (PAM) Registers
-	 *
-	 * Configure legacy segments C/D/E/F to system RAM
-	 */
-	for (i = 0; i < PAM_NUM; i++)
-		x86_pci_write_config8(PCI_BDF(0, 0, 0), pam + i, PAM_RW);
-
-	if (i440fx) {
-		/*
-		 * Enable legacy IDE I/O ports decode
-		 *
-		 * Note: QEMU always decode legacy IDE I/O port on PIIX chipset.
-		 * However Linux ata_piix driver does sanity check on these two
-		 * registers to see whether legacy ports decode is turned on.
-		 * This is to make Linux ata_piix driver happy.
-		 */
-		x86_pci_write_config16(PIIX_IDE, IDE0_TIM, IDE_DECODE_EN);
-		x86_pci_write_config16(PIIX_IDE, IDE1_TIM, IDE_DECODE_EN);
-
-		/* Enable I/O APIC */
-		xbcs = x86_pci_read_config16(PIIX_ISA, XBCS);
-		xbcs |= APIC_EN;
-		x86_pci_write_config16(PIIX_ISA, XBCS, xbcs);
-	} else {
-		/* Configure PCIe ECAM base address */
-		x86_pci_write_config32(PCI_BDF(0, 0, 0), PCIEX_BAR,
-				       CONFIG_PCIE_ECAM_BASE | BAR_EN);
-	}
-
-	/*
-	 * QEMU emulated graphic card shows in the PCI configuration space with
-	 * PCI vendor id and device id as an artificial pair 0x1234:0x1111.
-	 * It is on PCI bus 0, function 0, but device number is not consistent
-	 * for the two x86 targets it supports. For i440FX and PIIX chipset
-	 * board, it shows as device 2, while for Q35 and ICH9 chipset board,
-	 * it shows as device 1.
-	 */
-	vga = i440fx ? I440FX_VGA : Q35_VGA;
-	start = get_timer(0);
-	ret = pci_run_vga_bios(vga, NULL, PCI_ROM_USE_NATIVE);
-	debug("BIOS ran in %lums\n", get_timer(start));
-
-	return ret;
-}
-
-#ifdef CONFIG_GENERATE_MP_TABLE
-int mp_determine_pci_dstirq(int bus, int dev, int func, int pirq)
-{
-	u8 irq;
-
-	if (i440fx) {
-		/*
-		 * Not like most x86 platforms, the PIRQ[A-D] on PIIX3 are not
-		 * connected to I/O APIC INTPIN#16-19. Instead they are routed
-		 * to an irq number controled by the PIRQ routing register.
-		 */
-		irq = x86_pci_read_config8(PCI_BDF(bus, dev, func),
-					   PCI_INTERRUPT_LINE);
-	} else {
-		/*
-		 * ICH9's PIRQ[A-H] are not consecutive numbers from 0 to 7.
-		 * PIRQ[A-D] still maps to [0-3] but PIRQ[E-H] maps to [8-11].
-		 */
-		irq = pirq < 8 ? pirq + 16 : pirq + 12;
-	}
-
-	return irq;
-}
-#endif
diff --git a/arch/x86/cpu/qemu/qemu.c b/arch/x86/cpu/qemu/qemu.c
index 7c03e02..84fb082 100644
--- a/arch/x86/cpu/qemu/qemu.c
+++ b/arch/x86/cpu/qemu/qemu.c
@@ -6,8 +6,58 @@
 
 #include <common.h>
 #include <asm/irq.h>
+#include <asm/pci.h>
 #include <asm/post.h>
 #include <asm/processor.h>
+#include <asm/arch/device.h>
+#include <asm/arch/qemu.h>
+
+static bool i440fx;
+
+static void qemu_chipset_init(void)
+{
+	u16 device, xbcs;
+	int pam, i;
+
+	/*
+	 * i440FX and Q35 chipset have different PAM register offset, but with
+	 * the same bitfield layout. Here we determine the offset based on its
+	 * PCI device ID.
+	 */
+	device = x86_pci_read_config16(PCI_BDF(0, 0, 0), PCI_DEVICE_ID);
+	i440fx = (device == PCI_DEVICE_ID_INTEL_82441);
+	pam = i440fx ? I440FX_PAM : Q35_PAM;
+
+	/*
+	 * Initialize Programmable Attribute Map (PAM) Registers
+	 *
+	 * Configure legacy segments C/D/E/F to system RAM
+	 */
+	for (i = 0; i < PAM_NUM; i++)
+		x86_pci_write_config8(PCI_BDF(0, 0, 0), pam + i, PAM_RW);
+
+	if (i440fx) {
+		/*
+		 * Enable legacy IDE I/O ports decode
+		 *
+		 * Note: QEMU always decode legacy IDE I/O port on PIIX chipset.
+		 * However Linux ata_piix driver does sanity check on these two
+		 * registers to see whether legacy ports decode is turned on.
+		 * This is to make Linux ata_piix driver happy.
+		 */
+		x86_pci_write_config16(PIIX_IDE, IDE0_TIM, IDE_DECODE_EN);
+		x86_pci_write_config16(PIIX_IDE, IDE1_TIM, IDE_DECODE_EN);
+
+		/* Enable I/O APIC */
+		xbcs = x86_pci_read_config16(PIIX_ISA, XBCS);
+		xbcs |= APIC_EN;
+		x86_pci_write_config16(PIIX_ISA, XBCS, xbcs);
+	} else {
+		/* Configure PCIe ECAM base address */
+		x86_pci_write_config32(PCI_BDF(0, 0, 0), PCIEX_BAR,
+				       CONFIG_PCIE_ECAM_BASE | BAR_EN);
+	}
+}
 
 int arch_cpu_init(void)
 {
@@ -39,7 +89,39 @@
 	x86_full_reset();
 }
 
+int arch_early_init_r(void)
+{
+	qemu_chipset_init();
+
+	return 0;
+}
+
 int arch_misc_init(void)
 {
 	return pirq_init();
 }
+
+#ifdef CONFIG_GENERATE_MP_TABLE
+int mp_determine_pci_dstirq(int bus, int dev, int func, int pirq)
+{
+	u8 irq;
+
+	if (i440fx) {
+		/*
+		 * Not like most x86 platforms, the PIRQ[A-D] on PIIX3 are not
+		 * connected to I/O APIC INTPIN#16-19. Instead they are routed
+		 * to an irq number controled by the PIRQ routing register.
+		 */
+		irq = x86_pci_read_config8(PCI_BDF(bus, dev, func),
+					   PCI_INTERRUPT_LINE);
+	} else {
+		/*
+		 * ICH9's PIRQ[A-H] are not consecutive numbers from 0 to 7.
+		 * PIRQ[A-D] still maps to [0-3] but PIRQ[E-H] maps to [8-11].
+		 */
+		irq = pirq < 8 ? pirq + 16 : pirq + 12;
+	}
+
+	return irq;
+}
+#endif
diff --git a/arch/x86/cpu/queensbay/tnc.c b/arch/x86/cpu/queensbay/tnc.c
index 0c02a44..933d189 100644
--- a/arch/x86/cpu/queensbay/tnc.c
+++ b/arch/x86/cpu/queensbay/tnc.c
@@ -25,12 +25,26 @@
 
 static void __maybe_unused disable_igd(void)
 {
-	u32 gc;
-
-	gc = x86_pci_read_config32(TNC_IGD, IGD_GC);
-	gc &= ~GMS_MASK;
-	gc |= VGA_DISABLE;
-	x86_pci_write_config32(TNC_IGD, IGD_GC, gc);
+	/*
+	 * According to Atom E6xx datasheet, setting VGA Disable (bit17)
+	 * of Graphics Controller register (offset 0x50) prevents IGD
+	 * (D2:F0) from reporting itself as a VGA display controller
+	 * class in the PCI configuration space, and should also prevent
+	 * it from responding to VGA legacy memory range and I/O addresses.
+	 *
+	 * However test result shows that with just VGA Disable bit set and
+	 * a PCIe graphics card connected to one of the PCIe controllers on
+	 * the E6xx, accessing the VGA legacy space still causes system hang.
+	 * After a number of attempts, it turns out besides VGA Disable bit,
+	 * the SDVO (D3:F0) device should be disabled to make it work.
+	 *
+	 * To simplify, use the Function Disable register (offset 0xc4)
+	 * to disable both IGD (D2:F0) and SDVO (D3:F0) devices. Now these
+	 * two devices will be completely disabled (invisible in the PCI
+	 * configuration space) unless a system reset is performed.
+	 */
+	x86_pci_write_config32(TNC_IGD, IGD_FD, FUNC_DISABLE);
+	x86_pci_write_config32(TNC_SDVO, IGD_FD, FUNC_DISABLE);
 }
 
 int arch_cpu_init(void)
diff --git a/arch/x86/include/asm/arch-queensbay/tnc.h b/arch/x86/include/asm/arch-queensbay/tnc.h
index 2365394..8477d92 100644
--- a/arch/x86/include/asm/arch-queensbay/tnc.h
+++ b/arch/x86/include/asm/arch-queensbay/tnc.h
@@ -7,10 +7,9 @@
 #ifndef _X86_ARCH_TNC_H_
 #define _X86_ARCH_TNC_H_
 
-/* IGD Control Register */
-#define IGD_GC		0x50
-#define VGA_DISABLE	0x00020000
-#define GMS_MASK	0x00700000
+/* IGD Function Disable Register */
+#define IGD_FD		0xc4
+#define FUNC_DISABLE	0x00000001
 
 /* Memory BAR Enable */
 #define MEM_BAR_EN	0x00000001
diff --git a/arch/x86/include/asm/i8254.h b/arch/x86/include/asm/i8254.h
index 4116de1..48e4df2 100644
--- a/arch/x86/include/asm/i8254.h
+++ b/arch/x86/include/asm/i8254.h
@@ -5,38 +5,35 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
-
 /* i8254.h Intel 8254 PIT registers */
 
-
 #ifndef _ASMI386_I8254_H_
-#define _ASMI386_I8954_H_       1
+#define _ASMI386_I8954_H_
 
-
-#define PIT_T0		0x00		/* PIT channel 0 count/status */
-#define PIT_T1		0x01		/* PIT channel 1 count/status */
-#define PIT_T2		0x02		/* PIT channel 2 count/status */
-#define PIT_COMMAND	0x03		/* PIT mode control, latch and read back */
+#define PIT_T0		0x00	/* PIT channel 0 count/status */
+#define PIT_T1		0x01	/* PIT channel 1 count/status */
+#define PIT_T2		0x02	/* PIT channel 2 count/status */
+#define PIT_COMMAND	0x03	/* PIT mode control, latch and read back */
 
 /* PIT Command Register Bit Definitions */
 
-#define PIT_CMD_CTR0	0x00		/* Select PIT counter 0 */
-#define PIT_CMD_CTR1	0x40		/* Select PIT counter 1 */
-#define PIT_CMD_CTR2	0x80		/* Select PIT counter 2 */
+#define PIT_CMD_CTR0	0x00	/* Select PIT counter 0 */
+#define PIT_CMD_CTR1	0x40	/* Select PIT counter 1 */
+#define PIT_CMD_CTR2	0x80	/* Select PIT counter 2 */
 
-#define PIT_CMD_LATCH	0x00		/* Counter Latch Command */
-#define PIT_CMD_LOW	0x10		/* Access counter bits 7-0 */
-#define PIT_CMD_HIGH	0x20		/* Access counter bits 15-8 */
-#define PIT_CMD_BOTH	0x30		/* Access counter bits 15-0 in two accesses */
+#define PIT_CMD_LATCH	0x00	/* Counter Latch Command */
+#define PIT_CMD_LOW	0x10	/* Access counter bits 7-0 */
+#define PIT_CMD_HIGH	0x20	/* Access counter bits 15-8 */
+#define PIT_CMD_BOTH	0x30	/* Access counter bits 15-0 in two accesses */
 
-#define PIT_CMD_MODE0	0x00		/* Select mode 0 */
-#define PIT_CMD_MODE1	0x02		/* Select mode 1 */
-#define PIT_CMD_MODE2	0x04		/* Select mode 2 */
-#define PIT_CMD_MODE3	0x06		/* Select mode 3 */
-#define PIT_CMD_MODE4	0x08		/* Select mode 4 */
-#define PIT_CMD_MODE5	0x0A		/* Select mode 5 */
+#define PIT_CMD_MODE0	0x00	/* Select mode 0 */
+#define PIT_CMD_MODE1	0x02	/* Select mode 1 */
+#define PIT_CMD_MODE2	0x04	/* Select mode 2 */
+#define PIT_CMD_MODE3	0x06	/* Select mode 3 */
+#define PIT_CMD_MODE4	0x08	/* Select mode 4 */
+#define PIT_CMD_MODE5	0x0a	/* Select mode 5 */
 
 /* The clock frequency of the i8253/i8254 PIT */
-#define PIT_TICK_RATE	1193182ul
+#define PIT_TICK_RATE	1193182
 
-#endif
+#endif /* _ASMI386_I8954_H_ */
diff --git a/arch/x86/include/asm/i8259.h b/arch/x86/include/asm/i8259.h
index bc4033b..f216c23 100644
--- a/arch/x86/include/asm/i8259.h
+++ b/arch/x86/include/asm/i8259.h
@@ -8,11 +8,9 @@
 /* i8259.h i8259 PIC Registers */
 
 #ifndef _ASMI386_I8259_H_
-#define _ASMI386_I8959_H_       1
-
+#define _ASMI386_I8959_H_
 
 /* PIC I/O mapped registers */
-
 #define IRR		0x0	/* Interrupt Request Register */
 #define ISR		0x0	/* In-Service Register */
 #define ICW1		0x0	/* Initialization Control Word 1 */
@@ -23,7 +21,7 @@
 #define ICW4		0x1	/* Initialization Control Word 4 */
 #define IMR		0x1	/* Interrupt Mask Register */
 
-/* bits for IRR, IMR, ISR and ICW3 */
+/* IRR, IMR, ISR and ICW3 bits */
 #define	IR7		0x80	/* IR7 */
 #define	IR6		0x40	/* IR6 */
 #define	IR5		0x20	/* IR5 */
@@ -33,7 +31,7 @@
 #define	IR1		0x02	/* IR1 */
 #define	IR0		0x01	/* IR0 */
 
-/* bits for SEOI */
+/* SEOI bits */
 #define	SEOI_IR7	0x07	/* IR7 */
 #define	SEOI_IR6	0x06	/* IR6 */
 #define	SEOI_IR5	0x05	/* IR5 */
@@ -49,9 +47,9 @@
 #define OCW2_NOP	0x40	/* NOP */
 #define OCW2_SEOI	0x60	/* Specific EOI */
 #define OCW2_RSET	0x80	/* Rotate/set */
-#define OCW2_REOI	0xA0	/* Rotate on non specific EOI */
-#define OCW2_PSET	0xC0	/* Priority Set Command */
-#define OCW2_RSEOI	0xE0	/* Rotate on specific EOI */
+#define OCW2_REOI	0xa0	/* Rotate on non specific EOI */
+#define OCW2_PSET	0xc0	/* Priority Set Command */
+#define OCW2_RSEOI	0xe0	/* Rotate on specific EOI */
 
 /* ICW1 bits */
 #define ICW1_SEL	0x10	/* Select ICW1 */
@@ -60,15 +58,20 @@
 #define ICW1_SNGL	0x02	/* Single PIC */
 #define ICW1_EICW4	0x01	/* Expect initilization ICW4 */
 
-/* ICW2 is the starting vector number */
-
-/* ICW2 is bit-mask of present slaves for a master device,
- * or the slave ID for a slave device */
+/*
+ * ICW2 is the starting vector number
+ *
+ * ICW2 is bit-mask of present slaves for a master device,
+ * or the slave ID for a slave device
+ */
 
 /* ICW4 bits */
-#define	ICW4_AEOI	0x02	/* Automatic EOI Mode */
+#define ICW4_AEOI	0x02	/* Automatic EOI Mode */
 #define ICW4_PM		0x01	/* Microprocessor Mode */
 
+#define ELCR1		0x4d0
+#define ELCR2		0x4d1
+
 int i8259_init(void);
 
-#endif
+#endif /* _ASMI386_I8959_H_ */
diff --git a/arch/x86/include/asm/interrupt.h b/arch/x86/include/asm/interrupt.h
index fcd766b..95a4de0 100644
--- a/arch/x86/include/asm/interrupt.h
+++ b/arch/x86/include/asm/interrupt.h
@@ -13,6 +13,8 @@
 
 #include <asm/types.h>
 
+#define SYS_NUM_IRQS	16
+
 /* Architecture defined exceptions */
 enum x86_exception {
 	EXC_DE = 0,
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index f7e968e..a2945f1 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -25,27 +25,6 @@
 
 void pci_setup_type1(struct pci_controller *hose);
 
-/**
- * board_pci_setup_hose() - Set up the PCI hose
- *
- * This is called by the common x86 PCI code to set up the PCI controller
- * hose. It may be called when no memory/BSS is available so should just
- * store things in 'hose' and not in BSS variables.
- */
-void board_pci_setup_hose(struct pci_controller *hose);
-
-/**
- * pci_early_init_hose() - Set up PCI host before relocation
- *
- * This allocates memory for, sets up and returns the PCI hose. It can be
- * called before relocation. The hose will be stored in gd->hose for
- * later use, but will become invalid one DRAM is available.
- */
-int pci_early_init_hose(struct pci_controller **hosep);
-
-int board_pci_pre_scan(struct pci_controller *hose);
-int board_pci_post_scan(struct pci_controller *hose);
-
 /*
  * Simple PCI access routines - these work from either the early PCI hose
  * or the 'real' one, created after U-Boot has memory available
diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h
index 1c459d5..dbf8e95 100644
--- a/arch/x86/include/asm/u-boot-x86.h
+++ b/arch/x86/include/asm/u-boot-x86.h
@@ -29,7 +29,7 @@
 int register_timer_isr (timer_fnc_t *isr_func);
 unsigned long get_tbclk_mhz(void);
 void timer_set_base(uint64_t base);
-int pcat_timer_init(void);
+int i8254_init(void);
 
 /* cpu/.../interrupts.c */
 int cpu_init_interrupts(void);
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 2f82a21..d676e2c 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -19,8 +19,8 @@
 obj-y	+= mpspec.o
 obj-$(CONFIG_ENABLE_MRC_CACHE) += mrccache.o
 obj-y += cmd_mtrr.o
-obj-$(CONFIG_SYS_PCAT_INTERRUPTS) += pcat_interrupts.o
-obj-$(CONFIG_SYS_PCAT_TIMER) += pcat_timer.o
+obj-$(CONFIG_I8259_PIC) += i8259.o
+obj-$(CONFIG_I8254_TIMER) += i8254.o
 ifndef CONFIG_DM_PCI
 obj-$(CONFIG_PCI) += pci_type1.o
 endif
diff --git a/arch/x86/lib/fsp/fsp_common.c b/arch/x86/lib/fsp/fsp_common.c
index c78df94..5276ce6 100644
--- a/arch/x86/lib/fsp/fsp_common.c
+++ b/arch/x86/lib/fsp/fsp_common.c
@@ -35,11 +35,6 @@
 	return status ? -EPERM : 0;
 }
 
-int board_pci_post_scan(struct pci_controller *hose)
-{
-	return fsp_init_phase_pci();
-}
-
 void board_final_cleanup(void)
 {
 	u32 status;
diff --git a/arch/x86/lib/i8254.c b/arch/x86/lib/i8254.c
new file mode 100644
index 0000000..46a4245
--- /dev/null
+++ b/arch/x86/lib/i8254.c
@@ -0,0 +1,37 @@
+/*
+ * (C) Copyright 2002
+ * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/i8254.h>
+
+#define TIMER1_VALUE	18	/* 15.6us */
+#define TIMER2_VALUE	0x0a8e	/* 440Hz */
+
+int i8254_init(void)
+{
+	/*
+	 * Initialize counter 1, used to refresh request signal.
+	 * This is required for legacy purpose as some codes like
+	 * vgabios utilizes counter 1 to provide delay functionality.
+	 */
+	outb(PIT_CMD_CTR1 | PIT_CMD_LOW | PIT_CMD_MODE2,
+	     PIT_BASE + PIT_COMMAND);
+	outb(TIMER1_VALUE, PIT_BASE + PIT_T1);
+
+	/*
+	 * Initialize counter 2, used to drive the speaker.
+	 * To start a beep, set both bit0 and bit1 of port 0x61.
+	 * To stop it, clear both bit0 and bit1 of port 0x61.
+	 */
+	outb(PIT_CMD_CTR2 | PIT_CMD_BOTH | PIT_CMD_MODE3,
+	     PIT_BASE + PIT_COMMAND);
+	outb(TIMER2_VALUE & 0xff, PIT_BASE + PIT_T2);
+	outb(TIMER2_VALUE >> 8, PIT_BASE + PIT_T2);
+
+	return 0;
+}
diff --git a/arch/x86/lib/pcat_interrupts.c b/arch/x86/lib/i8259.c
similarity index 70%
rename from arch/x86/lib/pcat_interrupts.c
rename to arch/x86/lib/i8259.c
index a9af87e..b9d0614 100644
--- a/arch/x86/lib/pcat_interrupts.c
+++ b/arch/x86/lib/i8259.c
@@ -20,10 +20,6 @@
 #include <asm/ibmpc.h>
 #include <asm/interrupt.h>
 
-#if CONFIG_SYS_NUM_IRQS != 16
-#error "CONFIG_SYS_NUM_IRQS must equal 16 if CONFIG_SYS_NUM_IRQS is defined"
-#endif
-
 int i8259_init(void)
 {
 	u8 i;
@@ -32,10 +28,11 @@
 	outb(0xff, MASTER_PIC + IMR);
 	outb(0xff, SLAVE_PIC + IMR);
 
-	/* Master PIC */
-	/* Place master PIC interrupts at INT20 */
-	/* ICW3, One slave PIC is present */
-	outb(ICW1_SEL|ICW1_EICW4, MASTER_PIC + ICW1);
+	/*
+	 * Master PIC
+	 * Place master PIC interrupts at INT20
+	 */
+	outb(ICW1_SEL | ICW1_EICW4, MASTER_PIC + ICW1);
 	outb(0x20, MASTER_PIC + ICW2);
 	outb(IR2, MASTER_PIC + ICW3);
 	outb(ICW4_PM, MASTER_PIC + ICW4);
@@ -43,10 +40,11 @@
 	for (i = 0; i < 8; i++)
 		outb(OCW2_SEOI | i, MASTER_PIC + OCW2);
 
-	/* Slave PIC */
-	/* Place slave PIC interrupts at INT28 */
-	/* Slave ID */
-	outb(ICW1_SEL|ICW1_EICW4, SLAVE_PIC + ICW1);
+	/*
+	 * Slave PIC
+	 * Place slave PIC interrupts at INT28
+	 */
+	outb(ICW1_SEL | ICW1_EICW4, SLAVE_PIC + ICW1);
 	outb(0x28, SLAVE_PIC + ICW2);
 	outb(0x02, SLAVE_PIC + ICW3);
 	outb(ICW4_PM, SLAVE_PIC + ICW4);
@@ -70,7 +68,7 @@
 {
 	int imr_port;
 
-	if (irq >= CONFIG_SYS_NUM_IRQS)
+	if (irq >= SYS_NUM_IRQS)
 		return;
 
 	if (irq > 7)
@@ -85,7 +83,7 @@
 {
 	int imr_port;
 
-	if (irq >= CONFIG_SYS_NUM_IRQS)
+	if (irq >= SYS_NUM_IRQS)
 		return;
 
 	if (irq > 7)
@@ -98,7 +96,7 @@
 
 void specific_eoi(int irq)
 {
-	if (irq >= CONFIG_SYS_NUM_IRQS)
+	if (irq >= SYS_NUM_IRQS)
 		return;
 
 	if (irq > 7) {
@@ -114,9 +112,6 @@
 	outb(OCW2_SEOI | irq, MASTER_PIC + OCW2);
 }
 
-#define ELCR1			0x4d0
-#define ELCR2			0x4d1
-
 void configure_irq_trigger(int int_num, bool is_level_triggered)
 {
 	u16 int_bits = inb(ELCR1) | (((u16)inb(ELCR2)) << 8);
@@ -131,20 +126,4 @@
 	debug("%s: try to set interrupts 0x%x\n", __func__, int_bits);
 	outb((u8)(int_bits & 0xff), ELCR1);
 	outb((u8)(int_bits >> 8), ELCR2);
-
-#ifdef PARANOID_IRQ_TRIGGERS
-	/*
-	 * Try reading back the new values. This seems like an error but is
-	 * not
-	 */
-	if (inb(ELCR1) != (int_bits & 0xff)) {
-		printf("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
-		       __func__, (int_bits & 0xff), inb(ELCR1));
-	}
-
-	if (inb(ELCR2) != (int_bits >> 8)) {
-		printf("%s: higher order bits are wrong: want 0x%x, got 0x%x\n",
-		       __func__, (int_bits>>8), inb(ELCR2));
-	}
-#endif
 }
diff --git a/arch/x86/lib/interrupts.c b/arch/x86/lib/interrupts.c
index 146ad11..dd08402 100644
--- a/arch/x86/lib/interrupts.c
+++ b/arch/x86/lib/interrupts.c
@@ -39,7 +39,7 @@
 	unsigned int count;
 };
 
-static struct irq_action irq_handlers[CONFIG_SYS_NUM_IRQS] = { {0} };
+static struct irq_action irq_handlers[SYS_NUM_IRQS] = { {0} };
 static int spurious_irq_cnt;
 static int spurious_irq;
 
@@ -47,7 +47,7 @@
 {
 	int status;
 
-	if (irq < 0 || irq >= CONFIG_SYS_NUM_IRQS) {
+	if (irq < 0 || irq >= SYS_NUM_IRQS) {
 		printf("irq_install_handler: bad irq number %d\n", irq);
 		return;
 	}
@@ -75,7 +75,7 @@
 {
 	int status;
 
-	if (irq < 0 || irq >= CONFIG_SYS_NUM_IRQS) {
+	if (irq < 0 || irq >= SYS_NUM_IRQS) {
 		printf("irq_free_handler: bad irq number %d\n", irq);
 		return;
 	}
@@ -97,7 +97,7 @@
 {
 	int irq = hw_irq - 0x20;
 
-	if (irq < 0 || irq >= CONFIG_SYS_NUM_IRQS) {
+	if (irq < 0 || irq >= SYS_NUM_IRQS) {
 		printf("do_irq: bad irq number %d\n", irq);
 		return;
 	}
@@ -130,7 +130,7 @@
 	printf("Interrupt-Information:\n");
 	printf("Nr  Routine   Arg       Count\n");
 
-	for (irq = 0; irq < CONFIG_SYS_NUM_IRQS; irq++) {
+	for (irq = 0; irq < SYS_NUM_IRQS; irq++) {
 		if (irq_handlers[irq].handler != NULL) {
 			printf("%02d  %08lx  %08lx  %d\n",
 					irq,
diff --git a/arch/x86/lib/pcat_timer.c b/arch/x86/lib/pcat_timer.c
deleted file mode 100644
index 3545a50..0000000
--- a/arch/x86/lib/pcat_timer.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * (C) Copyright 2002
- * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se>
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#include <common.h>
-#include <asm/io.h>
-#include <asm/i8254.h>
-
-#define TIMER2_VALUE 0x0a8e /* 440Hz */
-
-int pcat_timer_init(void)
-{
-	/*
-	 * initialize 2, used to drive the speaker
-	 * (to start a beep: write 3 to port 0x61,
-	 * to stop it again: write 0)
-	 */
-	outb(PIT_CMD_CTR2 | PIT_CMD_BOTH | PIT_CMD_MODE3,
-			PIT_BASE + PIT_COMMAND);
-	outb(TIMER2_VALUE & 0xff, PIT_BASE + PIT_T2);
-	outb(TIMER2_VALUE >> 8, PIT_BASE + PIT_T2);
-
-	return 0;
-}
diff --git a/arch/x86/lib/tsc_timer.c b/arch/x86/lib/tsc_timer.c
index 0df1af2..e02b918 100644
--- a/arch/x86/lib/tsc_timer.c
+++ b/arch/x86/lib/tsc_timer.c
@@ -368,9 +368,9 @@
 
 int timer_init(void)
 {
-#ifdef CONFIG_SYS_PCAT_TIMER
-	/* Set up the PCAT timer if required */
-	pcat_timer_init();
+#ifdef CONFIG_I8254_TIMER
+	/* Set up the i8254 timer if required */
+	i8254_init();
 #endif
 
 	return 0;
diff --git a/board/BuR/kwb/board.c b/board/BuR/kwb/board.c
index 039ec20..ad74ff2 100644
--- a/board/BuR/kwb/board.c
+++ b/board/BuR/kwb/board.c
@@ -47,10 +47,6 @@
 #define	RSTCTRL_FORCE_PWR_NEN			0x0404
 #define	RSTCTRL_CAN_STB				0x4040
 
-#define VXWORKS_BOOTLINE			0x80001100
-#define DEFAULT_BOOTLINE	"cpsw(0,0):pme/vxWorks"
-#define VXWORKS_USER		"u=vxWorksFTP pw=vxWorks tn=vxtarget"
-
 DECLARE_GLOBAL_DATA_PTR;
 
 #if defined(CONFIG_SPL_BUILD)
@@ -281,20 +277,15 @@
 	} else {
 		puts("ERROR: i2c_set_bus_speed failed! (scratchregister)\n");
 	}
-	/* setup vxworks bootline */
-	char *vxworksbootline = (char *)VXWORKS_BOOTLINE;
-	sprintf(vxworksbootline,
-		"%s h=%s e=%s:%s g=%s %s o=0x%08x;0x%08x;0x%08x;0x%08x",
-		DEFAULT_BOOTLINE,
-		getenv("serverip"),
-		getenv("ipaddr"), getenv("netmask"),
-		getenv("gatewayip"),
-		VXWORKS_USER,
-		(unsigned int) gd->fb_base-0x20,
-		(u32)getenv_ulong("vx_memtop", 16, gd->fb_base-0x20),
-		(u32)getenv_ulong("vx_romfsbase", 16, 0),
-		(u32)getenv_ulong("vx_romfssize", 16, 0));
-
+	/* setup othbootargs for bootvx-command (vxWorks bootline) */
+	char othbootargs[128];
+	snprintf(othbootargs, sizeof(othbootargs),
+		 "u=vxWorksFTP pw=vxWorks o=0x%08x;0x%08x;0x%08x;0x%08x",
+		 (unsigned int) gd->fb_base-0x20,
+		 (u32)getenv_ulong("vx_memtop", 16, gd->fb_base-0x20),
+		 (u32)getenv_ulong("vx_romfsbase", 16, 0),
+		 (u32)getenv_ulong("vx_romfssize", 16, 0));
+	setenv("othbootargs", othbootargs);
 	/*
 	 * reset VBAR registers to its reset location, VxWorks 6.9.3.2 does
 	 * expect that vectors are there, original u-boot moves them to _start
diff --git a/board/emulation/qemu-x86/Makefile b/board/emulation/qemu-x86/Makefile
index ad2bbb9..a855255 100644
--- a/board/emulation/qemu-x86/Makefile
+++ b/board/emulation/qemu-x86/Makefile
@@ -4,4 +4,4 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
-obj-y	+= qemu-x86.o start.o
+obj-y	+= start.o
diff --git a/board/emulation/qemu-x86/qemu-x86.c b/board/emulation/qemu-x86/qemu-x86.c
deleted file mode 100644
index fedea81..0000000
--- a/board/emulation/qemu-x86/qemu-x86.c
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#include <common.h>
-#include <netdev.h>
-
-int board_eth_init(bd_t *bis)
-{
-	return pci_eth_init(bis);
-}
diff --git a/board/gdsys/405ep/dlvision-10g.c b/board/gdsys/405ep/dlvision-10g.c
index 35dfbbc..54c7eb3 100644
--- a/board/gdsys/405ep/dlvision-10g.c
+++ b/board/gdsys/405ep/dlvision-10g.c
@@ -25,17 +25,19 @@
 #define LATCH2_MC2_PRESENT_N 0x0080
 
 enum {
-	UNITTYPE_VIDEO_USER = 0,
-	UNITTYPE_MAIN_USER = 1,
-	UNITTYPE_VIDEO_SERVER = 2,
-	UNITTYPE_MAIN_SERVER = 3,
+	UNITTYPE_MAIN = 1<<0,
+	UNITTYPE_SERVER = 1<<1,
+	UNITTYPE_DISPLAYPORT = 1<<2,
 };
 
 enum {
 	HWVER_101 = 0,
 	HWVER_110 = 1,
-	HWVER_120 = 2,
-	HWVER_130 = 3,
+	HWVER_130 = 2,
+	HWVER_140 = 3,
+	HWVER_150 = 4,
+	HWVER_160 = 5,
+	HWVER_170 = 6,
 };
 
 enum {
@@ -121,27 +123,20 @@
 	feature_carriers = (fpga_features >> 2) & 0x0003;
 	feature_video_channels = fpga_features & 0x0003;
 
-	switch (unit_type) {
-	case UNITTYPE_VIDEO_USER:
-		printf("Videochannel Userside");
-		break;
+	if (unit_type & UNITTYPE_MAIN)
+		printf("Mainchannel ");
+	else
+		printf("Videochannel ");
 
-	case UNITTYPE_MAIN_USER:
-		printf("Mainchannel Userside");
-		break;
+	if (unit_type & UNITTYPE_SERVER)
+		printf("Serverside ");
+	else
+		printf("Userside ");
 
-	case UNITTYPE_VIDEO_SERVER:
-		printf("Videochannel Serverside");
-		break;
-
-	case UNITTYPE_MAIN_SERVER:
-		printf("Mainchannel Serverside");
-		break;
-
-	default:
-		printf("UnitType %d(not supported)", unit_type);
-		break;
-	}
+	if (unit_type & UNITTYPE_DISPLAYPORT)
+		printf("DisplayPort");
+	else
+		printf("DVI-DL");
 
 	switch (hardware_version) {
 	case HWVER_101:
@@ -149,17 +144,29 @@
 		break;
 
 	case HWVER_110:
-		printf(" HW-Ver 1.10-1.12\n");
-		break;
-
-	case HWVER_120:
-		printf(" HW-Ver 1.20\n");
+		printf(" HW-Ver 1.10-1.20\n");
 		break;
 
 	case HWVER_130:
 		printf(" HW-Ver 1.30\n");
 		break;
 
+	case HWVER_140:
+		printf(" HW-Ver 1.40-1.43\n");
+		break;
+
+	case HWVER_150:
+		printf(" HW-Ver 1.50\n");
+		break;
+
+	case HWVER_160:
+		printf(" HW-Ver 1.60-1.61\n");
+		break;
+
+	case HWVER_170:
+		printf(" HW-Ver 1.70\n");
+		break;
+
 	default:
 		printf(" HW-Ver %d(not supported)\n",
 		       hardware_version);
@@ -260,7 +267,7 @@
 	if (get_mc2_present())
 		print_fpga_info(1);
 
-	if (((versions >> 4) & 0x000f) != UNITTYPE_MAIN_USER)
+	if (((versions >> 4) & 0x000f) & UNITTYPE_SERVER)
 		return 0;
 
 	if (!get_fpga_state(0) || (get_hwver() == HWVER_101))
diff --git a/board/gdsys/405ep/iocon.c b/board/gdsys/405ep/iocon.c
index 3a51d86..7484624 100644
--- a/board/gdsys/405ep/iocon.c
+++ b/board/gdsys/405ep/iocon.c
@@ -381,7 +381,7 @@
 		ch0_rgmii2_present = !pca9698_get_value(0x20, 30);
 	}
 
-	/* wait for FPGA done */
+	/* wait for FPGA done; then reset FPGA */
 	for (k = 0; k < ARRAY_SIZE(mclink_controllers); ++k) {
 		unsigned int ctr = 0;
 
@@ -396,6 +396,12 @@
 				break;
 			}
 		}
+
+		pca953x_set_dir(mclink_controllers[k], MCFPGA_RESET_N, 0);
+		pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N, 0);
+		udelay(10);
+		pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N,
+				MCFPGA_RESET_N);
 	}
 
 	if (!legacy && (feature_carrier_speed == CARRIER_SPEED_1G)) {
diff --git a/board/gdsys/common/Makefile b/board/gdsys/common/Makefile
index 4957943..ce23045 100644
--- a/board/gdsys/common/Makefile
+++ b/board/gdsys/common/Makefile
@@ -9,7 +9,10 @@
 obj-$(CONFIG_CMD_IOLOOP) += cmd_ioloop.o
 obj-$(CONFIG_IO) += miiphybb.o
 obj-$(CONFIG_IO64) += miiphybb.o
-obj-$(CONFIG_IOCON) += osd.o mclink.o dp501.o phy.o
-obj-$(CONFIG_DLVISION_10G) += osd.o
+obj-$(CONFIG_IOCON) += osd.o mclink.o dp501.o phy.o ch7301.o
+obj-$(CONFIG_DLVISION_10G) += osd.o dp501.o
 obj-$(CONFIG_CONTROLCENTERD) += dp501.o
-obj-$(CONFIG_HRCON) += osd.o mclink.o dp501.o phy.o
+obj-$(CONFIG_HRCON) += osd.o mclink.o dp501.o phy.o ioep-fpga.o fanctrl.o
+obj-$(CONFIG_STRIDER) += mclink.o dp501.o phy.o ioep-fpga.o adv7611.o ch7301.o
+obj-$(CONFIG_STRIDER) += fanctrl.o
+obj-$(CONFIG_STRIDER_CON) += osd.o
diff --git a/board/gdsys/common/adv7611.c b/board/gdsys/common/adv7611.c
new file mode 100644
index 0000000..b728274
--- /dev/null
+++ b/board/gdsys/common/adv7611.c
@@ -0,0 +1,177 @@
+/*
+ * (C) Copyright 2014
+ * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <i2c.h>
+
+#define ADV7611_I2C_ADDR 0x4c
+#define ADV7611_RDINFO 0x2051
+
+/*
+ * ADV7611 I2C Addresses in u-boot notation
+ */
+enum {
+	CP_I2C_ADDR = 0x22,
+	DPLL_I2C_ADDR = 0x26,
+	KSV_I2C_ADDR = 0x32,
+	HDMI_I2C_ADDR = 0x34,
+	EDID_I2C_ADDR = 0x36,
+	INFOFRAME_I2C_ADDR = 0x3e,
+	CEC_I2C_ADDR = 0x40,
+	IO_I2C_ADDR = ADV7611_I2C_ADDR,
+};
+
+/*
+ * Global Control Registers
+ */
+enum {
+	IO_RD_INFO_MSB = 0xea,
+	IO_RD_INFO_LSB = 0xeb,
+	IO_CEC_ADDR = 0xf4,
+	IO_INFOFRAME_ADDR = 0xf5,
+	IO_DPLL_ADDR = 0xf8,
+	IO_KSV_ADDR = 0xf9,
+	IO_EDID_ADDR = 0xfa,
+	IO_HDMI_ADDR = 0xfb,
+	IO_CP_ADDR = 0xfd,
+};
+
+int adv7611_i2c[] = CONFIG_SYS_ADV7611_I2C;
+
+int adv7611_probe(unsigned int screen)
+{
+	int old_bus = i2c_get_bus_num();
+	unsigned int rd_info;
+	int res = 0;
+
+	i2c_set_bus_num(adv7611_i2c[screen]);
+
+	rd_info = (i2c_reg_read(IO_I2C_ADDR, IO_RD_INFO_MSB) << 8)
+		  | i2c_reg_read(IO_I2C_ADDR, IO_RD_INFO_LSB);
+
+	if (rd_info != ADV7611_RDINFO) {
+		res = -1;
+		goto out;
+	}
+
+	/*
+	 * set I2C addresses to default values
+	 */
+	i2c_reg_write(IO_I2C_ADDR, IO_CEC_ADDR, CEC_I2C_ADDR << 1);
+	i2c_reg_write(IO_I2C_ADDR, IO_INFOFRAME_ADDR, INFOFRAME_I2C_ADDR << 1);
+	i2c_reg_write(IO_I2C_ADDR, IO_DPLL_ADDR, DPLL_I2C_ADDR << 1);
+	i2c_reg_write(IO_I2C_ADDR, IO_KSV_ADDR, KSV_I2C_ADDR << 1);
+	i2c_reg_write(IO_I2C_ADDR, IO_EDID_ADDR, EDID_I2C_ADDR << 1);
+	i2c_reg_write(IO_I2C_ADDR, IO_HDMI_ADDR, HDMI_I2C_ADDR << 1);
+	i2c_reg_write(IO_I2C_ADDR, IO_CP_ADDR, CP_I2C_ADDR << 1);
+
+	/*
+	 * do magic initialization sequence from
+	 * "ADV7611 Register Settings Recommendations Revision 1.5"
+	 * with most registers undocumented
+	 */
+	i2c_reg_write(CP_I2C_ADDR, 0x6c, 0x00);
+	i2c_reg_write(HDMI_I2C_ADDR, 0x9b, 0x03);
+	i2c_reg_write(HDMI_I2C_ADDR, 0x6f, 0x08);
+	i2c_reg_write(HDMI_I2C_ADDR, 0x85, 0x1f);
+	i2c_reg_write(HDMI_I2C_ADDR, 0x87, 0x70);
+	i2c_reg_write(HDMI_I2C_ADDR, 0x57, 0xda);
+	i2c_reg_write(HDMI_I2C_ADDR, 0x58, 0x01);
+	i2c_reg_write(HDMI_I2C_ADDR, 0x03, 0x98);
+	i2c_reg_write(HDMI_I2C_ADDR, 0x4c, 0x44);
+
+	/*
+	 * IO_REG_02, default 0xf0
+	 *
+	 * INP_COLOR_SPACE (IO, Address 0x02[7:4])
+	 * default: 0b1111 auto
+	 * set to : 0b0001 force RGB (range 0 to 255) input
+	 *
+	 * RGB_OUT (IO, Address 0x02[1])
+	 * default: 0 YPbPr color space output
+	 * set to : 1 RGB color space output
+	 */
+	i2c_reg_write(IO_I2C_ADDR, 0x02, 0x12);
+
+	/*
+	 * IO_REG_03, default 0x00
+	 *
+	 * OP_FORMAT_SEL (IO, Address 0x03[7:0])
+	 * default: 0x00 8-bit SDR ITU-656 mode
+	 * set to : 0x40 24-bit 4:4:4 SDR mode
+	 */
+	i2c_reg_write(IO_I2C_ADDR, 0x03, 0x40);
+
+	/*
+	 * IO_REG_05, default 0x2c
+	 *
+	 * AVCODE_INSERT_EN (IO, Address 0x05[2])
+	 * default: 1 insert AV codes into data stream
+	 * set to : 0 do not insert AV codes into data stream
+	 */
+	i2c_reg_write(IO_I2C_ADDR, 0x05, 0x28);
+
+	/*
+	 * IO_REG_0C, default 0x62
+	 *
+	 * POWER_DOWN (IO, Address 0x0C[5])
+	 * default: 1 chip is powered down
+	 * set to : 0 chip is operational
+	 */
+	i2c_reg_write(IO_I2C_ADDR, 0x0c, 0x42);
+
+	/*
+	 * IO_REG_15, default 0xbe
+	 *
+	 * TRI_SYNCS (IO, Address 0x15[3)
+	 * TRI_LLC (IO, Address 0x15[2])
+	 * TRI_PIX (IO, Address 0x15[1])
+	 * default: 1 video output pins are tristate
+	 * set to : 0 video output pins are active
+	 */
+	i2c_reg_write(IO_I2C_ADDR, 0x15, 0xb0);
+
+	/*
+	 * HDMI_REGISTER_02H, default 0xff
+	 *
+	 * CLOCK_TERMA_DISABLE (HDMI, Address 0x83[0])
+	 * default: 1 disable termination
+	 * set to : 0 enable termination
+	 * Future options are:
+	 * - use the chips automatic termination control
+	 * - set this manually on cable detect
+	 * but at the moment this seems a safe default.
+	 */
+	i2c_reg_write(HDMI_I2C_ADDR, 0x83, 0xfe);
+
+	/*
+	 * HDMI_CP_CNTRL_1, default 0x01
+	 *
+	 * HDMI_FRUN_EN (CP, Address 0xBA[0])
+	 * default: 1 Enable the free run feature in HDMI mode
+	 * set to : 0 Disable the free run feature in HDMI mode
+	 */
+	i2c_reg_write(CP_I2C_ADDR, 0xba, 0x00);
+
+	/*
+	 * INT1_CONFIGURATION, default 0x20
+	 *
+	 * INTRQ_DUR_SEL[1:0] (IO, Address 0x40[7:6])
+	 * default: 00 Interrupt signal is active for 4 Xtal periods
+	 * set to : 11 Active until cleared
+	 *
+	 * INTRQ_OP_SEL[1:0] (IO, Address 0x40[1:0])
+	 * default: 00 Open drain
+	 * set to : 10 Drives high when active
+	 */
+	i2c_reg_write(IO_I2C_ADDR, 0x40, 0xc2);
+
+out:
+	i2c_set_bus_num(old_bus);
+
+	return res;
+}
diff --git a/board/gdsys/common/adv7611.h b/board/gdsys/common/adv7611.h
new file mode 100644
index 0000000..25a8367
--- /dev/null
+++ b/board/gdsys/common/adv7611.h
@@ -0,0 +1,13 @@
+/*
+ * (C) Copyright 2014
+ * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _ADV7611_H_
+#define _ADV7611_H_
+
+int adv7611_probe(unsigned int screen);
+
+#endif
diff --git a/board/gdsys/common/ch7301.c b/board/gdsys/common/ch7301.c
new file mode 100644
index 0000000..c054e55
--- /dev/null
+++ b/board/gdsys/common/ch7301.c
@@ -0,0 +1,64 @@
+/*
+ * (C) Copyright 2014
+ * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/* Chrontel CH7301C DVI Transmitter */
+
+#include <common.h>
+#include <asm/io.h>
+#include <errno.h>
+#include <i2c.h>
+
+#define CH7301_I2C_ADDR 0x75
+
+enum {
+	CH7301_CM = 0x1c,		/* Clock Mode Register */
+	CH7301_IC = 0x1d,		/* Input Clock Register */
+	CH7301_GPIO = 0x1e,		/* GPIO Control Register */
+	CH7301_IDF = 0x1f,		/* Input Data Format Register */
+	CH7301_CD = 0x20,		/* Connection Detect Register */
+	CH7301_DC = 0x21,		/* DAC Control Register */
+	CH7301_HPD = 0x23,		/* Hot Plug Detection Register */
+	CH7301_TCTL = 0x31,		/* DVI Control Input Register */
+	CH7301_TPCP = 0x33,		/* DVI PLL Charge Pump Ctrl Register */
+	CH7301_TPD = 0x34,		/* DVI PLL Divide Register */
+	CH7301_TPVT = 0x35,		/* DVI PLL Supply Control Register */
+	CH7301_TPF = 0x36,		/* DVI PLL Filter Register */
+	CH7301_TCT = 0x37,		/* DVI Clock Test Register */
+	CH7301_TSTP = 0x48,		/* Test Pattern Register */
+	CH7301_PM = 0x49,		/* Power Management register */
+	CH7301_VID = 0x4a,		/* Version ID Register */
+	CH7301_DID = 0x4b,		/* Device ID Register */
+	CH7301_DSP = 0x56,		/* DVI Sync polarity Register */
+};
+
+int ch7301_i2c[] = CONFIG_SYS_CH7301_I2C;
+
+int ch7301_probe(unsigned screen, bool power)
+{
+	u8 value;
+
+	i2c_set_bus_num(ch7301_i2c[screen]);
+	if (i2c_probe(CH7301_I2C_ADDR))
+		return -1;
+
+	value = i2c_reg_read(CH7301_I2C_ADDR, CH7301_DID);
+	if (value != 0x17)
+		return -1;
+
+	if (power) {
+		i2c_reg_write(CH7301_I2C_ADDR, CH7301_TPCP, 0x08);
+		i2c_reg_write(CH7301_I2C_ADDR, CH7301_TPD, 0x16);
+		i2c_reg_write(CH7301_I2C_ADDR, CH7301_TPF, 0x60);
+		i2c_reg_write(CH7301_I2C_ADDR, CH7301_DC, 0x09);
+		i2c_reg_write(CH7301_I2C_ADDR, CH7301_PM, 0xc0);
+	} else {
+		i2c_reg_write(CH7301_I2C_ADDR, CH7301_DC, 0x00);
+		i2c_reg_write(CH7301_I2C_ADDR, CH7301_PM, 0x01);
+	}
+
+	return 0;
+}
diff --git a/board/gdsys/common/ch7301.h b/board/gdsys/common/ch7301.h
new file mode 100644
index 0000000..8383719
--- /dev/null
+++ b/board/gdsys/common/ch7301.h
@@ -0,0 +1,13 @@
+/*
+ * (C) Copyright 2014
+ * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _CH7301_H_
+#define _CH7301_H_
+
+int ch7301_probe(unsigned screen, bool power);
+
+#endif
diff --git a/board/gdsys/common/dp501.c b/board/gdsys/common/dp501.c
index 7eb15ed..d35aee0 100644
--- a/board/gdsys/common/dp501.c
+++ b/board/gdsys/common/dp501.c
@@ -40,11 +40,29 @@
 static void dp501_link_training(u8 addr)
 {
 	u8 val;
+	u8 link_bw;
+	u8 max_lane_cnt;
+	u8 lane_cnt;
 
 	val = i2c_reg_read(addr, 0x51);
-	i2c_reg_write(addr, 0x5d, val); /* set link_bw */
+	if (val >= 0x0a)
+		link_bw = 0x0a;
+	else
+		link_bw = 0x06;
+	if (link_bw != val)
+		printf("DP sink supports %d Mbps link rate, set to %d Mbps\n",
+		       val * 270, link_bw * 270);
+	i2c_reg_write(addr, 0x5d, link_bw); /* set link_bw */
 	val = i2c_reg_read(addr, 0x52);
-	i2c_reg_write(addr, 0x5e, val); /* set lane_cnt */
+	max_lane_cnt = val & 0x1f;
+	if (max_lane_cnt >= 4)
+		lane_cnt = 4;
+	else
+		lane_cnt = max_lane_cnt;
+	if (lane_cnt != max_lane_cnt)
+		printf("DP sink supports %d lanes, set to %d lanes\n",
+		       max_lane_cnt, lane_cnt);
+	i2c_reg_write(addr, 0x5e, lane_cnt | (val & 0x80)); /* set lane_cnt */
 	val = i2c_reg_read(addr, 0x53);
 	i2c_reg_write(addr, 0x5c, val); /* set downspread_ctl */
 
@@ -77,6 +95,8 @@
 	i2c_reg_write(addr + 2, 0x24, 0x02); /* clock input single ended */
 #endif
 
+	i2c_reg_write(addr + 2, 0x1a, 0x04); /* SPDIF input method TTL */
+
 	i2c_reg_write(addr + 2, 0x00, 0x18); /* driving strength */
 	i2c_reg_write(addr + 2, 0x03, 0x06); /* driving strength */
 	i2c_reg_write(addr, 0x2c, 0x00); /* configure N value */
@@ -86,7 +106,8 @@
 	dp501_setbits(addr, 0x78, 0x03); /* clear all interrupt */
 	i2c_reg_write(addr, 0x75, 0xf8); /* aux channel reset */
 	i2c_reg_write(addr, 0x75, 0x00); /* clear aux channel reset */
-	i2c_reg_write(addr, 0x87, 0x70); /* set retry counter as 7 */
+	i2c_reg_write(addr, 0x87, 0x7f); /* set retry counter as 7
+					    retry interval 400us */
 
 	if (dp501_detect_cable_adapter(addr)) {
 		printf("DVI/HDMI cable adapter detected\n");
diff --git a/board/gdsys/common/fanctrl.c b/board/gdsys/common/fanctrl.c
new file mode 100644
index 0000000..44569bb
--- /dev/null
+++ b/board/gdsys/common/fanctrl.c
@@ -0,0 +1,32 @@
+/*
+ * (C) Copyright 2015
+ * Dirk Eibach,  Guntermann & Drunck GmbH, eibach@gdsys.de
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <i2c.h>
+
+enum {
+	FAN_CONFIG = 0x03,
+	FAN_TACHLIM_LSB = 0x48,
+	FAN_TACHLIM_MSB = 0x49,
+	FAN_PWM_FREQ = 0x4D,
+};
+
+void init_fan_controller(u8 addr)
+{
+	int val;
+
+	/* set PWM Frequency to 2.5% resolution */
+	i2c_reg_write(addr, FAN_PWM_FREQ, 20);
+
+	/* set Tachometer Limit */
+	i2c_reg_write(addr, FAN_TACHLIM_LSB, 0x10);
+	i2c_reg_write(addr, FAN_TACHLIM_MSB, 0x0a);
+
+	/* enable Tach input */
+	val = i2c_reg_read(addr, FAN_CONFIG) | 0x04;
+	i2c_reg_write(addr, FAN_CONFIG, val);
+}
diff --git a/board/gdsys/common/fanctrl.h b/board/gdsys/common/fanctrl.h
new file mode 100644
index 0000000..12bc850
--- /dev/null
+++ b/board/gdsys/common/fanctrl.h
@@ -0,0 +1,13 @@
+/*
+ * (C) Copyright 2015
+ * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _FANCTRL_H_
+#define _FANCTRL_H_
+
+void init_fan_controller(u8 addr);
+
+#endif
diff --git a/board/gdsys/common/ioep-fpga.c b/board/gdsys/common/ioep-fpga.c
new file mode 100644
index 0000000..96f02d6
--- /dev/null
+++ b/board/gdsys/common/ioep-fpga.c
@@ -0,0 +1,232 @@
+/*
+ * (C) Copyright 2014
+ * Dirk Eibach,  Guntermann & Drunck GmbH, eibach@gdsys.de
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+
+#include <gdsys_fpga.h>
+
+enum {
+	UNITTYPE_MAIN_SERVER = 0,
+	UNITTYPE_MAIN_USER = 1,
+	UNITTYPE_VIDEO_SERVER = 2,
+	UNITTYPE_VIDEO_USER = 3,
+};
+
+enum {
+	UNITTYPEPCB_DVI = 0,
+	UNITTYPEPCB_DP_165 = 1,
+	UNITTYPEPCB_DP_300 = 2,
+	UNITTYPEPCB_HDMI = 3,
+};
+
+enum {
+	COMPRESSION_NONE = 0,
+	COMPRESSION_TYPE1_DELTA = 1,
+	COMPRESSION_TYPE1_TYPE2_DELTA = 3,
+};
+
+enum {
+	AUDIO_NONE = 0,
+	AUDIO_TX = 1,
+	AUDIO_RX = 2,
+	AUDIO_RXTX = 3,
+};
+
+enum {
+	SYSCLK_147456 = 0,
+};
+
+enum {
+	RAM_DDR2_32 = 0,
+	RAM_DDR3_32 = 1,
+	RAM_DDR3_48 = 2,
+};
+
+enum {
+	CARRIER_SPEED_1G = 0,
+	CARRIER_SPEED_2_5G = 1,
+};
+
+bool ioep_fpga_has_osd(unsigned int fpga)
+{
+	u16 fpga_features;
+	unsigned feature_osd;
+
+	FPGA_GET_REG(0, fpga_features, &fpga_features);
+	feature_osd = fpga_features & (1<<11);
+
+	return feature_osd;
+}
+
+void ioep_fpga_print_info(unsigned int fpga)
+{
+	u16 versions;
+	u16 fpga_version;
+	u16 fpga_features;
+	unsigned unit_type;
+	unsigned unit_type_pcb_video;
+	unsigned feature_compression;
+	unsigned feature_osd;
+	unsigned feature_audio;
+	unsigned feature_sysclock;
+	unsigned feature_ramconfig;
+	unsigned feature_carrier_speed;
+	unsigned feature_carriers;
+	unsigned feature_video_channels;
+
+	FPGA_GET_REG(fpga, versions, &versions);
+	FPGA_GET_REG(fpga, fpga_version, &fpga_version);
+	FPGA_GET_REG(fpga, fpga_features, &fpga_features);
+
+	unit_type = (versions & 0xf000) >> 12;
+	unit_type_pcb_video = (versions & 0x01c0) >> 6;
+	feature_compression = (fpga_features & 0xe000) >> 13;
+	feature_osd = fpga_features & (1<<11);
+	feature_audio = (fpga_features & 0x0600) >> 9;
+	feature_sysclock = (fpga_features & 0x0180) >> 7;
+	feature_ramconfig = (fpga_features & 0x0060) >> 5;
+	feature_carrier_speed = fpga_features & (1<<4);
+	feature_carriers = (fpga_features & 0x000c) >> 2;
+	feature_video_channels = fpga_features & 0x0003;
+
+	switch (unit_type) {
+	case UNITTYPE_MAIN_SERVER:
+	case UNITTYPE_MAIN_USER:
+		printf("Mainchannel");
+		break;
+
+	case UNITTYPE_VIDEO_SERVER:
+	case UNITTYPE_VIDEO_USER:
+		printf("Videochannel");
+		break;
+
+	default:
+		printf("UnitType %d(not supported)", unit_type);
+		break;
+	}
+
+	switch (unit_type) {
+	case UNITTYPE_MAIN_SERVER:
+	case UNITTYPE_VIDEO_SERVER:
+		printf(" Server");
+		if (versions & (1<<4))
+			printf(" UC");
+		break;
+
+	case UNITTYPE_MAIN_USER:
+	case UNITTYPE_VIDEO_USER:
+		printf(" User");
+		break;
+
+	default:
+		break;
+	}
+
+	if (versions & (1<<5))
+		printf(" Fiber");
+	else
+		printf(" CAT");
+
+	switch (unit_type_pcb_video) {
+	case UNITTYPEPCB_DVI:
+		printf(" DVI,");
+		break;
+
+	case UNITTYPEPCB_DP_165:
+		printf(" DP 165MPix/s,");
+		break;
+
+	case UNITTYPEPCB_DP_300:
+		printf(" DP 300MPix/s,");
+		break;
+
+	case UNITTYPEPCB_HDMI:
+		printf(" HDMI,");
+		break;
+	}
+
+	printf(" FPGA V %d.%02d\n       features:",
+	       fpga_version / 100, fpga_version % 100);
+
+
+	switch (feature_compression) {
+	case COMPRESSION_NONE:
+		printf(" no compression");
+		break;
+
+	case COMPRESSION_TYPE1_DELTA:
+		printf(" type1-deltacompression");
+		break;
+
+	case COMPRESSION_TYPE1_TYPE2_DELTA:
+		printf(" type1-deltacompression, type2-inlinecompression");
+		break;
+
+	default:
+		printf(" compression %d(not supported)", feature_compression);
+		break;
+	}
+
+	printf(", %sosd", feature_osd ? "" : "no ");
+
+	switch (feature_audio) {
+	case AUDIO_NONE:
+		printf(", no audio");
+		break;
+
+	case AUDIO_TX:
+		printf(", audio tx");
+		break;
+
+	case AUDIO_RX:
+		printf(", audio rx");
+		break;
+
+	case AUDIO_RXTX:
+		printf(", audio rx+tx");
+		break;
+
+	default:
+		printf(", audio %d(not supported)", feature_audio);
+		break;
+	}
+
+	puts(",\n       ");
+
+	switch (feature_sysclock) {
+	case SYSCLK_147456:
+		printf("clock 147.456 MHz");
+		break;
+
+	default:
+		printf("clock %d(not supported)", feature_sysclock);
+		break;
+	}
+
+	switch (feature_ramconfig) {
+	case RAM_DDR2_32:
+		printf(", RAM 32 bit DDR2");
+		break;
+
+	case RAM_DDR3_32:
+		printf(", RAM 32 bit DDR3");
+		break;
+
+	case RAM_DDR3_48:
+		printf(", RAM 48 bit DDR3");
+		break;
+
+	default:
+		printf(", RAM %d(not supported)", feature_ramconfig);
+		break;
+	}
+
+	printf(", %d carrier(s) %s", feature_carriers,
+	       feature_carrier_speed ? "2.5Gbit/s" : "1Gbit/s");
+
+	printf(", %d video channel(s)\n", feature_video_channels);
+}
diff --git a/board/gdsys/common/ioep-fpga.h b/board/gdsys/common/ioep-fpga.h
new file mode 100644
index 0000000..44f7139
--- /dev/null
+++ b/board/gdsys/common/ioep-fpga.h
@@ -0,0 +1,14 @@
+/*
+ * (C) Copyright 2014
+ * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _IOEP_FPGA_H_
+#define _IOEP_FPGA_H_
+
+void ioep_fpga_print_info(unsigned int fpga);
+bool ioep_fpga_has_osd(unsigned int fpga);
+
+#endif
diff --git a/board/gdsys/common/osd.c b/board/gdsys/common/osd.c
index 55ecdf1..7444bee 100644
--- a/board/gdsys/common/osd.c
+++ b/board/gdsys/common/osd.c
@@ -9,11 +9,10 @@
 #include <i2c.h>
 #include <malloc.h>
 
+#include "ch7301.h"
 #include "dp501.h"
 #include <gdsys_fpga.h>
 
-#define CH7301_I2C_ADDR 0x75
-
 #define ICS8N3QV01_I2C_ADDR 0x6E
 #define ICS8N3QV01_FREF 114285000
 #define ICS8N3QV01_FREF_LL 114285000LL
@@ -28,43 +27,53 @@
 #define DP501_I2C_ADDR 0x08
 
 #define PIXCLK_640_480_60 25180000
+#define MAX_X_CHARS 53
+#define MAX_Y_CHARS 26
 
-enum {
-	CH7301_CM = 0x1c,		/* Clock Mode Register */
-	CH7301_IC = 0x1d,		/* Input Clock Register */
-	CH7301_GPIO = 0x1e,		/* GPIO Control Register */
-	CH7301_IDF = 0x1f,		/* Input Data Format Register */
-	CH7301_CD = 0x20,		/* Connection Detect Register */
-	CH7301_DC = 0x21,		/* DAC Control Register */
-	CH7301_HPD = 0x23,		/* Hot Plug Detection Register */
-	CH7301_TCTL = 0x31,		/* DVI Control Input Register */
-	CH7301_TPCP = 0x33,		/* DVI PLL Charge Pump Ctrl Register */
-	CH7301_TPD = 0x34,		/* DVI PLL Divide Register */
-	CH7301_TPVT = 0x35,		/* DVI PLL Supply Control Register */
-	CH7301_TPF = 0x36,		/* DVI PLL Filter Register */
-	CH7301_TCT = 0x37,		/* DVI Clock Test Register */
-	CH7301_TSTP = 0x48,		/* Test Pattern Register */
-	CH7301_PM = 0x49,		/* Power Management register */
-	CH7301_VID = 0x4a,		/* Version ID Register */
-	CH7301_DID = 0x4b,		/* Device ID Register */
-	CH7301_DSP = 0x56,		/* DVI Sync polarity Register */
-};
+#ifdef CONFIG_SYS_OSD_DH
+#define MAX_OSD_SCREEN 8
+#define OSD_DH_BASE 4
+#else
+#define MAX_OSD_SCREEN 4
+#endif
+
+#ifdef CONFIG_SYS_OSD_DH
+#define OSD_SET_REG(screen, fld, val) \
+	do { \
+		if (screen >= OSD_DH_BASE) \
+			FPGA_SET_REG(screen - OSD_DH_BASE, osd1.fld, val); \
+		else \
+			FPGA_SET_REG(screen, osd0.fld, val); \
+	} while (0)
+#else
+#define OSD_SET_REG(screen, fld, val) \
+		FPGA_SET_REG(screen, osd0.fld, val)
+#endif
+
+#ifdef CONFIG_SYS_OSD_DH
+#define OSD_GET_REG(screen, fld, val) \
+	do {					\
+		if (screen >= OSD_DH_BASE) \
+			FPGA_GET_REG(screen - OSD_DH_BASE, osd1.fld, val); \
+		else \
+			FPGA_GET_REG(screen, osd0.fld, val); \
+	} while (0)
+#else
+#define OSD_GET_REG(screen, fld, val) \
+		FPGA_GET_REG(screen, osd0.fld, val)
+#endif
 
 unsigned int base_width;
 unsigned int base_height;
 size_t bufsize;
 u16 *buf;
 
-unsigned int max_osd_screen = CONFIG_SYS_OSD_SCREENS - 1;
+unsigned int osd_screen_mask = 0;
 
 #ifdef CONFIG_SYS_ICS8N3QV01_I2C
 int ics8n3qv01_i2c[] = CONFIG_SYS_ICS8N3QV01_I2C;
 #endif
 
-#ifdef CONFIG_SYS_CH7301_I2C
-int ch7301_i2c[] = CONFIG_SYS_CH7301_I2C;
-#endif
-
 #ifdef CONFIG_SYS_SIL1178_I2C
 int sil1178_i2c[] = CONFIG_SYS_SIL1178_I2C;
 #endif
@@ -73,6 +82,9 @@
 int dp501_i2c[] = CONFIG_SYS_DP501_I2C;
 #endif
 
+#ifdef CONFIG_SYS_DP501_BASE
+int dp501_base[] = CONFIG_SYS_DP501_BASE;
+#endif
 
 #ifdef CONFIG_SYS_MPC92469AC
 static void mpc92469ac_calc_parameters(unsigned int fout,
@@ -242,7 +254,15 @@
 	for (k = 0; k < charcount; ++k) {
 		if (offset + k >= bufsize)
 			return -1;
-		FPGA_SET_REG(screen, videomem[offset + k], data[k]);
+#ifdef CONFIG_SYS_OSD_DH
+		if (screen >= OSD_DH_BASE)
+			FPGA_SET_REG(screen - OSD_DH_BASE,
+				     videomem1[offset + k], data[k]);
+		else
+			FPGA_SET_REG(screen, videomem0[offset + k], data[k]);
+#else
+		FPGA_SET_REG(screen, videomem0[offset + k], data[k]);
+#endif
 	}
 
 	return charcount;
@@ -252,7 +272,12 @@
 {
 	unsigned screen;
 
-	for (screen = 0; screen <= max_osd_screen; ++screen) {
+	if (argc < 5) {
+		cmd_usage(cmdtp);
+		return 1;
+	}
+
+	for (screen = 0; screen < MAX_OSD_SCREEN; ++screen) {
 		unsigned x;
 		unsigned y;
 		unsigned charcount;
@@ -262,10 +287,8 @@
 		char *text;
 		int res;
 
-		if (argc < 5) {
-			cmd_usage(cmdtp);
-			return 1;
-		}
+		if (!(osd_screen_mask & (1 << screen)))
+			continue;
 
 		x = simple_strtoul(argv[1], NULL, 16);
 		y = simple_strtoul(argv[2], NULL, 16);
@@ -280,6 +303,8 @@
 		res = osd_write_videomem(screen, y * base_width + x, buf, len);
 		if (res < 0)
 			return res;
+
+		OSD_SET_REG(screen, control, 0x0049);
 	}
 
 	return 0;
@@ -292,9 +317,16 @@
 	int old_bus = i2c_get_bus_num();
 	bool pixclock_present = false;
 	bool output_driver_present = false;
+#ifdef CONFIG_SYS_DP501_I2C
+#ifdef CONFIG_SYS_DP501_BASE
+	uint8_t dp501_addr = dp501_base[screen];
+#else
+	uint8_t dp501_addr = DP501_I2C_ADDR;
+#endif
+#endif
 
-	FPGA_GET_REG(0, osd.version, &version);
-	FPGA_GET_REG(0, osd.features, &features);
+	OSD_GET_REG(0, version, &version);
+	OSD_GET_REG(0, features, &features);
 
 	base_width = ((features & 0x3f00) >> 8) + 1;
 	base_height = (features & 0x001f) + 1;
@@ -303,9 +335,15 @@
 	if (!buf)
 		return -1;
 
+#ifdef CONFIG_SYS_OSD_DH
+	printf("OSD%d-%d: Digital-OSD version %01d.%02d, %d" "x%d characters\n",
+	       (screen >= OSD_DH_BASE) ? (screen - OSD_DH_BASE) : screen,
+	       (screen > 3) ? 1 : 0, version/100, version%100, base_width,
+	       base_height);
+#else
 	printf("OSD%d:  Digital-OSD version %01d.%02d, %d" "x%d characters\n",
-		screen, version/100, version%100, base_width, base_height);
-
+	       screen, version/100, version%100, base_width, base_height);
+#endif
 	/* setup pixclock */
 
 #ifdef CONFIG_SYS_MPC92469AC
@@ -327,19 +365,8 @@
 	/* setup output driver */
 
 #ifdef CONFIG_SYS_CH7301_I2C
-	i2c_set_bus_num(ch7301_i2c[screen]);
-	if (!i2c_probe(CH7301_I2C_ADDR)) {
-		u8 value = i2c_reg_read(CH7301_I2C_ADDR, CH7301_DID);
-
-		if (value == 0x17) {
-			i2c_reg_write(CH7301_I2C_ADDR, CH7301_TPCP, 0x08);
-			i2c_reg_write(CH7301_I2C_ADDR, CH7301_TPD, 0x16);
-			i2c_reg_write(CH7301_I2C_ADDR, CH7301_TPF, 0x60);
-			i2c_reg_write(CH7301_I2C_ADDR, CH7301_DC, 0x09);
-			i2c_reg_write(CH7301_I2C_ADDR, CH7301_PM, 0xc0);
-			output_driver_present = true;
-		}
-	}
+	if (!ch7301_probe(screen, true))
+		output_driver_present = true;
 #endif
 
 #ifdef CONFIG_SYS_SIL1178_I2C
@@ -367,8 +394,8 @@
 
 #ifdef CONFIG_SYS_DP501_I2C
 	i2c_set_bus_num(dp501_i2c[screen]);
-	if (!i2c_probe(DP501_I2C_ADDR)) {
-		dp501_powerup(DP501_I2C_ADDR);
+	if (!i2c_probe(dp501_addr)) {
+		dp501_powerup(dp501_addr);
 		output_driver_present = true;
 	}
 #endif
@@ -376,14 +403,12 @@
 	if (!output_driver_present)
 		printf("       no output driver found\n");
 
-	FPGA_SET_REG(screen, osd.control, 0x0049);
+	OSD_SET_REG(screen, xy_size, ((32 - 1) << 8) | (16 - 1));
+	OSD_SET_REG(screen, x_pos, 0x007f);
+	OSD_SET_REG(screen, y_pos, 0x005f);
 
-	FPGA_SET_REG(screen, osd.xy_size, ((32 - 1) << 8) | (16 - 1));
-	FPGA_SET_REG(screen, osd.x_pos, 0x007f);
-	FPGA_SET_REG(screen, osd.y_pos, 0x005f);
-
-	if (screen > max_osd_screen)
-		max_osd_screen = screen;
+	if (pixclock_present && output_driver_present)
+		osd_screen_mask |= 1 << screen;
 
 	i2c_set_bus_num(old_bus);
 
@@ -394,7 +419,12 @@
 {
 	unsigned screen;
 
-	for (screen = 0; screen <= max_osd_screen; ++screen) {
+	if ((argc < 4) || (strlen(argv[3]) % 4)) {
+		cmd_usage(cmdtp);
+		return 1;
+	}
+
+	for (screen = 0; screen < MAX_OSD_SCREEN; ++screen) {
 		unsigned x;
 		unsigned y;
 		unsigned k;
@@ -404,10 +434,8 @@
 		unsigned count = (argc > 4) ?
 			simple_strtoul(argv[4], NULL, 16) : 1;
 
-		if ((argc < 4) || (strlen(argv[3]) % 4)) {
-			cmd_usage(cmdtp);
-			return 1;
-		}
+		if (!(osd_screen_mask & (1 << screen)))
+			continue;
 
 		x = simple_strtoul(argv[1], NULL, 16);
 		y = simple_strtoul(argv[2], NULL, 16);
@@ -433,6 +461,37 @@
 			osd_write_videomem(screen, offset, buffer,
 				wp - buffer);
 		}
+
+		OSD_SET_REG(screen, control, 0x0049);
+	}
+
+	return 0;
+}
+
+int osd_size(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	unsigned screen;
+	unsigned x;
+	unsigned y;
+
+	if (argc < 3) {
+		cmd_usage(cmdtp);
+		return 1;
+	}
+
+	x = simple_strtoul(argv[1], NULL, 16);
+	y = simple_strtoul(argv[2], NULL, 16);
+
+	if (!x || (x > 64) || (x > MAX_X_CHARS) ||
+	    !y || (y > 32) || (y > MAX_Y_CHARS)) {
+		cmd_usage(cmdtp);
+		return 1;
+	}
+
+	for (screen = 0; screen < MAX_OSD_SCREEN; ++screen) {
+		OSD_SET_REG(screen, xy_size, ((x - 1) << 8) | (y - 1));
+		OSD_SET_REG(screen, x_pos, 32767 * (640 - 12 * x) / 65535);
+		OSD_SET_REG(screen, y_pos, 32767 * (480 - 18 * y) / 65535);
 	}
 
 	return 0;
@@ -449,3 +508,10 @@
 	"write ASCII buffer to osd memory",
 	"pos_x pos_y color text\n"
 );
+
+U_BOOT_CMD(
+	osdsize, 3, 0, osd_size,
+	"set OSD XY size in characters",
+	"size_x(max. " __stringify(MAX_X_CHARS)
+	") size_y(max. " __stringify(MAX_Y_CHARS) ")\n"
+);
diff --git a/board/gdsys/common/osd.h b/board/gdsys/common/osd.h
index 440b276..5b3f14b 100644
--- a/board/gdsys/common/osd.h
+++ b/board/gdsys/common/osd.h
@@ -8,6 +8,7 @@
 #ifndef _OSD_H_
 #define _OSD_H_
 
+int ch7301_probe(unsigned screen, bool power);
 int osd_probe(unsigned screen);
 
 #endif
diff --git a/board/gdsys/mpc8308/Kconfig b/board/gdsys/mpc8308/Kconfig
index 43e1663..9a1a3a2 100644
--- a/board/gdsys/mpc8308/Kconfig
+++ b/board/gdsys/mpc8308/Kconfig
@@ -10,3 +10,16 @@
 	default "hrcon"
 
 endif
+
+if TARGET_STRIDER
+
+config SYS_BOARD
+	default "mpc8308"
+
+config SYS_VENDOR
+	default "gdsys"
+
+config SYS_CONFIG_NAME
+	default "strider"
+
+endif
diff --git a/board/gdsys/mpc8308/MAINTAINERS b/board/gdsys/mpc8308/MAINTAINERS
index a7853a5..3895b01 100644
--- a/board/gdsys/mpc8308/MAINTAINERS
+++ b/board/gdsys/mpc8308/MAINTAINERS
@@ -4,3 +4,7 @@
 F:	board/gdsys/mpc8308/
 F:	include/configs/hrcon.h
 F:	configs/hrcon_defconfig
+F:	configs/hrcon_dh_defconfig
+F:	include/configs/strider.h
+F:	configs/strider_cpu_defconfig
+F:	configs/strider_con_defconfig
diff --git a/board/gdsys/mpc8308/Makefile b/board/gdsys/mpc8308/Makefile
index b5dfdbb..42702fb 100644
--- a/board/gdsys/mpc8308/Makefile
+++ b/board/gdsys/mpc8308/Makefile
@@ -7,3 +7,4 @@
 
 obj-y := mpc8308.o sdram.o
 obj-$(CONFIG_HRCON) += hrcon.o
+obj-$(CONFIG_STRIDER) += strider.o
diff --git a/board/gdsys/mpc8308/hrcon.c b/board/gdsys/mpc8308/hrcon.c
index e4434b3..880b638 100644
--- a/board/gdsys/mpc8308/hrcon.c
+++ b/board/gdsys/mpc8308/hrcon.c
@@ -22,9 +22,11 @@
 
 #include <gdsys_fpga.h>
 
+#include "../common/ioep-fpga.h"
 #include "../common/osd.h"
 #include "../common/mclink.h"
 #include "../common/phy.h"
+#include "../common/fanctrl.h"
 
 #include <pca953x.h>
 #include <pca9698.h>
@@ -36,57 +38,6 @@
 #define MAX_MUX_CHANNELS 2
 
 enum {
-	UNITTYPE_MAIN_SERVER = 0,
-	UNITTYPE_MAIN_USER = 1,
-	UNITTYPE_VIDEO_SERVER = 2,
-	UNITTYPE_VIDEO_USER = 3,
-};
-
-enum {
-	UNITTYPEPCB_DVI = 0,
-	UNITTYPEPCB_DP_165 = 1,
-	UNITTYPEPCB_DP_300 = 2,
-	UNITTYPEPCB_HDMI = 3,
-};
-
-enum {
-	HWVER_100 = 0,
-	HWVER_110 = 1,
-};
-
-enum {
-	FPGA_HWVER_200 = 0,
-	FPGA_HWVER_210 = 1,
-};
-
-enum {
-	COMPRESSION_NONE = 0,
-	COMPRESSION_TYPE1_DELTA = 1,
-	COMPRESSION_TYPE1_TYPE2_DELTA = 3,
-};
-
-enum {
-	AUDIO_NONE = 0,
-	AUDIO_TX = 1,
-	AUDIO_RX = 2,
-	AUDIO_RXTX = 3,
-};
-
-enum {
-	SYSCLK_147456 = 0,
-};
-
-enum {
-	RAM_DDR2_32 = 0,
-	RAM_DDR3_32 = 1,
-};
-
-enum {
-	CARRIER_SPEED_1G = 0,
-	CARRIER_SPEED_2_5G = 1,
-};
-
-enum {
 	MCFPGA_DONE = 1 << 0,
 	MCFPGA_INIT_N = 1 << 1,
 	MCFPGA_PROGRAM_N = 1 << 2,
@@ -102,6 +53,11 @@
 unsigned int mclink_fpgacount;
 struct ihs_fpga *fpga_ptr[] = CONFIG_SYS_FPGA_PTR;
 
+struct {
+	u8 bus;
+	u8 addr;
+} hrcon_fans[] = CONFIG_HRCON_FANS;
+
 int fpga_set_reg(u32 fpga, u16 *reg, off_t regoff, u16 data)
 {
 	int res;
@@ -164,197 +120,12 @@
 	return 0;
 }
 
-static void print_fpga_info(unsigned int fpga, bool rgmii2_present)
-{
-	u16 versions;
-	u16 fpga_version;
-	u16 fpga_features;
-	unsigned unit_type;
-	unsigned unit_type_pcb_video;
-	unsigned hardware_version;
-	unsigned feature_compression;
-	unsigned feature_osd;
-	unsigned feature_audio;
-	unsigned feature_sysclock;
-	unsigned feature_ramconfig;
-	unsigned feature_carrier_speed;
-	unsigned feature_carriers;
-	unsigned feature_video_channels;
-
-	FPGA_GET_REG(fpga, versions, &versions);
-	FPGA_GET_REG(fpga, fpga_version, &fpga_version);
-	FPGA_GET_REG(fpga, fpga_features, &fpga_features);
-
-	unit_type = (versions & 0xf000) >> 12;
-	unit_type_pcb_video = (versions & 0x01c0) >> 6;
-	feature_compression = (fpga_features & 0xe000) >> 13;
-	feature_osd = fpga_features & (1<<11);
-	feature_audio = (fpga_features & 0x0600) >> 9;
-	feature_sysclock = (fpga_features & 0x0180) >> 7;
-	feature_ramconfig = (fpga_features & 0x0060) >> 5;
-	feature_carrier_speed = fpga_features & (1<<4);
-	feature_carriers = (fpga_features & 0x000c) >> 2;
-	feature_video_channels = fpga_features & 0x0003;
-
-	switch (unit_type) {
-	case UNITTYPE_MAIN_USER:
-		printf("Mainchannel");
-		break;
-
-	case UNITTYPE_VIDEO_USER:
-		printf("Videochannel");
-		break;
-
-	default:
-		printf("UnitType %d(not supported)", unit_type);
-		break;
-	}
-
-	if (unit_type == UNITTYPE_MAIN_USER) {
-		hardware_version =
-			  (!!pca9698_get_value(0x20, 24) << 0)
-			| (!!pca9698_get_value(0x20, 25) << 1)
-			| (!!pca9698_get_value(0x20, 26) << 2)
-			| (!!pca9698_get_value(0x20, 27) << 3)
-			| (!!pca9698_get_value(0x20, 28) << 4);
-		switch (hardware_version) {
-		case HWVER_100:
-			printf(" HW-Ver 1.00,");
-			break;
-
-		case HWVER_110:
-			printf(" HW-Ver 1.10,");
-			break;
-
-		default:
-			printf(" HW-Ver %d(not supported),",
-			       hardware_version);
-			break;
-		}
-		if (rgmii2_present)
-			printf(" RGMII2,");
-	}
-
-	if (unit_type == UNITTYPE_VIDEO_USER) {
-		hardware_version = versions & 0x000f;
-		switch (hardware_version) {
-		case FPGA_HWVER_200:
-			printf(" HW-Ver 2.00,");
-			break;
-
-		case FPGA_HWVER_210:
-			printf(" HW-Ver 2.10,");
-			break;
-
-		default:
-			printf(" HW-Ver %d(not supported),",
-			       hardware_version);
-			break;
-		}
-	}
-
-	switch (unit_type_pcb_video) {
-	case UNITTYPEPCB_DVI:
-		printf(" DVI,");
-		break;
-
-	case UNITTYPEPCB_DP_165:
-		printf(" DP 165MPix/s,");
-		break;
-
-	case UNITTYPEPCB_DP_300:
-		printf(" DP 300MPix/s,");
-		break;
-
-	case UNITTYPEPCB_HDMI:
-		printf(" HDMI,");
-		break;
-	}
-
-	printf(" FPGA V %d.%02d\n       features:",
-	       fpga_version / 100, fpga_version % 100);
-
-
-	switch (feature_compression) {
-	case COMPRESSION_NONE:
-		printf(" no compression");
-		break;
-
-	case COMPRESSION_TYPE1_DELTA:
-		printf(" type1-deltacompression");
-		break;
-
-	case COMPRESSION_TYPE1_TYPE2_DELTA:
-		printf(" type1-deltacompression, type2-inlinecompression");
-		break;
-
-	default:
-		printf(" compression %d(not supported)", feature_compression);
-		break;
-	}
-
-	printf(", %sosd", feature_osd ? "" : "no ");
-
-	switch (feature_audio) {
-	case AUDIO_NONE:
-		printf(", no audio");
-		break;
-
-	case AUDIO_TX:
-		printf(", audio tx");
-		break;
-
-	case AUDIO_RX:
-		printf(", audio rx");
-		break;
-
-	case AUDIO_RXTX:
-		printf(", audio rx+tx");
-		break;
-
-	default:
-		printf(", audio %d(not supported)", feature_audio);
-		break;
-	}
-
-	puts(",\n       ");
-
-	switch (feature_sysclock) {
-	case SYSCLK_147456:
-		printf("clock 147.456 MHz");
-		break;
-
-	default:
-		printf("clock %d(not supported)", feature_sysclock);
-		break;
-	}
-
-	switch (feature_ramconfig) {
-	case RAM_DDR2_32:
-		printf(", RAM 32 bit DDR2");
-		break;
-
-	case RAM_DDR3_32:
-		printf(", RAM 32 bit DDR3");
-		break;
-
-	default:
-		printf(", RAM %d(not supported)", feature_ramconfig);
-		break;
-	}
-
-	printf(", %d carrier(s) %s", feature_carriers,
-	       feature_carrier_speed ? "2.5Gbit/s" : "1Gbit/s");
-
-	printf(", %d video channel(s)\n", feature_video_channels);
-}
-
 int last_stage_init(void)
 {
 	int slaves;
 	unsigned int k;
 	unsigned int mux_ch;
-	unsigned char mclink_controllers[] = { 0x24, 0x25, 0x26 };
+	unsigned char mclink_controllers[] = { 0x3c, 0x3d, 0x3e };
 	u16 fpga_features;
 	bool hw_type_cat = pca9698_get_value(0x20, 20);
 	bool ch0_rgmii2_present = false;
@@ -363,10 +134,11 @@
 
 	/* Turn on Parade DP501 */
 	pca9698_direction_output(0x20, 10, 1);
+	pca9698_direction_output(0x20, 11, 1);
 
 	ch0_rgmii2_present = !pca9698_get_value(0x20, 30);
 
-	/* wait for FPGA done */
+	/* wait for FPGA done, then reset FPGA */
 	for (k = 0; k < ARRAY_SIZE(mclink_controllers); ++k) {
 		unsigned int ctr = 0;
 
@@ -381,6 +153,12 @@
 				break;
 			}
 		}
+
+		pca953x_set_dir(mclink_controllers[k], MCFPGA_RESET_N, 0);
+		pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N, 0);
+		udelay(10);
+		pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N,
+				MCFPGA_RESET_N);
 	}
 
 	if (hw_type_cat) {
@@ -401,8 +179,11 @@
 	slaves = mclink_probe();
 	mclink_fpgacount = 0;
 
-	print_fpga_info(0, ch0_rgmii2_present);
+	ioep_fpga_print_info(0);
 	osd_probe(0);
+#ifdef CONFIG_SYS_OSD_DH
+	osd_probe(4);
+#endif
 
 	if (slaves <= 0)
 		return 0;
@@ -412,8 +193,11 @@
 	for (k = 1; k <= slaves; ++k) {
 		FPGA_GET_REG(k, fpga_features, &fpga_features);
 
-		print_fpga_info(k, false);
+		ioep_fpga_print_info(k);
 		osd_probe(k);
+#ifdef CONFIG_SYS_OSD_DH
+		osd_probe(k + 4);
+#endif
 		if (hw_type_cat) {
 			miiphy_register(bb_miiphy_buses[k].name,
 					bb_miiphy_read, bb_miiphy_write);
@@ -421,32 +205,53 @@
 		}
 	}
 
+	for (k = 0; k < ARRAY_SIZE(hrcon_fans); ++k) {
+		i2c_set_bus_num(hrcon_fans[k].bus);
+		init_fan_controller(hrcon_fans[k].addr);
+	}
+
 	return 0;
 }
 
 /*
- * provide access to fpga gpios (for I2C bitbang)
+ * provide access to fpga gpios and controls (for I2C bitbang)
  * (these may look all too simple but make iocon.h much more readable)
  */
 void fpga_gpio_set(unsigned int bus, int pin)
 {
-	FPGA_SET_REG(bus, gpio.set, pin);
+	FPGA_SET_REG(bus >= 4 ? (bus - 4) : bus, gpio.set, pin);
 }
 
 void fpga_gpio_clear(unsigned int bus, int pin)
 {
-	FPGA_SET_REG(bus, gpio.clear, pin);
+	FPGA_SET_REG(bus >= 4 ? (bus - 4) : bus, gpio.clear, pin);
 }
 
 int fpga_gpio_get(unsigned int bus, int pin)
 {
 	u16 val;
 
-	FPGA_GET_REG(bus, gpio.read, &val);
+	FPGA_GET_REG(bus >= 4 ? (bus - 4) : bus, gpio.read, &val);
 
 	return val & pin;
 }
 
+void fpga_control_set(unsigned int bus, int pin)
+{
+	u16 val;
+
+	FPGA_GET_REG(bus >= 4 ? (bus - 4) : bus, control, &val);
+	FPGA_SET_REG(bus >= 4 ? (bus - 4) : bus, control, val | pin);
+}
+
+void fpga_control_clear(unsigned int bus, int pin)
+{
+	u16 val;
+
+	FPGA_GET_REG(bus >= 4 ? (bus - 4) : bus, control, &val);
+	FPGA_SET_REG(bus >= 4 ? (bus - 4) : bus, control, val & ~pin);
+}
+
 void mpc8308_init(void)
 {
 	pca9698_direction_output(0x20, 4, 1);
diff --git a/board/gdsys/mpc8308/strider.c b/board/gdsys/mpc8308/strider.c
new file mode 100644
index 0000000..ef5b6c0
--- /dev/null
+++ b/board/gdsys/mpc8308/strider.c
@@ -0,0 +1,479 @@
+/*
+ * (C) Copyright 2014
+ * Dirk Eibach,  Guntermann & Drunck GmbH, eibach@gdsys.de
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <hwconfig.h>
+#include <i2c.h>
+#include <spi.h>
+#include <libfdt.h>
+#include <fdt_support.h>
+#include <pci.h>
+#include <mpc83xx.h>
+#include <fsl_esdhc.h>
+#include <asm/io.h>
+#include <asm/fsl_serdes.h>
+#include <asm/fsl_mpc83xx_serdes.h>
+
+#include "mpc8308.h"
+
+#include <gdsys_fpga.h>
+
+#include "../common/adv7611.h"
+#include "../common/ch7301.h"
+#include "../common/ioep-fpga.h"
+#include "../common/mclink.h"
+#include "../common/osd.h"
+#include "../common/phy.h"
+#include "../common/fanctrl.h"
+
+#include <pca953x.h>
+#include <pca9698.h>
+
+#include <miiphy.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define MAX_MUX_CHANNELS 2
+
+enum {
+	MCFPGA_DONE = 1 << 0,
+	MCFPGA_INIT_N = 1 << 1,
+	MCFPGA_PROGRAM_N = 1 << 2,
+	MCFPGA_UPDATE_ENABLE_N = 1 << 3,
+	MCFPGA_RESET_N = 1 << 4,
+};
+
+enum {
+	GPIO_MDC = 1 << 14,
+	GPIO_MDIO = 1 << 15,
+};
+
+unsigned int mclink_fpgacount;
+struct ihs_fpga *fpga_ptr[] = CONFIG_SYS_FPGA_PTR;
+
+struct {
+	u8 bus;
+	u8 addr;
+} strider_fans[] = CONFIG_STRIDER_FANS;
+
+int fpga_set_reg(u32 fpga, u16 *reg, off_t regoff, u16 data)
+{
+	int res;
+
+	switch (fpga) {
+	case 0:
+		out_le16(reg, data);
+		break;
+	default:
+		res = mclink_send(fpga - 1, regoff, data);
+		if (res < 0) {
+			printf("mclink_send reg %02lx data %04x returned %d\n",
+			       regoff, data, res);
+			return res;
+		}
+		break;
+	}
+
+	return 0;
+}
+
+int fpga_get_reg(u32 fpga, u16 *reg, off_t regoff, u16 *data)
+{
+	int res;
+
+	switch (fpga) {
+	case 0:
+		*data = in_le16(reg);
+		break;
+	default:
+		if (fpga > mclink_fpgacount)
+			return -EINVAL;
+		res = mclink_receive(fpga - 1, regoff, data);
+		if (res < 0) {
+			printf("mclink_receive reg %02lx returned %d\n",
+			       regoff, res);
+			return res;
+		}
+	}
+
+	return 0;
+}
+
+int checkboard(void)
+{
+	char *s = getenv("serial#");
+	bool hw_type_cat = pca9698_get_value(0x20, 18);
+
+	puts("Board: ");
+
+	printf("Strider %s", hw_type_cat ? "CAT" : "Fiber");
+
+	if (s != NULL) {
+		puts(", serial# ");
+		puts(s);
+	}
+
+	puts("\n");
+
+	return 0;
+}
+
+int last_stage_init(void)
+{
+	int slaves;
+	unsigned int k;
+	unsigned int mux_ch;
+	unsigned char mclink_controllers[] = { 0x3c, 0x3d, 0x3e };
+	bool hw_type_cat = pca9698_get_value(0x20, 18);
+	bool ch0_sgmii2_present = false;
+
+	/* Turn on Analog Devices ADV7611 */
+	pca9698_direction_output(0x20, 8, 0);
+
+	/* Turn on Parade DP501 */
+	pca9698_direction_output(0x20, 9, 1);
+
+	ch0_sgmii2_present = !pca9698_get_value(0x20, 37);
+
+	/* wait for FPGA done, then reset FPGA */
+	for (k = 0; k < ARRAY_SIZE(mclink_controllers); ++k) {
+		unsigned int ctr = 0;
+
+		if (i2c_probe(mclink_controllers[k]))
+			continue;
+
+		while (!(pca953x_get_val(mclink_controllers[k])
+		       & MCFPGA_DONE)) {
+			udelay(100000);
+			if (ctr++ > 5) {
+				printf("no done for mclink_controller %d\n", k);
+				break;
+			}
+		}
+
+		pca953x_set_dir(mclink_controllers[k], MCFPGA_RESET_N, 0);
+		pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N, 0);
+		udelay(10);
+		pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N,
+				MCFPGA_RESET_N);
+	}
+
+	if (hw_type_cat) {
+		miiphy_register(bb_miiphy_buses[0].name, bb_miiphy_read,
+				bb_miiphy_write);
+		for (mux_ch = 0; mux_ch < MAX_MUX_CHANNELS; ++mux_ch) {
+			if ((mux_ch == 1) && !ch0_sgmii2_present)
+				continue;
+
+			setup_88e1514(bb_miiphy_buses[0].name, mux_ch);
+		}
+	}
+
+	/* give slave-PLLs and Parade DP501 some time to be up and running */
+	udelay(500000);
+
+	mclink_fpgacount = CONFIG_SYS_MCLINK_MAX;
+	slaves = mclink_probe();
+	mclink_fpgacount = 0;
+
+	ioep_fpga_print_info(0);
+
+	if (!adv7611_probe(0))
+		printf("       Advantiv ADV7611 HDMI Receiver\n");
+
+#ifdef CONFIG_STRIDER_CON
+	if (ioep_fpga_has_osd(0))
+		osd_probe(0);
+#endif
+
+#ifdef CONFIG_STRIDER_CPU
+	ch7301_probe(0, false);
+#endif
+
+	if (slaves <= 0)
+		return 0;
+
+	mclink_fpgacount = slaves;
+
+	for (k = 1; k <= slaves; ++k) {
+		ioep_fpga_print_info(k);
+#ifdef CONFIG_STRIDER_CON
+		if (ioep_fpga_has_osd(k))
+			osd_probe(k);
+#endif
+#ifdef CONFIG_STRIDER_CPU
+		FPGA_SET_REG(k, extended_control, 0); /* enable video in*/
+		if (!adv7611_probe(k))
+			printf("       Advantiv ADV7611 HDMI Receiver\n");
+		ch7301_probe(k, false);
+#endif
+		if (hw_type_cat) {
+			miiphy_register(bb_miiphy_buses[k].name,
+					bb_miiphy_read, bb_miiphy_write);
+			setup_88e1514(bb_miiphy_buses[k].name, 0);
+		}
+	}
+
+	for (k = 0; k < ARRAY_SIZE(strider_fans); ++k) {
+		i2c_set_bus_num(strider_fans[k].bus);
+		init_fan_controller(strider_fans[k].addr);
+	}
+
+	return 0;
+}
+
+/*
+ * provide access to fpga gpios (for I2C bitbang)
+ * (these may look all too simple but make iocon.h much more readable)
+ */
+void fpga_gpio_set(unsigned int bus, int pin)
+{
+	FPGA_SET_REG(bus, gpio.set, pin);
+}
+
+void fpga_gpio_clear(unsigned int bus, int pin)
+{
+	FPGA_SET_REG(bus, gpio.clear, pin);
+}
+
+int fpga_gpio_get(unsigned int bus, int pin)
+{
+	u16 val;
+
+	FPGA_GET_REG(bus, gpio.read, &val);
+
+	return val & pin;
+}
+
+void mpc8308_init(void)
+{
+	pca9698_direction_output(0x20, 26, 1);
+}
+
+void mpc8308_set_fpga_reset(unsigned state)
+{
+	pca9698_set_value(0x20, 26, state ? 0 : 1);
+}
+
+void mpc8308_setup_hw(void)
+{
+	immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
+
+	/*
+	 * set "startup-finished"-gpios
+	 */
+	setbits_be32(&immr->gpio[0].dir, (1 << (31-11)) | (1 << (31-12)));
+	setbits_be32(&immr->gpio[0].dat, 1 << (31-12));
+}
+
+int mpc8308_get_fpga_done(unsigned fpga)
+{
+	return pca9698_get_value(0x20, 20);
+}
+
+#ifdef CONFIG_FSL_ESDHC
+int board_mmc_init(bd_t *bd)
+{
+	immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
+	sysconf83xx_t *sysconf = &immr->sysconf;
+
+	/* Enable cache snooping in eSDHC system configuration register */
+	out_be32(&sysconf->sdhccr, 0x02000000);
+
+	return fsl_esdhc_mmc_init(bd);
+}
+#endif
+
+static struct pci_region pcie_regions_0[] = {
+	{
+		.bus_start = CONFIG_SYS_PCIE1_MEM_BASE,
+		.phys_start = CONFIG_SYS_PCIE1_MEM_PHYS,
+		.size = CONFIG_SYS_PCIE1_MEM_SIZE,
+		.flags = PCI_REGION_MEM,
+	},
+	{
+		.bus_start = CONFIG_SYS_PCIE1_IO_BASE,
+		.phys_start = CONFIG_SYS_PCIE1_IO_PHYS,
+		.size = CONFIG_SYS_PCIE1_IO_SIZE,
+		.flags = PCI_REGION_IO,
+	},
+};
+
+void pci_init_board(void)
+{
+	immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
+	sysconf83xx_t *sysconf = &immr->sysconf;
+	law83xx_t *pcie_law = sysconf->pcielaw;
+	struct pci_region *pcie_reg[] = { pcie_regions_0 };
+
+	fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_PEX,
+			 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V);
+
+	/* Deassert the resets in the control register */
+	out_be32(&sysconf->pecr1, 0xE0008000);
+	udelay(2000);
+
+	/* Configure PCI Express Local Access Windows */
+	out_be32(&pcie_law[0].bar, CONFIG_SYS_PCIE1_BASE & LAWBAR_BAR);
+	out_be32(&pcie_law[0].ar, LBLAWAR_EN | LBLAWAR_512MB);
+
+	mpc83xx_pcie_init(1, pcie_reg);
+}
+
+ulong board_flash_get_legacy(ulong base, int banknum, flash_info_t *info)
+{
+	info->portwidth = FLASH_CFI_16BIT;
+	info->chipwidth = FLASH_CFI_BY16;
+	info->interface = FLASH_CFI_X16;
+	return 1;
+}
+
+#if defined(CONFIG_OF_BOARD_SETUP)
+int ft_board_setup(void *blob, bd_t *bd)
+{
+	ft_cpu_setup(blob, bd);
+	fdt_fixup_dr_usb(blob, bd);
+	fdt_fixup_esdhc(blob, bd);
+
+	return 0;
+}
+#endif
+
+/*
+ * FPGA MII bitbang implementation
+ */
+
+struct fpga_mii {
+	unsigned fpga;
+	int mdio;
+} fpga_mii[] = {
+	{ 0, 1},
+	{ 1, 1},
+	{ 2, 1},
+	{ 3, 1},
+};
+
+static int mii_dummy_init(struct bb_miiphy_bus *bus)
+{
+	return 0;
+}
+
+static int mii_mdio_active(struct bb_miiphy_bus *bus)
+{
+	struct fpga_mii *fpga_mii = bus->priv;
+
+	if (fpga_mii->mdio)
+		FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
+	else
+		FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDIO);
+
+	return 0;
+}
+
+static int mii_mdio_tristate(struct bb_miiphy_bus *bus)
+{
+	struct fpga_mii *fpga_mii = bus->priv;
+
+	FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
+
+	return 0;
+}
+
+static int mii_set_mdio(struct bb_miiphy_bus *bus, int v)
+{
+	struct fpga_mii *fpga_mii = bus->priv;
+
+	if (v)
+		FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
+	else
+		FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDIO);
+
+	fpga_mii->mdio = v;
+
+	return 0;
+}
+
+static int mii_get_mdio(struct bb_miiphy_bus *bus, int *v)
+{
+	u16 gpio;
+	struct fpga_mii *fpga_mii = bus->priv;
+
+	FPGA_GET_REG(fpga_mii->fpga, gpio.read, &gpio);
+
+	*v = ((gpio & GPIO_MDIO) != 0);
+
+	return 0;
+}
+
+static int mii_set_mdc(struct bb_miiphy_bus *bus, int v)
+{
+	struct fpga_mii *fpga_mii = bus->priv;
+
+	if (v)
+		FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDC);
+	else
+		FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDC);
+
+	return 0;
+}
+
+static int mii_delay(struct bb_miiphy_bus *bus)
+{
+	udelay(1);
+
+	return 0;
+}
+
+struct bb_miiphy_bus bb_miiphy_buses[] = {
+	{
+		.name = "board0",
+		.init = mii_dummy_init,
+		.mdio_active = mii_mdio_active,
+		.mdio_tristate = mii_mdio_tristate,
+		.set_mdio = mii_set_mdio,
+		.get_mdio = mii_get_mdio,
+		.set_mdc = mii_set_mdc,
+		.delay = mii_delay,
+		.priv = &fpga_mii[0],
+	},
+	{
+		.name = "board1",
+		.init = mii_dummy_init,
+		.mdio_active = mii_mdio_active,
+		.mdio_tristate = mii_mdio_tristate,
+		.set_mdio = mii_set_mdio,
+		.get_mdio = mii_get_mdio,
+		.set_mdc = mii_set_mdc,
+		.delay = mii_delay,
+		.priv = &fpga_mii[1],
+	},
+	{
+		.name = "board2",
+		.init = mii_dummy_init,
+		.mdio_active = mii_mdio_active,
+		.mdio_tristate = mii_mdio_tristate,
+		.set_mdio = mii_set_mdio,
+		.get_mdio = mii_get_mdio,
+		.set_mdc = mii_set_mdc,
+		.delay = mii_delay,
+		.priv = &fpga_mii[2],
+	},
+	{
+		.name = "board3",
+		.init = mii_dummy_init,
+		.mdio_active = mii_mdio_active,
+		.mdio_tristate = mii_mdio_tristate,
+		.set_mdio = mii_set_mdio,
+		.get_mdio = mii_get_mdio,
+		.set_mdc = mii_set_mdc,
+		.delay = mii_delay,
+		.priv = &fpga_mii[3],
+	},
+};
+
+int bb_miiphy_buses_num = sizeof(bb_miiphy_buses) /
+			  sizeof(bb_miiphy_buses[0]);
diff --git a/board/gdsys/p1022/controlcenterd.c b/board/gdsys/p1022/controlcenterd.c
index 64d90dd..2f98e47 100644
--- a/board/gdsys/p1022/controlcenterd.c
+++ b/board/gdsys/p1022/controlcenterd.c
@@ -57,6 +57,8 @@
 	u32 versions;		/* 0x0004 */
 	u32 fpga_version;	/* 0x0008 */
 	u32 fpga_features;	/* 0x000c */
+	u32 reserved[4];	/* 0x0010 */
+	u32 control;		/* 0x0020 */
 };
 
 #ifndef CONFIG_TRAILBLAZER
@@ -384,6 +386,9 @@
 		fpga = pci_map_bar(devno, PCI_BASE_ADDRESS_0,
 			PCI_REGION_MEM);
 
+		/* disable sideband clocks */
+		writel(1, &fpga->control);
+
 		versions = readl(&fpga->versions);
 		fpga_version = readl(&fpga->fpga_version);
 		fpga_features = readl(&fpga->fpga_features);
diff --git a/board/nvidia/jetson-tk1/jetson-tk1.c b/board/nvidia/jetson-tk1/jetson-tk1.c
index 3c21767..52425a8 100644
--- a/board/nvidia/jetson-tk1/jetson-tk1.c
+++ b/board/nvidia/jetson-tk1/jetson-tk1.c
@@ -11,7 +11,6 @@
 
 #include <asm/arch/gpio.h>
 #include <asm/arch/pinmux.h>
-#include <asm/arch-tegra/gpu.h>
 
 #include "pinmux-config-jetson-tk1.h"
 
@@ -80,10 +79,3 @@
 	return pci_eth_init(bis);
 }
 #endif /* PCI */
-
-int ft_board_setup(void *blob, bd_t *bd)
-{
-	gpu_enable_node(blob, "/gpu@0,57000000");
-
-	return 0;
-}
diff --git a/board/nvidia/p2371-2180/p2371-2180.c b/board/nvidia/p2371-2180/p2371-2180.c
index cf2dd0b..57f577d8 100644
--- a/board/nvidia/p2371-2180/p2371-2180.c
+++ b/board/nvidia/p2371-2180/p2371-2180.c
@@ -6,6 +6,7 @@
  */
 
 #include <common.h>
+#include <netdev.h>
 #include <i2c.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/pinmux.h>
@@ -49,3 +50,32 @@
 	pinmux_config_drvgrp_table(p2371_2180_drvgrps,
 				   ARRAY_SIZE(p2371_2180_drvgrps));
 }
+
+#ifdef CONFIG_PCI_TEGRA
+int tegra_pcie_board_init(void)
+{
+	struct udevice *dev;
+	uchar val;
+	int ret;
+
+	/* Turn on MAX77620 LDO1 to 1.05V for PEX power */
+	debug("%s: Set LDO1 for PEX power to 1.05V\n", __func__);
+	ret = i2c_get_chip_for_busnum(0, MAX77620_I2C_ADDR_7BIT, 1, &dev);
+	if (ret) {
+		printf("%s: Cannot find MAX77620 I2C chip\n", __func__);
+		return -1;
+	}
+	/* 0xCA for 1.05v, enabled: bit7:6 = 11 = enable, bit5:0 = voltage */
+	val = 0xCA;
+	ret = dm_i2c_write(dev, MAX77620_CNFG1_L1_REG, &val, 1);
+	if (ret)
+		printf("i2c_write 0 0x3c 0x25 failed: %d\n", ret);
+
+	return 0;
+}
+
+int board_eth_init(bd_t *bis)
+{
+	return pci_eth_init(bis);
+}
+#endif /* PCI */
diff --git a/board/nvidia/p2571/p2571.c b/board/nvidia/p2571/p2571.c
index d33e4d1..d80a7d0 100644
--- a/board/nvidia/p2571/p2571.c
+++ b/board/nvidia/p2571/p2571.c
@@ -11,7 +11,6 @@
 #include <asm/arch/pinmux.h>
 #include <asm/gpio.h>
 #include "max77620_init.h"
-#include <asm/arch-tegra/gpu.h>
 #include "pinmux-config-p2571.h"
 
 void pin_mux_mmc(void)
@@ -62,9 +61,3 @@
 	gpio_request(GPIO_PE4, "FAN_VDD");
 	gpio_direction_output(GPIO_PE4, 1);
 }
-
-int ft_board_setup(void *blob, bd_t *bd)
-{
-	gpu_enable_node(blob, "/gpu@0,57000000");
-	return 0;
-}
diff --git a/board/nvidia/venice2/venice2.c b/board/nvidia/venice2/venice2.c
index 3e2b9a7..c56ef12 100644
--- a/board/nvidia/venice2/venice2.c
+++ b/board/nvidia/venice2/venice2.c
@@ -8,7 +8,6 @@
 #include <common.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/pinmux.h>
-#include <asm/arch-tegra/gpu.h>
 #include "pinmux-config-venice2.h"
 
 /*
@@ -28,10 +27,3 @@
 	pinmux_config_drvgrp_table(venice2_drvgrps,
 				   ARRAY_SIZE(venice2_drvgrps));
 }
-
-int ft_board_setup(void *blob, bd_t *bd)
-{
-	gpu_enable_node(blob, "/gpu@0,57000000");
-
-	return 0;
-}
diff --git a/board/silica/pengwyn/board.c b/board/silica/pengwyn/board.c
index 815c9a7..1f5a586 100644
--- a/board/silica/pengwyn/board.c
+++ b/board/silica/pengwyn/board.c
@@ -141,12 +141,6 @@
 	{
 		.slave_reg_ofs	= 0x208,
 		.sliver_reg_ofs	= 0xd80,
-		.phy_addr	= 0,
-		.phy_if		= PHY_INTERFACE_MODE_MII,
-	},
-	{
-		.slave_reg_ofs	= 0x308,
-		.sliver_reg_ofs	= 0xdc0,
 		.phy_addr	= 1,
 		.phy_if		= PHY_INTERFACE_MODE_MII,
 	},
diff --git a/board/ti/am335x/mux.c b/board/ti/am335x/mux.c
index 28c29a2..79ed02f 100644
--- a/board/ti/am335x/mux.c
+++ b/board/ti/am335x/mux.c
@@ -317,7 +317,6 @@
 	/* Do board-specific muxes. */
 	if (board_is_bone(header)) {
 		/* Beaglebone pinmux */
-		configure_module_pin_mux(i2c1_pin_mux);
 		configure_module_pin_mux(mii1_pin_mux);
 		configure_module_pin_mux(mmc0_pin_mux);
 #if defined(CONFIG_NAND)
@@ -356,7 +355,6 @@
 		configure_module_pin_mux(mmc0_pin_mux_sk_evm);
 	} else if (board_is_bone_lt(header)) {
 		/* Beaglebone LT pinmux */
-		configure_module_pin_mux(i2c1_pin_mux);
 		configure_module_pin_mux(mii1_pin_mux);
 		configure_module_pin_mux(mmc0_pin_mux);
 #if defined(CONFIG_NAND) && defined(CONFIG_EMMC_BOOT)
diff --git a/common/Kconfig b/common/Kconfig
index 0388a6c..440cb37 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -455,6 +455,20 @@
 
 menu "Misc commands"
 
+config CMD_AMBAPP
+	bool "ambapp"
+	depends on LEON3
+	default y
+	help
+	  Lists AMBA Plug-n-Play information.
+
+config SYS_AMBAPP_PRINT_ON_STARTUP
+	bool "Show AMBA PnP info on startup"
+	depends on CMD_AMBAPP
+	default n
+	help
+	  Show AMBA Plug-n-Play information on startup.
+
 config CMD_TIME
 	bool "time"
 	help
diff --git a/common/Makefile b/common/Makefile
index d986cde..d8dc892 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -276,10 +276,15 @@
 obj-y += stdio.o
 
 # This option is not just y/n - it can have a numeric value
+ifdef CONFIG_FASTBOOT_FLASH
+obj-y += image-sparse.o
 ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
-obj-y += aboot.o
 obj-y += fb_mmc.o
 endif
+ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
+obj-y += fb_nand.o
+endif
+endif
 
 obj-$(CONFIG_CMD_BLOB) += cmd_blob.o
 
diff --git a/common/aboot.c b/common/aboot.c
deleted file mode 100644
index fba8e3e..0000000
--- a/common/aboot.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (c) 2009, Google Inc.
- * All rights reserved.
- *
- * Copyright (c) 2009-2014, The Linux Foundation. All rights reserved.
- * Portions Copyright 2014 Broadcom Corporation.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of The Linux Foundation nor
- *       the names of its contributors may be used to endorse or promote
- *       products derived from this software without specific prior written
- *       permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * NOTE:
- *   Although it is very similar, this license text is not identical
- *   to the "BSD-3-Clause", therefore, DO NOT MODIFY THIS LICENSE TEXT!
- */
-
-#include <config.h>
-#include <common.h>
-#include <aboot.h>
-#include <malloc.h>
-#include <part.h>
-#include <sparse_format.h>
-
-void write_sparse_image(block_dev_desc_t *dev_desc,
-		disk_partition_t *info, const char *part_name,
-		void *data, unsigned sz)
-{
-	lbaint_t blk;
-	lbaint_t blkcnt;
-	lbaint_t blks;
-	uint32_t bytes_written = 0;
-	unsigned int chunk;
-	unsigned int chunk_data_sz;
-	uint32_t *fill_buf = NULL;
-	uint32_t fill_val;
-	sparse_header_t *sparse_header;
-	chunk_header_t *chunk_header;
-	uint32_t total_blocks = 0;
-	int i;
-
-	/* Read and skip over sparse image header */
-	sparse_header = (sparse_header_t *) data;
-
-	data += sparse_header->file_hdr_sz;
-	if (sparse_header->file_hdr_sz > sizeof(sparse_header_t))
-	{
-		/*
-		 * Skip the remaining bytes in a header that is longer than
-		 * we expected.
-		 */
-		data += (sparse_header->file_hdr_sz - sizeof(sparse_header_t));
-	}
-
-	debug("=== Sparse Image Header ===\n");
-	debug("magic: 0x%x\n", sparse_header->magic);
-	debug("major_version: 0x%x\n", sparse_header->major_version);
-	debug("minor_version: 0x%x\n", sparse_header->minor_version);
-	debug("file_hdr_sz: %d\n", sparse_header->file_hdr_sz);
-	debug("chunk_hdr_sz: %d\n", sparse_header->chunk_hdr_sz);
-	debug("blk_sz: %d\n", sparse_header->blk_sz);
-	debug("total_blks: %d\n", sparse_header->total_blks);
-	debug("total_chunks: %d\n", sparse_header->total_chunks);
-
-	/* verify sparse_header->blk_sz is an exact multiple of info->blksz */
-	if (sparse_header->blk_sz !=
-	    (sparse_header->blk_sz & ~(info->blksz - 1))) {
-		printf("%s: Sparse image block size issue [%u]\n",
-		       __func__, sparse_header->blk_sz);
-		fastboot_fail("sparse image block size issue");
-		return;
-	}
-
-	puts("Flashing Sparse Image\n");
-
-	/* Start processing chunks */
-	blk = info->start;
-	for (chunk=0; chunk<sparse_header->total_chunks; chunk++)
-	{
-		/* Read and skip over chunk header */
-		chunk_header = (chunk_header_t *) data;
-		data += sizeof(chunk_header_t);
-
-		if (chunk_header->chunk_type != CHUNK_TYPE_RAW) {
-			debug("=== Chunk Header ===\n");
-			debug("chunk_type: 0x%x\n", chunk_header->chunk_type);
-			debug("chunk_data_sz: 0x%x\n", chunk_header->chunk_sz);
-			debug("total_size: 0x%x\n", chunk_header->total_sz);
-		}
-
-		if (sparse_header->chunk_hdr_sz > sizeof(chunk_header_t))
-		{
-			/*
-			 * Skip the remaining bytes in a header that is longer
-			 * than we expected.
-			 */
-			data += (sparse_header->chunk_hdr_sz -
-				 sizeof(chunk_header_t));
-		}
-
-		chunk_data_sz = sparse_header->blk_sz * chunk_header->chunk_sz;
-		blkcnt = chunk_data_sz / info->blksz;
-		switch (chunk_header->chunk_type)
-		{
-			case CHUNK_TYPE_RAW:
-			if (chunk_header->total_sz !=
-			    (sparse_header->chunk_hdr_sz + chunk_data_sz))
-			{
-				fastboot_fail(
-					"Bogus chunk size for chunk type Raw");
-				return;
-			}
-
-			if (blk + blkcnt > info->start + info->size) {
-				printf(
-				    "%s: Request would exceed partition size!\n",
-				    __func__);
-				fastboot_fail(
-				    "Request would exceed partition size!");
-				return;
-			}
-
-			blks = dev_desc->block_write(dev_desc->dev, blk, blkcnt,
-						     data);
-			if (blks != blkcnt) {
-				printf("%s: Write failed " LBAFU "\n",
-				       __func__, blks);
-				fastboot_fail("flash write failure");
-				return;
-			}
-			blk += blkcnt;
-			bytes_written += blkcnt * info->blksz;
-			total_blocks += chunk_header->chunk_sz;
-			data += chunk_data_sz;
-			break;
-
-			case CHUNK_TYPE_FILL:
-			if (chunk_header->total_sz !=
-			    (sparse_header->chunk_hdr_sz + sizeof(uint32_t)))
-			{
-				fastboot_fail(
-					"Bogus chunk size for chunk type FILL");
-				return;
-			}
-
-			fill_buf = (uint32_t *)
-				   memalign(ARCH_DMA_MINALIGN,
-					    ROUNDUP(info->blksz,
-						    ARCH_DMA_MINALIGN));
-			if (!fill_buf)
-			{
-				fastboot_fail(
-					"Malloc failed for: CHUNK_TYPE_FILL");
-				return;
-			}
-
-			fill_val = *(uint32_t *)data;
-			data = (char *) data + sizeof(uint32_t);
-
-			for (i = 0; i < (info->blksz / sizeof(fill_val)); i++)
-				fill_buf[i] = fill_val;
-
-			if (blk + blkcnt > info->start + info->size) {
-				printf(
-				    "%s: Request would exceed partition size!\n",
-				    __func__);
-				fastboot_fail(
-				    "Request would exceed partition size!");
-				return;
-			}
-
-			for (i = 0; i < blkcnt; i++) {
-				blks = dev_desc->block_write(dev_desc->dev,
-							     blk, 1, fill_buf);
-				if (blks != 1) {
-					printf(
-					    "%s: Write failed, block # " LBAFU "\n",
-					    __func__, blkcnt);
-					fastboot_fail("flash write failure");
-					free(fill_buf);
-					return;
-				}
-				blk++;
-			}
-			bytes_written += blkcnt * info->blksz;
-			total_blocks += chunk_data_sz / sparse_header->blk_sz;
-
-			free(fill_buf);
-			break;
-
-			case CHUNK_TYPE_DONT_CARE:
-			blk += blkcnt;
-			total_blocks += chunk_header->chunk_sz;
-			break;
-
-			case CHUNK_TYPE_CRC32:
-			if (chunk_header->total_sz !=
-			    sparse_header->chunk_hdr_sz)
-			{
-				fastboot_fail(
-					"Bogus chunk size for chunk type Dont Care");
-				return;
-			}
-			total_blocks += chunk_header->chunk_sz;
-			data += chunk_data_sz;
-			break;
-
-			default:
-			printf("%s: Unknown chunk type: %x\n", __func__,
-			       chunk_header->chunk_type);
-			fastboot_fail("Unknown chunk type");
-			return;
-		}
-	}
-
-	debug("Wrote %d blocks, expected to write %d blocks\n",
-	      total_blocks, sparse_header->total_blks);
-	printf("........ wrote %u bytes to '%s'\n", bytes_written, part_name);
-
-	if (total_blocks != sparse_header->total_blks)
-		fastboot_fail("sparse image write failure");
-
-	fastboot_okay("");
-	return;
-}
diff --git a/common/board_f.c b/common/board_f.c
index 725eb18..04c273e 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -796,7 +796,7 @@
 	/* TODO: can we rename this to timer_init()? */
 	init_timebase,
 #endif
-#if defined(CONFIG_ARM) || defined(CONFIG_MIPS) || \
+#if defined(CONFIG_X86) || defined(CONFIG_ARM) || defined(CONFIG_MIPS) || \
 		defined(CONFIG_BLACKFIN) || defined(CONFIG_NDS32)
 	timer_init,		/* initialize timer */
 #endif
@@ -808,10 +808,7 @@
 #if defined(CONFIG_BOARD_POSTCLK_INIT)
 	board_postclk_init,
 #endif
-#ifdef CONFIG_SYS_FSL_CLK
-	get_clocks,
-#endif
-#ifdef CONFIG_M68K
+#if defined(CONFIG_SYS_FSL_CLK) || defined(CONFIG_M68K)
 	get_clocks,
 #endif
 	env_init,		/* initialize environment */
diff --git a/common/board_r.c b/common/board_r.c
index c4fd3ea..c6aa7e5 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -46,6 +46,9 @@
 #include <stdio_dev.h>
 #include <trace.h>
 #include <watchdog.h>
+#ifdef CONFIG_CMD_AMBAPP
+#include <ambapp.h>
+#endif
 #ifdef CONFIG_ADDR_MAP
 #include <asm/mmu.h>
 #endif
@@ -559,6 +562,18 @@
 }
 #endif
 
+#if defined(CONFIG_CMD_AMBAPP) && defined(CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP)
+extern int do_ambapp_print(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+
+static int initr_ambapp_print(void)
+{
+	puts("AMBA:\n");
+	do_ambapp_print(NULL, 0, 0, NULL);
+
+	return 0;
+}
+#endif
+
 #if defined(CONFIG_CMD_SCSI)
 static int initr_scsi(void)
 {
@@ -837,8 +852,7 @@
 #if defined(CONFIG_ARM) || defined(CONFIG_AVR32)
 	initr_enable_interrupts,
 #endif
-#if defined(CONFIG_X86) || defined(CONFIG_MICROBLAZE) || defined(CONFIG_AVR32) \
-	|| defined(CONFIG_M68K)
+#if defined(CONFIG_MICROBLAZE) || defined(CONFIG_AVR32) || defined(CONFIG_M68K)
 	timer_init,		/* initialize timer */
 #endif
 #if defined(CONFIG_STATUS_LED)
@@ -851,6 +865,12 @@
 #ifdef CONFIG_BOARD_LATE_INIT
 	board_late_init,
 #endif
+#if defined(CONFIG_CMD_AMBAPP)
+	ambapp_init_reloc,
+#if defined(CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP)
+	initr_ambapp_print,
+#endif
+#endif
 #ifdef CONFIG_CMD_SCSI
 	INIT_FUNC_WATCHDOG_RESET
 	initr_scsi,
diff --git a/common/cmd_ambapp.c b/common/cmd_ambapp.c
index 2a1995a..4b6d174 100644
--- a/common/cmd_ambapp.c
+++ b/common/cmd_ambapp.c
@@ -15,92 +15,375 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* We put these variables into .data section so that they are zero
- * when entering the AMBA Plug & Play routines (in cpu/cpu/ambapp.c)
- * the first time. BSS is not garantueed to be zero since BSS
- * hasn't been cleared the first times entering the CPU AMBA functions.
- *
- * The AMBA PnP routines call these functions if ambapp_???_print is set.
- *
- */
-int ambapp_apb_print __attribute__ ((section(".data"))) = 0;
-int ambapp_ahb_print __attribute__ ((section(".data"))) = 0;
-
 typedef struct {
 	int device_id;
 	char *name;
+	char *desc;
 } ambapp_device_name;
 
-static ambapp_device_name gaisler_devices[] = {
-	{GAISLER_LEON3, "GAISLER_LEON3"},
-	{GAISLER_LEON3DSU, "GAISLER_LEON3DSU"},
-	{GAISLER_ETHAHB, "GAISLER_ETHAHB"},
-	{GAISLER_ETHMAC, "GAISLER_ETHMAC"},
-	{GAISLER_APBMST, "GAISLER_APBMST"},
-	{GAISLER_AHBUART, "GAISLER_AHBUART"},
-	{GAISLER_SRCTRL, "GAISLER_SRCTRL"},
-	{GAISLER_SDCTRL, "GAISLER_SDCTRL"},
-	{GAISLER_APBUART, "GAISLER_APBUART"},
-	{GAISLER_IRQMP, "GAISLER_IRQMP"},
-	{GAISLER_AHBRAM, "GAISLER_AHBRAM"},
-	{GAISLER_GPTIMER, "GAISLER_GPTIMER"},
-	{GAISLER_PCITRG, "GAISLER_PCITRG"},
-	{GAISLER_PCISBRG, "GAISLER_PCISBRG"},
-	{GAISLER_PCIFBRG, "GAISLER_PCIFBRG"},
-	{GAISLER_PCITRACE, "GAISLER_PCITRACE"},
-	{GAISLER_AHBTRACE, "GAISLER_AHBTRACE"},
-	{GAISLER_ETHDSU, "GAISLER_ETHDSU"},
-	{GAISLER_PIOPORT, "GAISLER_PIOPORT"},
-	{GAISLER_AHBJTAG, "GAISLER_AHBJTAG"},
-	{GAISLER_ATACTRL, "GAISLER_ATACTRL"},
-	{GAISLER_VGA, "GAISLER_VGA"},
-	{GAISLER_KBD, "GAISLER_KBD"},
-	{GAISLER_L2TIME, "GAISLER_L2TIME"},
-	{GAISLER_L2C, "GAISLER_L2C"},
-	{GAISLER_PLUGPLAY, "GAISLER_PLUGPLAY"},
-	{GAISLER_SPW, "GAISLER_SPW"},
-	{GAISLER_SPW2, "GAISLER_SPW2"},
-	{GAISLER_EHCI, "GAISLER_EHCI"},
-	{GAISLER_UHCI, "GAISLER_UHCI"},
-	{GAISLER_AHBSTAT, "GAISLER_AHBSTAT"},
-	{GAISLER_DDR2SPA, "GAISLER_DDR2SPA"},
-	{GAISLER_DDRSPA, "GAISLER_DDRSPA"},
-	{0, NULL}
-};
-
-static ambapp_device_name esa_devices[] = {
-	{ESA_LEON2, "ESA_LEON2"},
-	{ESA_MCTRL, "ESA_MCTRL"},
-	{0, NULL}
-};
-
-static ambapp_device_name opencores_devices[] = {
-	{OPENCORES_PCIBR, "OPENCORES_PCIBR"},
-	{OPENCORES_ETHMAC, "OPENCORES_ETHMAC"},
-	{0, NULL}
-};
-
 typedef struct {
 	unsigned int vendor_id;
 	char *name;
+	char *desc;
 	ambapp_device_name *devices;
 } ambapp_vendor_devnames;
 
-static ambapp_vendor_devnames vendors[] = {
-	{VENDOR_GAISLER, "VENDOR_GAISLER", gaisler_devices},
-	{VENDOR_ESA, "VENDOR_ESA", esa_devices},
-	{VENDOR_OPENCORES, "VENDOR_OPENCORES", opencores_devices},
-	{0, NULL, 0}
+/** Vendor GAISLER devices */
+static ambapp_device_name GAISLER_devices[] = {
+	{GAISLER_LEON2DSU, "LEON2DSU", "Leon2 Debug Support Unit"},
+	{GAISLER_LEON3, "LEON3", "Leon3 SPARC V8 Processor"},
+	{GAISLER_LEON3DSU, "LEON3DSU", "Leon3 Debug Support Unit"},
+	{GAISLER_ETHAHB, "ETHAHB", "OC ethernet AHB interface"},
+	{GAISLER_APBMST, "APBMST", "AHB/APB Bridge"},
+	{GAISLER_AHBUART, "AHBUART", "AHB Debug UART"},
+	{GAISLER_SRCTRL, "SRCTRL", "Simple SRAM Controller"},
+	{GAISLER_SDCTRL, "SDCTRL", "PC133 SDRAM Controller"},
+	{GAISLER_SSRCTRL, "SSRCTRL", "Synchronous SRAM Controller"},
+	{GAISLER_APBUART, "APBUART", "Generic UART"},
+	{GAISLER_IRQMP, "IRQMP", "Multi-processor Interrupt Ctrl."},
+	{GAISLER_AHBRAM, "AHBRAM", "Single-port AHB SRAM module"},
+	{GAISLER_AHBDPRAM, "AHBDPRAM", "Dual-port AHB SRAM module"},
+	{GAISLER_GPTIMER, "GPTIMER", "Modular Timer Unit"},
+	{GAISLER_PCITRG, "PCITRG", "Simple 32-bit PCI Target"},
+	{GAISLER_PCISBRG, "PCISBRG", "Simple 32-bit PCI Bridge"},
+	{GAISLER_PCIFBRG, "PCIFBRG", "Fast 32-bit PCI Bridge"},
+	{GAISLER_PCITRACE, "PCITRACE", "32-bit PCI Trace Buffer"},
+	{GAISLER_DMACTRL, "DMACTRL", "AMBA DMA controller"},
+	{GAISLER_AHBTRACE, "AHBTRACE", "AMBA Trace Buffer"},
+	{GAISLER_DSUCTRL, "DSUCTRL", "DSU/ETH controller"},
+	{GAISLER_CANAHB, "CANAHB", "OC CAN AHB interface"},
+	{GAISLER_GPIO, "GPIO", "General Purpose I/O port"},
+	{GAISLER_AHBROM, "AHBROM", "Generic AHB ROM"},
+	{GAISLER_AHBJTAG, "AHBJTAG", "JTAG Debug Link"},
+	{GAISLER_ETHMAC, "ETHMAC", "GR Ethernet MAC"},
+	{GAISLER_SWNODE, "SWNODE", "SpaceWire Node Interface"},
+	{GAISLER_SPW, "SPW", "SpaceWire Serial Link"},
+	{GAISLER_AHB2AHB, "AHB2AHB", "AHB-to-AHB Bridge"},
+	{GAISLER_USBDC, "USBDC", "GR USB 2.0 Device Controller"},
+	{GAISLER_USB_DCL, "USB_DCL", "USB Debug Communication Link"},
+	{GAISLER_DDRMP, "DDRMP", "Multi-port DDR controller"},
+	{GAISLER_ATACTRL, "ATACTRL", "ATA controller"},
+	{GAISLER_DDRSP, "DDRSP", "Single-port DDR266 controller"},
+	{GAISLER_EHCI, "EHCI", "USB Enhanced Host Controller"},
+	{GAISLER_UHCI, "UHCI", "USB Universal Host Controller"},
+	{GAISLER_I2CMST, "I2CMST", "AMBA Wrapper for OC I2C-master"},
+	{GAISLER_SPW2, "SPW2", "GRSPW2 SpaceWire Serial Link"},
+	{GAISLER_AHBDMA, "AHBDMA", ""},
+	{GAISLER_NUHOSP3, "NUHOSP3", "Nuhorizons Spartan3 IO I/F"},
+	{GAISLER_CLKGATE, "CLKGATE", "Clock gating unit"},
+	{GAISLER_SPICTRL, "SPICTRL", "SPI Controller"},
+	{GAISLER_DDR2SP, "DDR2SP", "Single-port DDR2 controller"},
+	{GAISLER_SLINK, "SLINK", "SLINK Master"},
+	{GAISLER_GRTM, "GRTM", "CCSDS Telemetry Encoder"},
+	{GAISLER_GRTC, "GRTC", "CCSDS Telecommand Decoder"},
+	{GAISLER_GRPW, "GRPW", "PacketWire to AMBA AHB I/F"},
+	{GAISLER_GRCTM, "GRCTM", "CCSDS Time Manager"},
+	{GAISLER_GRHCAN, "GRHCAN", "ESA HurriCANe CAN with DMA"},
+	{GAISLER_GRFIFO, "GRFIFO", "FIFO Controller"},
+	{GAISLER_GRADCDAC, "GRADCDAC", "ADC / DAC Interface"},
+	{GAISLER_GRPULSE, "GRPULSE", "General Purpose I/O with Pulses"},
+	{GAISLER_GRTIMER, "GRTIMER", "Timer Unit with Latches"},
+	{GAISLER_AHB2PP, "AHB2PP", "AMBA AHB to Packet Parallel I/F"},
+	{GAISLER_GRVERSION, "GRVERSION", "Version and Revision Register"},
+	{GAISLER_APB2PW, "APB2PW", "PacketWire Transmit Interface"},
+	{GAISLER_PW2APB, "PW2APB", "PacketWire Receive Interface"},
+	{GAISLER_GRCAN, "GRCAN", "CAN Controller with DMA"},
+	{GAISLER_I2CSLV, "I2CSLV", "I2C Slave"},
+	{GAISLER_U16550, "U16550", "Simple 16550 UART"},
+	{GAISLER_AHBMST_EM, "AHBMST_EM", "AMBA Master Emulator"},
+	{GAISLER_AHBSLV_EM, "AHBSLV_EM", "AMBA Slave Emulator"},
+	{GAISLER_GRTESTMOD, "GRTESTMOD", "Test report module"},
+	{GAISLER_ASCS, "ASCS", "ASCS Master"},
+	{GAISLER_IPMVBCTRL, "IPMVBCTRL", "IPM-bus/MVBC memory controller"},
+	{GAISLER_SPIMCTRL, "SPIMCTRL", "SPI Memory Controller"},
+	{GAISLER_L4STAT, "L4STAT", "Leon4 Statistics Module"},
+	{GAISLER_LEON4, "LEON4", "Leon4 SPARC V8 Processor"},
+	{GAISLER_LEON4DSU, "LEON4DSU", "Leon4 Debug Support Unit"},
+	{GAISLER_PWM, "PWM", "PWM generator"},
+	{GAISLER_L2CACHE, "L2CACHE", "L2-Cache Controller"},
+	{GAISLER_SDCTRL64, "SDCTRL64", "64-bit PC133 SDRAM Controller"},
+	{GAISLER_GR1553B, "GR1553B", "MIL-STD-1553B Interface"},
+	{GAISLER_1553TST, "1553TST", "MIL-STD-1553B Test Device"},
+	{GAISLER_GRIOMMU, "GRIOMMU", "I/O Memory Management Unit"},
+	{GAISLER_FTAHBRAM, "FTAHBRAM", "Generic FT AHB SRAM module"},
+	{GAISLER_FTSRCTRL, "FTSRCTRL", "Simple FT SRAM Controller"},
+	{GAISLER_AHBSTAT, "AHBSTAT", "AHB Status Register"},
+	{GAISLER_LEON3FT, "LEON3FT", "Leon3-FT SPARC V8 Processor"},
+	{GAISLER_FTMCTRL, "FTMCTRL", "Memory controller with EDAC"},
+	{GAISLER_FTSDCTRL, "FTSDCTRL", "FT PC133 SDRAM Controller"},
+	{GAISLER_FTSRCTRL8, "FTSRCTRL8", "FT 8-bit SRAM/16-bit IO Ctrl"},
+	{GAISLER_MEMSCRUB, "MEMSCRUB", "AHB Memory Scrubber"},
+	{GAISLER_FTSDCTRL64, "FTSDCTRL64", "64-bit FT SDRAM Controller"},
+	{GAISLER_APBPS2, "APBPS2", "PS2 interface"},
+	{GAISLER_VGACTRL, "VGACTRL", "VGA controller"},
+	{GAISLER_LOGAN, "LOGAN", "On chip Logic Analyzer"},
+	{GAISLER_SVGACTRL, "SVGACTRL", "SVGA frame buffer"},
+	{GAISLER_T1AHB, "T1AHB", "Niagara T1 PCX/AHB bridge"},
+	{GAISLER_MP7WRAP, "MP7WRAP", "CoreMP7 wrapper"},
+	{GAISLER_GRSYSMON, "GRSYSMON", "AMBA wrapper for System Monitor"},
+	{GAISLER_GRACECTRL, "GRACECTRL", "System ACE I/F Controller"},
+	{GAISLER_ATAHBSLV, "ATAHBSLV", "AMBA Test Framework AHB Slave"},
+	{GAISLER_ATAHBMST, "ATAHBMST", "AMBA Test Framework AHB Master"},
+	{GAISLER_ATAPBSLV, "ATAPBSLV", "AMBA Test Framework APB Slave"},
+	{GAISLER_B1553BC, "B1553BC", "AMBA Wrapper for Core1553BBC"},
+	{GAISLER_B1553RT, "B1553RT", "AMBA Wrapper for Core1553BRT"},
+	{GAISLER_B1553BRM, "B1553BRM", "AMBA Wrapper for Core1553BRM"},
+	{GAISLER_AES, "AES", "Advanced Encryption Standard"},
+	{GAISLER_ECC, "ECC", "Elliptic Curve Cryptography"},
+	{GAISLER_PCIF, "PCIF", "AMBA Wrapper for CorePCIF"},
+	{GAISLER_CLKMOD, "CLKMOD", "CPU Clock Switching Ctrl module"},
+	{GAISLER_HAPSTRAK, "HAPSTRAK", "HAPS HapsTrak I/O Port"},
+	{GAISLER_TEST_1X2, "TEST_1X2", "HAPS TEST_1x2 interface"},
+	{GAISLER_WILD2AHB, "WILD2AHB", "WildCard CardBus interface"},
+	{GAISLER_BIO1, "BIO1", "Basic I/O board BIO1"},
+	{GAISLER_AESDMA, "AESDMA", "AES 256 DMA"},
+	{GAISLER_SATCAN, "SATCAN", "SatCAN controller"},
+	{GAISLER_CANMUX, "CANMUX", "CAN Bus multiplexer"},
+	{GAISLER_GRTMRX, "GRTMRX", "CCSDS Telemetry Receiver"},
+	{GAISLER_GRTCTX, "GRTCTX", "CCSDS Telecommand Transmitter"},
+	{GAISLER_GRTMDESC, "GRTMDESC", "CCSDS Telemetry Descriptor"},
+	{GAISLER_GRTMVC, "GRTMVC", "CCSDS Telemetry VC Generator"},
+	{GAISLER_GEFFE, "GEFFE", "Geffe Generator"},
+	{GAISLER_GPREG, "GPREG", "General Purpose Register"},
+	{GAISLER_GRTMPAHB, "GRTMPAHB", "CCSDS Telemetry VC AHB Input"},
+	{GAISLER_SPWCUC, "SPWCUC", "CCSDS CUC / SpaceWire I/F"},
+	{GAISLER_SPW2_DMA, "SPW2_DMA", "GRSPW Router DMA interface"},
+	{GAISLER_SPWROUTER, "SPWROUTER", "GRSPW Router"},
+	{0, NULL, NULL}
 };
 
-static char *ambapp_get_devname(ambapp_device_name * devs, int id)
+
+/** Vendor PENDER devices */
+static ambapp_device_name PENDER_devices[] = {
+	{0, NULL, NULL}
+};
+
+
+/** Vendor ESA devices */
+static ambapp_device_name ESA_devices[] = {
+	{ESA_LEON2, "LEON2", "Leon2 SPARC V8 Processor"},
+	{ESA_LEON2APB, "LEON2APB", "Leon2 Peripheral Bus"},
+	{ESA_IRQ, "IRQ", "Leon2 Interrupt Controller"},
+	{ESA_TIMER, "TIMER", "Leon2 Timer"},
+	{ESA_UART, "UART", "Leon2 UART"},
+	{ESA_CFG, "CFG", "Leon2 Configuration Register"},
+	{ESA_IO, "IO", "Leon2 Input/Output"},
+	{ESA_MCTRL, "MCTRL", "Leon2 Memory Controller"},
+	{ESA_PCIARB, "PCIARB", "PCI Arbiter"},
+	{ESA_HURRICANE, "HURRICANE", "HurriCANe/HurryAMBA CAN Ctrl"},
+	{ESA_SPW_RMAP, "SPW_RMAP", "UoD/Saab SpaceWire/RMAP link"},
+	{ESA_AHBUART, "AHBUART", "Leon2 AHB Debug UART"},
+	{ESA_SPWA, "SPWA", "ESA/ASTRIUM SpaceWire link"},
+	{ESA_BOSCHCAN, "BOSCHCAN", "SSC/BOSCH CAN Ctrl"},
+	{ESA_IRQ2, "IRQ2", "Leon2 Secondary Irq Controller"},
+	{ESA_AHBSTAT, "AHBSTAT", "Leon2 AHB Status Register"},
+	{ESA_WPROT, "WPROT", "Leon2 Write Protection"},
+	{ESA_WPROT2, "WPROT2", "Leon2 Extended Write Protection"},
+	{ESA_PDEC3AMBA, "PDEC3AMBA", "ESA CCSDS PDEC3AMBA TC Decoder"},
+	{ESA_PTME3AMBA, "PTME3AMBA", "ESA CCSDS PTME3AMBA TM Encoder"},
+	{0, NULL, NULL}
+};
+
+
+/** Vendor ASTRIUM devices */
+static ambapp_device_name ASTRIUM_devices[] = {
+	{0, NULL, NULL}
+};
+
+
+/** Vendor OPENCHIP devices */
+static ambapp_device_name OPENCHIP_devices[] = {
+	{OPENCHIP_APBGPIO, "APBGPIO", "APB General Purpose IO"},
+	{OPENCHIP_APBI2C, "APBI2C", "APB I2C Interface"},
+	{OPENCHIP_APBSPI, "APBSPI", "APB SPI Interface"},
+	{OPENCHIP_APBCHARLCD, "APBCHARLCD", "APB Character LCD"},
+	{OPENCHIP_APBPWM, "APBPWM", "APB PWM"},
+	{OPENCHIP_APBPS2, "APBPS2", "APB PS/2 Interface"},
+	{OPENCHIP_APBMMCSD, "APBMMCSD", "APB MMC/SD Card Interface"},
+	{OPENCHIP_APBNAND, "APBNAND", "APB NAND(SmartMedia) Interface"},
+	{OPENCHIP_APBLPC, "APBLPC", "APB LPC Interface"},
+	{OPENCHIP_APBCF, "APBCF", "APB CompactFlash (IDE)"},
+	{OPENCHIP_APBSYSACE, "APBSYSACE", "APB SystemACE Interface"},
+	{OPENCHIP_APB1WIRE, "APB1WIRE", "APB 1-Wire Interface"},
+	{OPENCHIP_APBJTAG, "APBJTAG", "APB JTAG TAP Master"},
+	{OPENCHIP_APBSUI, "APBSUI", "APB Simple User Interface"},
+	{0, NULL, NULL}
+};
+
+
+/** Vendor OPENCORES devices */
+static ambapp_device_name OPENCORES_devices[] = {
+	{OPENCORES_PCIBR, "PCIBR", "PCI Bridge"},
+	{OPENCORES_ETHMAC, "ETHMAC", "Ethernet MAC"},
+	{0, NULL}
+};
+
+
+/** Vendor CONTRIB devices */
+static ambapp_device_name CONTRIB_devices[] = {
+	{CONTRIB_CORE1, "CORE1", "Contributed core 1"},
+	{CONTRIB_CORE2, "CORE2", "Contributed core 2"},
+	{0, NULL, NULL}
+};
+
+
+/** Vendor EONIC devices */
+static ambapp_device_name EONIC_devices[] = {
+	{0, NULL, NULL}
+};
+
+
+/** Vendor RADIONOR devices */
+static ambapp_device_name RADIONOR_devices[] = {
+	{0, NULL, NULL}
+};
+
+
+/** Vendor GLEICHMANN devices */
+static ambapp_device_name GLEICHMANN_devices[] = {
+	{GLEICHMANN_CUSTOM, "CUSTOM", "Custom device"},
+	{GLEICHMANN_GEOLCD01, "GEOLCD01", "GEOLCD01 graphics system"},
+	{GLEICHMANN_DAC, "DAC", "Sigma delta DAC"},
+	{GLEICHMANN_HPI, "HPI", "AHB-to-HPI bridge"},
+	{GLEICHMANN_SPI, "SPI", "SPI master"},
+	{GLEICHMANN_HIFC, "HIFC", "Human interface controller"},
+	{GLEICHMANN_ADCDAC, "ADCDAC", "Sigma delta ADC/DAC"},
+	{GLEICHMANN_SPIOC, "SPIOC", ""},
+	{GLEICHMANN_AC97, "AC97", ""},
+	{0, NULL, NULL}
+};
+
+
+/** Vendor MENTA devices */
+static ambapp_device_name MENTA_devices[] = {
+	{0, NULL, NULL}
+};
+
+
+/** Vendor SUN devices */
+static ambapp_device_name SUN_devices[] = {
+	{SUN_T1, "T1", "Niagara T1 SPARC V9 Processor"},
+	{SUN_S1, "S1", "Niagara S1 SPARC V9 Processor"},
+	{0, NULL, NULL}
+};
+
+
+/** Vendor MOVIDIA devices */
+static ambapp_device_name MOVIDIA_devices[] = {
+	{0, NULL, NULL}
+};
+
+
+/** Vendor ORBITA devices */
+static ambapp_device_name ORBITA_devices[] = {
+	{ORBITA_1553B, "1553B", "MIL-STD-1553B Controller"},
+	{ORBITA_429, "429", "429 Interface"},
+	{ORBITA_SPI, "SPI", "SPI Interface"},
+	{ORBITA_I2C, "I2C", "I2C Interface"},
+	{ORBITA_SMARTCARD, "SMARTCARD", "Smart Card Reader"},
+	{ORBITA_SDCARD, "SDCARD", "SD Card Reader"},
+	{ORBITA_UART16550, "UART16550", "16550 UART"},
+	{ORBITA_CRYPTO, "CRYPTO", "Crypto Engine"},
+	{ORBITA_SYSIF, "SYSIF", "System Interface"},
+	{ORBITA_PIO, "PIO", "Programmable IO module"},
+	{ORBITA_RTC, "RTC", "Real-Time Clock"},
+	{ORBITA_COLORLCD, "COLORLCD", "Color LCD Controller"},
+	{ORBITA_PCI, "PCI", "PCI Module"},
+	{ORBITA_DSP, "DSP", "DPS Co-Processor"},
+	{ORBITA_USBHOST, "USBHOST", "USB Host"},
+	{ORBITA_USBDEV, "USBDEV", "USB Device"},
+	{0, NULL, NULL}
+};
+
+
+/** Vendor SYNOPSYS devices */
+static ambapp_device_name SYNOPSYS_devices[] = {
+	{0, NULL, NULL}
+};
+
+
+/** Vendor NASA devices */
+static ambapp_device_name NASA_devices[] = {
+	{NASA_EP32, "EP32", "EP32 Forth processor"},
+	{0, NULL, NULL}
+};
+
+
+/** Vendor CAL devices */
+static ambapp_device_name CAL_devices[] = {
+	{CAL_DDRCTRL, "DDRCTRL", ""},
+	{0, NULL, NULL}
+};
+
+
+/** Vendor EMBEDDIT devices */
+static ambapp_device_name EMBEDDIT_devices[] = {
+	{0, NULL, NULL}
+};
+
+
+/** Vendor CETON devices */
+static ambapp_device_name CETON_devices[] = {
+	{0, NULL, NULL}
+};
+
+
+/** Vendor S3 devices */
+static ambapp_device_name S3_devices[] = {
+	{0, NULL, NULL}
+};
+
+
+/** Vendor ACTEL devices */
+static ambapp_device_name ACTEL_devices[] = {
+	{ACTEL_COREMP7, "COREMP7", "CoreMP7 Processor"},
+	{0, NULL, NULL}
+};
+
+
+/** Vendor APPLECORE devices */
+static ambapp_device_name APPLECORE_devices[] = {
+	{APPLECORE_UTLEON3, "UTLEON3", "AppleCore uT-LEON3 Processor"},
+	{APPLECORE_UTLEON3DSU, "UTLEON3DSU", "AppleCore uT-LEON3 DSU"},
+	{0, NULL, NULL}
+};
+
+
+/** Vendors and their devices */
+static ambapp_vendor_devnames vendors[] = {
+	{VENDOR_GAISLER, "GAISLER", "Gaisler Research", GAISLER_devices},
+	{VENDOR_PENDER, "PENDER", "", PENDER_devices},
+	{VENDOR_ESA, "ESA", "European Space Agency", ESA_devices},
+	{VENDOR_ASTRIUM, "ASTRIUM", "", ASTRIUM_devices},
+	{VENDOR_OPENCHIP, "OPENCHIP", "OpenChip", OPENCHIP_devices},
+	{VENDOR_OPENCORES, "OPENCORES", "OpenCores", OPENCORES_devices},
+	{VENDOR_CONTRIB, "CONTRIB", "Various contributions", CONTRIB_devices},
+	{VENDOR_EONIC, "EONIC", "Eonic BV", EONIC_devices},
+	{VENDOR_RADIONOR, "RADIONOR", "Radionor Communications", RADIONOR_devices},
+	{VENDOR_GLEICHMANN, "GLEICHMANN", "Gleichmann Electronics", GLEICHMANN_devices},
+	{VENDOR_MENTA, "MENTA", "Menta", MENTA_devices},
+	{VENDOR_SUN, "SUN", "Sun Microsystems", SUN_devices},
+	{VENDOR_MOVIDIA, "MOVIDIA", "", MOVIDIA_devices},
+	{VENDOR_ORBITA, "ORBITA", "Orbita", ORBITA_devices},
+	{VENDOR_SYNOPSYS, "SYNOPSYS", "Synopsys Inc.", SYNOPSYS_devices},
+	{VENDOR_NASA, "NASA", "NASA", NASA_devices},
+	{VENDOR_S3, "S3", "S3 Group", S3_devices},
+	{VENDOR_CAL, "CAL", "", CAL_devices},
+	{VENDOR_EMBEDDIT, "EMBEDDIT", "Embedd.it", EMBEDDIT_devices},
+	{VENDOR_CETON, "CETON", "Ceton Corporation", CETON_devices},
+	{VENDOR_ACTEL, "ACTEL", "Actel Corporation", ACTEL_devices},
+	{VENDOR_APPLECORE, "APPLECORE", "AppleCore", APPLECORE_devices},
+	{0, NULL, NULL, NULL}
+};
+
+static ambapp_device_name *ambapp_get_dev(ambapp_device_name *devs, int id)
 {
 	if (!devs)
 		return NULL;
 
 	while (devs->device_id > 0) {
 		if (devs->device_id == id)
-			return devs->name;
+			return devs;
 		devs++;
 	}
 	return NULL;
@@ -109,10 +392,31 @@
 char *ambapp_device_id2str(int vendor, int id)
 {
 	ambapp_vendor_devnames *ven = &vendors[0];
+	ambapp_device_name *dev;
 
 	while (ven->vendor_id > 0) {
 		if (ven->vendor_id == vendor) {
-			return ambapp_get_devname(ven->devices, id);
+			dev = ambapp_get_dev(ven->devices, id);
+			if (!dev)
+				return NULL;
+			return dev->name;
+		}
+		ven++;
+	}
+	return NULL;
+}
+
+char *ambapp_device_id2desc(int vendor, int id)
+{
+	ambapp_vendor_devnames *ven = &vendors[0];
+	ambapp_device_name *dev;
+
+	while (ven->vendor_id > 0) {
+		if (ven->vendor_id == vendor) {
+			dev = ambapp_get_dev(ven->devices, id);
+			if (!dev)
+				return NULL;
+			return dev->desc;
 		}
 		ven++;
 	}
@@ -134,101 +438,106 @@
 
 static char *unknown = "unknown";
 
+char *ambapp_type_names[4] = {
+	/* 0 */ "UNUSED",
+	/* 1 */ "apb",
+	/* 2 */ "ahbmem",
+	/* 3 */ "ahbio"
+};
+
 /* Print one APB device */
-void ambapp_print_apb(apbctrl_pp_dev * apb, ambapp_ahbdev * apbmst, int index)
+void ambapp_print_apb(ambapp_apbdev *dev, int index)
 {
 	char *dev_str, *ven_str;
-	int irq, ver, vendor, deviceid;
-	unsigned int address, apbmst_base, mask;
+	unsigned int freq;
 
-	vendor = amba_vendor(apb->conf);
-	deviceid = amba_device(apb->conf);
-	irq = amba_irq(apb->conf);
-	ver = amba_ver(apb->conf);
-	apbmst_base = apbmst->address[0] & LEON3_IO_AREA;
-	address = (apbmst_base | (((apb->bar & 0xfff00000) >> 12))) &
-	    (((apb->bar & 0x0000fff0) << 4) | 0xfff00000);
-
-	mask = amba_membar_mask(apb->bar) << 8;
-	mask = ((~mask) & 0x000fffff) + 1;
-
-	ven_str = ambapp_vendor_id2str(vendor);
+	ven_str = ambapp_vendor_id2str(dev->vendor);
 	if (!ven_str) {
 		ven_str = unknown;
 		dev_str = unknown;
 	} else {
-		dev_str = ambapp_device_id2str(vendor, deviceid);
+		dev_str = ambapp_device_id2str(dev->vendor, dev->device);
 		if (!dev_str)
 			dev_str = unknown;
 	}
 
-	printf("0x%02x:0x%02x:0x%02x: %s  %s\n"
+	/* Get Frequency of Core */
+	freq = ambapp_bus_freq(&ambapp_plb, dev->ahb_bus_index);
+
+	printf("0x%02x:0x%02x:0x%02x: %s  %s  (%dkHz)\n"
 	       "   apb: 0x%08x - 0x%08x\n"
 	       "   irq: %-2d (ver: %-2d)\n",
-	       index, vendor, deviceid, ven_str, dev_str, address,
-	       address + mask, irq, ver);
+	       index, dev->vendor, dev->device, ven_str, dev_str, freq / 1000,
+	       dev->address, dev->address + (dev->mask-1),
+	       dev->irq, dev->ver);
 }
 
-void ambapp_print_ahb(ahbctrl_pp_dev * ahb, int index)
+void ambapp_print_ahb(ambapp_ahbdev *dev, int index)
 {
-	char *dev_str, *ven_str;
-	int irq, ver, vendor, deviceid;
-	unsigned int addr, mask;
-	int j;
+	char *dev_str, *ven_str, *type_str;
+	int i;
+	unsigned int freq;
 
-	vendor = amba_vendor(ahb->conf);
-	deviceid = amba_device(ahb->conf);
-	irq = amba_irq(ahb->conf);
-	ver = amba_ver(ahb->conf);
-
-	ven_str = ambapp_vendor_id2str(vendor);
+	ven_str = ambapp_vendor_id2str(dev->vendor);
 	if (!ven_str) {
 		ven_str = unknown;
 		dev_str = unknown;
 	} else {
-		dev_str = ambapp_device_id2str(vendor, deviceid);
+		dev_str = ambapp_device_id2str(dev->vendor, dev->device);
 		if (!dev_str)
 			dev_str = unknown;
 	}
 
-	printf("0x%02x:0x%02x:0x%02x: %s  %s\n",
-	       index, vendor, deviceid, ven_str, dev_str);
+	/* Get Frequency of Core */
+	freq = ambapp_bus_freq(&ambapp_plb, dev->ahb_bus_index);
 
-	for (j = 0; j < 4; j++) {
-		addr = amba_membar_start(ahb->bars[j]);
-		if (amba_membar_type(ahb->bars[j]) == 0)
+	printf("0x%02x:0x%02x:0x%02x: %s  %s  (%dkHz)\n",
+	       index, dev->vendor, dev->device, ven_str, dev_str, freq / 1000);
+
+	for (i = 0; i < 4; i++) {
+		if (dev->type[i] == 0)
 			continue;
-		if (amba_membar_type(ahb->bars[j]) == AMBA_TYPE_AHBIO)
-			addr = AMBA_TYPE_AHBIO_ADDR(addr);
-		mask = amba_membar_mask(ahb->bars[j]) << 20;
-		printf("   mem: 0x%08x - 0x%08x\n", addr, addr + ((~mask) + 1));
+		type_str = ambapp_type_names[dev->type[i]];
+		printf("   %-7s: 0x%08x - 0x%08x\n", type_str, dev->address[i],
+			dev->address[i] + (dev->mask[i]-1));
 	}
 
-	printf("   irq: %-2d (ver: %d)\n", irq, ver);
+	printf("   irq: %-2d (ver: %d)\n", dev->irq, dev->ver);
 }
 
 int do_ambapp_print(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
+	int index;
+	ambapp_apbdev apbdev;
+	ambapp_ahbdev ahbdev;
 
 	/* Print AHB Masters */
-	puts("--------- AHB Masters ---------\n");
-	ambapp_apb_print = 0;
-	ambapp_ahb_print = 1;
-	ambapp_ahbmst_count(99, 99);	/* Get vendor&device 99 = nonexistent... */
+	puts("\n--------- AHB Masters ---------\n");
+	index = 0;
+	while (ambapp_ahbmst_find(&ambapp_plb, 0, 0, index, &ahbdev) == 1) {
+		/* Found a AHB Master Device */
+		ambapp_print_ahb(&ahbdev, index);
+		index++;
+	}
 
 	/* Print AHB Slaves */
-	puts("--------- AHB Slaves  ---------\n");
-	ambapp_ahbslv_count(99, 99);	/* Get vendor&device 99 = nonexistent... */
+	puts("\n--------- AHB Slaves  ---------\n");
+	index = 0;
+	while (ambapp_ahbslv_find(&ambapp_plb, 0, 0, index, &ahbdev) == 1) {
+		/* Found a AHB Slave Device */
+		ambapp_print_ahb(&ahbdev, index);
+		index++;
+	}
 
 	/* Print APB Slaves */
-	puts("--------- APB Slaves  ---------\n");
-	ambapp_apb_print = 1;
-	ambapp_ahb_print = 0;
-	ambapp_apb_count(99, 99);	/* Get vendor&device 99 = nonexistent... */
+	puts("\n--------- APB Slaves  ---------\n");
+	index = 0;
+	while (ambapp_apb_find(&ambapp_plb, 0, 0, index, &apbdev) == 1) {
+		/* Found a APB Slave Device */
+		ambapp_print_apb(&apbdev, index);
+		index++;
+	}
 
-	/* Reset, no futher printing */
-	ambapp_apb_print = 0;
-	ambapp_ahb_print = 0;
 	puts("\n");
 	return 0;
 }
@@ -240,16 +549,18 @@
 
 	while (vend->vendor_id && vend->name) {
 		vend->name = (char *)((unsigned int)vend->name + gd->reloc_off);
-		vend->devices =
-		    (ambapp_device_name *) ((unsigned int)vend->devices +
-					    gd->reloc_off);;
+		vend->desc = (char *)((unsigned int)vend->desc + gd->reloc_off);
+		vend->devices = (ambapp_device_name *)
+			((unsigned int)vend->devices + gd->reloc_off);
 		dev = vend->devices;
 		vend++;
 		if (!dev)
 			continue;
 		while (dev->device_id && dev->name) {
 			dev->name =
-			    (char *)((unsigned int)dev->name + gd->reloc_off);;
+			    (char *)((unsigned int)dev->name + gd->reloc_off);
+			dev->desc =
+			    (char *)((unsigned int)dev->desc + gd->reloc_off);
 			dev++;
 		}
 	}
diff --git a/common/cmd_gpt.c b/common/cmd_gpt.c
index c56fe15..e3c0297 100644
--- a/common/cmd_gpt.c
+++ b/common/cmd_gpt.c
@@ -218,6 +218,23 @@
 			strcpy((char *)parts[i].uuid, p);
 			free(val);
 		}
+#ifdef CONFIG_PARTITION_TYPE_GUID
+		/* guid */
+		val = extract_val(tok, "type");
+		if (val) {
+			/* 'type' is optional */
+			if (extract_env(val, &p))
+				p = val;
+			if (strlen(p) >= sizeof(parts[i].type_guid)) {
+				printf("Wrong type guid format for partition %d\n",
+				       i);
+				errno = -4;
+				goto err;
+			}
+			strcpy((char *)parts[i].type_guid, p);
+			free(val);
+		}
+#endif
 		/* name */
 		val = extract_val(tok, "name");
 		if (!val) { /* name is mandatory */
diff --git a/common/fb_mmc.c b/common/fb_mmc.c
index 0c48cf9..b480e76 100644
--- a/common/fb_mmc.c
+++ b/common/fb_mmc.c
@@ -6,32 +6,24 @@
 
 #include <config.h>
 #include <common.h>
+#include <errno.h>
+#include <fastboot.h>
 #include <fb_mmc.h>
+#include <image-sparse.h>
 #include <part.h>
-#include <aboot.h>
 #include <sparse_format.h>
 #include <mmc.h>
+#include <div64.h>
 
 #ifndef CONFIG_FASTBOOT_GPT_NAME
 #define CONFIG_FASTBOOT_GPT_NAME GPT_ENTRY_NAME
 #endif
 
-/* The 64 defined bytes plus the '\0' */
-#define RESPONSE_LEN	(64 + 1)
-
 static char *response_str;
 
-void fastboot_fail(const char *s)
-{
-	strncpy(response_str, "FAIL\0", 5);
-	strncat(response_str, s, RESPONSE_LEN - 4 - 1);
-}
-
-void fastboot_okay(const char *s)
-{
-	strncpy(response_str, "OKAY\0", 5);
-	strncat(response_str, s, RESPONSE_LEN - 4 - 1);
-}
+struct fb_mmc_sparse {
+	block_dev_desc_t	*dev_desc;
+};
 
 static int get_partition_info_efi_by_name_or_alias(block_dev_desc_t *dev_desc,
 		const char *name, disk_partition_t *info)
@@ -55,6 +47,24 @@
 	return ret;
 }
 
+
+static int fb_mmc_sparse_write(struct sparse_storage *storage,
+			       void *priv,
+			       unsigned int offset,
+			       unsigned int size,
+			       char *data)
+{
+	struct fb_mmc_sparse *sparse = priv;
+	block_dev_desc_t *dev_desc = sparse->dev_desc;
+	int ret;
+
+	ret = dev_desc->block_write(dev_desc->dev, offset, size, data);
+	if (!ret)
+		return -EIO;
+
+	return ret;
+}
+
 static void write_raw_image(block_dev_desc_t *dev_desc, disk_partition_t *info,
 		const char *part_name, void *buffer,
 		unsigned int download_bytes)
@@ -64,11 +74,11 @@
 
 	/* determine number of blocks to write */
 	blkcnt = ((download_bytes + (info->blksz - 1)) & ~(info->blksz - 1));
-	blkcnt = blkcnt / info->blksz;
+	blkcnt = lldiv(blkcnt, info->blksz);
 
 	if (blkcnt > info->size) {
 		error("too large for partition: '%s'\n", part_name);
-		fastboot_fail("too large for partition");
+		fastboot_fail(response_str, "too large for partition");
 		return;
 	}
 
@@ -78,17 +88,18 @@
 				     buffer);
 	if (blks != blkcnt) {
 		error("failed writing to device %d\n", dev_desc->dev);
-		fastboot_fail("failed writing to device");
+		fastboot_fail(response_str, "failed writing to device");
 		return;
 	}
 
 	printf("........ wrote " LBAFU " bytes to '%s'\n", blkcnt * info->blksz,
 	       part_name);
-	fastboot_okay("");
+	fastboot_okay(response_str, "");
 }
 
-void fb_mmc_flash_write(const char *cmd, void *download_buffer,
-			unsigned int download_bytes, char *response)
+void fb_mmc_flash_write(const char *cmd, unsigned int session_id,
+			void *download_buffer, unsigned int download_bytes,
+			char *response)
 {
 	block_dev_desc_t *dev_desc;
 	disk_partition_t info;
@@ -99,7 +110,7 @@
 	dev_desc = get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
 	if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
 		error("invalid mmc device\n");
-		fastboot_fail("invalid mmc device");
+		fastboot_fail(response_str, "invalid mmc device");
 		return;
 	}
 
@@ -109,29 +120,47 @@
 		if (is_valid_gpt_buf(dev_desc, download_buffer)) {
 			printf("%s: invalid GPT - refusing to write to flash\n",
 			       __func__);
-			fastboot_fail("invalid GPT partition");
+			fastboot_fail(response_str, "invalid GPT partition");
 			return;
 		}
 		if (write_mbr_and_gpt_partitions(dev_desc, download_buffer)) {
 			printf("%s: writing GPT partitions failed\n", __func__);
-			fastboot_fail("writing GPT partitions failed");
+			fastboot_fail(response_str,
+				      "writing GPT partitions failed");
 			return;
 		}
 		printf("........ success\n");
-		fastboot_okay("");
+		fastboot_okay(response_str, "");
 		return;
 	} else if (get_partition_info_efi_by_name_or_alias(dev_desc, cmd, &info)) {
 		error("cannot find partition: '%s'\n", cmd);
-		fastboot_fail("cannot find partition");
+		fastboot_fail(response_str, "cannot find partition");
 		return;
 	}
 
-	if (is_sparse_image(download_buffer))
-		write_sparse_image(dev_desc, &info, cmd, download_buffer,
-				   download_bytes);
-	else
+	if (is_sparse_image(download_buffer)) {
+		struct fb_mmc_sparse sparse_priv;
+		sparse_storage_t sparse;
+
+		sparse_priv.dev_desc = dev_desc;
+
+		sparse.block_sz = info.blksz;
+		sparse.start = info.start;
+		sparse.size = info.size;
+		sparse.name = cmd;
+		sparse.write = fb_mmc_sparse_write;
+
+		printf("Flashing sparse image at offset " LBAFU "\n",
+		       info.start);
+
+		store_sparse_image(&sparse, &sparse_priv, session_id,
+				   download_buffer);
+	} else {
 		write_raw_image(dev_desc, &info, cmd, download_buffer,
 				download_bytes);
+	}
+
+	fastboot_okay(response_str, "");
 }
 
 void fb_mmc_erase(const char *cmd, char *response)
@@ -144,7 +173,7 @@
 
 	if (mmc == NULL) {
 		error("invalid mmc device");
-		fastboot_fail("invalid mmc device");
+		fastboot_fail(response_str, "invalid mmc device");
 		return;
 	}
 
@@ -154,14 +183,14 @@
 	dev_desc = get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
 	if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
 		error("invalid mmc device");
-		fastboot_fail("invalid mmc device");
+		fastboot_fail(response_str, "invalid mmc device");
 		return;
 	}
 
 	ret = get_partition_info_efi_by_name_or_alias(dev_desc, cmd, &info);
 	if (ret) {
 		error("cannot find partition: '%s'", cmd);
-		fastboot_fail("cannot find partition");
+		fastboot_fail(response_str, "cannot find partition");
 		return;
 	}
 
@@ -180,11 +209,11 @@
 	blks = dev_desc->block_erase(dev_desc->dev, blks_start, blks_size);
 	if (blks != blks_size) {
 		error("failed erasing from device %d", dev_desc->dev);
-		fastboot_fail("failed erasing from device");
+		fastboot_fail(response_str, "failed erasing from device");
 		return;
 	}
 
 	printf("........ erased " LBAFU " bytes from '%s'\n",
 	       blks_size * info.blksz, cmd);
-	fastboot_okay("");
+	fastboot_okay(response_str, "");
 }
diff --git a/common/fb_nand.c b/common/fb_nand.c
new file mode 100644
index 0000000..9ca8602
--- /dev/null
+++ b/common/fb_nand.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2014 Broadcom Corporation.
+ * Copyright 2015 Free Electrons.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+#include <common.h>
+
+#include <fastboot.h>
+#include <image-sparse.h>
+#include <sparse_format.h>
+
+#include <linux/mtd/mtd.h>
+#include <jffs2/jffs2.h>
+#include <nand.h>
+
+static char *response_str;
+
+struct fb_nand_sparse {
+	nand_info_t		*nand;
+	struct part_info	*part;
+};
+
+__weak int board_fastboot_erase_partition_setup(char *name)
+{
+	return 0;
+}
+
+__weak int board_fastboot_write_partition_setup(char *name)
+{
+	return 0;
+}
+
+static int fb_nand_lookup(const char *partname, char *response,
+			  nand_info_t **nand,
+			  struct part_info **part)
+{
+	struct mtd_device *dev;
+	int ret;
+	u8 pnum;
+
+	ret = mtdparts_init();
+	if (ret) {
+		error("Cannot initialize MTD partitions\n");
+		fastboot_fail(response_str, "cannot init mtdparts");
+		return ret;
+	}
+
+	ret = find_dev_and_part(partname, &dev, &pnum, part);
+	if (ret) {
+		error("cannot find partition: '%s'", partname);
+		fastboot_fail(response_str, "cannot find partition");
+		return ret;
+	}
+
+	if (dev->id->type != MTD_DEV_TYPE_NAND) {
+		error("partition '%s' is not stored on a NAND device",
+		      partname);
+		fastboot_fail(response_str, "not a NAND device");
+		return -EINVAL;
+	}
+
+	*nand = &nand_info[dev->id->num];
+
+	return 0;
+}
+
+static int _fb_nand_erase(nand_info_t *nand, struct part_info *part)
+{
+	nand_erase_options_t opts;
+	int ret;
+
+	memset(&opts, 0, sizeof(opts));
+	opts.offset = part->offset;
+	opts.length = part->size;
+	opts.quiet = 1;
+
+	printf("Erasing blocks 0x%llx to 0x%llx\n",
+	       part->offset, part->offset + part->size);
+
+	ret = nand_erase_opts(nand, &opts);
+	if (ret)
+		return ret;
+
+	printf("........ erased 0x%llx bytes from '%s'\n",
+	       part->size, part->name);
+
+	return 0;
+}
+
+static int _fb_nand_write(nand_info_t *nand, struct part_info *part,
+			  void *buffer, unsigned int offset,
+			  unsigned int length, size_t *written)
+{
+	int flags = WITH_WR_VERIFY;
+
+#ifdef CONFIG_FASTBOOT_FLASH_NAND_TRIMFFS
+	flags |= WITH_DROP_FFS;
+#endif
+
+	return nand_write_skip_bad(nand, offset, &length, written,
+				   part->size - (offset - part->offset),
+				   buffer, flags);
+}
+
+static int fb_nand_sparse_write(struct sparse_storage *storage,
+				void *priv,
+				unsigned int offset,
+				unsigned int size,
+				char *data)
+{
+	struct fb_nand_sparse *sparse = priv;
+	size_t written;
+	int ret;
+
+	ret = _fb_nand_write(sparse->nand, sparse->part, data,
+			     offset * storage->block_sz,
+			     size * storage->block_sz, &written);
+	if (ret < 0) {
+		printf("Failed to write sparse chunk\n");
+		return ret;
+	}
+
+	return written / storage->block_sz;
+}
+
+void fb_nand_flash_write(const char *partname, unsigned int session_id,
+			 void *download_buffer, unsigned int download_bytes,
+			 char *response)
+{
+	struct part_info *part;
+	nand_info_t *nand = NULL;
+	int ret;
+
+	/* initialize the response buffer */
+	response_str = response;
+
+	ret = fb_nand_lookup(partname, response, &nand, &part);
+	if (ret) {
+		error("invalid NAND device");
+		fastboot_fail(response_str, "invalid NAND device");
+		return;
+	}
+
+	ret = board_fastboot_write_partition_setup(part->name);
+	if (ret)
+		return;
+
+	if (is_sparse_image(download_buffer)) {
+		struct fb_nand_sparse sparse_priv;
+		sparse_storage_t sparse;
+
+		sparse_priv.nand = nand;
+		sparse_priv.part = part;
+
+		sparse.block_sz = nand->writesize;
+		sparse.start = part->offset / sparse.block_sz;
+		sparse.size = part->size  / sparse.block_sz;
+		sparse.name = part->name;
+		sparse.write = fb_nand_sparse_write;
+
+		ret = store_sparse_image(&sparse, &sparse_priv, session_id,
+					 download_buffer);
+	} else {
+		printf("Flashing raw image at offset 0x%llx\n",
+		       part->offset);
+
+		ret = _fb_nand_write(nand, part, download_buffer, part->offset,
+				     download_bytes, NULL);
+
+		printf("........ wrote %u bytes to '%s'\n",
+		       download_bytes, part->name);
+	}
+
+	if (ret) {
+		fastboot_fail(response_str, "error writing the image");
+		return;
+	}
+
+	fastboot_okay(response_str, "");
+}
+
+void fb_nand_erase(const char *partname, char *response)
+{
+	struct part_info *part;
+	nand_info_t *nand = NULL;
+	int ret;
+
+	/* initialize the response buffer */
+	response_str = response;
+
+	ret = fb_nand_lookup(partname, response, &nand, &part);
+	if (ret) {
+		error("invalid NAND device");
+		fastboot_fail(response_str, "invalid NAND device");
+		return;
+	}
+
+	ret = board_fastboot_erase_partition_setup(part->name);
+	if (ret)
+		return;
+
+	ret = _fb_nand_erase(nand, part);
+	if (ret) {
+		error("failed erasing from device %s", nand->name);
+		fastboot_fail(response_str, "failed erasing from device");
+		return;
+	}
+
+	fastboot_okay(response_str, "");
+}
diff --git a/common/image-sparse.c b/common/image-sparse.c
new file mode 100644
index 0000000..dffe844
--- /dev/null
+++ b/common/image-sparse.c
@@ -0,0 +1,393 @@
+/*
+ * Copyright (c) 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Copyright (c) 2009-2014, The Linux Foundation. All rights reserved.
+ * Portions Copyright 2014 Broadcom Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of The Linux Foundation nor
+ *       the names of its contributors may be used to endorse or promote
+ *       products derived from this software without specific prior written
+ *       permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * NOTE:
+ *   Although it is very similar, this license text is not identical
+ *   to the "BSD-3-Clause", therefore, DO NOT MODIFY THIS LICENSE TEXT!
+ */
+
+#include <config.h>
+#include <common.h>
+#include <div64.h>
+#include <errno.h>
+#include <image-sparse.h>
+#include <malloc.h>
+#include <part.h>
+#include <sparse_format.h>
+
+#include <linux/math64.h>
+
+typedef struct sparse_buffer {
+	void	*data;
+	u32	length;
+	u32	repeat;
+	u16	type;
+} sparse_buffer_t;
+
+static uint32_t last_offset;
+
+static unsigned int sparse_get_chunk_data_size(sparse_header_t *sparse,
+					       chunk_header_t *chunk)
+{
+	return chunk->total_sz - sparse->chunk_hdr_sz;
+}
+
+static unsigned int sparse_block_size_to_storage(unsigned int size,
+						 sparse_storage_t *storage,
+						 sparse_header_t *sparse)
+{
+	return size * sparse->blk_sz / storage->block_sz;
+}
+
+static bool sparse_chunk_has_buffer(chunk_header_t *chunk)
+{
+	switch (chunk->chunk_type) {
+	case CHUNK_TYPE_RAW:
+	case CHUNK_TYPE_FILL:
+		return true;
+
+	default:
+		return false;
+	}
+}
+
+static sparse_header_t *sparse_parse_header(void **data)
+{
+	/* Read and skip over sparse image header */
+	sparse_header_t *sparse_header = (sparse_header_t *) *data;
+
+	*data += sparse_header->file_hdr_sz;
+
+	debug("=== Sparse Image Header ===\n");
+	debug("magic: 0x%x\n", sparse_header->magic);
+	debug("major_version: 0x%x\n", sparse_header->major_version);
+	debug("minor_version: 0x%x\n", sparse_header->minor_version);
+	debug("file_hdr_sz: %d\n", sparse_header->file_hdr_sz);
+	debug("chunk_hdr_sz: %d\n", sparse_header->chunk_hdr_sz);
+	debug("blk_sz: %d\n", sparse_header->blk_sz);
+	debug("total_blks: %d\n", sparse_header->total_blks);
+	debug("total_chunks: %d\n", sparse_header->total_chunks);
+
+	return sparse_header;
+}
+
+static int sparse_parse_fill_chunk(sparse_header_t *sparse,
+				   chunk_header_t *chunk)
+{
+	unsigned int chunk_data_sz = sparse_get_chunk_data_size(sparse, chunk);
+
+	if (chunk_data_sz != sizeof(uint32_t))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int sparse_parse_raw_chunk(sparse_header_t *sparse,
+				  chunk_header_t *chunk)
+{
+	unsigned int chunk_data_sz = sparse_get_chunk_data_size(sparse, chunk);
+
+	/* Check if the data size is a multiple of the main block size */
+	if (chunk_data_sz % sparse->blk_sz)
+		return -EINVAL;
+
+	/* Check that the chunk size is consistent */
+	if ((chunk_data_sz / sparse->blk_sz) != chunk->chunk_sz)
+		return -EINVAL;
+
+	return 0;
+}
+
+static chunk_header_t *sparse_parse_chunk(sparse_header_t *sparse,
+					  void **image)
+{
+	chunk_header_t *chunk = (chunk_header_t *) *image;
+	int ret;
+
+	debug("=== Chunk Header ===\n");
+	debug("chunk_type: 0x%x\n", chunk->chunk_type);
+	debug("chunk_data_sz: 0x%x\n", chunk->chunk_sz);
+	debug("total_size: 0x%x\n", chunk->total_sz);
+
+	switch (chunk->chunk_type) {
+	case CHUNK_TYPE_RAW:
+		ret = sparse_parse_raw_chunk(sparse, chunk);
+		if (ret)
+			return NULL;
+		break;
+
+	case CHUNK_TYPE_FILL:
+		ret = sparse_parse_fill_chunk(sparse, chunk);
+		if (ret)
+			return NULL;
+		break;
+
+	case CHUNK_TYPE_DONT_CARE:
+	case CHUNK_TYPE_CRC32:
+		debug("Ignoring chunk\n");
+		break;
+
+	default:
+		printf("%s: Unknown chunk type: %x\n", __func__,
+		       chunk->chunk_type);
+		return NULL;
+	}
+
+	*image += sparse->chunk_hdr_sz;
+
+	return chunk;
+}
+
+static int sparse_get_fill_buffer(sparse_header_t *sparse,
+				  chunk_header_t *chunk,
+				  sparse_buffer_t *buffer,
+				  unsigned int blk_sz,
+				  void *data)
+{
+	int i;
+
+	buffer->type = CHUNK_TYPE_FILL;
+
+	/*
+	 * We create a buffer of one block, and ask it to be
+	 * repeated as many times as needed.
+	 */
+	buffer->length = blk_sz;
+	buffer->repeat = (chunk->chunk_sz * sparse->blk_sz) / blk_sz;
+
+	buffer->data = memalign(ARCH_DMA_MINALIGN,
+				ROUNDUP(blk_sz,
+					ARCH_DMA_MINALIGN));
+	if (!buffer->data)
+		return -ENOMEM;
+
+	for (i = 0; i < (buffer->length / sizeof(uint32_t)); i++)
+		((uint32_t *)buffer->data)[i] = *(uint32_t *)(data);
+
+	return 0;
+}
+
+static int sparse_get_raw_buffer(sparse_header_t *sparse,
+				 chunk_header_t *chunk,
+				 sparse_buffer_t *buffer,
+				 unsigned int blk_sz,
+				 void *data)
+{
+	unsigned int chunk_data_sz = sparse_get_chunk_data_size(sparse, chunk);
+
+	buffer->type = CHUNK_TYPE_RAW;
+	buffer->length = chunk_data_sz;
+	buffer->data = data;
+	buffer->repeat = 1;
+
+	return 0;
+}
+
+static sparse_buffer_t *sparse_get_data_buffer(sparse_header_t *sparse,
+					       chunk_header_t *chunk,
+					       unsigned int blk_sz,
+					       void **image)
+{
+	unsigned int chunk_data_sz = sparse_get_chunk_data_size(sparse, chunk);
+	sparse_buffer_t *buffer;
+	void *data = *image;
+	int ret;
+
+	*image += chunk_data_sz;
+
+	if (!sparse_chunk_has_buffer(chunk))
+		return NULL;
+
+	buffer = calloc(sizeof(sparse_buffer_t), 1);
+	if (!buffer)
+		return NULL;
+
+	switch (chunk->chunk_type) {
+	case CHUNK_TYPE_RAW:
+		ret = sparse_get_raw_buffer(sparse, chunk, buffer, blk_sz,
+					    data);
+		if (ret)
+			return NULL;
+		break;
+
+	case CHUNK_TYPE_FILL:
+		ret = sparse_get_fill_buffer(sparse, chunk, buffer, blk_sz,
+					     data);
+		if (ret)
+			return NULL;
+		break;
+
+	default:
+		return NULL;
+	}
+
+	debug("=== Buffer ===\n");
+	debug("length: 0x%x\n", buffer->length);
+	debug("repeat: 0x%x\n", buffer->repeat);
+	debug("type: 0x%x\n", buffer->type);
+	debug("data: 0x%p\n", buffer->data);
+
+	return buffer;
+}
+
+static void sparse_put_data_buffer(sparse_buffer_t *buffer)
+{
+	if (buffer->type == CHUNK_TYPE_FILL)
+		free(buffer->data);
+
+	free(buffer);
+}
+
+int store_sparse_image(sparse_storage_t *storage, void *storage_priv,
+		       unsigned int session_id, void *data)
+{
+	unsigned int chunk, offset;
+	sparse_header_t *sparse_header;
+	chunk_header_t *chunk_header;
+	sparse_buffer_t *buffer;
+	uint32_t start;
+	uint32_t total_blocks = 0;
+	uint32_t skipped = 0;
+	int i;
+
+	debug("=== Storage ===\n");
+	debug("name: %s\n", storage->name);
+	debug("block_size: 0x%x\n", storage->block_sz);
+	debug("start: 0x%x\n", storage->start);
+	debug("size: 0x%x\n", storage->size);
+	debug("write: 0x%p\n", storage->write);
+	debug("priv: 0x%p\n", storage_priv);
+
+	sparse_header = sparse_parse_header(&data);
+	if (!sparse_header) {
+		printf("sparse header issue\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * Verify that the sparse block size is a multiple of our
+	 * storage backend block size
+	 */
+	div_u64_rem(sparse_header->blk_sz, storage->block_sz, &offset);
+	if (offset) {
+		printf("%s: Sparse image block size issue [%u]\n",
+		       __func__, sparse_header->blk_sz);
+		return -EINVAL;
+	}
+
+	/*
+	 * If it's a new flashing session, start at the beginning of
+	 * the partition. If not, then simply resume where we were.
+	 */
+	if (session_id > 0)
+		start = last_offset;
+	else
+		start = storage->start;
+
+	printf("Flashing sparse image on partition %s at offset 0x%x (ID: %d)\n",
+	       storage->name, start * storage->block_sz, session_id);
+
+	/* Start processing chunks */
+	for (chunk = 0; chunk < sparse_header->total_chunks; chunk++) {
+		uint32_t blkcnt;
+
+		chunk_header = sparse_parse_chunk(sparse_header, &data);
+		if (!chunk_header) {
+			printf("Unknown chunk type");
+			return -EINVAL;
+		}
+
+		/*
+		 * If we have a DONT_CARE type, just skip the blocks
+		 * and go on parsing the rest of the chunks
+		 */
+		if (chunk_header->chunk_type == CHUNK_TYPE_DONT_CARE) {
+			skipped += sparse_block_size_to_storage(chunk_header->chunk_sz,
+								storage,
+								sparse_header);
+			continue;
+		}
+
+		/* Retrieve the buffer we're going to write */
+		buffer = sparse_get_data_buffer(sparse_header, chunk_header,
+						storage->block_sz, &data);
+		if (!buffer)
+			continue;
+
+		blkcnt = (buffer->length / storage->block_sz) * buffer->repeat;
+
+		if ((start + total_blocks + blkcnt) >
+		    (storage->start + storage->size)) {
+			printf("%s: Request would exceed partition size!\n",
+			       __func__);
+			return -EINVAL;
+		}
+
+		for (i = 0; i < buffer->repeat; i++) {
+			unsigned long buffer_blk_cnt;
+			int ret;
+
+			buffer_blk_cnt = buffer->length / storage->block_sz;
+
+			ret = storage->write(storage, storage_priv,
+					     start + total_blocks,
+					     buffer_blk_cnt,
+					     buffer->data);
+			if (ret < 0) {
+				printf("%s: Write %d failed %d\n",
+				       __func__, i, ret);
+				return ret;
+			}
+
+			total_blocks += ret;
+		}
+
+		sparse_put_data_buffer(buffer);
+	}
+
+	debug("Wrote %d blocks, skipped %d, expected to write %d blocks\n",
+	      total_blocks, skipped,
+	      sparse_block_size_to_storage(sparse_header->total_blks,
+					   storage, sparse_header));
+	printf("........ wrote %d blocks to '%s'\n", total_blocks,
+	       storage->name);
+
+	if ((total_blocks + skipped) !=
+	    sparse_block_size_to_storage(sparse_header->total_blks,
+					 storage, sparse_header)) {
+		printf("sparse image write failure\n");
+		return -EIO;
+	}
+
+	last_offset = start + total_blocks;
+
+	return 0;
+}
diff --git a/common/init/board_init.c b/common/init/board_init.c
index e74b63b..1c6126d 100644
--- a/common/init/board_init.c
+++ b/common/init/board_init.c
@@ -50,8 +50,7 @@
 #endif
 	arch_setup_gd(gd_ptr);
 
-#if defined(CONFIG_SYS_MALLOC_F) && \
-	(!defined(CONFIG_SPL_BUILD) || !defined(CONFIG_SYS_SPL_MALLOC_START))
+#if defined(CONFIG_SYS_MALLOC_F)
 	top -= CONFIG_SYS_MALLOC_F_LEN;
 	gd->malloc_base = top;
 #endif
diff --git a/configs/A13-OLinuXino_defconfig b/configs/A13-OLinuXino_defconfig
index 34bf4ea..390803a 100644
--- a/configs/A13-OLinuXino_defconfig
+++ b/configs/A13-OLinuXino_defconfig
@@ -4,6 +4,7 @@
 CONFIG_DRAM_CLK=408
 CONFIG_DRAM_EMR1=0
 CONFIG_MMC0_CD_PIN="PG0"
+CONFIG_USB0_VBUS_DET="PG1"
 CONFIG_USB1_VBUS_PIN="PG11"
 CONFIG_AXP_GPIO=y
 # CONFIG_VIDEO_HDMI is not set
@@ -11,6 +12,8 @@
 CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH=y
 CONFIG_VIDEO_LCD_POWER="AXP0-0"
 CONFIG_VIDEO_LCD_BL_PWM="PB2"
+CONFIG_USB_MUSB_SUNXI=y
+CONFIG_USB_MUSB_GADGET=y
 CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-olinuxino"
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_SPL=y
diff --git a/configs/Cubietruck_defconfig b/configs/Cubietruck_defconfig
index efe2317..bb9c42a 100644
--- a/configs/Cubietruck_defconfig
+++ b/configs/Cubietruck_defconfig
@@ -14,3 +14,8 @@
 # CONFIG_CMD_FPGA is not set
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_USB_EHCI_HCD=y
+CONFIG_USB0_ID_DET="PH19"
+CONFIG_USB0_VBUS_DET="PH22"
+CONFIG_USB0_VBUS_PIN="PH17"
+CONFIG_USB_MUSB_SUNXI=y
+CONFIG_USB_MUSB_GADGET=y
diff --git a/configs/bct-brettl2_defconfig b/configs/bct-brettl2_defconfig
index 9e6f1ee..efcfe4d 100644
--- a/configs/bct-brettl2_defconfig
+++ b/configs/bct-brettl2_defconfig
@@ -2,4 +2,3 @@
 CONFIG_TARGET_BCT_BRETTL2=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_NET_RANDOM_ETHADDR=y
-CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED=y
diff --git a/configs/bf526-ezbrd_defconfig b/configs/bf526-ezbrd_defconfig
index c8dab57..624484c 100644
--- a/configs/bf526-ezbrd_defconfig
+++ b/configs/bf526-ezbrd_defconfig
@@ -3,4 +3,3 @@
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_SPI_FLASH=y
-CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED=y
diff --git a/configs/bf527-ezkit-v2_defconfig b/configs/bf527-ezkit-v2_defconfig
index 74f352e..ad29088 100644
--- a/configs/bf527-ezkit-v2_defconfig
+++ b/configs/bf527-ezkit-v2_defconfig
@@ -3,5 +3,4 @@
 CONFIG_SYS_EXTRA_OPTIONS="BF527_EZKIT_REV_2_1"
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_SPI_FLASH=y
-CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED=y
 CONFIG_LIB_RAND=y
diff --git a/configs/bf527-ezkit_defconfig b/configs/bf527-ezkit_defconfig
index 0cc81cc..8752267 100644
--- a/configs/bf527-ezkit_defconfig
+++ b/configs/bf527-ezkit_defconfig
@@ -3,5 +3,4 @@
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_SPI_FLASH=y
-CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED=y
 CONFIG_NET_TFTP_VARS=n
diff --git a/configs/bf537-stamp_defconfig b/configs/bf537-stamp_defconfig
index 294d0d9..a60c1b7 100644
--- a/configs/bf537-stamp_defconfig
+++ b/configs/bf537-stamp_defconfig
@@ -3,4 +3,3 @@
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_SPI_FLASH=y
-CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED=y
diff --git a/configs/bf538f-ezkit_defconfig b/configs/bf538f-ezkit_defconfig
index 668f9cb..0edaae5 100644
--- a/configs/bf538f-ezkit_defconfig
+++ b/configs/bf538f-ezkit_defconfig
@@ -1,6 +1,5 @@
 CONFIG_BLACKFIN=y
 CONFIG_TARGET_BF538F_EZKIT=y
 # CONFIG_CMD_SETEXPR is not set
-CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED=y
 # CONFIG_REGEX is not set
 CONFIG_LIB_RAND=y
diff --git a/configs/grsim_defconfig b/configs/grsim_defconfig
index f0fa23f..d2f709f 100644
--- a/configs/grsim_defconfig
+++ b/configs/grsim_defconfig
@@ -11,4 +11,10 @@
 # CONFIG_CMD_MEMORY is not set
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_SETEXPR is not set
+# CONFIG_CMD_NET is not set
 # CONFIG_CMD_NFS is not set
+CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_APBUART=y
+CONFIG_DEBUG_UART_BASE=0x80000100
+CONFIG_DEBUG_UART_CLOCK=40000000
diff --git a/configs/hrcon_dh_defconfig b/configs/hrcon_dh_defconfig
new file mode 100644
index 0000000..a059dd9
--- /dev/null
+++ b/configs/hrcon_dh_defconfig
@@ -0,0 +1,5 @@
+CONFIG_SYS_EXTRA_OPTIONS="HRCON_DH"
+
+CONFIG_PPC=y
+CONFIG_MPC83xx=y
+CONFIG_TARGET_HRCON=y
diff --git a/configs/kwb_defconfig b/configs/kwb_defconfig
index f82fcf3..0bbe0a7 100644
--- a/configs/kwb_defconfig
+++ b/configs/kwb_defconfig
@@ -3,6 +3,9 @@
 CONFIG_SPL=y
 CONFIG_SYS_EXTRA_OPTIONS="SERIAL1,CONS_INDEX=1"
 CONFIG_SYS_PROMPT="U-Boot (BuR V2.0)# "
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_BOOTM is not set
+# CONFIG_CMD_GO is not set
 # CONFIG_CMD_IMI is not set
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_XIMG is not set
diff --git a/configs/qemu-x86_defconfig b/configs/qemu-x86_defconfig
index f4cc862..366ccc4 100644
--- a/configs/qemu-x86_defconfig
+++ b/configs/qemu-x86_defconfig
@@ -15,9 +15,12 @@
 CONFIG_OF_CONTROL=y
 CONFIG_CPU=y
 CONFIG_SPI_FLASH=y
-CONFIG_NETDEVICES=y
+CONFIG_DM_ETH=y
 CONFIG_E1000=y
+CONFIG_DM_PCI=y
 CONFIG_DM_RTC=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
 CONFIG_VIDEO_VESA=y
 CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
 CONFIG_FRAMEBUFFER_VESA_MODE_111=y
diff --git a/configs/strider_con_defconfig b/configs/strider_con_defconfig
new file mode 100644
index 0000000..74ef69e
--- /dev/null
+++ b/configs/strider_con_defconfig
@@ -0,0 +1,7 @@
+CONFIG_SYS_EXTRA_OPTIONS="STRIDER_CON"
+CONFIG_PPC=y
+CONFIG_MPC83xx=y
+CONFIG_TARGET_STRIDER=y
+CONFIG_AUTOBOOT_KEYED=y
+CONFIG_AUTOBOOT_STOP_STR=" "
+# CONFIG_CMD_SETEXPR is not set
diff --git a/configs/strider_cpu_defconfig b/configs/strider_cpu_defconfig
new file mode 100644
index 0000000..fc0a823
--- /dev/null
+++ b/configs/strider_cpu_defconfig
@@ -0,0 +1,7 @@
+CONFIG_SYS_EXTRA_OPTIONS="STRIDER_CPU"
+CONFIG_PPC=y
+CONFIG_MPC83xx=y
+CONFIG_TARGET_STRIDER=y
+CONFIG_AUTOBOOT_KEYED=y
+CONFIG_AUTOBOOT_STOP_STR=" "
+# CONFIG_CMD_SETEXPR is not set
diff --git a/disk/part.c b/disk/part.c
index e57a252..909712e 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -392,6 +392,9 @@
 	/* The common case is no UUID support */
 	info->uuid[0] = 0;
 #endif
+#ifdef CONFIG_PARTITION_TYPE_GUID
+	info->type_guid[0] = 0;
+#endif
 
 	switch (dev_desc->part_type) {
 #ifdef CONFIG_MAC_PARTITION
@@ -532,6 +535,9 @@
 #ifdef CONFIG_PARTITION_UUIDS
 		info->uuid[0] = 0;
 #endif
+#ifdef CONFIG_PARTITION_TYPE_GUID
+		info->type_guid[0] = 0;
+#endif
 
 		return 0;
 	}
@@ -639,6 +645,9 @@
 #ifdef CONFIG_PARTITION_UUIDS
 		info->uuid[0] = 0;
 #endif
+#ifdef CONFIG_PARTITION_TYPE_GUID
+		info->type_guid[0] = 0;
+#endif
 
 		ret = 0;
 		goto cleanup;
diff --git a/disk/part_efi.c b/disk/part_efi.c
index 15627f2..ea9c615 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -223,6 +223,10 @@
 		uuid_bin = (unsigned char *)gpt_pte[i].partition_type_guid.b;
 		uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID);
 		printf("\ttype:\t%s\n", uuid);
+#ifdef CONFIG_PARTITION_TYPE_GUID
+		if (!uuid_guid_get_str(uuid_bin, uuid))
+			printf("\ttype:\t%s\n", uuid);
+#endif
 		uuid_bin = (unsigned char *)gpt_pte[i].unique_partition_guid.b;
 		uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID);
 		printf("\tguid:\t%s\n", uuid);
@@ -283,6 +287,10 @@
 	uuid_bin_to_str(gpt_pte[part - 1].unique_partition_guid.b, info->uuid,
 			UUID_STR_FORMAT_GUID);
 #endif
+#ifdef CONFIG_PARTITION_TYPE_GUID
+	uuid_bin_to_str(gpt_pte[part - 1].partition_type_guid.b,
+			info->type_guid, UUID_STR_FORMAT_GUID);
+#endif
 
 	debug("%s: start 0x" LBAF ", size 0x" LBAF ", name %s\n", __func__,
 	      info->start, info->size, info->name);
@@ -419,6 +427,10 @@
 	char *str_uuid;
 	unsigned char *bin_uuid;
 #endif
+#ifdef CONFIG_PARTITION_TYPE_GUID
+	char *str_type_guid;
+	unsigned char *bin_type_guid;
+#endif
 
 	for (i = 0; i < parts; i++) {
 		/* partition starting lba */
@@ -445,9 +457,26 @@
 		else
 			gpt_e[i].ending_lba = cpu_to_le64(offset - 1);
 
+#ifdef CONFIG_PARTITION_TYPE_GUID
+		str_type_guid = partitions[i].type_guid;
+		bin_type_guid = gpt_e[i].partition_type_guid.b;
+		if (strlen(str_type_guid)) {
+			if (uuid_str_to_bin(str_type_guid, bin_type_guid,
+					    UUID_STR_FORMAT_GUID)) {
+				printf("Partition no. %d: invalid type guid: %s\n",
+				       i, str_type_guid);
+				return -1;
+			}
+		} else {
+			/* default partition type GUID */
+			memcpy(bin_type_guid,
+			       &PARTITION_BASIC_DATA_GUID, 16);
+		}
+#else
 		/* partition type GUID */
 		memcpy(gpt_e[i].partition_type_guid.b,
 			&PARTITION_BASIC_DATA_GUID, 16);
+#endif
 
 #ifdef CONFIG_PARTITION_UUIDS
 		str_uuid = partitions[i].uuid;
diff --git a/doc/README.gpt b/doc/README.gpt
index 59fdeeb..35902ce 100644
--- a/doc/README.gpt
+++ b/doc/README.gpt
@@ -31,7 +31,8 @@
 separated by hyphens, in the form 8-4-4-4-12 for a total of 36 characters
 (32 digits and 4 hyphens)
 
-For instance, GUID of Linux data partition: EBD0A0A2-B9E5-4433-87C0-68B6B72699C7
+For instance, GUID of Basic data partition: EBD0A0A2-B9E5-4433-87C0-68B6B72699C7
+and GUID of Linux filesystem data: 0FC63DAF-8483-4772-8E79-3D69D8477DE4
 
 Historically there are 5 methods to generate this number. The oldest one is
 combining machine's MAC address and timer (epoch) value.
@@ -170,6 +171,43 @@
 2. From u-boot prompt type:
    gpt write mmc 0 $partitions
 
+Partition type GUID:
+====================
+
+For created partition, the used partition type GUID is
+PARTITION_BASIC_DATA_GUID (EBD0A0A2-B9E5-4433-87C0-68B6B72699C7).
+
+If you define 'CONFIG_PARTITION_TYPE_GUID', a optionnal parameter 'type'
+can specify a other partition type guid:
+
+     "partitions=uuid_disk=...;name=u-boot,size=60MiB,uuid=...;
+	name=kernel,size=60MiB,uuid=...,
+	type=0FC63DAF-8483-4772-8E79-3D69D8477DE4;"
+
+Some strings can be also used at the place of known GUID :
+	"system" = PARTITION_SYSTEM_GUID
+	           (C12A7328-F81F-11D2-BA4B-00A0C93EC93B)
+	"mbr"    = LEGACY_MBR_PARTITION_GUID
+	           (024DEE41-33E7-11D3-9D69-0008C781F39F)
+	"msft"   = PARTITION_MSFT_RESERVED_GUID
+	           (E3C9E316-0B5C-4DB8-817D-F92DF00215AE)
+	"data"   = PARTITION_BASIC_DATA_GUID
+	            (EBD0A0A2-B9E5-4433-87C0-68B6B72699C7)
+	"linux"  = PARTITION_LINUX_FILE_SYSTEM_DATA_GUID
+	           (0FC63DAF-8483-4772-8E79-3D69D8477DE4)
+	"raid"   = PARTITION_LINUX_RAID_GUID
+	           (A19D880F-05FC-4D3B-A006-743F0F84911E)
+	"swap"   = PARTITION_LINUX_SWAP_GUID
+	           (0657FD6D-A4AB-43C4-84E5-0933C84B4F4F)
+	"lvm"    = PARTITION_LINUX_LVM_GUID
+	           (E6D6D379-F507-44C2-A23C-238F2A3DF928)
+
+    "partitions=uuid_disk=...;name=u-boot,size=60MiB,uuid=...;
+	name=kernel,size=60MiB,uuid=...,type=linux;"
+
+They are also used to display the type of partition in "part list" command.
+
+
 Useful info:
 ============
 
diff --git a/doc/git-mailrc b/doc/git-mailrc
index 6fe78a1..1b26e23 100644
--- a/doc/git-mailrc
+++ b/doc/git-mailrc
@@ -106,7 +106,7 @@
 alias sandbox        sjg
 alias sb             sandbox
 
-alias sparc          uboot, Daniel Hellstrom <daniel@gaisler.com>
+alias sparc          uboot, Francois Retief <fgretief@spaceteq.co.za>
 
 alias superh         uboot, iwamatsu
 alias sh             superh
diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c
index 82c6843..1ad638e 100644
--- a/drivers/block/ahci.c
+++ b/drivers/block/ahci.c
@@ -485,36 +485,6 @@
 #endif
 }
 
-
-#ifdef CONFIG_AHCI_SETFEATURES_XFER
-static void ahci_set_feature(u8 port)
-{
-	struct ahci_ioports *pp = &(probe_ent->port[port]);
-	void __iomem *port_mmio = pp->port_mmio;
-	u32 cmd_fis_len = 5;	/* five dwords */
-	u8 fis[20];
-
-	/* set feature */
-	memset(fis, 0, sizeof(fis));
-	fis[0] = 0x27;
-	fis[1] = 1 << 7;
-	fis[2] = ATA_CMD_SET_FEATURES;
-	fis[3] = SETFEATURES_XFER;
-	fis[12] = __ilog2(probe_ent->udma_mask + 1) + 0x40 - 0x01;
-
-	memcpy((unsigned char *)pp->cmd_tbl, fis, sizeof(fis));
-	ahci_fill_cmd_slot(pp, cmd_fis_len);
-	ahci_dcache_flush_sata_cmd(pp);
-	writel(1, port_mmio + PORT_CMD_ISSUE);
-	readl(port_mmio + PORT_CMD_ISSUE);
-
-	if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE,
-				WAIT_MS_DATAIO, 0x1)) {
-		printf("set feature error on port %d!\n", port);
-	}
-}
-#endif
-
 static int wait_spinup(void __iomem *port_mmio)
 {
 	ulong start;
@@ -956,9 +926,6 @@
 				printf("Can not start port %d\n", i);
 				continue;
 			}
-#ifdef CONFIG_AHCI_SETFEATURES_XFER
-			ahci_set_feature((u8) i);
-#endif
 		}
 	}
 }
@@ -1002,9 +969,6 @@
 				printf("Can not start port %d\n", i);
 				continue;
 			}
-#ifdef CONFIG_AHCI_SETFEATURES_XFER
-			ahci_set_feature((u8) i);
-#endif
 		}
 	}
 err_out:
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c
index 7371cd4..c8c8637 100644
--- a/drivers/gpio/pca953x.c
+++ b/drivers/gpio/pca953x.c
@@ -88,8 +88,10 @@
 		if (i2c_read(chip, addr << 1, 1, (u8*)&valw, 2))
 			return -1;
 
+		valw = le16_to_cpu(valw);
 		valw &= ~mask;
 		valw |= data;
+		valw = cpu_to_le16(valw);
 
 		return i2c_write(chip, addr << 1, 1, (u8*)&valw, 2);
 	}
@@ -107,7 +109,7 @@
 	} else {
 		if (i2c_read(chip, addr << 1, 1, (u8*)&valw, 2))
 			return -1;
-		*data = (int)valw;
+		*data = (uint)le16_to_cpu(valw);
 	}
 	return 0;
 }
diff --git a/drivers/i2c/ihs_i2c.c b/drivers/i2c/ihs_i2c.c
index 19fbe59..b05c15f 100644
--- a/drivers/i2c/ihs_i2c.c
+++ b/drivers/i2c/ihs_i2c.c
@@ -11,6 +11,32 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifdef CONFIG_SYS_I2C_IHS_DUAL
+#define I2C_SET_REG(fld, val) \
+	do { \
+		if (I2C_ADAP_HWNR & 0x10) \
+			FPGA_SET_REG(I2C_ADAP_HWNR & 0xf, i2c1.fld, val); \
+		else \
+			FPGA_SET_REG(I2C_ADAP_HWNR, i2c0.fld, val); \
+	} while (0)
+#else
+#define I2C_SET_REG(fld, val) \
+		FPGA_SET_REG(I2C_ADAP_HWNR, i2c0.fld, val)
+#endif
+
+#ifdef CONFIG_SYS_I2C_IHS_DUAL
+#define I2C_GET_REG(fld, val) \
+	do {					\
+		if (I2C_ADAP_HWNR & 0x10) \
+			FPGA_GET_REG(I2C_ADAP_HWNR & 0xf, i2c1.fld, val); \
+		else \
+			FPGA_GET_REG(I2C_ADAP_HWNR, i2c0.fld, val); \
+	} while (0)
+#else
+#define I2C_GET_REG(fld, val) \
+		FPGA_GET_REG(I2C_ADAP_HWNR, i2c0.fld, val)
+#endif
+
 enum {
 	I2CINT_ERROR_EV = 1 << 13,
 	I2CINT_TRANSMIT_EV = 1 << 14,
@@ -29,14 +55,14 @@
 	u16 val;
 	unsigned int ctr = 0;
 
-	FPGA_GET_REG(I2C_ADAP_HWNR, i2c.interrupt_status, &val);
+	I2C_GET_REG(interrupt_status, &val);
 	while (!(val & (I2CINT_ERROR_EV
 	       | (read ? I2CINT_RECEIVE_EV : I2CINT_TRANSMIT_EV)))) {
 		udelay(10);
 		if (ctr++ > 5000) {
 			return 1;
 		}
-		FPGA_GET_REG(I2C_ADAP_HWNR, i2c.interrupt_status, &val);
+		I2C_GET_REG(interrupt_status, &val);
 	}
 
 	return (val & I2CINT_ERROR_EV) ? 1 : 0;
@@ -47,30 +73,30 @@
 {
 	u16 val;
 
-	FPGA_SET_REG(I2C_ADAP_HWNR, i2c.interrupt_status, I2CINT_ERROR_EV
+	I2C_SET_REG(interrupt_status, I2CINT_ERROR_EV
 		     | I2CINT_RECEIVE_EV | I2CINT_TRANSMIT_EV);
-	FPGA_GET_REG(I2C_ADAP_HWNR, i2c.interrupt_status, &val);
+	I2C_GET_REG(interrupt_status, &val);
 
 	if (!read && len) {
 		val = buffer[0];
 
 		if (len > 1)
 			val |= buffer[1] << 8;
-		FPGA_SET_REG(I2C_ADAP_HWNR, i2c.write_mailbox_ext, val);
+		I2C_SET_REG(write_mailbox_ext, val);
 	}
 
-	FPGA_SET_REG(I2C_ADAP_HWNR, i2c.write_mailbox,
-		     I2CMB_NATIVE
-		     | (read ? 0 : I2CMB_WRITE)
-		     | (chip << 1)
-		     | ((len > 1) ? I2CMB_2BYTE : 0)
-		     | (is_last ? 0 : I2CMB_HOLD_BUS));
+	I2C_SET_REG(write_mailbox,
+		    I2CMB_NATIVE
+		    | (read ? 0 : I2CMB_WRITE)
+		    | (chip << 1)
+		    | ((len > 1) ? I2CMB_2BYTE : 0)
+		    | (is_last ? 0 : I2CMB_HOLD_BUS));
 
 	if (wait_for_int(read))
 		return 1;
 
 	if (read) {
-		FPGA_GET_REG(I2C_ADAP_HWNR, i2c.read_mailbox_ext, &val);
+		I2C_GET_REG(read_mailbox_ext, &val);
 		buffer[0] = val & 0xff;
 		if (len > 1)
 			buffer[1] = val >> 8;
@@ -109,7 +135,7 @@
 	if (len <= 0)
 		return 1;
 
-	if (ihs_i2c_address(chip, addr, alen, !read))
+	if (ihs_i2c_address(chip, addr, alen, len))
 		return 1;
 
 	while (len) {
@@ -163,7 +189,7 @@
 }
 
 static unsigned int ihs_i2c_set_bus_speed(struct i2c_adapter *adap,
-					     unsigned int speed)
+					  unsigned int speed)
 {
 	if (speed != adap->speed)
 		return 1;
@@ -179,6 +205,13 @@
 			 ihs_i2c_set_bus_speed,
 			 CONFIG_SYS_I2C_IHS_SPEED_0,
 			 CONFIG_SYS_I2C_IHS_SLAVE_0, 0)
+#ifdef CONFIG_SYS_I2C_IHS_DUAL
+U_BOOT_I2C_ADAP_COMPLETE(ihs0_1, ihs_i2c_init, ihs_i2c_probe,
+			 ihs_i2c_read, ihs_i2c_write,
+			 ihs_i2c_set_bus_speed,
+			 CONFIG_SYS_I2C_IHS_SPEED_0_1,
+			 CONFIG_SYS_I2C_IHS_SLAVE_0_1, 16)
+#endif
 #endif
 #ifdef CONFIG_SYS_I2C_IHS_CH1
 U_BOOT_I2C_ADAP_COMPLETE(ihs1, ihs_i2c_init, ihs_i2c_probe,
@@ -186,6 +219,13 @@
 			 ihs_i2c_set_bus_speed,
 			 CONFIG_SYS_I2C_IHS_SPEED_1,
 			 CONFIG_SYS_I2C_IHS_SLAVE_1, 1)
+#ifdef CONFIG_SYS_I2C_IHS_DUAL
+U_BOOT_I2C_ADAP_COMPLETE(ihs1_1, ihs_i2c_init, ihs_i2c_probe,
+			 ihs_i2c_read, ihs_i2c_write,
+			 ihs_i2c_set_bus_speed,
+			 CONFIG_SYS_I2C_IHS_SPEED_1_1,
+			 CONFIG_SYS_I2C_IHS_SLAVE_1_1, 17)
+#endif
 #endif
 #ifdef CONFIG_SYS_I2C_IHS_CH2
 U_BOOT_I2C_ADAP_COMPLETE(ihs2, ihs_i2c_init, ihs_i2c_probe,
@@ -193,6 +233,13 @@
 			 ihs_i2c_set_bus_speed,
 			 CONFIG_SYS_I2C_IHS_SPEED_2,
 			 CONFIG_SYS_I2C_IHS_SLAVE_2, 2)
+#ifdef CONFIG_SYS_I2C_IHS_DUAL
+U_BOOT_I2C_ADAP_COMPLETE(ihs2_1, ihs_i2c_init, ihs_i2c_probe,
+			 ihs_i2c_read, ihs_i2c_write,
+			 ihs_i2c_set_bus_speed,
+			 CONFIG_SYS_I2C_IHS_SPEED_2_1,
+			 CONFIG_SYS_I2C_IHS_SLAVE_2_1, 18)
+#endif
 #endif
 #ifdef CONFIG_SYS_I2C_IHS_CH3
 U_BOOT_I2C_ADAP_COMPLETE(ihs3, ihs_i2c_init, ihs_i2c_probe,
@@ -200,4 +247,11 @@
 			 ihs_i2c_set_bus_speed,
 			 CONFIG_SYS_I2C_IHS_SPEED_3,
 			 CONFIG_SYS_I2C_IHS_SLAVE_3, 3)
+#ifdef CONFIG_SYS_I2C_IHS_DUAL
+U_BOOT_I2C_ADAP_COMPLETE(ihs3_1, ihs_i2c_init, ihs_i2c_probe,
+			 ihs_i2c_read, ihs_i2c_write,
+			 ihs_i2c_set_bus_speed,
+			 CONFIG_SYS_I2C_IHS_SPEED_3_1,
+			 CONFIG_SYS_I2C_IHS_SLAVE_3_1, 19)
+#endif
 #endif
diff --git a/drivers/i2c/soft_i2c.c b/drivers/i2c/soft_i2c.c
index db9b402..05bf4d4 100644
--- a/drivers/i2c/soft_i2c.c
+++ b/drivers/i2c/soft_i2c.c
@@ -448,28 +448,84 @@
 /*
  * Register soft i2c adapters
  */
-U_BOOT_I2C_ADAP_COMPLETE(soft0, soft_i2c_init, soft_i2c_probe,
+U_BOOT_I2C_ADAP_COMPLETE(soft00, soft_i2c_init, soft_i2c_probe,
 			 soft_i2c_read, soft_i2c_write, NULL,
 			 CONFIG_SYS_I2C_SOFT_SPEED, CONFIG_SYS_I2C_SOFT_SLAVE,
 			 0)
 #if defined(I2C_SOFT_DECLARATIONS2)
-U_BOOT_I2C_ADAP_COMPLETE(soft1, soft_i2c_init, soft_i2c_probe,
+U_BOOT_I2C_ADAP_COMPLETE(soft01, soft_i2c_init, soft_i2c_probe,
 			 soft_i2c_read, soft_i2c_write, NULL,
 			 CONFIG_SYS_I2C_SOFT_SPEED_2,
 			 CONFIG_SYS_I2C_SOFT_SLAVE_2,
 			 1)
 #endif
 #if defined(I2C_SOFT_DECLARATIONS3)
-U_BOOT_I2C_ADAP_COMPLETE(soft2, soft_i2c_init, soft_i2c_probe,
+U_BOOT_I2C_ADAP_COMPLETE(soft02, soft_i2c_init, soft_i2c_probe,
 			 soft_i2c_read, soft_i2c_write, NULL,
 			 CONFIG_SYS_I2C_SOFT_SPEED_3,
 			 CONFIG_SYS_I2C_SOFT_SLAVE_3,
 			 2)
 #endif
 #if defined(I2C_SOFT_DECLARATIONS4)
-U_BOOT_I2C_ADAP_COMPLETE(soft3, soft_i2c_init, soft_i2c_probe,
+U_BOOT_I2C_ADAP_COMPLETE(soft03, soft_i2c_init, soft_i2c_probe,
 			 soft_i2c_read, soft_i2c_write, NULL,
 			 CONFIG_SYS_I2C_SOFT_SPEED_4,
 			 CONFIG_SYS_I2C_SOFT_SLAVE_4,
 			 3)
 #endif
+#if defined(I2C_SOFT_DECLARATIONS5)
+U_BOOT_I2C_ADAP_COMPLETE(soft04, soft_i2c_init, soft_i2c_probe,
+			 soft_i2c_read, soft_i2c_write, NULL,
+			 CONFIG_SYS_I2C_SOFT_SPEED_5,
+			 CONFIG_SYS_I2C_SOFT_SLAVE_5,
+			 4)
+#endif
+#if defined(I2C_SOFT_DECLARATIONS6)
+U_BOOT_I2C_ADAP_COMPLETE(soft05, soft_i2c_init, soft_i2c_probe,
+			 soft_i2c_read, soft_i2c_write, NULL,
+			 CONFIG_SYS_I2C_SOFT_SPEED_6,
+			 CONFIG_SYS_I2C_SOFT_SLAVE_6,
+			 5)
+#endif
+#if defined(I2C_SOFT_DECLARATIONS7)
+U_BOOT_I2C_ADAP_COMPLETE(soft06, soft_i2c_init, soft_i2c_probe,
+			 soft_i2c_read, soft_i2c_write, NULL,
+			 CONFIG_SYS_I2C_SOFT_SPEED_7,
+			 CONFIG_SYS_I2C_SOFT_SLAVE_7,
+			 6)
+#endif
+#if defined(I2C_SOFT_DECLARATIONS8)
+U_BOOT_I2C_ADAP_COMPLETE(soft07, soft_i2c_init, soft_i2c_probe,
+			 soft_i2c_read, soft_i2c_write, NULL,
+			 CONFIG_SYS_I2C_SOFT_SPEED_8,
+			 CONFIG_SYS_I2C_SOFT_SLAVE_8,
+			 7)
+#endif
+#if defined(I2C_SOFT_DECLARATIONS9)
+U_BOOT_I2C_ADAP_COMPLETE(soft08, soft_i2c_init, soft_i2c_probe,
+			 soft_i2c_read, soft_i2c_write, NULL,
+			 CONFIG_SYS_I2C_SOFT_SPEED_9,
+			 CONFIG_SYS_I2C_SOFT_SLAVE_9,
+			 8)
+#endif
+#if defined(I2C_SOFT_DECLARATIONS10)
+U_BOOT_I2C_ADAP_COMPLETE(soft09, soft_i2c_init, soft_i2c_probe,
+			 soft_i2c_read, soft_i2c_write, NULL,
+			 CONFIG_SYS_I2C_SOFT_SPEED_10,
+			 CONFIG_SYS_I2C_SOFT_SLAVE_10,
+			 9)
+#endif
+#if defined(I2C_SOFT_DECLARATIONS11)
+U_BOOT_I2C_ADAP_COMPLETE(soft10, soft_i2c_init, soft_i2c_probe,
+			 soft_i2c_read, soft_i2c_write, NULL,
+			 CONFIG_SYS_I2C_SOFT_SPEED_11,
+			 CONFIG_SYS_I2C_SOFT_SLAVE_11,
+			 10)
+#endif
+#if defined(I2C_SOFT_DECLARATIONS12)
+U_BOOT_I2C_ADAP_COMPLETE(soft11, soft_i2c_init, soft_i2c_probe,
+			 soft_i2c_read, soft_i2c_write, NULL,
+			 CONFIG_SYS_I2C_SOFT_SPEED_12,
+			 CONFIG_SYS_I2C_SOFT_SLAVE_12,
+			 11)
+#endif
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 26d34ae..4375abc 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -40,7 +40,7 @@
 	desc->flags = desc0;
 	desc->cnt = desc1;
 	desc->addr = desc2;
-	desc->next_addr = (unsigned int)desc + sizeof(struct dwmci_idmac);
+	desc->next_addr = (ulong)desc + sizeof(struct dwmci_idmac);
 }
 
 static void dwmci_prepare_data(struct dwmci_host *host,
@@ -58,7 +58,7 @@
 	dwmci_wait_reset(host, DWMCI_CTRL_FIFO_RESET);
 
 	data_start = (ulong)cur_idmac;
-	dwmci_writel(host, DWMCI_DBADDR, (unsigned int)cur_idmac);
+	dwmci_writel(host, DWMCI_DBADDR, (ulong)cur_idmac);
 
 	do {
 		flags = DWMCI_IDMAC_OWN | DWMCI_IDMAC_CH ;
@@ -70,7 +70,7 @@
 			cnt = data->blocksize * 8;
 
 		dwmci_set_idma_desc(cur_idmac, flags, cnt,
-				    (u32)bounce_buffer + (i * PAGE_SIZE));
+				    (ulong)bounce_buffer + (i * PAGE_SIZE));
 
 		if (blk_cnt <= 8)
 			break;
diff --git a/drivers/mmc/hi6220_dw_mmc.c b/drivers/mmc/hi6220_dw_mmc.c
index 731458c..b0d063c 100644
--- a/drivers/mmc/hi6220_dw_mmc.c
+++ b/drivers/mmc/hi6220_dw_mmc.c
@@ -48,7 +48,7 @@
 		return -ENOMEM;
 	}
 
-	host->ioaddr = (void *)regbase;
+	host->ioaddr = (void *)(ulong)regbase;
 	host->buswidth = bus_width;
 	host->bus_hz = MMC0_DEFAULT_FREQ;
 
diff --git a/drivers/mtd/mtd_uboot.c b/drivers/mtd/mtd_uboot.c
index c517b9c..2138695 100644
--- a/drivers/mtd/mtd_uboot.c
+++ b/drivers/mtd/mtd_uboot.c
@@ -37,7 +37,7 @@
 
 	return 0;
 #else
-	puts("offset is not a number\n");
+	puts("mtdparts support missing.\n");
 	return -1;
 #endif
 }
diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c
index d832464..384224d 100644
--- a/drivers/mtd/spi/sf_ops.c
+++ b/drivers/mtd/spi/sf_ops.c
@@ -268,9 +268,12 @@
 		return -1;
 	}
 
-	if (flash->flash_is_locked(flash, offset, len) > 0) {
-		printf("offset 0x%x is protected and cannot be erased\n", offset);
-		return -EINVAL;
+	if (flash->flash_is_locked) {
+		if (flash->flash_is_locked(flash, offset, len) > 0) {
+			printf("offset 0x%x is protected and cannot be erased\n",
+			       offset);
+			return -EINVAL;
+		}
 	}
 
 	cmd[0] = flash->erase_cmd;
@@ -315,9 +318,12 @@
 
 	page_size = flash->page_size;
 
-	if (flash->flash_is_locked(flash, offset, len) > 0) {
-		printf("offset 0x%x is protected and cannot be written\n", offset);
-		return -EINVAL;
+	if (flash->flash_is_locked) {
+		if (flash->flash_is_locked(flash, offset, len) > 0) {
+			printf("offset 0x%x is protected and cannot be written\n",
+			       offset);
+			return -EINVAL;
+		}
 	}
 
 	cmd[0] = flash->write_cmd;
diff --git a/drivers/net/greth.c b/drivers/net/greth.c
index 9bc8a8d..0624eb8 100644
--- a/drivers/net/greth.c
+++ b/drivers/net/greth.c
@@ -20,7 +20,7 @@
 #include <ambapp.h>
 #include <asm/leon.h>
 
-#include "greth.h"
+#include <grlib/greth.h>
 
 /* Default to 3s timeout on autonegotiation */
 #ifndef GRETH_PHY_TIMEOUT_MS
@@ -34,6 +34,13 @@
 #define GRETH_PHY_ADR_DEFAULT 0
 #endif
 
+/* Let board select which GRETH to use as network interface, set
+ * this to zero if only one GRETH is available.
+ */
+#ifndef CONFIG_SYS_GRLIB_GRETH_INDEX
+#define CONFIG_SYS_GRLIB_GRETH_INDEX 0
+#endif
+
 /* ByPass Cache when reading regs */
 #define GRETH_REGLOAD(addr)		SPARC_NOCACHE_READ(addr)
 /* Write-through cache ==> no bypassing needed on writes */
@@ -593,8 +600,12 @@
 
 	debug("Scanning for GRETH\n");
 
-	/* Find Device & IRQ via AMBA Plug&Play information */
-	if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_ETHMAC, &apbdev) != 1) {
+	/* Find Device & IRQ via AMBA Plug&Play information,
+	 * CONFIG_SYS_GRLIB_GRETH_INDEX select which GRETH if multiple
+	 * GRETHs in system.
+	 */
+	if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_ETHMAC,
+			CONFIG_SYS_GRLIB_GRETH_INDEX, &apbdev) != 1) {
 		return -1;	/* GRETH not found */
 	}
 
diff --git a/drivers/net/phy/natsemi.c b/drivers/net/phy/natsemi.c
index ea9fe83..d2e4c3c 100644
--- a/drivers/net/phy/natsemi.c
+++ b/drivers/net/phy/natsemi.c
@@ -53,7 +53,7 @@
 
 
 /* NatSemi DP83865 */
-static int dp83865_config(struct phy_device *phydev)
+static int dp838xx_config(struct phy_device *phydev)
 {
 	phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
 	genphy_config_aneg(phydev);
@@ -105,15 +105,56 @@
 	.uid = 0x20005c70,
 	.mask = 0xfffffff0,
 	.features = PHY_GBIT_FEATURES,
-	.config = &dp83865_config,
+	.config = &dp838xx_config,
 	.startup = &dp83865_startup,
 	.shutdown = &genphy_shutdown,
 };
 
+/* NatSemi DP83848 */
+static int dp83848_parse_status(struct phy_device *phydev)
+{
+	int mii_reg;
+
+	mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+
+	if(mii_reg & (BMSR_100FULL | BMSR_100HALF)) {
+		phydev->speed = SPEED_100;
+	} else {
+		phydev->speed = SPEED_10;
+	}
+
+	if (mii_reg & (BMSR_10FULL | BMSR_100FULL)) {
+		phydev->duplex = DUPLEX_FULL;
+	} else {
+		phydev->duplex = DUPLEX_HALF;
+	}
+
+	return 0;
+}
+
+static int dp83848_startup(struct phy_device *phydev)
+{
+	genphy_update_link(phydev);
+	dp83848_parse_status(phydev);
+
+	return 0;
+}
+
+static struct phy_driver DP83848_driver = {
+	.name = "NatSemi DP83848",
+	.uid = 0x20005c90,
+	.mask = 0x2000ff90,
+	.features = PHY_BASIC_FEATURES,
+	.config = &dp838xx_config,
+	.startup = &dp83848_startup,
+	.shutdown = &genphy_shutdown,
+};
+
 int phy_natsemi_init(void)
 {
 	phy_register(&DP83630_driver);
 	phy_register(&DP83865_driver);
+	phy_register(&DP83848_driver);
 
 	return 0;
 }
diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
index 9175d2c..5637a0d 100644
--- a/drivers/net/zynq_gem.c
+++ b/drivers/net/zynq_gem.c
@@ -327,13 +327,13 @@
 		for (i = 0; i < RX_BUF; i++) {
 			priv->rx_bd[i].status = 0xF0000000;
 			priv->rx_bd[i].addr =
-					((u32)(priv->rxbuffers) +
+					((ulong)(priv->rxbuffers) +
 							(i * PKTSIZE_ALIGN));
 		}
 		/* WRAP bit to last BD */
 		priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK;
 		/* Write RxBDs to IP */
-		writel((u32)priv->rx_bd, &regs->rxqbase);
+		writel((ulong)priv->rx_bd, &regs->rxqbase);
 
 		/* Setup for DMA Configuration register */
 		writel(ZYNQ_GEM_DMACR_INIT, &regs->dmacr);
@@ -396,22 +396,22 @@
 	struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase;
 
 	/* setup BD */
-	writel((u32)priv->tx_bd, &regs->txqbase);
+	writel((ulong)priv->tx_bd, &regs->txqbase);
 
 	/* Setup Tx BD */
 	memset(priv->tx_bd, 0, sizeof(struct emac_bd));
 
-	priv->tx_bd->addr = (u32)ptr;
+	priv->tx_bd->addr = (ulong)ptr;
 	priv->tx_bd->status = (len & ZYNQ_GEM_TXBUF_FRMLEN_MASK) |
 			       ZYNQ_GEM_TXBUF_LAST_MASK |
 			       ZYNQ_GEM_TXBUF_WRAP_MASK;
 
-	addr = (u32) ptr;
+	addr = (ulong) ptr;
 	addr &= ~(ARCH_DMA_MINALIGN - 1);
 	size = roundup(len, ARCH_DMA_MINALIGN);
 	flush_dcache_range(addr, addr + size);
 
-	addr = (u32)priv->rxbuffers;
+	addr = (ulong)priv->rxbuffers;
 	addr &= ~(ARCH_DMA_MINALIGN - 1);
 	size = roundup((RX_BUF * PKTSIZE_ALIGN), ARCH_DMA_MINALIGN);
 	flush_dcache_range(addr, addr + size);
@@ -451,7 +451,7 @@
 		u32 addr = current_bd->addr & ZYNQ_GEM_RXBUF_ADD_MASK;
 		addr &= ~(ARCH_DMA_MINALIGN - 1);
 
-		net_process_received_packet((u8 *)addr, frame_len);
+		net_process_received_packet((u8 *)(ulong)addr, frame_len);
 
 		if (current_bd->status & ZYNQ_GEM_RXBUF_SOF_MASK)
 			priv->rx_first_buf = priv->rxbd_current;
@@ -530,7 +530,7 @@
 
 	/* Initialize the bd spaces for tx and rx bd's */
 	priv->tx_bd = (struct emac_bd *)bd_space;
-	priv->rx_bd = (struct emac_bd *)((u32)bd_space + BD_SEPRN_SPACE);
+	priv->rx_bd = (struct emac_bd *)((ulong)bd_space + BD_SEPRN_SPACE);
 
 	priv->phyaddr = phy_addr;
 	priv->emio = emio;
diff --git a/drivers/pci/pci_common.c b/drivers/pci/pci_common.c
index 07f1726..a64792f 100644
--- a/drivers/pci/pci_common.c
+++ b/drivers/pci/pci_common.c
@@ -231,7 +231,7 @@
 	 * if PCI_REGION_MEM is set we do a two pass search with preference
 	 * on matches that don't have PCI_REGION_SYS_MEMORY set
 	 */
-	if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) {
+	if ((flags & PCI_REGION_TYPE) == PCI_REGION_MEM) {
 		ret = __pci_hose_bus_to_phys(hose, bus_addr,
 				flags, PCI_REGION_SYS_MEMORY, &phys_addr);
 		if (!ret)
@@ -298,7 +298,7 @@
 	 * if PCI_REGION_MEM is set we do a two pass search with preference
 	 * on matches that don't have PCI_REGION_SYS_MEMORY set
 	 */
-	if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) {
+	if ((flags & PCI_REGION_TYPE) == PCI_REGION_MEM) {
 		ret = __pci_hose_phys_to_bus(hose, phys_addr,
 				flags, PCI_REGION_SYS_MEMORY, &bus_addr);
 		if (!ret)
diff --git a/drivers/pci/pci_tegra.c b/drivers/pci/pci_tegra.c
index ebb959f..690896f 100644
--- a/drivers/pci/pci_tegra.c
+++ b/drivers/pci/pci_tegra.c
@@ -166,6 +166,9 @@
 #define RP_VEND_XP	0x00000F00
 #define  RP_VEND_XP_DL_UP	(1 << 30)
 
+#define RP_VEND_CTL2				0x00000FA8
+#define  RP_VEND_CTL2_PCA_ENABLE		(1 << 7)
+
 #define RP_PRIV_MISC	0x00000FE0
 #define  RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT (0xE << 0)
 #define  RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT (0xF << 0)
@@ -194,6 +197,7 @@
 	bool has_pex_bias_ctrl;
 	bool has_cml_clk;
 	bool has_gen2;
+	bool force_pca_enable;
 };
 
 struct tegra_pcie {
@@ -383,6 +387,7 @@
 		break;
 
 	case COMPAT_NVIDIA_TEGRA124_PCIE:
+	case COMPAT_NVIDIA_TEGRA210_PCIE:
 		switch (lanes) {
 		case 0x0000104:
 			debug("4x1, 1x1 configuration\n");
@@ -406,9 +411,34 @@
 static int tegra_pcie_parse_dt_ranges(const void *fdt, int node,
 				      struct tegra_pcie *pcie)
 {
+	int parent, na_parent, na_pcie, ns_pcie;
 	const u32 *ptr, *end;
 	int len;
 
+	parent = fdt_parent_offset(fdt, node);
+	if (parent < 0) {
+		error("Can't find PCI parent node\n");
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	na_parent = fdt_address_cells(fdt, parent);
+	if (na_parent < 1) {
+		error("bad #address-cells for PCIE parent\n");
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	na_pcie = fdt_address_cells(fdt, node);
+	if (na_pcie < 1) {
+		error("bad #address-cells for PCIE\n");
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	ns_pcie = fdt_size_cells(fdt, node);
+	if (ns_pcie < 1) {
+		error("bad #size-cells for PCIE\n");
+		return -FDT_ERR_NOTFOUND;
+	}
+
 	ptr = fdt_getprop(fdt, node, "ranges", &len);
 	if (!ptr) {
 		error("missing \"ranges\" property");
@@ -437,11 +467,13 @@
 		}
 
 		if (res) {
-			res->start = fdt32_to_cpu(ptr[3]);
-			res->end = res->start + fdt32_to_cpu(ptr[5]);
+			int start_low = na_pcie + (na_parent - 1);
+			int size_low = na_pcie + na_parent + (ns_pcie - 1);
+			res->start = fdt32_to_cpu(ptr[start_low]);
+			res->end = res->start + fdt32_to_cpu(ptr[size_low]);
 		}
 
-		ptr += 3 + 1 + 2;
+		ptr += na_pcie + na_parent + ns_pcie;
 	}
 
 	debug("PCI regions:\n");
@@ -587,8 +619,6 @@
 		return err;
 	}
 
-	tegra_pcie_board_init();
-
 	err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE,
 						PERIPH_ID_PCIE);
 	if (err < 0) {
@@ -860,6 +890,7 @@
 
 static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
 {
+	const struct tegra_pcie_soc *soc = port->pcie->soc;
 	unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
 	unsigned long value;
 
@@ -875,6 +906,12 @@
 	afi_writel(port->pcie, value, ctrl);
 
 	tegra_pcie_port_reset(port);
+
+	if (soc->force_pca_enable) {
+		value = rp_readl(port, RP_VEND_CTL2);
+		value |= RP_VEND_CTL2_PCA_ENABLE;
+		rp_writel(port, value, RP_VEND_CTL2);
+	}
 }
 
 static bool tegra_pcie_port_check_link(struct tegra_pcie_port *port)
@@ -972,6 +1009,7 @@
 	.has_pex_bias_ctrl = false,
 	.has_cml_clk = false,
 	.has_gen2 = false,
+	.force_pca_enable = false,
 };
 
 static const struct tegra_pcie_soc tegra30_pcie_soc = {
@@ -982,6 +1020,7 @@
 	.has_pex_bias_ctrl = true,
 	.has_cml_clk = true,
 	.has_gen2 = false,
+	.force_pca_enable = false,
 };
 
 static const struct tegra_pcie_soc tegra124_pcie_soc = {
@@ -992,11 +1031,31 @@
 	.has_pex_bias_ctrl = true,
 	.has_cml_clk = true,
 	.has_gen2 = true,
+	.force_pca_enable = false,
+};
+
+static const struct tegra_pcie_soc tegra210_pcie_soc = {
+	.num_ports = 2,
+	.pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
+	.tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
+	.has_pex_clkreq_en = true,
+	.has_pex_bias_ctrl = true,
+	.has_cml_clk = true,
+	.has_gen2 = true,
+	.force_pca_enable = true,
 };
 
 static int process_nodes(const void *fdt, int nodes[], unsigned int count)
 {
 	unsigned int i;
+	uint64_t dram_end;
+	uint32_t pci_dram_size;
+
+	/* Clip PCI-accessible DRAM to 32-bits */
+	dram_end = ((uint64_t)NV_PA_SDRAM_BASE) + gd->ram_size;
+	if (dram_end > 0x100000000)
+		dram_end = 0x100000000;
+	pci_dram_size = dram_end - NV_PA_SDRAM_BASE;
 
 	for (i = 0; i < count; i++) {
 		const struct tegra_pcie_soc *soc;
@@ -1021,6 +1080,10 @@
 			soc = &tegra124_pcie_soc;
 			break;
 
+		case COMPAT_NVIDIA_TEGRA210_PCIE:
+			soc = &tegra210_pcie_soc;
+			break;
+
 		default:
 			error("unsupported compatible: %s",
 			      fdtdec_get_compatible(id));
@@ -1069,7 +1132,7 @@
 		pcie->hose.last_busno = 0;
 
 		pci_set_region(&pcie->hose.regions[0], NV_PA_SDRAM_BASE,
-			       NV_PA_SDRAM_BASE, gd->ram_size,
+			       NV_PA_SDRAM_BASE, pci_dram_size,
 			       PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
 
 		pci_set_region(&pcie->hose.regions[1], pcie->io.start,
@@ -1115,6 +1178,14 @@
 	const void *fdt = gd->fdt_blob;
 	int count, nodes[1];
 
+	tegra_pcie_board_init();
+
+	count = fdtdec_find_aliases_for_id(fdt, "pcie-controller",
+					   COMPAT_NVIDIA_TEGRA210_PCIE,
+					   nodes, ARRAY_SIZE(nodes));
+	if (process_nodes(fdt, nodes, count))
+		return;
+
 	count = fdtdec_find_aliases_for_id(fdt, "pcie-controller",
 					   COMPAT_NVIDIA_TEGRA124_PCIE,
 					   nodes, ARRAY_SIZE(nodes));
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index d462244..eba96f4 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -98,6 +98,14 @@
 	  will need to provide parameters to make this work. The driver will
 	  be available until the real driver-model serial is running.
 
+config DEBUG_UART_APBUART
+	depends on LEON3
+	bool "Gaisler APBUART"
+	help
+	  Select this to enable a debug UART using the serial_leon3 driver. You
+	  will need to provide parameters to make this work. The driver will
+	  be available until the real driver model serial is running.
+
 endchoice
 
 config DEBUG_UART_BASE
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 7d7a9d0..a0dbd8b 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -123,6 +123,13 @@
 	  be used to access the SPI NOR flash on platforms embedding this
 	  nVidia Tegra20/Tegra30 IP cores.
 
+config TEGRA210_QSPI
+	bool "nVidia Tegra210 QSPI driver"
+	help
+	  Enable the Tegra Quad-SPI (QSPI) driver for T210. This driver
+	  be used to access SPI chips on platforms embedding this
+	  NVIDIA Tegra210 IP core.
+
 config XILINX_SPI
 	bool "Xilinx SPI driver"
 	help
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 637fea8..3eca745 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -46,6 +46,7 @@
 obj-$(CONFIG_TEGRA114_SPI) += tegra114_spi.o
 obj-$(CONFIG_TEGRA20_SFLASH) += tegra20_sflash.o
 obj-$(CONFIG_TEGRA20_SLINK) += tegra20_slink.o
+obj-$(CONFIG_TEGRA210_QSPI) += tegra210_qspi.o
 obj-$(CONFIG_TI_QSPI) += ti_qspi.o
 obj-$(CONFIG_XILINX_SPI) += xilinx_spi.o
 obj-$(CONFIG_ZYNQ_SPI) += zynq_spi.o
diff --git a/drivers/spi/tegra210_qspi.c b/drivers/spi/tegra210_qspi.c
new file mode 100644
index 0000000..6bbbe93
--- /dev/null
+++ b/drivers/spi/tegra210_qspi.c
@@ -0,0 +1,417 @@
+/*
+ * NVIDIA Tegra210 QSPI controller driver
+ *
+ * (C) Copyright 2015 NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch-tegra/clk_rst.h>
+#include <spi.h>
+#include <fdtdec.h>
+#include "tegra_spi.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* COMMAND1 */
+#define QSPI_CMD1_GO			BIT(31)
+#define QSPI_CMD1_M_S			BIT(30)
+#define QSPI_CMD1_MODE_MASK		GENMASK(1,0)
+#define QSPI_CMD1_MODE_SHIFT		28
+#define QSPI_CMD1_CS_SEL_MASK		GENMASK(1,0)
+#define QSPI_CMD1_CS_SEL_SHIFT		26
+#define QSPI_CMD1_CS_POL_INACTIVE0	BIT(22)
+#define QSPI_CMD1_CS_SW_HW		BIT(21)
+#define QSPI_CMD1_CS_SW_VAL		BIT(20)
+#define QSPI_CMD1_IDLE_SDA_MASK		GENMASK(1,0)
+#define QSPI_CMD1_IDLE_SDA_SHIFT	18
+#define QSPI_CMD1_BIDIR			BIT(17)
+#define QSPI_CMD1_LSBI_FE		BIT(16)
+#define QSPI_CMD1_LSBY_FE		BIT(15)
+#define QSPI_CMD1_BOTH_EN_BIT		BIT(14)
+#define QSPI_CMD1_BOTH_EN_BYTE		BIT(13)
+#define QSPI_CMD1_RX_EN			BIT(12)
+#define QSPI_CMD1_TX_EN			BIT(11)
+#define QSPI_CMD1_PACKED		BIT(5)
+#define QSPI_CMD1_BITLEN_MASK		GENMASK(4,0)
+#define QSPI_CMD1_BITLEN_SHIFT		0
+
+/* COMMAND2 */
+#define QSPI_CMD2_TX_CLK_TAP_DELAY	BIT(6)
+#define QSPI_CMD2_TX_CLK_TAP_DELAY_MASK	GENMASK(11,6)
+#define QSPI_CMD2_RX_CLK_TAP_DELAY	BIT(0)
+#define QSPI_CMD2_RX_CLK_TAP_DELAY_MASK	GENMASK(5,0)
+
+/* TRANSFER STATUS */
+#define QSPI_XFER_STS_RDY		BIT(30)
+
+/* FIFO STATUS */
+#define QSPI_FIFO_STS_CS_INACTIVE	BIT(31)
+#define QSPI_FIFO_STS_FRAME_END		BIT(30)
+#define QSPI_FIFO_STS_RX_FIFO_FLUSH	BIT(15)
+#define QSPI_FIFO_STS_TX_FIFO_FLUSH	BIT(14)
+#define QSPI_FIFO_STS_ERR		BIT(8)
+#define QSPI_FIFO_STS_TX_FIFO_OVF	BIT(7)
+#define QSPI_FIFO_STS_TX_FIFO_UNR	BIT(6)
+#define QSPI_FIFO_STS_RX_FIFO_OVF	BIT(5)
+#define QSPI_FIFO_STS_RX_FIFO_UNR	BIT(4)
+#define QSPI_FIFO_STS_TX_FIFO_FULL	BIT(3)
+#define QSPI_FIFO_STS_TX_FIFO_EMPTY	BIT(2)
+#define QSPI_FIFO_STS_RX_FIFO_FULL	BIT(1)
+#define QSPI_FIFO_STS_RX_FIFO_EMPTY	BIT(0)
+
+#define QSPI_TIMEOUT		1000
+
+struct qspi_regs {
+	u32 command1;	/* 000:QSPI_COMMAND1 register */
+	u32 command2;	/* 004:QSPI_COMMAND2 register */
+	u32 timing1;	/* 008:QSPI_CS_TIM1 register */
+	u32 timing2;	/* 00c:QSPI_CS_TIM2 register */
+	u32 xfer_status;/* 010:QSPI_TRANS_STATUS register */
+	u32 fifo_status;/* 014:QSPI_FIFO_STATUS register */
+	u32 tx_data;	/* 018:QSPI_TX_DATA register */
+	u32 rx_data;	/* 01c:QSPI_RX_DATA register */
+	u32 dma_ctl;	/* 020:QSPI_DMA_CTL register */
+	u32 dma_blk;	/* 024:QSPI_DMA_BLK register */
+	u32 rsvd[56];	/* 028-107 reserved */
+	u32 tx_fifo;	/* 108:QSPI_FIFO1 register */
+	u32 rsvd2[31];	/* 10c-187 reserved */
+	u32 rx_fifo;	/* 188:QSPI_FIFO2 register */
+	u32 spare_ctl;	/* 18c:QSPI_SPARE_CTRL register */
+};
+
+struct tegra210_qspi_priv {
+	struct qspi_regs *regs;
+	unsigned int freq;
+	unsigned int mode;
+	int periph_id;
+	int valid;
+	int last_transaction_us;
+};
+
+static int tegra210_qspi_ofdata_to_platdata(struct udevice *bus)
+{
+	struct tegra_spi_platdata *plat = bus->platdata;
+	const void *blob = gd->fdt_blob;
+	int node = bus->of_offset;
+
+	plat->base = dev_get_addr(bus);
+	plat->periph_id = clock_decode_periph_id(blob, node);
+
+	if (plat->periph_id == PERIPH_ID_NONE) {
+		debug("%s: could not decode periph id %d\n", __func__,
+		      plat->periph_id);
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	/* Use 500KHz as a suitable default */
+	plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
+					500000);
+	plat->deactivate_delay_us = fdtdec_get_int(blob, node,
+					"spi-deactivate-delay", 0);
+	debug("%s: base=%#08lx, periph_id=%d, max-frequency=%d, deactivate_delay=%d\n",
+	      __func__, plat->base, plat->periph_id, plat->frequency,
+	      plat->deactivate_delay_us);
+
+	return 0;
+}
+
+static int tegra210_qspi_probe(struct udevice *bus)
+{
+	struct tegra_spi_platdata *plat = dev_get_platdata(bus);
+	struct tegra210_qspi_priv *priv = dev_get_priv(bus);
+
+	priv->regs = (struct qspi_regs *)plat->base;
+
+	priv->last_transaction_us = timer_get_us();
+	priv->freq = plat->frequency;
+	priv->periph_id = plat->periph_id;
+
+	return 0;
+}
+
+static int tegra210_qspi_claim_bus(struct udevice *bus)
+{
+	struct tegra210_qspi_priv *priv = dev_get_priv(bus);
+	struct qspi_regs *regs = priv->regs;
+
+	/* Change SPI clock to correct frequency, PLLP_OUT0 source */
+	clock_start_periph_pll(priv->periph_id, CLOCK_ID_PERIPH, priv->freq);
+
+	debug("%s: FIFO STATUS = %08x\n", __func__, readl(&regs->fifo_status));
+
+	/* Set master mode and sw controlled CS */
+	setbits_le32(&regs->command1, QSPI_CMD1_M_S | QSPI_CMD1_CS_SW_HW |
+		     (priv->mode << QSPI_CMD1_MODE_SHIFT));
+	debug("%s: COMMAND1 = %08x\n", __func__, readl(&regs->command1));
+
+	return 0;
+}
+
+/**
+ * Activate the CS by driving it LOW
+ *
+ * @param slave	Pointer to spi_slave to which controller has to
+ *		communicate with
+ */
+static void spi_cs_activate(struct udevice *dev)
+{
+	struct udevice *bus = dev->parent;
+	struct tegra_spi_platdata *pdata = dev_get_platdata(bus);
+	struct tegra210_qspi_priv *priv = dev_get_priv(bus);
+
+	/* If it's too soon to do another transaction, wait */
+	if (pdata->deactivate_delay_us &&
+	    priv->last_transaction_us) {
+		ulong delay_us;		/* The delay completed so far */
+		delay_us = timer_get_us() - priv->last_transaction_us;
+		if (delay_us < pdata->deactivate_delay_us)
+			udelay(pdata->deactivate_delay_us - delay_us);
+	}
+
+	clrbits_le32(&priv->regs->command1, QSPI_CMD1_CS_SW_VAL);
+}
+
+/**
+ * Deactivate the CS by driving it HIGH
+ *
+ * @param slave	Pointer to spi_slave to which controller has to
+ *		communicate with
+ */
+static void spi_cs_deactivate(struct udevice *dev)
+{
+	struct udevice *bus = dev->parent;
+	struct tegra_spi_platdata *pdata = dev_get_platdata(bus);
+	struct tegra210_qspi_priv *priv = dev_get_priv(bus);
+
+	setbits_le32(&priv->regs->command1, QSPI_CMD1_CS_SW_VAL);
+
+	/* Remember time of this transaction so we can honour the bus delay */
+	if (pdata->deactivate_delay_us)
+		priv->last_transaction_us = timer_get_us();
+
+	debug("Deactivate CS, bus '%s'\n", bus->name);
+}
+
+static int tegra210_qspi_xfer(struct udevice *dev, unsigned int bitlen,
+			     const void *data_out, void *data_in,
+			     unsigned long flags)
+{
+	struct udevice *bus = dev->parent;
+	struct tegra210_qspi_priv *priv = dev_get_priv(bus);
+	struct qspi_regs *regs = priv->regs;
+	u32 reg, tmpdout, tmpdin = 0;
+	const u8 *dout = data_out;
+	u8 *din = data_in;
+	int num_bytes, tm, ret;
+
+	debug("%s: slave %u:%u dout %p din %p bitlen %u\n",
+	      __func__, bus->seq, spi_chip_select(dev), dout, din, bitlen);
+	if (bitlen % 8)
+		return -1;
+	num_bytes = bitlen / 8;
+
+	ret = 0;
+
+	/* clear all error status bits */
+	reg = readl(&regs->fifo_status);
+	writel(reg, &regs->fifo_status);
+
+	/* flush RX/TX FIFOs */
+	setbits_le32(&regs->fifo_status,
+		     (QSPI_FIFO_STS_RX_FIFO_FLUSH |
+		      QSPI_FIFO_STS_TX_FIFO_FLUSH));
+
+	tm = QSPI_TIMEOUT;
+	while ((tm && readl(&regs->fifo_status) &
+		      (QSPI_FIFO_STS_RX_FIFO_FLUSH |
+		       QSPI_FIFO_STS_TX_FIFO_FLUSH))) {
+		tm--;
+		udelay(1);
+	}
+
+	if (!tm) {
+		printf("%s: timeout during QSPI FIFO flush!\n",
+		       __func__);
+		return -1;
+	}
+
+	/*
+	 * Notes:
+	 *   1. don't set LSBY_FE, so no need to swap bytes from/to TX/RX FIFOs;
+	 *   2. don't set RX_EN and TX_EN yet.
+	 *      (SW needs to make sure that while programming the blk_size,
+	 *       tx_en and rx_en bits must be zero)
+	 *      [TODO] I (Yen Lin) have problems when both RX/TX EN bits are set
+	 *	       i.e., both dout and din are not NULL.
+	 */
+	clrsetbits_le32(&regs->command1,
+			(QSPI_CMD1_LSBI_FE | QSPI_CMD1_LSBY_FE |
+			 QSPI_CMD1_RX_EN | QSPI_CMD1_TX_EN),
+			(spi_chip_select(dev) << QSPI_CMD1_CS_SEL_SHIFT));
+
+	/* set xfer size to 1 block (32 bits) */
+	writel(0, &regs->dma_blk);
+
+	if (flags & SPI_XFER_BEGIN)
+		spi_cs_activate(dev);
+
+	/* handle data in 32-bit chunks */
+	while (num_bytes > 0) {
+		int bytes;
+
+		tmpdout = 0;
+		bytes = (num_bytes > 4) ?  4 : num_bytes;
+
+		if (dout != NULL) {
+			memcpy((void *)&tmpdout, (void *)dout, bytes);
+			dout += bytes;
+			num_bytes -= bytes;
+			writel(tmpdout, &regs->tx_fifo);
+			setbits_le32(&regs->command1, QSPI_CMD1_TX_EN);
+		}
+
+		if (din != NULL)
+			setbits_le32(&regs->command1, QSPI_CMD1_RX_EN);
+
+		/* clear ready bit */
+		setbits_le32(&regs->xfer_status, QSPI_XFER_STS_RDY);
+
+		clrsetbits_le32(&regs->command1,
+				QSPI_CMD1_BITLEN_MASK << QSPI_CMD1_BITLEN_SHIFT,
+				(bytes * 8 - 1) << QSPI_CMD1_BITLEN_SHIFT);
+
+		/* Need to stabilize other reg bits before GO bit set.
+		 * As per the TRM:
+		 * "For successful operation at various freq combinations,
+		 * a minimum of 4-5 spi_clk cycle delay might be required
+		 * before enabling the PIO or DMA bits. The worst case delay
+		 * calculation can be done considering slowest qspi_clk as
+		 * 1MHz. Based on that 1us delay should be enough before
+		 * enabling PIO or DMA." Padded another 1us for safety.
+		 */
+		udelay(2);
+		setbits_le32(&regs->command1, QSPI_CMD1_GO);
+		udelay(1);
+
+		/*
+		 * Wait for SPI transmit FIFO to empty, or to time out.
+		 * The RX FIFO status will be read and cleared last
+		 */
+		for (tm = 0; tm < QSPI_TIMEOUT; ++tm) {
+			u32 fifo_status, xfer_status;
+
+			xfer_status = readl(&regs->xfer_status);
+			if (!(xfer_status & QSPI_XFER_STS_RDY))
+				continue;
+
+			fifo_status = readl(&regs->fifo_status);
+			if (fifo_status & QSPI_FIFO_STS_ERR) {
+				debug("%s: got a fifo error: ", __func__);
+				if (fifo_status & QSPI_FIFO_STS_TX_FIFO_OVF)
+					debug("tx FIFO overflow ");
+				if (fifo_status & QSPI_FIFO_STS_TX_FIFO_UNR)
+					debug("tx FIFO underrun ");
+				if (fifo_status & QSPI_FIFO_STS_RX_FIFO_OVF)
+					debug("rx FIFO overflow ");
+				if (fifo_status & QSPI_FIFO_STS_RX_FIFO_UNR)
+					debug("rx FIFO underrun ");
+				if (fifo_status & QSPI_FIFO_STS_TX_FIFO_FULL)
+					debug("tx FIFO full ");
+				if (fifo_status & QSPI_FIFO_STS_TX_FIFO_EMPTY)
+					debug("tx FIFO empty ");
+				if (fifo_status & QSPI_FIFO_STS_RX_FIFO_FULL)
+					debug("rx FIFO full ");
+				if (fifo_status & QSPI_FIFO_STS_RX_FIFO_EMPTY)
+					debug("rx FIFO empty ");
+				debug("\n");
+				break;
+			}
+
+			if (!(fifo_status & QSPI_FIFO_STS_RX_FIFO_EMPTY)) {
+				tmpdin = readl(&regs->rx_fifo);
+				if (din != NULL) {
+					memcpy(din, &tmpdin, bytes);
+					din += bytes;
+					num_bytes -= bytes;
+				}
+			}
+			break;
+		}
+
+		if (tm >= QSPI_TIMEOUT)
+			ret = tm;
+
+		/* clear ACK RDY, etc. bits */
+		writel(readl(&regs->fifo_status), &regs->fifo_status);
+	}
+
+	if (flags & SPI_XFER_END)
+		spi_cs_deactivate(dev);
+
+	debug("%s: transfer ended. Value=%08x, fifo_status = %08x\n",
+	      __func__, tmpdin, readl(&regs->fifo_status));
+
+	if (ret) {
+		printf("%s: timeout during SPI transfer, tm %d\n",
+		       __func__, ret);
+		return -1;
+	}
+
+	return ret;
+}
+
+static int tegra210_qspi_set_speed(struct udevice *bus, uint speed)
+{
+	struct tegra_spi_platdata *plat = bus->platdata;
+	struct tegra210_qspi_priv *priv = dev_get_priv(bus);
+
+	if (speed > plat->frequency)
+		speed = plat->frequency;
+	priv->freq = speed;
+	debug("%s: regs=%p, speed=%d\n", __func__, priv->regs, priv->freq);
+
+	return 0;
+}
+
+static int tegra210_qspi_set_mode(struct udevice *bus, uint mode)
+{
+	struct tegra210_qspi_priv *priv = dev_get_priv(bus);
+
+	priv->mode = mode;
+	debug("%s: regs=%p, mode=%d\n", __func__, priv->regs, priv->mode);
+
+	return 0;
+}
+
+static const struct dm_spi_ops tegra210_qspi_ops = {
+	.claim_bus	= tegra210_qspi_claim_bus,
+	.xfer		= tegra210_qspi_xfer,
+	.set_speed	= tegra210_qspi_set_speed,
+	.set_mode	= tegra210_qspi_set_mode,
+	/*
+	 * cs_info is not needed, since we require all chip selects to be
+	 * in the device tree explicitly
+	 */
+};
+
+static const struct udevice_id tegra210_qspi_ids[] = {
+	{ .compatible = "nvidia,tegra210-qspi" },
+	{ }
+};
+
+U_BOOT_DRIVER(tegra210_qspi) = {
+	.name = "tegra210-qspi",
+	.id = UCLASS_SPI,
+	.of_match = tegra210_qspi_ids,
+	.ops = &tegra210_qspi_ops,
+	.ofdata_to_platdata = tegra210_qspi_ofdata_to_platdata,
+	.platdata_auto_alloc_size = sizeof(struct tegra_spi_platdata),
+	.priv_auto_alloc_size = sizeof(struct tegra210_qspi_priv),
+	.per_child_auto_alloc_size = sizeof(struct spi_slave),
+	.probe = tegra210_qspi_probe,
+};
diff --git a/drivers/usb/eth/smsc95xx.c b/drivers/usb/eth/smsc95xx.c
index 202e482..3099bf4 100644
--- a/drivers/usb/eth/smsc95xx.c
+++ b/drivers/usb/eth/smsc95xx.c
@@ -680,7 +680,8 @@
 	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, msg,
 				 PKTSIZE + sizeof(tx_cmd_a) + sizeof(tx_cmd_b));
 
-	debug("** %s(), len %d, buf %#x\n", __func__, length, (int)msg);
+	debug("** %s(), len %d, buf %#x\n", __func__, length,
+	      (unsigned int)(ulong)msg);
 	if (length > PKTSIZE)
 		return -ENOSPC;
 
@@ -701,8 +702,8 @@
 				&actual_len,
 				USB_BULK_SEND_TIMEOUT);
 	debug("Tx: len = %u, actual = %u, err = %d\n",
-	      length + sizeof(tx_cmd_a) + sizeof(tx_cmd_b),
-	      actual_len, err);
+	      (unsigned int)(length + sizeof(tx_cmd_a) + sizeof(tx_cmd_b)),
+	      (unsigned int)actual_len, err);
 
 	return err;
 }
@@ -784,7 +785,7 @@
 		/* Adjust for next iteration */
 		actual_len -= sizeof(packet_len) + packet_len;
 		buf_ptr += sizeof(packet_len) + packet_len;
-		cur_buf_align = (int)buf_ptr - (int)recv_buf;
+		cur_buf_align = (ulong)buf_ptr - (ulong)recv_buf;
 
 		if (cur_buf_align & 0x03) {
 			int align = 4 - (cur_buf_align & 0x03);
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index ece48e6..20b6c18 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -13,6 +13,7 @@
 #include <config.h>
 #include <common.h>
 #include <errno.h>
+#include <fastboot.h>
 #include <malloc.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
@@ -23,6 +24,9 @@
 #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
 #include <fb_mmc.h>
 #endif
+#ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
+#include <fb_nand.h>
+#endif
 
 #define FASTBOOT_VERSION		"0.4"
 
@@ -34,9 +38,6 @@
 #define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_1_1  (0x0040)
 #define TX_ENDPOINT_MAXIMUM_PACKET_SIZE      (0x0040)
 
-/* The 64 defined bytes plus \0 */
-#define RESPONSE_LEN	(64 + 1)
-
 #define EP_BUFFER_SIZE			4096
 
 struct f_fastboot {
@@ -53,6 +54,7 @@
 }
 
 static struct f_fastboot *fastboot_func;
+static unsigned int fastboot_flash_session_id;
 static unsigned int download_size;
 static unsigned int download_bytes;
 static bool is_high_speed;
@@ -125,6 +127,19 @@
 static void rx_handler_command(struct usb_ep *ep, struct usb_request *req);
 static int strcmp_l1(const char *s1, const char *s2);
 
+
+void fastboot_fail(char *response, const char *reason)
+{
+	strncpy(response, "FAIL\0", 5);
+	strncat(response, reason, FASTBOOT_RESPONSE_LEN - 4 - 1);
+}
+
+void fastboot_okay(char *response, const char *reason)
+{
+	strncpy(response, "OKAY\0", 5);
+	strncat(response, reason, FASTBOOT_RESPONSE_LEN - 4 - 1);
+}
+
 static void fastboot_complete(struct usb_ep *ep, struct usb_request *req)
 {
 	int status = req->status;
@@ -358,7 +373,7 @@
 static void cb_getvar(struct usb_ep *ep, struct usb_request *req)
 {
 	char *cmd = req->buf;
-	char response[RESPONSE_LEN];
+	char response[FASTBOOT_RESPONSE_LEN];
 	const char *s;
 	size_t chars_left;
 
@@ -382,6 +397,15 @@
 
 		sprintf(str_num, "0x%08x", CONFIG_FASTBOOT_BUF_SIZE);
 		strncat(response, str_num, chars_left);
+
+		/*
+		 * This also indicates the start of a new flashing
+		 * "session", in which we could have 1-N buffers to
+		 * write to a partition.
+		 *
+		 * Reset our session counter.
+		 */
+		fastboot_flash_session_id = 0;
 	} else if (!strcmp_l1("serialno", cmd)) {
 		s = getenv("serial#");
 		if (s)
@@ -415,7 +439,7 @@
 #define BYTES_PER_DOT	0x20000
 static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req)
 {
-	char response[RESPONSE_LEN];
+	char response[FASTBOOT_RESPONSE_LEN];
 	unsigned int transfer_size = download_size - download_bytes;
 	const unsigned char *buffer = req->buf;
 	unsigned int buffer_size = req->actual;
@@ -472,7 +496,7 @@
 static void cb_download(struct usb_ep *ep, struct usb_request *req)
 {
 	char *cmd = req->buf;
-	char response[RESPONSE_LEN];
+	char response[FASTBOOT_RESPONSE_LEN];
 	unsigned int max;
 
 	strsep(&cmd, ":");
@@ -533,7 +557,7 @@
 static void cb_flash(struct usb_ep *ep, struct usb_request *req)
 {
 	char *cmd = req->buf;
-	char response[RESPONSE_LEN];
+	char response[FASTBOOT_RESPONSE_LEN];
 
 	strsep(&cmd, ":");
 	if (!cmd) {
@@ -544,9 +568,16 @@
 
 	strcpy(response, "FAILno flash device defined");
 #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
-	fb_mmc_flash_write(cmd, (void *)CONFIG_FASTBOOT_BUF_ADDR,
+	fb_mmc_flash_write(cmd, fastboot_flash_session_id,
+			   (void *)CONFIG_FASTBOOT_BUF_ADDR,
 			   download_bytes, response);
 #endif
+#ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
+	fb_nand_flash_write(cmd, fastboot_flash_session_id,
+			    (void *)CONFIG_FASTBOOT_BUF_ADDR,
+			    download_bytes, response);
+#endif
+	fastboot_flash_session_id++;
 	fastboot_tx_write_str(response);
 }
 #endif
@@ -577,7 +608,7 @@
 static void cb_erase(struct usb_ep *ep, struct usb_request *req)
 {
 	char *cmd = req->buf;
-	char response[RESPONSE_LEN];
+	char response[FASTBOOT_RESPONSE_LEN];
 
 	strsep(&cmd, ":");
 	if (!cmd) {
@@ -591,6 +622,9 @@
 #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
 	fb_mmc_erase(cmd, response);
 #endif
+#ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
+	fb_nand_erase(cmd, response);
+#endif
 	fastboot_tx_write_str(response);
 }
 #endif
diff --git a/include/aboot.h b/include/aboot.h
deleted file mode 100644
index 30e4d36..0000000
--- a/include/aboot.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2014 Broadcom Corporation.
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#include <part.h>
-#include <sparse_format.h>
-
-#define ROUNDUP(x, y)	(((x) + ((y) - 1)) & ~((y) - 1))
-
-void fastboot_fail(const char *s);
-void fastboot_okay(const char *s);
-
-static inline int is_sparse_image(void *buf)
-{
-	sparse_header_t *s_header = (sparse_header_t *)buf;
-
-	if ((le32_to_cpu(s_header->magic) == SPARSE_HEADER_MAGIC) &&
-	    (le16_to_cpu(s_header->major_version) == 1))
-		return 1;
-
-	return 0;
-}
-
-void write_sparse_image(block_dev_desc_t *dev_desc,
-		disk_partition_t *info, const char *part_name,
-		void *data, unsigned sz);
diff --git a/include/ambapp.h b/include/ambapp.h
index 405637d..d79fced 100644
--- a/include/ambapp.h
+++ b/include/ambapp.h
@@ -3,8 +3,8 @@
  * the APB bus, also freely available in GRLIB at
  * www.gaisler.com.
  *
- * (C) Copyright 2007
- * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ * (C) Copyright 2009, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
@@ -12,116 +12,136 @@
 #ifndef __AMBAPP_H__
 #define __AMBAPP_H__
 
-/* Default location of Plug&Play info
- * normally 0xfffff000 for AHB masters
- * and 0xfffff800 for AHB slaves.
- * Normally no need to change this.
- */
-#define LEON3_IO_AREA 0xfff00000
-#define LEON3_CONF_AREA  0xff000
-#define LEON3_AHB_SLAVE_CONF_AREA (1 << 11)
-
-/* Max devices this software will support */
-#define LEON3_AHB_MASTERS 16
-#define LEON3_AHB_SLAVES 16
-/*#define LEON3_APB_MASTERS 1*/ /* Number of APB buses that has Plug&Play */
-#define LEON3_APB_SLAVES 16	/* Total number of APB slaves per APB bus */
-
-/* Vendor codes */
-#define VENDOR_GAISLER       1
-#define VENDOR_PENDER        2
-#define VENDOR_ESA           4
-#define VENDOR_ASTRIUM       6
-#define VENDOR_OPENCHIP      7
-#define VENDOR_OPENCORES     8
-#define VENDOR_CONTRIB       9
-#define VENDOR_EONIC         11
-#define VENDOR_RADIONOR      15
-#define VENDOR_GLEICHMANN    16
-#define VENDOR_MENTA         17
-#define VENDOR_SUN           19
-#define VENDOR_EMBEDDIT      234
-#define VENDOR_CAL           202
-
-/* Gaisler Research device id's */
-#define GAISLER_LEON3    0x003
-#define GAISLER_LEON3DSU 0x004
-#define GAISLER_ETHAHB   0x005
-#define GAISLER_APBMST   0x006
-#define GAISLER_AHBUART  0x007
-#define GAISLER_SRCTRL   0x008
-#define GAISLER_SDCTRL   0x009
-#define GAISLER_APBUART  0x00C
-#define GAISLER_IRQMP    0x00D
-#define GAISLER_AHBRAM   0x00E
-#define GAISLER_GPTIMER  0x011
-#define GAISLER_PCITRG   0x012
-#define GAISLER_PCISBRG  0x013
-#define GAISLER_PCIFBRG  0x014
-#define GAISLER_PCITRACE 0x015
-#define GAISLER_PCIDMA   0x016
-#define GAISLER_AHBTRACE 0x017
-#define GAISLER_ETHDSU   0x018
-#define GAISLER_PIOPORT  0x01A
-#define GAISLER_AHBJTAG  0x01c
-#define GAISLER_SPW      0x01f
-#define GAISLER_ATACTRL  0x024
-#define GAISLER_VGA      0x061
-#define GAISLER_KBD      0X060
-#define GAISLER_ETHMAC   0x01D
-#define GAISLER_DDRSPA   0x025
-#define GAISLER_EHCI     0x026
-#define GAISLER_UHCI     0x027
-#define GAISLER_SPW2     0x029
-#define GAISLER_DDR2SPA  0x02E
-#define GAISLER_AHBSTAT  0x052
-#define GAISLER_FTMCTRL  0x054
-
-#define GAISLER_L2TIME   0xffd	/* internal device: leon2 timer */
-#define GAISLER_L2C      0xffe	/* internal device: leon2compat */
-#define GAISLER_PLUGPLAY 0xfff	/* internal device: plug & play configarea */
-
-/* European Space Agency device id's */
-#define ESA_LEON2        0x2
-#define ESA_MCTRL        0xF
-
-/* Opencores device id's */
-#define OPENCORES_PCIBR  0x4
-#define OPENCORES_ETHMAC 0x5
-
-/* Vendor codes */
-
-/*
- *
- * Macros for manipulating Configuration registers
- *
- */
-
-#define amba_vendor(x) (((x) >> 24) & 0xff)
-
-#define amba_device(x) (((x) >> 12) & 0xfff)
-
-#define amba_membar_start(mbar) \
- (((mbar) & 0xfff00000) & (((mbar) & 0xfff0) << 16))
-
-#define amba_iobar_start(base, iobar) \
- ((base) | ((((iobar) & 0xfff00000)>>12) & (((iobar) & 0xfff0)<<4)) )
-
-#define amba_irq(conf) ((conf) & 0xf)
-
-#define amba_ver(conf) (((conf)>>5) & 0x1f)
-
-#define amba_membar_type(mbar) ((mbar) & 0xf)
-
-#define amba_membar_mask(mbar) (((mbar)>>4) & 0xfff)
-
-#define AMBA_TYPE_APBIO 0x1
-#define AMBA_TYPE_MEM   0x2
-#define AMBA_TYPE_AHBIO 0x3
-
-#define AMBA_TYPE_AHBIO_ADDR(addr) (LEON3_IO_AREA | ((addr) >> 12))
+#include <ambapp_ids.h>
 
 #ifndef __ASSEMBLER__
+/* Structures used to access Plug&Play information directly */
+struct ambapp_pnp_ahb {
+	const unsigned int	id;		/* VENDOR, DEVICE, VER, IRQ, */
+	const unsigned int	custom[3];
+	const unsigned int	mbar[4];	/* MASK, ADDRESS, TYPE,
+						 * CACHABLE/PREFETCHABLE */
+};
+
+struct ambapp_pnp_apb {
+	const unsigned int	id;		/* VENDOR, DEVICE, VER, IRQ, */
+	const unsigned int	iobar;		/* MASK, ADDRESS, TYPE,
+						 * CACHABLE/PREFETCHABLE */
+};
+
+/* AMBA Plug&Play AHB Masters & Slaves information locations
+ * Max devices is 64 supported by HW, however often only 16
+ * are used.
+ */
+struct ambapp_pnp_info {
+	struct ambapp_pnp_ahb	masters[64];
+	struct ambapp_pnp_ahb	slaves[63];
+	const unsigned int	unused[4];
+	const unsigned int	systemid[4];
+};
+
+/* Describes a AMBA PnP bus */
+struct ambapp_bus {
+	int		buses;		/* Number of buses */
+	unsigned int	ioareas[6];	/* PnP I/O AREAs of AHB buses */
+	unsigned int	freq;		/* Frequency of bus0 [Hz] */
+};
+
+/* Processor Local AMBA bus */
+extern struct ambapp_bus ambapp_plb;
+
+/* Get Bus frequency of a certain AMBA bus */
+extern unsigned int ambapp_bus_freq(
+	struct ambapp_bus *abus,
+	int ahb_bus_index
+	);
+
+/* AMBA PnP information of a APB Device */
+typedef struct {
+	unsigned int vendor;
+	unsigned int device;
+	unsigned char irq;
+	unsigned char ver;
+	unsigned int address;
+	unsigned int mask;
+	int ahb_bus_index;
+} ambapp_apbdev;
+
+/* AMBA PnP information of a AHB Device */
+typedef struct {
+	unsigned int vendor;
+	unsigned int device;
+	unsigned char irq;
+	unsigned char ver;
+	unsigned int userdef[3];
+	unsigned int address[4];
+	unsigned int mask[4];
+	int type[4];
+	int ahb_bus_index;
+} ambapp_ahbdev;
+
+/* Scan AMBA Bus for AHB Bridges */
+extern void ambapp_bus_init(
+	unsigned int ioarea,
+	unsigned int freq,
+	struct ambapp_bus *abus);
+
+/* Find APB Slave device by index using breath first search.
+ *
+ * When vendor and device are both set to zero, any device
+ * with a non-zero device ID will match the search. It may be
+ * useful when processing all devices on a AMBA bus.
+ */
+extern int ambapp_apb_find(
+	struct ambapp_bus *abus,
+	int vendor,
+	int device,
+	int index,
+	ambapp_apbdev *dev
+	);
+
+/* Find AHB Master device by index using breath first search.
+ *
+ * When vendor and device are both set to zero, any device
+ * with a non-zero device ID will match the search. It may be
+ * useful when processing all devices on a AMBA bus.
+ */
+extern int ambapp_ahbmst_find(
+	struct ambapp_bus *abus,
+	int vendor,
+	int device,
+	int index,
+	ambapp_ahbdev *dev
+	);
+
+/* Find AHB Slave device by index using breath first search.
+ *
+ * When vendor and device are both set to zero, any device
+ * with a non-zero device ID will match the search. It may be
+ * useful when processing all devices on a AMBA bus.
+ */
+extern int ambapp_ahbslv_find(
+	struct ambapp_bus *abus,
+	int vendor,
+	int device,
+	int index,
+	ambapp_ahbdev *dev
+	);
+
+/* Return number of APB Slave devices of a certain ID (VENDOR:DEVICE)
+ * zero is returned if no devices was found.
+ */
+extern int ambapp_apb_count(struct ambapp_bus *abus, int vendor, int device);
+
+/* Return number of AHB Master devices of a certain ID (VENDOR:DEVICE)
+ * zero is returned if no devices was found.
+ */
+extern int ambapp_ahbmst_count(struct ambapp_bus *abus, int vendor, int device);
+
+/* Return number of AHB Slave devices of a certain ID (VENDOR:DEVICE)
+ * zero is returned if no devices was found.
+ */
+extern int ambapp_ahbslv_count(struct ambapp_bus *abus, int vendor, int device);
 
 #ifdef CONFIG_CMD_AMBAPP
 
@@ -135,243 +155,71 @@
 
 /* Return name of vendor */
 char *ambapp_vendor_id2str(int vendor);
-#endif
 
-/*
- *  Types and structure used for AMBA Plug & Play bus scanning
- */
-
-/* AMBA Plug&Play AHB information layout */
-typedef struct {
-	unsigned int conf;
-	unsigned int userdef[3];
-	unsigned int bars[4];
-} ahbctrl_pp_dev;
-
-/* Prototypes for scanning AMBA Plug&Play bus for AMBA
- *  i)   AHB Masters
- *  ii)  AHB Slaves
- *  iii) APB Slaves (APB MST is a AHB Slave)
- */
-
-typedef struct {
-	unsigned char irq;
-	unsigned char ver;
-	unsigned int address;
-} ambapp_apbdev;
-
-typedef struct {
-	unsigned char irq;
-	unsigned char ver;
-	unsigned int userdef[3];
-	unsigned int address[4];
-} ambapp_ahbdev;
-
-/* AMBA Plug&Play AHB Masters & Slaves information locations
- * Max devices is 64 supported by HW, however often only 8
- * are used.
- */
-typedef struct {
-	ahbctrl_pp_dev masters[64];
-	ahbctrl_pp_dev slaves[64];
-} ahbctrl_info;
-
-/* AMBA Plug&Play AHB information layout */
-typedef struct {
-	unsigned int conf;
-	unsigned int bar;
-} apbctrl_pp_dev;
-
-/* All functions return the number of found devices
- * 0 = no devices found
- */
-
-/****************************** APB SLAVES ******************************/
-int ambapp_apb_count(unsigned int vendor, unsigned int driver);
-
-int ambapp_apb_first(unsigned int vendor,
-		     unsigned int driver, ambapp_apbdev * dev);
-
-int ambapp_apb_next(unsigned int vendor,
-		    unsigned int driver, ambapp_apbdev * dev, int index);
-
-int ambapp_apbs_first(unsigned int vendor,
-		      unsigned int driver, ambapp_apbdev * dev, int max_cnt);
-
-/****************************** AHB MASTERS ******************************/
-int ambapp_ahbmst_count(unsigned int vendor, unsigned int driver);
-
-int ambapp_ahbmst_first(unsigned int vendor,
-			unsigned int driver, ambapp_ahbdev * dev);
-
-int ambapp_ahbmst_next(unsigned int vendor,
-		       unsigned int driver, ambapp_ahbdev * dev, int index);
-
-int ambapp_ahbmsts_first(unsigned int vendor,
-			 unsigned int driver, ambapp_ahbdev * dev, int max_cnt);
-
-/****************************** AHB SLAVES ******************************/
-int ambapp_ahbslv_count(unsigned int vendor, unsigned int driver);
-
-int ambapp_ahbslv_first(unsigned int vendor,
-			unsigned int driver, ambapp_ahbdev * dev);
-
-int ambapp_ahbslv_next(unsigned int vendor,
-		       unsigned int driver, ambapp_ahbdev * dev, int index);
-
-int ambapp_ahbslvs_first(unsigned int vendor,
-			 unsigned int driver, ambapp_ahbdev * dev, int max_cnt);
-
-/*************************** AHB/APB only regs functions *************************
- * During start up, no memory is available we can use the simplified functions
- * to get to the memory controller.
- *
- * Functions uses no stack/memory, only registers.
- */
-unsigned int ambapp_apb_next_nomem(register unsigned int vendor,	/* Plug&Play Vendor ID */
-				   register unsigned int driver,	/* Plug&Play Device ID */
-				   register int index);
-
-ahbctrl_pp_dev *ambapp_ahb_next_nomem(register unsigned int vendor,	/* Plug&Play Vendor ID */
-				      register unsigned int driver,	/* Plug&Play Device ID */
-				      register unsigned int opts,	/* scan for AHB 1=slave, 0=masters */
-				      register int index);
-
-unsigned int ambapp_ahb_get_info(ahbctrl_pp_dev * ahb, int info);
-
-/*************************** AMBA Plug&Play device register MAPS *****************/
-
-/*
- *  The following defines the bits in the LEON UART Status Registers.
- */
-
-#define LEON_REG_UART_STATUS_DR   0x00000001	/* Data Ready */
-#define LEON_REG_UART_STATUS_TSE  0x00000002	/* TX Send Register Empty */
-#define LEON_REG_UART_STATUS_THE  0x00000004	/* TX Hold Register Empty */
-#define LEON_REG_UART_STATUS_BR   0x00000008	/* Break Error */
-#define LEON_REG_UART_STATUS_OE   0x00000010	/* RX Overrun Error */
-#define LEON_REG_UART_STATUS_PE   0x00000020	/* RX Parity Error */
-#define LEON_REG_UART_STATUS_FE   0x00000040	/* RX Framing Error */
-#define LEON_REG_UART_STATUS_ERR  0x00000078	/* Error Mask */
-
-/*
- *  The following defines the bits in the LEON UART Ctrl Registers.
- */
-
-#define LEON_REG_UART_CTRL_RE     0x00000001	/* Receiver enable */
-#define LEON_REG_UART_CTRL_TE     0x00000002	/* Transmitter enable */
-#define LEON_REG_UART_CTRL_RI     0x00000004	/* Receiver interrupt enable */
-#define LEON_REG_UART_CTRL_TI     0x00000008	/* Transmitter interrupt enable */
-#define LEON_REG_UART_CTRL_PS     0x00000010	/* Parity select */
-#define LEON_REG_UART_CTRL_PE     0x00000020	/* Parity enable */
-#define LEON_REG_UART_CTRL_FL     0x00000040	/* Flow control enable */
-#define LEON_REG_UART_CTRL_LB     0x00000080	/* Loop Back enable */
-#define LEON_REG_UART_CTRL_DBG    (1<<11)	/* Debug Bit used by GRMON */
-
-#define LEON3_GPTIMER_EN 1
-#define LEON3_GPTIMER_RL 2
-#define LEON3_GPTIMER_LD 4
-#define LEON3_GPTIMER_IRQEN 8
-
-/*
- *  The following defines the bits in the LEON PS/2 Status Registers.
- */
-
-#define LEON_REG_PS2_STATUS_DR   0x00000001	/* Data Ready */
-#define LEON_REG_PS2_STATUS_PE   0x00000002	/* Parity error */
-#define LEON_REG_PS2_STATUS_FE   0x00000004	/* Framing error */
-#define LEON_REG_PS2_STATUS_KI   0x00000008	/* Keyboard inhibit */
-
-/*
- *  The following defines the bits in the LEON PS/2 Ctrl Registers.
- */
-
-#define LEON_REG_PS2_CTRL_RE     0x00000001	/* Receiver enable */
-#define LEON_REG_PS2_CTRL_TE     0x00000002	/* Transmitter enable */
-#define LEON_REG_PS2_CTRL_RI     0x00000004	/* Keyboard receive interrupt  */
-#define LEON_REG_PS2_CTRL_TI     0x00000008	/* Keyboard transmit interrupt */
-
-typedef struct {
-	volatile unsigned int ilevel;
-	volatile unsigned int ipend;
-	volatile unsigned int iforce;
-	volatile unsigned int iclear;
-	volatile unsigned int mstatus;
-	volatile unsigned int notused[11];
-	volatile unsigned int cpu_mask[16];
-	volatile unsigned int cpu_force[16];
-} ambapp_dev_irqmp;
-
-typedef struct {
-	volatile unsigned int data;
-	volatile unsigned int status;
-	volatile unsigned int ctrl;
-	volatile unsigned int scaler;
-} ambapp_dev_apbuart;
-
-typedef struct {
-	volatile unsigned int val;
-	volatile unsigned int rld;
-	volatile unsigned int ctrl;
-	volatile unsigned int unused;
-} ambapp_dev_gptimer_element;
-
-#define LEON3_GPTIMER_CTRL_EN	0x1	/* Timer enable */
-#define LEON3_GPTIMER_CTRL_RS	0x2	/* Timer reStart  */
-#define LEON3_GPTIMER_CTRL_LD	0x4	/* Timer reLoad */
-#define LEON3_GPTIMER_CTRL_IE	0x8	/* interrupt enable */
-#define LEON3_GPTIMER_CTRL_IP	0x10	/* interrupt flag/pending */
-#define LEON3_GPTIMER_CTRL_CH	0x20	/* Chain with previous timer */
-
-typedef struct {
-	volatile unsigned int scalar;
-	volatile unsigned int scalar_reload;
-	volatile unsigned int config;
-	volatile unsigned int unused;
-	volatile ambapp_dev_gptimer_element e[8];
-} ambapp_dev_gptimer;
-
-typedef struct {
-	volatile unsigned int iodata;
-	volatile unsigned int ioout;
-	volatile unsigned int iodir;
-	volatile unsigned int irqmask;
-	volatile unsigned int irqpol;
-	volatile unsigned int irqedge;
-} ambapp_dev_ioport;
-
-typedef struct {
-	volatile unsigned int write;
-	volatile unsigned int dummy;
-	volatile unsigned int txcolor;
-	volatile unsigned int bgcolor;
-} ambapp_dev_textvga;
-
-typedef struct {
-	volatile unsigned int data;
-	volatile unsigned int status;
-	volatile unsigned int ctrl;
-} ambapp_dev_apbps2;
-
-typedef struct {
-	unsigned int mcfg1, mcfg2, mcfg3;
-} ambapp_dev_mctrl;
-
-typedef struct {
-	unsigned int sdcfg;
-} ambapp_dev_sdctrl;
-
-typedef struct {
-	unsigned int cfg1;
-	unsigned int cfg2;
-	unsigned int cfg3;
-} ambapp_dev_ddr2spa;
-
-typedef struct {
-	unsigned int ctrl;
-	unsigned int cfg;
-} ambapp_dev_ddrspa;
+/* Return description of a device */
+char *ambapp_device_id2desc(int vendor, int id);
 
 #endif
 
+#endif /* defined(__ASSEMBLER__) */
+
+#define AMBA_DEFAULT_IOAREA 0xfff00000
+#define AMBA_CONF_AREA 0xff000
+#define AMBA_AHB_SLAVE_CONF_AREA 0x800
+
+#define DEV_NONE	0
+#define DEV_AHB_MST	1
+#define DEV_AHB_SLV	2
+#define DEV_APB_SLV	3
+
+#define AMBA_TYPE_APBIO 0x1
+#define AMBA_TYPE_MEM 0x2
+#define AMBA_TYPE_AHBIO 0x3
+
+/* ID layout for APB and AHB devices */
+#define AMBA_PNP_ID(vendor, device) (((vendor)<<24) | ((device)<<12))
+
+/* APB Slave PnP layout definitions */
+#define AMBA_APB_ID_OFS		(0*4)
+#define AMBA_APB_IOBAR_OFS	(1*4)
+#define AMBA_APB_CONF_LENGH	(2*4)
+
+/* AHB Master/Slave layout PnP definitions */
+#define AMBA_AHB_ID_OFS		(0*4)
+#define AMBA_AHB_CUSTOM0_OFS	(1*4)
+#define AMBA_AHB_CUSTOM1_OFS	(2*4)
+#define AMBA_AHB_CUSTOM2_OFS	(3*4)
+#define AMBA_AHB_MBAR0_OFS	(4*4)
+#define AMBA_AHB_MBAR1_OFS	(5*4)
+#define AMBA_AHB_MBAR2_OFS	(6*4)
+#define AMBA_AHB_MBAR3_OFS	(7*4)
+#define AMBA_AHB_CONF_LENGH	(8*4)
+
+/* Macros for extracting information from AMBA PnP information
+ * registers.
+ */
+
+#define amba_vendor(x) (((x) >> 24) & 0xff)
+
+#define amba_device(x) (((x) >> 12) & 0xfff)
+
+#define amba_irq(conf) ((conf) & 0x1f)
+
+#define amba_ver(conf) (((conf)>>5) & 0x1f)
+
+#define amba_iobar_start(base, iobar) \
+	((base) | ((((iobar) & 0xfff00000)>>12) & (((iobar) & 0xfff0)<<4)))
+
+#define amba_membar_start(mbar) \
+	(((mbar) & 0xfff00000) & (((mbar) & 0xfff0) << 16))
+
+#define amba_membar_type(mbar) ((mbar) & 0xf)
+
+#define amba_membar_mask(mbar) (((mbar) >> 4) & 0xfff)
+
+#define amba_ahbio_adr(addr, base_ioarea) \
+	((unsigned int)(base_ioarea) | ((addr) >> 12))
+
+#define amba_apb_mask(iobar) ((~(amba_membar_mask(iobar)<<8) & 0x000fffff) + 1)
+
 #endif
diff --git a/include/ambapp_ids.h b/include/ambapp_ids.h
new file mode 100644
index 0000000..1eae34e
--- /dev/null
+++ b/include/ambapp_ids.h
@@ -0,0 +1,250 @@
+/* AMBA Plug & Play Bus Vendor and Device IDs.
+ *
+ * (C) Copyright 2010, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+
+#ifndef __AMBAPP_IDS_H__
+#define __AMBAPP_IDS_H__
+
+/* Vendor ID defines */
+#define VENDOR_GAISLER       0x01
+#define VENDOR_PENDER        0x02
+#define VENDOR_ESA           0x04
+#define VENDOR_ASTRIUM       0x06
+#define VENDOR_OPENCHIP      0x07
+#define VENDOR_OPENCORES     0x08
+#define VENDOR_CONTRIB       0x09
+#define VENDOR_EONIC         0x0b
+#define VENDOR_RADIONOR      0x0f
+#define VENDOR_GLEICHMANN    0x10
+#define VENDOR_MENTA         0x11
+#define VENDOR_SUN           0x13
+#define VENDOR_MOVIDIA       0x14
+#define VENDOR_ORBITA        0x17
+#define VENDOR_SYNOPSYS      0x21
+#define VENDOR_NASA          0x22
+#define VENDOR_S3            0x31
+#define VENDOR_CAL           0xca
+#define VENDOR_EMBEDDIT      0xea
+#define VENDOR_CETON         0xcb
+#define VENDOR_ACTEL         0xac
+#define VENDOR_APPLECORE     0xae
+
+/* Aeroflex Gaisler device ID defines */
+#define GAISLER_LEON2DSU     0x002
+#define GAISLER_LEON3        0x003
+#define GAISLER_LEON3DSU     0x004
+#define GAISLER_ETHAHB       0x005
+#define GAISLER_APBMST       0x006
+#define GAISLER_AHBUART      0x007
+#define GAISLER_SRCTRL       0x008
+#define GAISLER_SDCTRL       0x009
+#define GAISLER_SSRCTRL      0x00a
+#define GAISLER_APBUART      0x00c
+#define GAISLER_IRQMP        0x00d
+#define GAISLER_AHBRAM       0x00e
+#define GAISLER_AHBDPRAM     0x00f
+#define GAISLER_GPTIMER      0x011
+#define GAISLER_PCITRG       0x012
+#define GAISLER_PCISBRG      0x013
+#define GAISLER_PCIFBRG      0x014
+#define GAISLER_PCITRACE     0x015
+#define GAISLER_DMACTRL      0x016
+#define GAISLER_AHBTRACE     0x017
+#define GAISLER_DSUCTRL      0x018
+#define GAISLER_CANAHB       0x019
+#define GAISLER_GPIO         0x01a
+#define GAISLER_AHBROM       0x01b
+#define GAISLER_AHBJTAG      0x01c
+#define GAISLER_ETHMAC       0x01d
+#define GAISLER_SWNODE       0x01e
+#define GAISLER_SPW          0x01f
+#define GAISLER_AHB2AHB      0x020
+#define GAISLER_USBDC        0x021
+#define GAISLER_USB_DCL      0x022
+#define GAISLER_DDRMP        0x023
+#define GAISLER_ATACTRL      0x024
+#define GAISLER_DDRSP        0x025
+#define GAISLER_EHCI         0x026
+#define GAISLER_UHCI         0x027
+#define GAISLER_I2CMST       0x028
+#define GAISLER_SPW2         0x029
+#define GAISLER_AHBDMA       0x02a
+#define GAISLER_NUHOSP3      0x02b
+#define GAISLER_CLKGATE      0x02c
+#define GAISLER_SPICTRL      0x02d
+#define GAISLER_DDR2SP       0x02e
+#define GAISLER_SLINK        0x02f
+#define GAISLER_GRTM         0x030
+#define GAISLER_GRTC         0x031
+#define GAISLER_GRPW         0x032
+#define GAISLER_GRCTM        0x033
+#define GAISLER_GRHCAN       0x034
+#define GAISLER_GRFIFO       0x035
+#define GAISLER_GRADCDAC     0x036
+#define GAISLER_GRPULSE      0x037
+#define GAISLER_GRTIMER      0x038
+#define GAISLER_AHB2PP       0x039
+#define GAISLER_GRVERSION    0x03a
+#define GAISLER_APB2PW       0x03b
+#define GAISLER_PW2APB       0x03c
+#define GAISLER_GRCAN        0x03d
+#define GAISLER_I2CSLV       0x03e
+#define GAISLER_U16550       0x03f
+#define GAISLER_AHBMST_EM    0x040
+#define GAISLER_AHBSLV_EM    0x041
+#define GAISLER_GRTESTMOD    0x042
+#define GAISLER_ASCS         0x043
+#define GAISLER_IPMVBCTRL    0x044
+#define GAISLER_SPIMCTRL     0x045
+#define GAISLER_L4STAT       0x047
+#define GAISLER_LEON4        0x048
+#define GAISLER_LEON4DSU     0x049
+#define GAISLER_PWM          0x04a
+#define GAISLER_L2CACHE      0x04b
+#define GAISLER_SDCTRL64     0x04c
+#define GAISLER_GR1553B      0x04d
+#define GAISLER_1553TST      0x04e
+#define GAISLER_GRIOMMU      0x04f
+#define GAISLER_FTAHBRAM     0x050
+#define GAISLER_FTSRCTRL     0x051
+#define GAISLER_AHBSTAT      0x052
+#define GAISLER_LEON3FT      0x053
+#define GAISLER_FTMCTRL      0x054
+#define GAISLER_FTSDCTRL     0x055
+#define GAISLER_FTSRCTRL8    0x056
+#define GAISLER_MEMSCRUB     0x057
+#define GAISLER_FTSDCTRL64   0x058
+#define GAISLER_APBPS2       0x060
+#define GAISLER_VGACTRL      0x061
+#define GAISLER_LOGAN        0x062
+#define GAISLER_SVGACTRL     0x063
+#define GAISLER_T1AHB        0x064
+#define GAISLER_MP7WRAP      0x065
+#define GAISLER_GRSYSMON     0x066
+#define GAISLER_GRACECTRL    0x067
+#define GAISLER_ATAHBSLV     0x068
+#define GAISLER_ATAHBMST     0x069
+#define GAISLER_ATAPBSLV     0x06a
+#define GAISLER_B1553BC      0x070
+#define GAISLER_B1553RT      0x071
+#define GAISLER_B1553BRM     0x072
+#define GAISLER_AES          0x073
+#define GAISLER_ECC          0x074
+#define GAISLER_PCIF         0x075
+#define GAISLER_CLKMOD       0x076
+#define GAISLER_HAPSTRAK     0x077
+#define GAISLER_TEST_1X2     0x078
+#define GAISLER_WILD2AHB     0x079
+#define GAISLER_BIO1         0x07a
+#define GAISLER_AESDMA       0x07b
+#define GAISLER_SATCAN       0x080
+#define GAISLER_CANMUX       0x081
+#define GAISLER_GRTMRX       0x082
+#define GAISLER_GRTCTX       0x083
+#define GAISLER_GRTMDESC     0x084
+#define GAISLER_GRTMVC       0x085
+#define GAISLER_GEFFE        0x086
+#define GAISLER_GPREG        0x087
+#define GAISLER_GRTMPAHB     0x088
+#define GAISLER_SPWCUC       0x089
+#define GAISLER_SPW2_DMA     0x08a
+#define GAISLER_SPWROUTER    0x08b
+
+/* European Space Agency device ID defines */
+#define ESA_LEON2            0x002
+#define ESA_LEON2APB         0x003
+#define ESA_IRQ              0x005
+#define ESA_TIMER            0x006
+#define ESA_UART             0x007
+#define ESA_CFG              0x008
+#define ESA_IO               0x009
+#define ESA_MCTRL            0x00f
+#define ESA_PCIARB           0x010
+#define ESA_HURRICANE        0x011
+#define ESA_SPW_RMAP         0x012
+#define ESA_AHBUART          0x013
+#define ESA_SPWA             0x014
+#define ESA_BOSCHCAN         0x015
+#define ESA_IRQ2             0x016
+#define ESA_AHBSTAT          0x017
+#define ESA_WPROT            0x018
+#define ESA_WPROT2           0x019
+#define ESA_PDEC3AMBA        0x020
+#define ESA_PTME3AMBA        0x021
+
+/* OpenChip device ID defines */
+#define OPENCHIP_APBGPIO     0x001
+#define OPENCHIP_APBI2C      0x002
+#define OPENCHIP_APBSPI      0x003
+#define OPENCHIP_APBCHARLCD  0x004
+#define OPENCHIP_APBPWM      0x005
+#define OPENCHIP_APBPS2      0x006
+#define OPENCHIP_APBMMCSD    0x007
+#define OPENCHIP_APBNAND     0x008
+#define OPENCHIP_APBLPC      0x009
+#define OPENCHIP_APBCF       0x00a
+#define OPENCHIP_APBSYSACE   0x00b
+#define OPENCHIP_APB1WIRE    0x00c
+#define OPENCHIP_APBJTAG     0x00d
+#define OPENCHIP_APBSUI      0x00e
+
+/* Various contributions device ID defines */
+#define CONTRIB_CORE1        0x001
+#define CONTRIB_CORE2        0x002
+
+/* Gleichmann Electronics device ID defines */
+#define GLEICHMANN_CUSTOM    0x001
+#define GLEICHMANN_GEOLCD01  0x002
+#define GLEICHMANN_DAC       0x003
+#define GLEICHMANN_HPI       0x004
+#define GLEICHMANN_SPI       0x005
+#define GLEICHMANN_HIFC      0x006
+#define GLEICHMANN_ADCDAC    0x007
+#define GLEICHMANN_SPIOC     0x008
+#define GLEICHMANN_AC97      0x009
+
+/* Sun Microsystems device ID defines */
+#define SUN_T1               0x001
+#define SUN_S1               0x011
+
+/* Orbita device ID defines */
+#define ORBITA_1553B         0x001
+#define ORBITA_429           0x002
+#define ORBITA_SPI           0x003
+#define ORBITA_I2C           0x004
+#define ORBITA_SMARTCARD     0x064
+#define ORBITA_SDCARD        0x065
+#define ORBITA_UART16550     0x066
+#define ORBITA_CRYPTO        0x067
+#define ORBITA_SYSIF         0x068
+#define ORBITA_PIO           0x069
+#define ORBITA_RTC           0x0c8
+#define ORBITA_COLORLCD      0x12c
+#define ORBITA_PCI           0x190
+#define ORBITA_DSP           0x1f4
+#define ORBITA_USBHOST       0x258
+#define ORBITA_USBDEV        0x2bc
+
+/* NASA device ID defines */
+#define NASA_EP32            0x001
+
+/* CAL device ID defines */
+#define CAL_DDRCTRL          0x188
+
+/* Actel Corporation device ID defines */
+#define ACTEL_COREMP7        0x001
+
+/* AppleCore device ID defines */
+#define APPLECORE_UTLEON3    0x001
+#define APPLECORE_UTLEON3DSU 0x002
+
+/* Opencores device id's */
+#define OPENCORES_PCIBR  0x4
+#define OPENCORES_ETHMAC 0x5
+
+#endif
diff --git a/include/config_cmd_all.h b/include/config_cmd_all.h
index 8832552..424721b 100644
--- a/include/config_cmd_all.h
+++ b/include/config_cmd_all.h
@@ -13,7 +13,6 @@
  * Alphabetical list of all possible commands.
  */
 
-#define CONFIG_CMD_AMBAPP	/* AMBA Plug & Play Bus print utility */
 #define CONFIG_CMD_ASKENV	/* ask for env variable		*/
 #define CONFIG_CMD_BEDBUG	/* Include BedBug Debugger	*/
 #define CONFIG_CMD_BMP		/* BMP support			*/
diff --git a/include/configs/am43xx_evm.h b/include/configs/am43xx_evm.h
index d93e3e7..b02abd3 100644
--- a/include/configs/am43xx_evm.h
+++ b/include/configs/am43xx_evm.h
@@ -177,11 +177,22 @@
 	"fdt ram 0x80f80000 0x80000;" \
 	"ramdisk ram 0x81000000 0x4000000\0"
 
+#define CONFIG_DFU_SF
+#define DFU_ALT_INFO_QSPI \
+	"dfu_alt_info_qspi=" \
+	"u-boot.bin raw 0x0 0x080000;" \
+	"u-boot.backup raw 0x080000 0x080000;" \
+	"u-boot-spl-os raw 0x100000 0x010000;" \
+	"u-boot-env raw 0x110000 0x010000;" \
+	"u-boot-env.backup raw 0x120000 0x010000;" \
+	"kernel raw 0x130000 0x800000\0"
+
 #define DFUARGS \
 	"dfu_bufsiz=0x10000\0" \
 	DFU_ALT_INFO_MMC \
 	DFU_ALT_INFO_EMMC \
-	DFU_ALT_INFO_RAM
+	DFU_ALT_INFO_RAM \
+	DFU_ALT_INFO_QSPI
 #else
 #define DFUARGS
 #endif
diff --git a/include/configs/bayleybay.h b/include/configs/bayleybay.h
index 1ba2998..b102c68 100644
--- a/include/configs/bayleybay.h
+++ b/include/configs/bayleybay.h
@@ -16,7 +16,6 @@
 #define CONFIG_SYS_MONITOR_LEN		(1 << 20)
 #define CONFIG_ARCH_MISC_INIT
 
-#define CONFIG_SYS_EARLY_PCI_INIT
 #define CONFIG_PCI_PNP
 
 #define CONFIG_STD_DEVICES_SETTINGS	"stdin=serial,vga,usbkbd\0" \
diff --git a/include/configs/crownbay.h b/include/configs/crownbay.h
index 7f91fff..54a2905 100644
--- a/include/configs/crownbay.h
+++ b/include/configs/crownbay.h
@@ -20,19 +20,6 @@
 
 #define CONFIG_SMSC_LPC47M
 
-#define CONFIG_PCI_MEM_BUS		0x40000000
-#define CONFIG_PCI_MEM_PHYS		CONFIG_PCI_MEM_BUS
-#define CONFIG_PCI_MEM_SIZE		0x80000000
-
-#define CONFIG_PCI_PREF_BUS		0xc0000000
-#define CONFIG_PCI_PREF_PHYS		CONFIG_PCI_PREF_BUS
-#define CONFIG_PCI_PREF_SIZE		0x20000000
-
-#define CONFIG_PCI_IO_BUS		0x2000
-#define CONFIG_PCI_IO_PHYS		CONFIG_PCI_IO_BUS
-#define CONFIG_PCI_IO_SIZE		0xe000
-
-#define CONFIG_SYS_EARLY_PCI_INIT
 #define CONFIG_PCI_PNP
 
 #define CONFIG_STD_DEVICES_SETTINGS	"stdin=serial,vga,usbkbd\0" \
diff --git a/include/configs/dlvision-10g.h b/include/configs/dlvision-10g.h
index 0b804eb..b614f19 100644
--- a/include/configs/dlvision-10g.h
+++ b/include/configs/dlvision-10g.h
@@ -67,7 +67,7 @@
 #undef CONFIG_CMD_DHCP
 #undef CONFIG_CMD_DIAG
 #undef CONFIG_CMD_EEPROM
-#undef CONFIG_CMD_I2C
+#define CONFIG_CMD_I2C
 #undef CONFIG_CMD_IRQ
 
 /*
@@ -105,17 +105,22 @@
 #define CONFIG_SYS_I2C_PPC4XX_SLAVE_0		0x7F
 
 #define CONFIG_SYS_I2C_IHS
+#define CONFIG_SYS_I2C_IHS_DUAL
 #define CONFIG_SYS_I2C_IHS_CH0
 #define CONFIG_SYS_I2C_IHS_SPEED_0		50000
 #define CONFIG_SYS_I2C_IHS_SLAVE_0		0x7F
+#define CONFIG_SYS_I2C_IHS_SPEED_0_1		50000
+#define CONFIG_SYS_I2C_IHS_SLAVE_0_1		0x7F
 #define CONFIG_SYS_I2C_IHS_CH1
 #define CONFIG_SYS_I2C_IHS_SPEED_1		50000
 #define CONFIG_SYS_I2C_IHS_SLAVE_1		0x7F
+#define CONFIG_SYS_I2C_IHS_SPEED_1_1		50000
+#define CONFIG_SYS_I2C_IHS_SLAVE_1_1		0x7F
 
-#define CONFIG_SYS_SPD_BUS_NUM		2
+#define CONFIG_SYS_SPD_BUS_NUM		4
 
 /* Temp sensor/hwmon/dtt */
-#define CONFIG_SYS_DTT_BUS_NUM	2
+#define CONFIG_SYS_DTT_BUS_NUM	4
 #define CONFIG_DTT_LM63		1	/* National LM63	*/
 #define CONFIG_DTT_SENSORS	{ 0x4c, 0x4e, 0x18 } /* Sensor addresses */
 #define CONFIG_DTT_PWM_LOOKUPTABLE	\
@@ -123,8 +128,9 @@
 		  { 54, 27 }, { 56, 31 }, { 58, 36 }, { 60, 40 } }
 #define CONFIG_DTT_TACH_LIMIT	0xa10
 
-#define CONFIG_SYS_ICS8N3QV01_I2C	{0, 1}
-#define CONFIG_SYS_SIL1178_I2C		{0, 1}
+#define CONFIG_SYS_ICS8N3QV01_I2C	{1, 3}
+#define CONFIG_SYS_SIL1178_I2C		{0, 2}
+#define CONFIG_SYS_DP501_I2C		{0, 2}
 
 /* EBC peripherals */
 
@@ -327,5 +333,7 @@
  */
 #define CONFIG_SYS_MPC92469AC
 #define CONFIG_SYS_OSD_SCREENS		CONFIG_SYS_FPGA_COUNT
+#define CONFIG_SYS_DP501_DIFFERENTIAL
+#define CONFIG_SYS_DP501_VCAPCTRL0	0x01 /* DDR mode 0, DE for H/VSYNC */
 
 #endif	/* __CONFIG_H */
diff --git a/include/configs/galileo.h b/include/configs/galileo.h
index ba6c8f1..eb16a5e 100644
--- a/include/configs/galileo.h
+++ b/include/configs/galileo.h
@@ -21,7 +21,6 @@
 /* ns16550 UART is memory-mapped in Quark SoC */
 #undef  CONFIG_SYS_NS16550_PORT_MAPPED
 
-#define CONFIG_SYS_EARLY_PCI_INIT
 #define CONFIG_PCI_PNP
 
 #define CONFIG_STD_DEVICES_SETTINGS	"stdin=serial\0" \
diff --git a/include/configs/gr_cpci_ax2000.h b/include/configs/gr_cpci_ax2000.h
index 782746e..5bbf1aa 100644
--- a/include/configs/gr_cpci_ax2000.h
+++ b/include/configs/gr_cpci_ax2000.h
@@ -60,7 +60,6 @@
  * Supported commands
  */
 #define CONFIG_CMD_REGINFO
-#define CONFIG_CMD_AMBAPP
 #define CONFIG_CMD_PING
 #define CONFIG_CMD_DIAG
 #define CONFIG_CMD_IRQ
@@ -311,40 +310,38 @@
 
 /***** Gaisler GRLIB IP-Cores Config ********/
 
-/* AMBA Plug & Play info display on startup */
-/*#define CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP*/
-
 #define CONFIG_SYS_GRLIB_SDRAM    0
 
+/* No SDRAM Configuration */
+#undef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1
+
 /* See, GRLIB Docs (grip.pdf) on how to set up
  * These the memory controller registers.
  */
-#define CONFIG_SYS_GRLIB_MEMCFG1   (0x10f800ff | (1<<11))
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG1   (0x10f800ff | (1<<11))
 #if CONFIG_LEON_RAM_SELECT == CONFIG_LEON_RAM_SDRAM_NOSRAM
-#define CONFIG_SYS_GRLIB_MEMCFG2   0x82206000
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2   0x82206000
 #else
-#define CONFIG_SYS_GRLIB_MEMCFG2   0x82205260
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2   0x82205260
 #endif
-#define CONFIG_SYS_GRLIB_MEMCFG3   0x0809a000
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG3   0x0809a000
 
-#define CONFIG_SYS_GRLIB_FT_MEMCFG1   (0x10f800ff | (1<<11))
+/* GRLIB FT-MCTRL configuration */
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG1   (0x10f800ff | (1<<11))
 #if CONFIG_LEON_RAM_SELECT == CONFIG_LEON_RAM_SDRAM_NOSRAM
-#define CONFIG_SYS_GRLIB_FT_MEMCFG2   0x82206000
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2   0x82206000
 #else
-#define CONFIG_SYS_GRLIB_FT_MEMCFG2   0x82205260
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2   0x82205260
 #endif
-#define CONFIG_SYS_GRLIB_FT_MEMCFG3   0x0809a000
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG3   0x0809a000
 
 /* no DDR controller */
-#define CONFIG_SYS_GRLIB_DDR_CFG   0x00000000
+#undef CONFIG_SYS_GRLIB_GAISLER_DDRSPA1
 
 /* no DDR2 Controller */
-#define CONFIG_SYS_GRLIB_DDR2_CFG1 0x00000000
-#define CONFIG_SYS_GRLIB_DDR2_CFG3 0x00000000
-
-/* Calculate scaler register value from default baudrate */
-#define CONFIG_SYS_GRLIB_APBUART_SCALER \
- ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10)
+#undef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1
 
 /* Identification string */
 #define CONFIG_IDENT_STRING "GAISLER LEON3 GR-CPCI-AX2000"
diff --git a/include/configs/gr_ep2s60.h b/include/configs/gr_ep2s60.h
index 5c466f2..b55ca77 100644
--- a/include/configs/gr_ep2s60.h
+++ b/include/configs/gr_ep2s60.h
@@ -54,7 +54,6 @@
  * Supported commands
  */
 #define CONFIG_CMD_REGINFO
-#define CONFIG_CMD_AMBAPP
 #define CONFIG_CMD_PING
 #define CONFIG_CMD_DIAG
 #define CONFIG_CMD_IRQ
@@ -288,30 +287,31 @@
 
 /***** Gaisler GRLIB IP-Cores Config ********/
 
-/* AMBA Plug & Play info display on startup */
-/*#define CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP*/
-
 #define CONFIG_SYS_GRLIB_SDRAM    0
 
+/* No SDRAM Configuration */
+#undef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1
+
 /* See, GRLIB Docs (grip.pdf) on how to set up
  * These the memory controller registers.
  */
-#define CONFIG_SYS_GRLIB_MEMCFG1  (0x10f800ff | (1<<11))
-#define CONFIG_SYS_GRLIB_MEMCFG2  0x00000000
-#define CONFIG_SYS_GRLIB_MEMCFG3  0x00000000
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG1  (0x10f800ff | (1<<11))
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2  0x00000000
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG3  0x00000000
 
-#define CONFIG_SYS_GRLIB_FT_MEMCFG1  (0x10f800ff | (1<<11))
-#define CONFIG_SYS_GRLIB_FT_MEMCFG2  0x00000000
-#define CONFIG_SYS_GRLIB_FT_MEMCFG3  0x00000000
+/* GRLIB FT-MCTRL configuration */
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG1  (0x10f800ff | (1<<11))
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2  0x00000000
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG3  0x00000000
 
-#define CONFIG_SYS_GRLIB_DDR_CFG  0xa900830a
+/* DDR controller */
+#define CONFIG_SYS_GRLIB_GAISLER_DDRSPA1
+#define CONFIG_SYS_GRLIB_GAISLER_DDRSPA1_CTRL  0xa900830a
 
-#define CONFIG_SYS_GRLIB_DDR2_CFG1 0x00000000
-#define CONFIG_SYS_GRLIB_DDR2_CFG3 0x00000000
-
-/* Calculate scaler register value from default baudrate */
-#define CONFIG_SYS_GRLIB_APBUART_SCALER \
- ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10)
+/* no DDR2 Controller */
+#undef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1
 
 /* Identification string */
 #define CONFIG_IDENT_STRING "GAISLER LEON3 EP2S60"
diff --git a/include/configs/gr_xc3s_1500.h b/include/configs/gr_xc3s_1500.h
index e01578c..d086b69 100644
--- a/include/configs/gr_xc3s_1500.h
+++ b/include/configs/gr_xc3s_1500.h
@@ -41,7 +41,6 @@
  * Supported commands
  */
 #define CONFIG_CMD_REGINFO
-#define CONFIG_CMD_AMBAPP
 #define CONFIG_CMD_PING
 #define CONFIG_CMD_DIAG
 #define CONFIG_CMD_IRQ
@@ -251,32 +250,30 @@
 
 /***** Gaisler GRLIB IP-Cores Config ********/
 
-/* AMBA Plug & Play info display on startup */
-/*#define CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP*/
-
 #define CONFIG_SYS_GRLIB_SDRAM    0
 
+/* No SDRAM Configuration */
+#undef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1
+
 /* See, GRLIB Docs (grip.pdf) on how to set up
  * These the memory controller registers.
  */
-#define CONFIG_SYS_GRLIB_MEMCFG1   (0x000000ff | (1<<11))
-#define CONFIG_SYS_GRLIB_MEMCFG2   0x82206000
-#define CONFIG_SYS_GRLIB_MEMCFG3   0x00136000
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG1   (0x000000ff | (1<<11))
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2   0x82206000
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG3   0x00136000
 
-#define CONFIG_SYS_GRLIB_FT_MEMCFG1   (0x000000ff | (1<<11))
-#define CONFIG_SYS_GRLIB_FT_MEMCFG2   0x82206000
-#define CONFIG_SYS_GRLIB_FT_MEMCFG3   0x00136000
+/* GRLIB FT-MCTRL configuration */
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG1   (0x000000ff | (1<<11))
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2   0x82206000
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG3   0x00136000
 
 /* no DDR controller */
-#define CONFIG_SYS_GRLIB_DDR_CFG   0x00000000
+#undef CONFIG_SYS_GRLIB_GAISLER_DDRSPA1
 
 /* no DDR2 Controller */
-#define CONFIG_SYS_GRLIB_DDR2_CFG1 0x00000000
-#define CONFIG_SYS_GRLIB_DDR2_CFG3 0x00000000
-
-/* Calculate scaler register value from default baudrate */
-#define CONFIG_SYS_GRLIB_APBUART_SCALER \
- ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10)
+#undef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1
 
 /* Identification string */
 #define CONFIG_IDENT_STRING "GAISLER LEON3 GR-XC3S-1500"
diff --git a/include/configs/grsim.h b/include/configs/grsim.h
index f54919e..e1f7dc3 100644
--- a/include/configs/grsim.h
+++ b/include/configs/grsim.h
@@ -19,9 +19,13 @@
  *
  * Select between TSIM or GRSIM by setting CONFIG_GRSIM or CONFIG_TSIM to 1.
  *
- * TSIM command
- *  tsim-leon3 -sdram 0 -ram 32000 -rom 8192 -mmu
+ * TSIM command:
+ * $ tsim-leon3 -sdram 32768 -ram 4096 -rom 2048 -mmu -cas
  *
+ * In the evaluation version of TSIM, the -sdram/-ram/-rom arguments are
+ * hard-coded to these values and need not be specified. (see below)
+ *
+ * Get TSIM from http://www.gaisler.com/index.php/downloads/simulators
  */
 
 #define CONFIG_GRSIM		0	/* ... not running on GRSIM */
@@ -47,7 +51,6 @@
 /*
  * Supported commands
  */
-#define CONFIG_CMD_AMBAPP	/* AMBA Plyg&Play information	*/
 #define CONFIG_CMD_DIAG
 #define CONFIG_CMD_FPGA_LOADMK
 #define CONFIG_CMD_IRQ
@@ -184,18 +187,18 @@
 /*
  * Memory map
  */
-#define CONFIG_SYS_SDRAM_BASE		0x40000000
-#define CONFIG_SYS_SDRAM_SIZE		0x02000000
-#define CONFIG_SYS_SDRAM_END		(CONFIG_SYS_SDRAM_BASE+CONFIG_SYS_SDRAM_SIZE)
+#define CONFIG_SYS_SDRAM_BASE		0x60000000
+#define CONFIG_SYS_SDRAM_SIZE		0x02000000 /* 32MiB SDRAM */
+#define CONFIG_SYS_SDRAM_END		(CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_SDRAM_SIZE)
 
-/* no SRAM available */
-#undef CONFIG_SYS_SRAM_BASE
-#undef CONFIG_SYS_SRAM_SIZE
+#define CONFIG_SYS_SRAM_BASE		0x40000000
+#define CONFIG_SYS_SRAM_SIZE		0x00400000 /* 4MiB SRAM */
+#define CONFIG_SYS_SRAM_END		(CONFIG_SYS_SRAM_BASE + CONFIG_SYS_SRAM_SIZE)
 
 /* Always Run U-Boot from SDRAM */
-#define CONFIG_SYS_RAM_BASE CONFIG_SYS_SDRAM_BASE
-#define CONFIG_SYS_RAM_SIZE CONFIG_SYS_SDRAM_SIZE
-#define CONFIG_SYS_RAM_END CONFIG_SYS_SDRAM_END
+#define CONFIG_SYS_RAM_BASE		CONFIG_SYS_SDRAM_BASE
+#define CONFIG_SYS_RAM_SIZE		CONFIG_SYS_SDRAM_SIZE
+#define CONFIG_SYS_RAM_END		CONFIG_SYS_SDRAM_END
 
 #define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_RAM_END - GENERATED_GBL_DATA_SIZE)
 
@@ -224,6 +227,7 @@
 /* make un relocated address from relocated address */
 #define UN_RELOC(address) (address-(CONFIG_SYS_RELOC_MONITOR_BASE-CONFIG_SYS_TEXT_BASE))
 
+#ifdef CONFIG_CMD_NET
 /*
  * Ethernet configuration
  */
@@ -235,6 +239,8 @@
 /* #define CONFIG_GRETH_10MBIT 1 */
 #define CONFIG_PHY_ADDR		0x00
 
+#endif /* CONFIG_CMD_NET */
+
 /*
  * Miscellaneous configurable options
  */
@@ -255,37 +261,65 @@
 
 /***** Gaisler GRLIB IP-Cores Config ********/
 
-/* AMBA Plug & Play info display on startup */
-/*#define CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP*/
-
 #define CONFIG_SYS_GRLIB_SDRAM     0
+
 #define CONFIG_SYS_GRLIB_MEMCFG1   (0x000000ff | (1<<11))
+
+/* No SDRAM Configuration */
+#undef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1
+
+/* LEON2 MCTRL configuration */
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG1   (0x000000ff | (1<<11))
 #if CONFIG_GRSIM
 /* GRSIM configuration */
-#define CONFIG_SYS_GRLIB_MEMCFG2   0x82206000
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2   0x82206000
 #else
 /* TSIM configuration */
-#define CONFIG_SYS_GRLIB_MEMCFG2   0x00001820
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2   0x81805220
 #endif
-#define CONFIG_SYS_GRLIB_MEMCFG3   0x00136000
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG3   0x00136000
 
-#define CONFIG_SYS_GRLIB_FT_MEMCFG1   (0x000000ff | (1<<11))
-#define CONFIG_SYS_GRLIB_FT_MEMCFG2   0x82206000
-#define CONFIG_SYS_GRLIB_FT_MEMCFG3   0x00136000
+/* GRLIB FT-MCTRL configuration */
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG1   (0x000000ff | (1<<11))
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2   0x82206000
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG3   0x00136000
 
 /* no DDR controller */
-#define CONFIG_SYS_GRLIB_DDR_CFG   0x00000000
+#undef CONFIG_SYS_GRLIB_GAISLER_DDRSPA1
 
 /* no DDR2 Controller */
-#define CONFIG_SYS_GRLIB_DDR2_CFG1 0x00000000
-#define CONFIG_SYS_GRLIB_DDR2_CFG3 0x00000000
-
-#define CONFIG_SYS_GRLIB_APBUART_SCALER \
- ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10)
+#undef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1
 
 /* default kernel command line */
 #define CONFIG_DEFAULT_KERNEL_COMMAND_LINE "console=ttyS0,38400\0\0"
 
 #define CONFIG_IDENT_STRING "Gaisler GRSIM"
 
+/* TSIM command:
+ * $ ./tsim-leon3 -mmu -cas
+ *
+ *  This TSIM evaluation version will expire 2015-04-02
+ *
+ *
+ *  TSIM/LEON3 SPARC simulator, version 2.0.35 (evaluation version)
+ *
+ *  Copyright (C) 2014, Aeroflex Gaisler - all rights reserved.
+ *  This software may only be used with a valid license.
+ *  For latest updates, go to http://www.gaisler.com/
+ *  Comments or bug-reports to support@gaisler.com
+ *
+ * serial port A on stdin/stdout
+ * allocated 4096 K SRAM memory, in 1 bank
+ * allocated 32 M SDRAM memory, in 1 bank
+ * allocated 2048 K ROM memory
+ * icache: 1 * 4 kbytes, 16 bytes/line (4 kbytes total)
+ * dcache: 1 * 4 kbytes, 16 bytes/line (4 kbytes total)
+ * tsim> leon
+ * 0x80000000   Memory configuration register 1   0x000002ff
+ * 0x80000004   Memory configuration register 2   0x81805220
+ * 0x80000008   Memory configuration register 3   0x00000000
+ */
+
 #endif				/* __CONFIG_H */
diff --git a/include/configs/grsim_leon2.h b/include/configs/grsim_leon2.h
index bd2eaa9..83fd7fa 100644
--- a/include/configs/grsim_leon2.h
+++ b/include/configs/grsim_leon2.h
@@ -264,8 +264,6 @@
 #define CONFIG_SYS_GRLIB_MEMCFG3  0x00136000
 
 /*** LEON2 UART 1 ***/
-#define CONFIG_SYS_LEON2_UART1_SCALER \
-	((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10)
 
 /* UART1 Define to 1 or 0 */
 #define LEON2_UART1_LOOPBACK_ENABLE 0
@@ -275,9 +273,6 @@
 
 /*** LEON2 UART 2 ***/
 
-#define CONFIG_SYS_LEON2_UART2_SCALER \
-	((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10)
-
 /* UART2 Define to 1 or 0 */
 #define LEON2_UART2_LOOPBACK_ENABLE 0
 #define LEON2_UART2_FLOWCTRL_ENABLE 0
diff --git a/include/configs/hrcon.h b/include/configs/hrcon.h
index 3cb279a..84d0928 100644
--- a/include/configs/hrcon.h
+++ b/include/configs/hrcon.h
@@ -20,7 +20,11 @@
 
 #define	CONFIG_SYS_TEXT_BASE	0xFE000000
 
+#ifdef CONFIG_HRCON_DH
+#define CONFIG_IDENT_STRING	" hrcon dh 0.01"
+#else
 #define CONFIG_IDENT_STRING	" hrcon 0.01"
+#endif
 
 
 #define CONFIG_BOARD_EARLY_INIT_F
@@ -343,6 +347,22 @@
 #define CONFIG_SYS_I2C_IHS_SPEED_3		50000
 #define CONFIG_SYS_I2C_IHS_SLAVE_3		0x7F
 
+#ifdef CONFIG_HRCON_DH
+#define CONFIG_SYS_I2C_IHS_DUAL
+#define CONFIG_SYS_I2C_IHS_CH0_1
+#define CONFIG_SYS_I2C_IHS_SPEED_0_1		50000
+#define CONFIG_SYS_I2C_IHS_SLAVE_0_1		0x7F
+#define CONFIG_SYS_I2C_IHS_CH1_1
+#define CONFIG_SYS_I2C_IHS_SPEED_1_1		50000
+#define CONFIG_SYS_I2C_IHS_SLAVE_1_1		0x7F
+#define CONFIG_SYS_I2C_IHS_CH2_1
+#define CONFIG_SYS_I2C_IHS_SPEED_2_1		50000
+#define CONFIG_SYS_I2C_IHS_SLAVE_2_1		0x7F
+#define CONFIG_SYS_I2C_IHS_CH3_1
+#define CONFIG_SYS_I2C_IHS_SPEED_3_1		50000
+#define CONFIG_SYS_I2C_IHS_SLAVE_3_1		0x7F
+#endif
+
 /*
  * Software (bit-bang) I2C driver configuration
  */
@@ -358,34 +378,85 @@
 #define I2C_SOFT_DECLARATIONS4
 #define CONFIG_SYS_I2C_SOFT_SPEED_4		50000
 #define CONFIG_SYS_I2C_SOFT_SLAVE_4		0x7F
+#define I2C_SOFT_DECLARATIONS5
+#define CONFIG_SYS_I2C_SOFT_SPEED_5		50000
+#define CONFIG_SYS_I2C_SOFT_SLAVE_5		0x7F
+#define I2C_SOFT_DECLARATIONS6
+#define CONFIG_SYS_I2C_SOFT_SPEED_6		50000
+#define CONFIG_SYS_I2C_SOFT_SLAVE_6		0x7F
+#define I2C_SOFT_DECLARATIONS7
+#define CONFIG_SYS_I2C_SOFT_SPEED_7		50000
+#define CONFIG_SYS_I2C_SOFT_SLAVE_7		0x7F
+#define I2C_SOFT_DECLARATIONS8
+#define CONFIG_SYS_I2C_SOFT_SPEED_8		50000
+#define CONFIG_SYS_I2C_SOFT_SLAVE_8		0x7F
 
-#define CONFIG_SYS_ICS8N3QV01_I2C		{5, 6, 7, 8}
-#define CONFIG_SYS_CH7301_I2C			{5, 6, 7, 8}
+#ifdef CONFIG_HRCON_DH
+#define I2C_SOFT_DECLARATIONS9
+#define CONFIG_SYS_I2C_SOFT_SPEED_9		50000
+#define CONFIG_SYS_I2C_SOFT_SLAVE_9		0x7F
+#define I2C_SOFT_DECLARATIONS10
+#define CONFIG_SYS_I2C_SOFT_SPEED_10		50000
+#define CONFIG_SYS_I2C_SOFT_SLAVE_10		0x7F
+#define I2C_SOFT_DECLARATIONS11
+#define CONFIG_SYS_I2C_SOFT_SPEED_11		50000
+#define CONFIG_SYS_I2C_SOFT_SLAVE_11		0x7F
+#define I2C_SOFT_DECLARATIONS12
+#define CONFIG_SYS_I2C_SOFT_SPEED_12		50000
+#define CONFIG_SYS_I2C_SOFT_SLAVE_12		0x7F
+#endif
+
+#ifdef CONFIG_HRCON_DH
+#define CONFIG_SYS_ICS8N3QV01_I2C		{13, 14, 15, 16, 17, 18, 19, 20}
+#define CONFIG_SYS_DP501_I2C			{1, 3, 5, 7, 2, 4, 6, 8}
+#define CONFIG_HRCON_FANS			{ {10, 0x4c}, {11, 0x4c}, \
+						  {12, 0x4c} }
+#else
+#define CONFIG_SYS_ICS8N3QV01_I2C		{9, 10, 11, 12}
 #define CONFIG_SYS_DP501_I2C			{1, 2, 3, 4}
+#define CONFIG_HRCON_FANS			{ {6, 0x4c}, {7, 0x4c}, \
+						  {8, 0x4c} }
+#endif
 
 #ifndef __ASSEMBLY__
 void fpga_gpio_set(unsigned int bus, int pin);
 void fpga_gpio_clear(unsigned int bus, int pin);
 int fpga_gpio_get(unsigned int bus, int pin);
+void fpga_control_set(unsigned int bus, int pin);
+void fpga_control_clear(unsigned int bus, int pin);
 #endif
 
+#define I2C_SDA_GPIO	((I2C_ADAP_HWNR > 3) ? 0x0040 : 0x0200)
+#define I2C_SCL_GPIO	((I2C_ADAP_HWNR > 3) ? 0x0020 : 0x0100)
+#define I2C_FPGA_IDX	(I2C_ADAP_HWNR % 4)
+
+#ifdef CONFIG_HRCON_DH
+#define I2C_ACTIVE \
+	do { \
+		if (I2C_ADAP_HWNR > 7) \
+			fpga_control_set(I2C_FPGA_IDX, 0x0004); \
+		else \
+			fpga_control_clear(I2C_FPGA_IDX, 0x0004); \
+	} while (0)
+#else
 #define I2C_ACTIVE	{ }
+#endif
 #define I2C_TRISTATE	{ }
 #define I2C_READ \
-	(fpga_gpio_get(I2C_ADAP_HWNR, 0x0040) ? 1 : 0)
+	(fpga_gpio_get(I2C_FPGA_IDX, I2C_SDA_GPIO) ? 1 : 0)
 #define I2C_SDA(bit) \
 	do { \
 		if (bit) \
-			fpga_gpio_set(I2C_ADAP_HWNR, 0x0040); \
+			fpga_gpio_set(I2C_FPGA_IDX, I2C_SDA_GPIO); \
 		else \
-			fpga_gpio_clear(I2C_ADAP_HWNR, 0x0040); \
+			fpga_gpio_clear(I2C_FPGA_IDX, I2C_SDA_GPIO); \
 	} while (0)
 #define I2C_SCL(bit) \
 	do { \
 		if (bit) \
-			fpga_gpio_set(I2C_ADAP_HWNR, 0x0020); \
+			fpga_gpio_set(I2C_FPGA_IDX, I2C_SCL_GPIO); \
 		else \
-			fpga_gpio_clear(I2C_ADAP_HWNR, 0x0020); \
+			fpga_gpio_clear(I2C_FPGA_IDX, I2C_SCL_GPIO); \
 	} while (0)
 #define I2C_DELAY	udelay(25)	/* 1/4 I2C clock duration */
 
@@ -402,6 +473,10 @@
 #define CONFIG_SYS_DP501_DIFFERENTIAL
 #define CONFIG_SYS_DP501_VCAPCTRL0	0x01 /* DDR mode 0, DE for H/VSYNC */
 
+#ifdef CONFIG_HRCON_DH
+#define CONFIG_SYS_OSD_DH
+#endif
+
 /*
  * General PCI
  * Addresses are mapped 1-1.
diff --git a/include/configs/jetson-tk1.h b/include/configs/jetson-tk1.h
index e87a010..f63957a 100644
--- a/include/configs/jetson-tk1.h
+++ b/include/configs/jetson-tk1.h
@@ -78,6 +78,4 @@
 #define CONFIG_ARMV7_SECURE_BASE		0xfff00000
 #define CONFIG_ARMV7_SECURE_RESERVE_SIZE	0x00100000
 
-#define CONFIG_OF_BOARD_SETUP
-
 #endif /* __CONFIG_H */
diff --git a/include/configs/kwb.h b/include/configs/kwb.h
index 96f2e9d..45253b8 100644
--- a/include/configs/kwb.h
+++ b/include/configs/kwb.h
@@ -57,6 +57,8 @@
 #ifndef CONFIG_SPL_BUILD
 #define CONFIG_EXTRA_ENV_SETTINGS \
 BUR_COMMON_ENV \
+"bootaddr=0x80001100\0" \
+"bootdev=cpsw(0,0)\0" \
 "vx_romfsbase=0x800E0000\0" \
 "vx_romfssize=0x20000\0" \
 "vx_memtop=0x8FBEF000\0" \
@@ -66,7 +68,7 @@
 "logoaddr=0x82000000\0" \
 "defaultARlen=0x8000\0" \
 "loaddefaultAR=mmc read ${loadaddr} 800 ${defaultARlen}\0" \
-"defaultAR=run loadromfs; run loaddefaultAR; go ${loadaddr}\0" \
+"defaultAR=run loadromfs; run loaddefaultAR; bootvx ${loadaddr}\0" \
 "logo0=fatload mmc 0:1 ${logoaddr} SYSTEM/ADDON/Bootlogo/Bootlogo.bmp.gz && " \
 	"bmp display ${logoaddr} 0 0\0" \
 "logo1=fatload mmc 0:1 ${logoaddr} SYSTEM/BASE/Bootlogo/Bootlogo.bmp.gz && " \
@@ -74,11 +76,11 @@
 "mmcboot=echo booting AR from eMMC-flash ...; "\
 	"run logo0 || run logo1; " \
 	"run loadromfs; " \
-	"fatload mmc 0:1 ${loadaddr} arimg && go ${loadaddr}; " \
+	"fatload mmc 0:1 ${loadaddr} arimg && bootvx ${loadaddr}; " \
 	"run defaultAR;\0" \
 "netboot=echo booting AR from network ...; " \
 	"run loadromfs; " \
-	"tftp ${loadaddr} arimg && go ${loadaddr}; " \
+	"tftp ${loadaddr} arimg && bootvx ${loadaddr}; " \
 	"puts 'networkboot failed!';\0" \
 "netscript=echo running script from network (tftp) ...; " \
 	"tftp 0x80000000 netscript.img && source; " \
diff --git a/include/configs/minnowmax.h b/include/configs/minnowmax.h
index 53d86a2..a20552e 100644
--- a/include/configs/minnowmax.h
+++ b/include/configs/minnowmax.h
@@ -19,7 +19,6 @@
 
 #define CONFIG_SMSC_LPC47M
 
-#define CONFIG_SYS_EARLY_PCI_INIT
 #define CONFIG_PCI_PNP
 #define CONFIG_RTL8169
 #define CONFIG_STD_DEVICES_SETTINGS     "stdin=usbkbd,vga,serial\0" \
diff --git a/include/configs/omap3_logic.h b/include/configs/omap3_logic.h
index ecd5615..7b60f29 100644
--- a/include/configs/omap3_logic.h
+++ b/include/configs/omap3_logic.h
@@ -272,13 +272,4 @@
 
 #endif /* (CONFIG_CMD_NET) */
 
-/*
- * BOOTP fields
- */
-
-#define CONFIG_BOOTP_SUBNETMASK		0x00000001
-#define CONFIG_BOOTP_GATEWAY		0x00000002
-#define CONFIG_BOOTP_HOSTNAME		0x00000004
-#define CONFIG_BOOTP_BOOTPATH		0x00000010
-
 #endif /* __CONFIG_H */
diff --git a/include/configs/p2371-2180.h b/include/configs/p2371-2180.h
index 3bdf196..94f8085 100644
--- a/include/configs/p2371-2180.h
+++ b/include/configs/p2371-2180.h
@@ -53,6 +53,16 @@
 #define CONFIG_USB_HOST_ETHER
 #define CONFIG_USB_ETHER_ASIX
 
+/* PCI host support */
+#define CONFIG_PCI
+#define CONFIG_PCI_TEGRA
+#define CONFIG_PCI_PNP
+#define CONFIG_CMD_PCI
+#define CONFIG_CMD_PCI_ENUM
+
+/* PCI networking support */
+#define CONFIG_RTL8169
+
 /* General networking support */
 #define CONFIG_CMD_DHCP
 
diff --git a/include/configs/p2571.h b/include/configs/p2571.h
index c65d3e5..a5de411 100644
--- a/include/configs/p2571.h
+++ b/include/configs/p2571.h
@@ -60,6 +60,4 @@
 #include "tegra-common-usb-gadget.h"
 #include "tegra-common-post.h"
 
-#define CONFIG_OF_BOARD_SETUP
-
 #endif /* _P2571_H */
diff --git a/include/configs/pengwyn.h b/include/configs/pengwyn.h
index ccb5dd3..d68cded 100644
--- a/include/configs/pengwyn.h
+++ b/include/configs/pengwyn.h
@@ -127,35 +127,58 @@
 #define CONFIG_CMD_NAND
 #define CONFIG_NAND_OMAP_GPMC
 #define CONFIG_NAND_OMAP_ELM
+
+/* NAND Configuration. */
 #define CONFIG_SYS_NAND_5_ADDR_CYCLE
 #define CONFIG_SYS_NAND_PAGE_COUNT	(CONFIG_SYS_NAND_BLOCK_SIZE / \
 					 CONFIG_SYS_NAND_PAGE_SIZE)
-#define CONFIG_SYS_NAND_PAGE_SIZE	2048
-#define CONFIG_SYS_NAND_OOBSIZE		64
-#define CONFIG_SYS_NAND_BLOCK_SIZE	(128*1024)
+#define CONFIG_SYS_NAND_PAGE_SIZE	4096
+#define CONFIG_SYS_NAND_OOBSIZE		224
+#define CONFIG_SYS_NAND_ONFI_DETECTION
+#define CONFIG_SYS_NAND_BLOCK_SIZE	(128*4096)
 #define CONFIG_SYS_NAND_BAD_BLOCK_POS	NAND_LARGE_BADBLOCK_POS
-#define CONFIG_SYS_NAND_ECCPOS		{ 2, 3, 4, 5, 6, 7, 8, 9, \
-					 10, 11, 12, 13, 14, 15, 16, 17, \
-					 18, 19, 20, 21, 22, 23, 24, 25, \
-					 26, 27, 28, 29, 30, 31, 32, 33, \
-					 34, 35, 36, 37, 38, 39, 40, 41, \
-					 42, 43, 44, 45, 46, 47, 48, 49, \
-					 50, 51, 52, 53, 54, 55, 56, 57, }
+#define CONFIG_SYS_NAND_ECCPOS		{   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,\
+					   18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,  30,  31,  32,  33,\
+					   34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,  49,\
+					   50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,  64,  65,\
+					   66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,\
+					   82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,\
+					   98,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,\
+					  114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133,\
+					  134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153,\
+					  154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173,\
+					  174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193,\
+					  194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209}
+
 
 #define CONFIG_SYS_NAND_ECCSIZE		512
-#define CONFIG_SYS_NAND_ECCBYTES	14
-#define CONFIG_SYS_NAND_ONFI_DETECTION
-#define CONFIG_NAND_OMAP_ECCSCHEME	OMAP_ECC_BCH8_CODE_HW
+#define CONFIG_SYS_NAND_ECCBYTES	26
+#define CONFIG_SYS_NAND_ECCSTEPS	8
+#define	CONFIG_SYS_NAND_ECCTOTAL	(CONFIG_SYS_NAND_ECCBYTES * \
+						CONFIG_SYS_NAND_ECCSTEPS)
+#define CONFIG_NAND_OMAP_ECCSCHEME	OMAP_ECC_BCH16_CODE_HW
+/* END NAND Configuration. */
+
 #define CONFIG_SYS_NAND_U_BOOT_START	CONFIG_SYS_TEXT_BASE
-#define CONFIG_SYS_NAND_U_BOOT_OFFS	0x80000
+/* #define CONFIG_SYS_NAND_U_BOOT_OFFS	0x80000 */
+#define CONFIG_SYS_NAND_U_BOOT_OFFS	0x200000
+
+
+
+#define CONFIG_CMD_MTDPARTS
+
+#define CONFIG_CMD_ASKENV /* monitor functions : ask for env variable */
+#define CONFIG_VERSION_VARIABLE /* monitor functions :  u-boot version */
+#define CONFIG_CMD_DIAG /* monitor functions : Diagnostics */
 
 #define MTDIDS_DEFAULT			"nand0=omap2-nand.0"
-#define MTDPARTS_DEFAULT		"mtdparts=omap2-nand.0:128k(SPL)," \
-					"128k(SPL.backup1)," \
-					"128k(SPL.backup2)," \
-					"128k(SPL.backup3),1792k(u-boot)," \
-					"128k(u-boot-spl-os)," \
-					"128k(u-boot-env),5m(kernel),-(rootfs)"
+/* Size must be a multiple of Nand erase size (524288 b) */
+#define MTDPARTS_DEFAULT		"mtdparts=omap2-nand.0:512k(SPL)," \
+					"512k(SPL.backup1)," \
+					"512k(SPL.backup2)," \
+					"512k(SPL.backup3),1536k(u-boot)," \
+					"512k(u-boot-spl-os)," \
+					"512k(u-boot-env),5m(kernel),-(rootfs)"
 #define CONFIG_ENV_IS_IN_NAND
 #define CONFIG_ENV_OFFSET		0x260000 /* environment starts here */
 #define CONFIG_SYS_ENV_SECT_SIZE	(128 << 10)	/* 128 KiB */
@@ -198,11 +221,15 @@
 #undef CONFIG_SPL_ETH_SUPPORT
 #endif
 
+/* CPSW ethernet */
+#define CONFIG_NET_MULTI
+
 /* Network */
 #define CONFIG_CMD_MII
 #define CONFIG_PHYLIB
 #define CONFIG_PHY_RESET	1
 #define CONFIG_PHY_NATSEMI
+#define CONFIG_PHY_REALTEK
 
 /* CPSW support */
 #define CONFIG_SPL_ETH_SUPPORT
diff --git a/include/configs/qemu-x86.h b/include/configs/qemu-x86.h
index 1b544c1..ecb385c 100644
--- a/include/configs/qemu-x86.h
+++ b/include/configs/qemu-x86.h
@@ -15,18 +15,7 @@
 
 #define CONFIG_SYS_MONITOR_LEN		(1 << 20)
 #define CONFIG_ARCH_MISC_INIT
-
-#define CONFIG_PCI_MEM_BUS		0xc0000000
-#define CONFIG_PCI_MEM_PHYS		CONFIG_PCI_MEM_BUS
-#define CONFIG_PCI_MEM_SIZE		0x10000000
-
-#define CONFIG_PCI_PREF_BUS		0xd0000000
-#define CONFIG_PCI_PREF_PHYS		CONFIG_PCI_PREF_BUS
-#define CONFIG_PCI_PREF_SIZE		0x10000000
-
-#define CONFIG_PCI_IO_BUS		0x2000
-#define CONFIG_PCI_IO_PHYS		CONFIG_PCI_IO_BUS
-#define CONFIG_PCI_IO_SIZE		0xe000
+#define CONFIG_ARCH_EARLY_INIT_R
 
 #define CONFIG_PCI_PNP
 
diff --git a/include/configs/som-6896.h b/include/configs/som-6896.h
index 300e9df..43a9623 100644
--- a/include/configs/som-6896.h
+++ b/include/configs/som-6896.h
@@ -20,7 +20,6 @@
 #define CONFIG_SCSI_DEV_LIST	\
 	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_AHCI}
 
-#define CONFIG_SYS_EARLY_PCI_INIT
 #define CONFIG_PCI_PNP
 
 #define VIDEO_IO_OFFSET			0
diff --git a/include/configs/strider.h b/include/configs/strider.h
new file mode 100644
index 0000000..fb7b7f9
--- /dev/null
+++ b/include/configs/strider.h
@@ -0,0 +1,651 @@
+/*
+ * (C) Copyright 2014
+ * Dirk Eibach,  Guntermann & Drunck GmbH, eibach@gdsys.de
+ *
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ */
+#define CONFIG_E300		1 /* E300 family */
+#define CONFIG_MPC83xx		1 /* MPC83xx family */
+#define CONFIG_MPC830x		1 /* MPC830x family */
+#define CONFIG_MPC8308		1 /* MPC8308 CPU specific */
+#define CONFIG_STRIDER		1 /* STRIDER board specific */
+
+#define	CONFIG_SYS_TEXT_BASE	0xFE000000
+
+#ifdef CONFIG_STRIDER_CPU
+#define CONFIG_IDENT_STRING	" strider cpu 0.01"
+#else
+#define CONFIG_IDENT_STRING	" strider con 0.01"
+#endif
+
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_BOARD_EARLY_INIT_R
+#define CONFIG_LAST_STAGE_INIT
+
+/* new uImage format support */
+#define CONFIG_FIT			1
+#define CONFIG_FIT_VERBOSE		1
+
+#define CONFIG_MMC
+#define CONFIG_FSL_ESDHC
+#define CONFIG_SYS_FSL_ESDHC_ADDR	CONFIG_SYS_MPC83xx_ESDHC_ADDR
+#define CONFIG_SYS_FSL_ERRATUM_ESDHC111
+
+#define CONFIG_CMD_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_DOS_PARTITION
+#define CONFIG_CMD_EXT2
+
+#define CONFIG_CMD_MEMTEST
+#define CONFIG_SYS_ALT_MEMTEST
+
+#define CONFIG_CMD_FPGAD
+#define CONFIG_CMD_IOLOOP
+
+/*
+ * System Clock Setup
+ */
+#define CONFIG_83XX_CLKIN	33333333 /* in Hz */
+#define CONFIG_SYS_CLK_FREQ	CONFIG_83XX_CLKIN
+
+/*
+ * Hardware Reset Configuration Word
+ * if CLKIN is 66.66MHz, then
+ * CSB = 133MHz, DDRC = 266MHz, LBC = 133MHz
+ * We choose the A type silicon as default, so the core is 400Mhz.
+ */
+#define CONFIG_SYS_HRCW_LOW (\
+	HRCWL_LCL_BUS_TO_SCB_CLK_1X1 |\
+	HRCWL_DDR_TO_SCB_CLK_2X1 |\
+	HRCWL_SVCOD_DIV_2 |\
+	HRCWL_CSB_TO_CLKIN_4X1 |\
+	HRCWL_CORE_TO_CSB_3X1)
+/*
+ * There are neither HRCWH_PCI_HOST nor HRCWH_PCI1_ARBITER_ENABLE bits
+ * in 8308's HRCWH according to the manual, but original Freescale's
+ * code has them and I've expirienced some problems using the board
+ * with BDI3000 attached when I've tried to set these bits to zero
+ * (UART doesn't work after the 'reset run' command).
+ */
+#define CONFIG_SYS_HRCW_HIGH (\
+	HRCWH_PCI_HOST |\
+	HRCWH_PCI1_ARBITER_ENABLE |\
+	HRCWH_CORE_ENABLE |\
+	HRCWH_FROM_0XFFF00100 |\
+	HRCWH_BOOTSEQ_DISABLE |\
+	HRCWH_SW_WATCHDOG_DISABLE |\
+	HRCWH_ROM_LOC_LOCAL_16BIT |\
+	HRCWH_RL_EXT_LEGACY |\
+	HRCWH_TSEC1M_IN_MII |\
+	HRCWH_TSEC2M_IN_RGMII |\
+	HRCWH_BIG_ENDIAN)
+
+/*
+ * System IO Config
+ */
+#define CONFIG_SYS_SICRH (\
+	SICRH_ESDHC_A_SD |\
+	SICRH_ESDHC_B_SD |\
+	SICRH_ESDHC_C_SD |\
+	SICRH_GPIO_A_GPIO |\
+	SICRH_GPIO_B_GPIO |\
+	SICRH_IEEE1588_A_GPIO |\
+	SICRH_USB |\
+	SICRH_GTM_GPIO |\
+	SICRH_IEEE1588_B_GPIO |\
+	SICRH_ETSEC2_GPIO |\
+	SICRH_GPIOSEL_1 |\
+	SICRH_TMROBI_V3P3 |\
+	SICRH_TSOBI1_V2P5 |\
+	SICRH_TSOBI2_V2P5)	/* 0x0037f103 */
+#define CONFIG_SYS_SICRL (\
+	SICRL_SPI_PF0 |\
+	SICRL_UART_PF0 |\
+	SICRL_IRQ_PF0 |\
+	SICRL_I2C2_PF0 |\
+	SICRL_ETSEC1_TX_CLK)	/* 0x00000000 */
+
+/*
+ * IMMR new address
+ */
+#define CONFIG_SYS_IMMR		0xE0000000
+
+/*
+ * SERDES
+ */
+#define CONFIG_FSL_SERDES
+#define CONFIG_FSL_SERDES1	0xe3000
+
+/*
+ * Arbiter Setup
+ */
+#define CONFIG_SYS_ACR_PIPE_DEP	3 /* Arbiter pipeline depth is 4 */
+#define CONFIG_SYS_ACR_RPTCNT	3 /* Arbiter repeat count is 4 */
+#define CONFIG_SYS_SPCR_TSECEP	3 /* eTSEC emergency priority is highest */
+
+/*
+ * DDR Setup
+ */
+#define CONFIG_SYS_DDR_BASE		0x00000000 /* DDR is system memory */
+#define CONFIG_SYS_SDRAM_BASE		CONFIG_SYS_DDR_BASE
+#define CONFIG_SYS_DDR_SDRAM_BASE	CONFIG_SYS_DDR_BASE
+#define CONFIG_SYS_DDR_SDRAM_CLK_CNTL	DDR_SDRAM_CLK_CNTL_CLK_ADJUST_05
+#define CONFIG_SYS_DDRCDR_VALUE	(DDRCDR_EN \
+				| DDRCDR_PZ_LOZ \
+				| DDRCDR_NZ_LOZ \
+				| DDRCDR_ODT \
+				| DDRCDR_Q_DRN)
+				/* 0x7b880001 */
+/*
+ * Manually set up DDR parameters
+ * consist of one chip NT5TU64M16HG from NANYA
+ */
+
+#define CONFIG_SYS_DDR_SIZE		128 /* MB */
+
+#define CONFIG_SYS_DDR_CS0_BNDS	0x00000007
+#define CONFIG_SYS_DDR_CS0_CONFIG	(CSCONFIG_EN \
+				| CSCONFIG_ODT_RD_NEVER \
+				| CSCONFIG_ODT_WR_ONLY_CURRENT \
+				| CSCONFIG_BANK_BIT_3 \
+				| CSCONFIG_ROW_BIT_13 | CSCONFIG_COL_BIT_10)
+				/* 0x80010102 */
+#define CONFIG_SYS_DDR_TIMING_3	0
+#define CONFIG_SYS_DDR_TIMING_0	((0 << TIMING_CFG0_RWT_SHIFT) \
+				| (0 << TIMING_CFG0_WRT_SHIFT) \
+				| (0 << TIMING_CFG0_RRT_SHIFT) \
+				| (0 << TIMING_CFG0_WWT_SHIFT) \
+				| (2 << TIMING_CFG0_ACT_PD_EXIT_SHIFT) \
+				| (6 << TIMING_CFG0_PRE_PD_EXIT_SHIFT) \
+				| (8 << TIMING_CFG0_ODT_PD_EXIT_SHIFT) \
+				| (2 << TIMING_CFG0_MRS_CYC_SHIFT))
+				/* 0x00260802 */
+#define CONFIG_SYS_DDR_TIMING_1	((2 << TIMING_CFG1_PRETOACT_SHIFT) \
+				| (6 << TIMING_CFG1_ACTTOPRE_SHIFT) \
+				| (2 << TIMING_CFG1_ACTTORW_SHIFT) \
+				| (7 << TIMING_CFG1_CASLAT_SHIFT) \
+				| (9 << TIMING_CFG1_REFREC_SHIFT) \
+				| (2 << TIMING_CFG1_WRREC_SHIFT) \
+				| (2 << TIMING_CFG1_ACTTOACT_SHIFT) \
+				| (2 << TIMING_CFG1_WRTORD_SHIFT))
+				/* 0x26279222 */
+#define CONFIG_SYS_DDR_TIMING_2	((0 << TIMING_CFG2_ADD_LAT_SHIFT) \
+				| (4 << TIMING_CFG2_CPO_SHIFT) \
+				| (3 << TIMING_CFG2_WR_LAT_DELAY_SHIFT) \
+				| (2 << TIMING_CFG2_RD_TO_PRE_SHIFT) \
+				| (2 << TIMING_CFG2_WR_DATA_DELAY_SHIFT) \
+				| (3 << TIMING_CFG2_CKE_PLS_SHIFT) \
+				| (5 << TIMING_CFG2_FOUR_ACT_SHIFT))
+				/* 0x021848c5 */
+#define CONFIG_SYS_DDR_INTERVAL	((0x0824 << SDRAM_INTERVAL_REFINT_SHIFT) \
+				| (0x0100 << SDRAM_INTERVAL_BSTOPRE_SHIFT))
+				/* 0x08240100 */
+#define CONFIG_SYS_DDR_SDRAM_CFG	(SDRAM_CFG_SREN \
+				| SDRAM_CFG_SDRAM_TYPE_DDR2 \
+				| SDRAM_CFG_DBW_16)
+				/* 0x43100000 */
+
+#define CONFIG_SYS_DDR_SDRAM_CFG2	0x00401000 /* 1 posted refresh */
+#define CONFIG_SYS_DDR_MODE		((0x0440 << SDRAM_MODE_ESD_SHIFT) \
+				| (0x0242 << SDRAM_MODE_SD_SHIFT))
+				/* ODT 150ohm CL=4, AL=0 on SDRAM */
+#define CONFIG_SYS_DDR_MODE2		0x00000000
+
+/*
+ * Memory test
+ */
+#define CONFIG_SYS_MEMTEST_START	0x00001000 /* memtest region */
+#define CONFIG_SYS_MEMTEST_END		0x07f00000
+
+/*
+ * The reserved memory
+ */
+#define CONFIG_SYS_MONITOR_BASE	CONFIG_SYS_TEXT_BASE /* start of monitor */
+
+#define CONFIG_SYS_MONITOR_LEN	(384 * 1024) /* Reserve 384 kB for Mon */
+#define CONFIG_SYS_MALLOC_LEN	(512 * 1024) /* Reserved for malloc */
+
+/*
+ * Initial RAM Base Address Setup
+ */
+#define CONFIG_SYS_INIT_RAM_LOCK	1
+#define CONFIG_SYS_INIT_RAM_ADDR	0xE6000000 /* Initial RAM address */
+#define CONFIG_SYS_INIT_RAM_SIZE	0x1000 /* Size of used area in RAM */
+#define CONFIG_SYS_GBL_DATA_OFFSET	\
+	(CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
+
+/*
+ * Local Bus Configuration & Clock Setup
+ */
+#define CONFIG_SYS_LCRR_DBYP		LCRR_DBYP
+#define CONFIG_SYS_LCRR_CLKDIV		LCRR_CLKDIV_2
+#define CONFIG_SYS_LBC_LBCR		0x00040000
+
+/*
+ * FLASH on the Local Bus
+ */
+#if 1
+#define CONFIG_SYS_FLASH_CFI		/* use the Common Flash Interface */
+#define CONFIG_FLASH_CFI_DRIVER		/* use the CFI driver */
+#define CONFIG_SYS_FLASH_CFI_WIDTH	FLASH_CFI_16BIT
+#define CONFIG_FLASH_CFI_LEGACY
+#define CONFIG_SYS_FLASH_LEGACY_512Kx16
+#else
+#define CONFIG_SYS_NO_FLASH
+#endif
+
+#define CONFIG_SYS_FLASH_BASE		0xFE000000 /* FLASH base address */
+#define CONFIG_SYS_FLASH_SIZE		8 /* FLASH size is up to 8M */
+#define CONFIG_SYS_FLASH_PROTECTION	1 /* Use h/w Flash protection. */
+
+/* Window base at flash base */
+#define CONFIG_SYS_LBLAWBAR0_PRELIM	CONFIG_SYS_FLASH_BASE
+#define CONFIG_SYS_LBLAWAR0_PRELIM	(LBLAWAR_EN | LBLAWAR_8MB)
+
+#define CONFIG_SYS_BR0_PRELIM	(CONFIG_SYS_FLASH_BASE \
+				| BR_PS_16	/* 16 bit port */ \
+				| BR_MS_GPCM	/* MSEL = GPCM */ \
+				| BR_V)		/* valid */
+#define CONFIG_SYS_OR0_PRELIM	(MEG_TO_AM(CONFIG_SYS_FLASH_SIZE) \
+				| OR_UPM_XAM \
+				| OR_GPCM_CSNT \
+				| OR_GPCM_ACS_DIV2 \
+				| OR_GPCM_XACS \
+				| OR_GPCM_SCY_15 \
+				| OR_GPCM_TRLX_SET \
+				| OR_GPCM_EHTR_SET)
+
+#define CONFIG_SYS_MAX_FLASH_BANKS	1 /* number of banks */
+#define CONFIG_SYS_MAX_FLASH_SECT	135
+
+#define CONFIG_SYS_FLASH_ERASE_TOUT	60000 /* Flash Erase Timeout (ms) */
+#define CONFIG_SYS_FLASH_WRITE_TOUT	500 /* Flash Write Timeout (ms) */
+
+/*
+ * FPGA
+ */
+#define CONFIG_SYS_FPGA0_BASE		0xE0600000
+#define CONFIG_SYS_FPGA0_SIZE		1 /* FPGA size is 1M */
+
+/* Window base at FPGA base */
+#define CONFIG_SYS_LBLAWBAR1_PRELIM	CONFIG_SYS_FPGA0_BASE
+#define CONFIG_SYS_LBLAWAR1_PRELIM	(LBLAWAR_EN | LBLAWAR_1MB)
+
+#define CONFIG_SYS_BR1_PRELIM	(CONFIG_SYS_FPGA0_BASE \
+				| BR_PS_16	/* 16 bit port */ \
+				| BR_MS_GPCM	/* MSEL = GPCM */ \
+				| BR_V)		/* valid */
+#define CONFIG_SYS_OR1_PRELIM	(MEG_TO_AM(CONFIG_SYS_FPGA0_SIZE) \
+				| OR_UPM_XAM \
+				| OR_GPCM_CSNT \
+				| OR_GPCM_ACS_DIV2 \
+				| OR_GPCM_XACS \
+				| OR_GPCM_SCY_15 \
+				| OR_GPCM_TRLX_SET \
+				| OR_GPCM_EHTR_SET)
+
+#define CONFIG_SYS_FPGA_BASE(k)		CONFIG_SYS_FPGA0_BASE
+#define CONFIG_SYS_FPGA_DONE(k)		0x0010
+
+#define CONFIG_SYS_FPGA_COUNT		1
+
+#define CONFIG_SYS_MCLINK_MAX		3
+
+#define CONFIG_SYS_FPGA_PTR \
+	{ (struct ihs_fpga *)CONFIG_SYS_FPGA0_BASE, NULL, NULL, NULL }
+
+#define CONFIG_SYS_FPGA_NO_RFL_HI
+
+/*
+ * Serial Port
+ */
+#define CONFIG_CONS_INDEX	2
+#define CONFIG_SYS_NS16550
+#define CONFIG_SYS_NS16550_SERIAL
+#define CONFIG_SYS_NS16550_REG_SIZE	1
+#define CONFIG_SYS_NS16550_CLK		get_bus_freq(0)
+
+#define CONFIG_SYS_BAUDRATE_TABLE  \
+	{300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200}
+
+#define CONFIG_SYS_NS16550_COM1	(CONFIG_SYS_IMMR + 0x4500)
+#define CONFIG_SYS_NS16550_COM2	(CONFIG_SYS_IMMR + 0x4600)
+
+/* Use the HUSH parser */
+#define CONFIG_SYS_HUSH_PARSER
+
+/* Pass open firmware flat tree */
+#define CONFIG_OF_LIBFDT		1
+#define CONFIG_OF_BOARD_SETUP		1
+#define CONFIG_OF_STDOUT_VIA_ALIAS	1
+
+/* I2C */
+#define CONFIG_SYS_I2C
+#define CONFIG_SYS_I2C_FSL
+#define CONFIG_SYS_FSL_I2C_SPEED	400000
+#define CONFIG_SYS_FSL_I2C_SLAVE	0x7F
+#define CONFIG_SYS_FSL_I2C_OFFSET	0x3000
+
+#define CONFIG_PCA953X			/* NXP PCA9554 */
+#define CONFIG_PCA9698			/* NXP PCA9698 */
+
+#define CONFIG_SYS_I2C_IHS
+#define CONFIG_SYS_I2C_IHS_CH0
+#define CONFIG_SYS_I2C_IHS_SPEED_0		50000
+#define CONFIG_SYS_I2C_IHS_SLAVE_0		0x7F
+#define CONFIG_SYS_I2C_IHS_CH1
+#define CONFIG_SYS_I2C_IHS_SPEED_1		50000
+#define CONFIG_SYS_I2C_IHS_SLAVE_1		0x7F
+#define CONFIG_SYS_I2C_IHS_CH2
+#define CONFIG_SYS_I2C_IHS_SPEED_2		50000
+#define CONFIG_SYS_I2C_IHS_SLAVE_2		0x7F
+#define CONFIG_SYS_I2C_IHS_CH3
+#define CONFIG_SYS_I2C_IHS_SPEED_3		50000
+#define CONFIG_SYS_I2C_IHS_SLAVE_3		0x7F
+
+/*
+ * Software (bit-bang) I2C driver configuration
+ */
+#define CONFIG_SYS_I2C_SOFT
+#define CONFIG_SOFT_I2C_READ_REPEATED_START
+#define CONFIG_SYS_I2C_SOFT_SPEED		50000
+#define CONFIG_SYS_I2C_SOFT_SLAVE		0x7F
+#define I2C_SOFT_DECLARATIONS2
+#define CONFIG_SYS_I2C_SOFT_SPEED_2		50000
+#define CONFIG_SYS_I2C_SOFT_SLAVE_2		0x7F
+#define I2C_SOFT_DECLARATIONS3
+#define CONFIG_SYS_I2C_SOFT_SPEED_3		50000
+#define CONFIG_SYS_I2C_SOFT_SLAVE_3		0x7F
+#define I2C_SOFT_DECLARATIONS4
+#define CONFIG_SYS_I2C_SOFT_SPEED_4		50000
+#define CONFIG_SYS_I2C_SOFT_SLAVE_4		0x7F
+#ifdef CONFIG_STRIDER_CON
+#define I2C_SOFT_DECLARATIONS5
+#define CONFIG_SYS_I2C_SOFT_SPEED_5		50000
+#define CONFIG_SYS_I2C_SOFT_SLAVE_5		0x7F
+#define I2C_SOFT_DECLARATIONS6
+#define CONFIG_SYS_I2C_SOFT_SPEED_6		50000
+#define CONFIG_SYS_I2C_SOFT_SLAVE_6		0x7F
+#define I2C_SOFT_DECLARATIONS7
+#define CONFIG_SYS_I2C_SOFT_SPEED_7		50000
+#define CONFIG_SYS_I2C_SOFT_SLAVE_7		0x7F
+#define I2C_SOFT_DECLARATIONS8
+#define CONFIG_SYS_I2C_SOFT_SPEED_8		50000
+#define CONFIG_SYS_I2C_SOFT_SLAVE_8		0x7F
+#endif
+
+#ifdef CONFIG_STRIDER_CON
+#define CONFIG_SYS_ICS8N3QV01_I2C		{5, 6, 7, 8}
+#define CONFIG_SYS_CH7301_I2C			{5, 6, 7, 8}
+#define CONFIG_SYS_ADV7611_I2C			{5, 6, 7, 8}
+#define CONFIG_SYS_DP501_I2C			{1, 2, 3, 4}
+#define CONFIG_STRIDER_FANS			{ {10, 0x4c}, {11, 0x4c}, \
+						  {12, 0x4c} }
+#else
+#define CONFIG_SYS_CH7301_I2C			{1, 2, 3, 4}
+#define CONFIG_SYS_ADV7611_I2C			{1, 2, 3, 4}
+#define CONFIG_SYS_DP501_I2C			{1, 2, 3, 4}
+#define CONFIG_STRIDER_FANS			{ {2, 0x18}, {3, 0x18}, \
+						  {4, 0x18} }
+#endif
+
+#ifndef __ASSEMBLY__
+void fpga_gpio_set(unsigned int bus, int pin);
+void fpga_gpio_clear(unsigned int bus, int pin);
+int fpga_gpio_get(unsigned int bus, int pin);
+#endif
+
+#ifdef CONFIG_STRIDER_CON
+#define I2C_SDA_GPIO	((I2C_ADAP_HWNR > 3) ? 0x0200 : 0x0040)
+#define I2C_SCL_GPIO	((I2C_ADAP_HWNR > 3) ? 0x0100 : 0x0020)
+#define I2C_FPGA_IDX	((I2C_ADAP_HWNR > 3) ? \
+			 (I2C_ADAP_HWNR - 4) : I2C_ADAP_HWNR)
+#else
+#define I2C_SDA_GPIO	0x0040
+#define I2C_SCL_GPIO	0x0020
+#define I2C_FPGA_IDX	I2C_ADAP_HWNR
+#endif
+#define I2C_ACTIVE	{ }
+#define I2C_TRISTATE	{ }
+#define I2C_READ \
+	(fpga_gpio_get(I2C_FPGA_IDX, I2C_SDA_GPIO) ? 1 : 0)
+#define I2C_SDA(bit) \
+	do { \
+		if (bit) \
+			fpga_gpio_set(I2C_FPGA_IDX, I2C_SDA_GPIO); \
+		else \
+			fpga_gpio_clear(I2C_FPGA_IDX, I2C_SDA_GPIO); \
+	} while (0)
+#define I2C_SCL(bit) \
+	do { \
+		if (bit) \
+			fpga_gpio_set(I2C_FPGA_IDX, I2C_SCL_GPIO); \
+		else \
+			fpga_gpio_clear(I2C_FPGA_IDX, I2C_SCL_GPIO); \
+	} while (0)
+#define I2C_DELAY	udelay(25)	/* 1/4 I2C clock duration */
+
+/*
+ * Software (bit-bang) MII driver configuration
+ */
+#define CONFIG_BITBANGMII		/* bit-bang MII PHY management */
+#define CONFIG_BITBANGMII_MULTI
+
+/*
+ * OSD Setup
+ */
+#define CONFIG_SYS_OSD_SCREENS		1
+#define CONFIG_SYS_DP501_DIFFERENTIAL
+#define CONFIG_SYS_DP501_VCAPCTRL0	0x01 /* DDR mode 0, DE for H/VSYNC */
+
+/*
+ * General PCI
+ * Addresses are mapped 1-1.
+ */
+#define CONFIG_SYS_PCIE1_BASE		0xA0000000
+#define CONFIG_SYS_PCIE1_MEM_BASE	0xA0000000
+#define CONFIG_SYS_PCIE1_MEM_PHYS	0xA0000000
+#define CONFIG_SYS_PCIE1_MEM_SIZE	0x10000000
+#define CONFIG_SYS_PCIE1_CFG_BASE	0xB0000000
+#define CONFIG_SYS_PCIE1_CFG_SIZE	0x01000000
+#define CONFIG_SYS_PCIE1_IO_BASE	0x00000000
+#define CONFIG_SYS_PCIE1_IO_PHYS	0xB1000000
+#define CONFIG_SYS_PCIE1_IO_SIZE	0x00800000
+
+/* enable PCIE clock */
+#define CONFIG_SYS_SCCR_PCIEXP1CM	1
+
+#define CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
+#define CONFIG_PCIE
+
+#define CONFIG_PCI_PNP		/* do pci plug-and-play */
+
+#define CONFIG_SYS_PCI_SUBSYS_VENDORID 0x1957	/* Freescale */
+#define CONFIG_83XX_GENERIC_PCIE_REGISTER_HOSES 1
+
+/*
+ * TSEC
+ */
+#define CONFIG_TSEC_ENET	/* TSEC ethernet support */
+#define CONFIG_SYS_TSEC1_OFFSET	0x24000
+#define CONFIG_SYS_TSEC1	(CONFIG_SYS_IMMR+CONFIG_SYS_TSEC1_OFFSET)
+
+/*
+ * TSEC ethernet configuration
+ */
+#define CONFIG_MII		1 /* MII PHY management */
+#define CONFIG_TSEC1
+#define CONFIG_TSEC1_NAME	"eTSEC0"
+#define TSEC1_PHY_ADDR		1
+#define TSEC1_PHYIDX		0
+#define TSEC1_FLAGS		0
+
+/* Options are: eTSEC[0-1] */
+#define CONFIG_ETHPRIME		"eTSEC0"
+
+/*
+ * Environment
+ */
+#if 1
+#define CONFIG_ENV_IS_IN_FLASH	1
+#define CONFIG_ENV_ADDR		(CONFIG_SYS_MONITOR_BASE + \
+				 CONFIG_SYS_MONITOR_LEN)
+#define CONFIG_ENV_SECT_SIZE	0x10000 /* 64K(one sector) for env */
+#define CONFIG_ENV_SIZE		0x2000
+#define CONFIG_ENV_ADDR_REDUND	(CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE)
+#define CONFIG_ENV_SIZE_REDUND	CONFIG_ENV_SIZE
+#else
+#define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_SIZE		0x2000		/* 8KB */
+#endif
+
+#define CONFIG_LOADS_ECHO	1	/* echo on for serial download */
+#define CONFIG_SYS_LOADS_BAUD_CHANGE	1	/* allow baudrate change */
+
+/*
+ * Command line configuration.
+ */
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_PCI
+#define CONFIG_CMD_PING
+
+#define CONFIG_CMDLINE_EDITING	1	/* add command line history */
+#define CONFIG_AUTO_COMPLETE		/* add autocompletion support */
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_SYS_LONGHELP		/* undef to save memory */
+#define CONFIG_SYS_LOAD_ADDR		0x2000000 /* default load address */
+#define CONFIG_SYS_HZ		1000	/* decrementer freq: 1ms ticks */
+
+#undef CONFIG_ZERO_BOOTDELAY_CHECK	/* ignore keypress on bootdelay==0 */
+
+#define CONFIG_SYS_CBSIZE	1024 /* Console I/O Buffer Size */
+
+#define CONFIG_SYS_CONSOLE_INFO_QUIET
+
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_MAXARGS	16	/* max number of command args */
+#define CONFIG_SYS_BARGSIZE	CONFIG_SYS_CBSIZE
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 256 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CONFIG_SYS_BOOTMAPSZ	(256 << 20) /* Initial Memory map for Linux */
+
+/*
+ * Core HID Setup
+ */
+#define CONFIG_SYS_HID0_INIT	0x000000000
+#define CONFIG_SYS_HID0_FINAL	(HID0_ENABLE_MACHINE_CHECK | \
+				 HID0_ENABLE_INSTRUCTION_CACHE | \
+				 HID0_ENABLE_DYNAMIC_POWER_MANAGMENT)
+#define CONFIG_SYS_HID2		HID2_HBE
+
+/*
+ * MMU Setup
+ */
+
+/* DDR: cache cacheable */
+#define CONFIG_SYS_IBAT0L	(CONFIG_SYS_SDRAM_BASE | BATL_PP_RW | \
+					BATL_MEMCOHERENCE)
+#define CONFIG_SYS_IBAT0U	(CONFIG_SYS_SDRAM_BASE | BATU_BL_128M | \
+					BATU_VS | BATU_VP)
+#define CONFIG_SYS_DBAT0L	CONFIG_SYS_IBAT0L
+#define CONFIG_SYS_DBAT0U	CONFIG_SYS_IBAT0U
+
+/* IMMRBAR, PCI IO and FPGA: cache-inhibit and guarded */
+#define CONFIG_SYS_IBAT1L	(CONFIG_SYS_IMMR | BATL_PP_RW | \
+			BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
+#define CONFIG_SYS_IBAT1U	(CONFIG_SYS_IMMR | BATU_BL_8M | BATU_VS | \
+					BATU_VP)
+#define CONFIG_SYS_DBAT1L	CONFIG_SYS_IBAT1L
+#define CONFIG_SYS_DBAT1U	CONFIG_SYS_IBAT1U
+
+/* FLASH: icache cacheable, but dcache-inhibit and guarded */
+#define CONFIG_SYS_IBAT2L	(CONFIG_SYS_FLASH_BASE | BATL_PP_RW | \
+					BATL_MEMCOHERENCE)
+#define CONFIG_SYS_IBAT2U	(CONFIG_SYS_FLASH_BASE | BATU_BL_8M | \
+					BATU_VS | BATU_VP)
+#define CONFIG_SYS_DBAT2L	(CONFIG_SYS_FLASH_BASE | BATL_PP_RW | \
+					BATL_CACHEINHIBIT | \
+					BATL_GUARDEDSTORAGE)
+#define CONFIG_SYS_DBAT2U	CONFIG_SYS_IBAT2U
+
+/* Stack in dcache: cacheable, no memory coherence */
+#define CONFIG_SYS_IBAT3L	(CONFIG_SYS_INIT_RAM_ADDR | BATL_PP_RW)
+#define CONFIG_SYS_IBAT3U	(CONFIG_SYS_INIT_RAM_ADDR | BATU_BL_128K | \
+					BATU_VS | BATU_VP)
+#define CONFIG_SYS_DBAT3L	CONFIG_SYS_IBAT3L
+#define CONFIG_SYS_DBAT3U	CONFIG_SYS_IBAT3U
+
+/*
+ * Environment Configuration
+ */
+
+#define CONFIG_ENV_OVERWRITE
+
+#if defined(CONFIG_TSEC_ENET)
+#define CONFIG_HAS_ETH0
+#endif
+
+#define CONFIG_BAUDRATE 115200
+
+#define CONFIG_LOADADDR	800000	/* default location for tftp and bootm */
+
+#define CONFIG_BOOTDELAY	5	/* -1 disables auto-boot */
+
+#define CONFIG_HOSTNAME		hrcon
+#define CONFIG_ROOTPATH		"/opt/nfsroot"
+#define CONFIG_BOOTFILE		"uImage"
+
+#define CONFIG_PREBOOT		/* enable preboot variable */
+
+#define	CONFIG_EXTRA_ENV_SETTINGS					\
+	"netdev=eth0\0"							\
+	"consoledev=ttyS1\0"						\
+	"u-boot=u-boot.bin\0"						\
+	"kernel_addr=1000000\0"					\
+	"fdt_addr=C00000\0"						\
+	"fdtfile=hrcon.dtb\0"				\
+	"load=tftp ${loadaddr} ${u-boot}\0"				\
+	"update=protect off " __stringify(CONFIG_SYS_MONITOR_BASE)	\
+		" +${filesize};era " __stringify(CONFIG_SYS_MONITOR_BASE)\
+		" +${filesize};cp.b ${fileaddr} "			\
+		__stringify(CONFIG_SYS_MONITOR_BASE) " ${filesize}\0"	\
+	"upd=run load update\0"						\
+
+#define CONFIG_NFSBOOTCOMMAND						\
+	"setenv bootargs root=/dev/nfs rw "				\
+	"nfsroot=$serverip:$rootpath "					\
+	"ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off " \
+	"console=$consoledev,$baudrate $othbootargs;"			\
+	"tftp ${kernel_addr} $bootfile;"				\
+	"tftp ${fdt_addr} $fdtfile;"					\
+	"bootm ${kernel_addr} - ${fdt_addr}"
+
+#define CONFIG_MMCBOOTCOMMAND						\
+	"setenv bootargs root=/dev/mmcblk0p3 rw rootwait "		\
+	"console=$consoledev,$baudrate $othbootargs;"			\
+	"ext2load mmc 0:2 ${kernel_addr} $bootfile;"			\
+	"ext2load mmc 0:2 ${fdt_addr} $fdtfile;"			\
+	"bootm ${kernel_addr} - ${fdt_addr}"
+
+#define CONFIG_BOOTCOMMAND		CONFIG_MMCBOOTCOMMAND
+
+
+#endif	/* __CONFIG_H */
diff --git a/include/configs/tegra-common.h b/include/configs/tegra-common.h
index a005e6a..32cc39b 100644
--- a/include/configs/tegra-common.h
+++ b/include/configs/tegra-common.h
@@ -143,4 +143,6 @@
 #define CONFIG_FAT_WRITE
 #endif
 
+#define CONFIG_OF_SYSTEM_SETUP
+
 #endif /* _TEGRA_COMMON_H_ */
diff --git a/include/configs/ti_armv7_common.h b/include/configs/ti_armv7_common.h
index 32bb805..7810dd6 100644
--- a/include/configs/ti_armv7_common.h
+++ b/include/configs/ti_armv7_common.h
@@ -67,11 +67,6 @@
 		"rootfstype=${mmcrootfstype}\0"
 
 /*
- * Default to a quick boot delay.
- */
-#define CONFIG_BOOTDELAY		1
-
-/*
  * DDR information.  If the CONFIG_NR_DRAM_BANKS is not defined,
  * we say (for simplicity) that we have 1 bank, always, even when
  * we have more.  We always start at 0x80000000, and we place the
@@ -288,4 +283,6 @@
 #define NETARGS ""
 #endif
 
+#include <config_distro_defaults.h>
+
 #endif	/* __CONFIG_TI_ARMV7_COMMON_H__ */
diff --git a/include/configs/venice2.h b/include/configs/venice2.h
index 0fc8cf7..a374cd9 100644
--- a/include/configs/venice2.h
+++ b/include/configs/venice2.h
@@ -60,6 +60,4 @@
 #include "tegra-common-usb-gadget.h"
 #include "tegra-common-post.h"
 
-#define CONFIG_OF_BOARD_SETUP
-
 #endif /* __CONFIG_H */
diff --git a/include/configs/x86-chromebook.h b/include/configs/x86-chromebook.h
index 2be8850..b0aa875 100644
--- a/include/configs/x86-chromebook.h
+++ b/include/configs/x86-chromebook.h
@@ -35,7 +35,6 @@
 #define CONFIG_PCI_IO_PHYS	CONFIG_PCI_IO_BUS
 #define CONFIG_PCI_IO_SIZE	0xefff
 
-#define CONFIG_SYS_EARLY_PCI_INIT
 #define CONFIG_PCI_PNP
 
 #define CONFIG_BIOSEMU
diff --git a/include/configs/x86-common.h b/include/configs/x86-common.h
index faadab8..ab9fa0b 100644
--- a/include/configs/x86-common.h
+++ b/include/configs/x86-common.h
@@ -155,9 +155,6 @@
  */
 
 #define CONFIG_SYS_X86_TSC_TIMER
-#define CONFIG_SYS_PCAT_INTERRUPTS
-#define CONFIG_SYS_PCAT_TIMER
-#define CONFIG_SYS_NUM_IRQS			16
 
 #define CONFIG_SYS_STACK_SIZE			(32 * 1024)
 #define CONFIG_SYS_MONITOR_BASE		CONFIG_SYS_TEXT_BASE
diff --git a/include/fastboot.h b/include/fastboot.h
new file mode 100644
index 0000000..db826d2
--- /dev/null
+++ b/include/fastboot.h
@@ -0,0 +1,22 @@
+/*
+ * (C) Copyright 2008 - 2009
+ * Windriver, <www.windriver.com>
+ * Tom Rix <Tom.Rix@windriver.com>
+ *
+ * Copyright 2011 Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ *
+ * Copyright 2014 Linaro, Ltd.
+ * Rob Herring <robh@kernel.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef _FASTBOOT_H_
+#define _FASTBOOT_H_
+
+/* The 64 defined bytes plus \0 */
+#define FASTBOOT_RESPONSE_LEN	(64 + 1)
+
+void fastboot_fail(char *response, const char *reason);
+void fastboot_okay(char *response, const char *reason);
+
+#endif /* _FASTBOOT_H_ */
diff --git a/include/fb_mmc.h b/include/fb_mmc.h
index 402ba9b..978a139 100644
--- a/include/fb_mmc.h
+++ b/include/fb_mmc.h
@@ -4,6 +4,7 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
-void fb_mmc_flash_write(const char *cmd, void *download_buffer,
-			unsigned int download_bytes, char *response);
+void fb_mmc_flash_write(const char *cmd, unsigned int session_id,
+			void *download_buffer, unsigned int download_bytes,
+			char *response);
 void fb_mmc_erase(const char *cmd, char *response);
diff --git a/include/fb_nand.h b/include/fb_nand.h
new file mode 100644
index 0000000..80ddef5
--- /dev/null
+++ b/include/fb_nand.h
@@ -0,0 +1,11 @@
+/*
+ * Copyright 2014 Broadcom Corporation.
+ * Copyright 2015 Free Electrons.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+void fb_nand_flash_write(const char *cmd, unsigned int session_id,
+			 void *download_buffer, unsigned int download_bytes,
+			 char *response);
+void fb_nand_erase(const char *cmd, char *response);
diff --git a/include/fdtdec.h b/include/fdtdec.h
index 0e36664..3a6ff1f 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -130,6 +130,7 @@
 	COMPAT_NVIDIA_TEGRA30_SDMMC,	/* Tegra30 SDMMC controller */
 	COMPAT_NVIDIA_TEGRA20_SDMMC,	/* Tegra20 SDMMC controller */
 	COMPAT_NVIDIA_TEGRA124_PCIE,	/* Tegra 124 PCIe controller */
+	COMPAT_NVIDIA_TEGRA210_PCIE,	/* Tegra 210 PCIe controller */
 	COMPAT_NVIDIA_TEGRA30_PCIE,	/* Tegra 30 PCIe controller */
 	COMPAT_NVIDIA_TEGRA20_PCIE,	/* Tegra 20 PCIe controller */
 	COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL,
diff --git a/include/gdsys_fpga.h b/include/gdsys_fpga.h
index 8a5efe7..3b8762d 100644
--- a/include/gdsys_fpga.h
+++ b/include/gdsys_fpga.h
@@ -143,7 +143,7 @@
 	u16 reserved_2[2];	/* 0x001c */
 	struct ihs_io_ep ep;	/* 0x0020 */
 	u16 reserved_3[9];	/* 0x002e */
-	struct ihs_i2c i2c;	/* 0x0040 */
+	struct ihs_i2c i2c0;	/* 0x0040 */
 	u16 reserved_4[10];	/* 0x004c */
 	u16 mc_int;		/* 0x0060 */
 	u16 mc_int_en;		/* 0x0062 */
@@ -157,9 +157,9 @@
 	u16 mc_rx_data;		/* 0x0072 */
 	u16 reserved_5[69];	/* 0x0074 */
 	u16 reflection_high;	/* 0x00fe */
-	struct ihs_osd osd;	/* 0x0100 */
+	struct ihs_osd osd0;	/* 0x0100 */
 	u16 reserved_6[889];	/* 0x010e */
-	u16 videomem[31736];	/* 0x0800 */
+	u16 videomem0[2048];	/* 0x0800 */
 };
 #endif
 
@@ -171,13 +171,89 @@
 	u16 fpga_features;	/* 0x0006 */
 	u16 reserved_0[1];	/* 0x0008 */
 	u16 top_interrupt;	/* 0x000a */
+	u16 reserved_1[2];	/* 0x000c */
+	u16 control;		/* 0x0010 */
+	u16 extended_control;	/* 0x0012 */
+	struct ihs_gpio gpio;	/* 0x0014 */
+	u16 mpc3w_control;	/* 0x001a */
+	u16 reserved_2[2];	/* 0x001c */
+	struct ihs_io_ep ep;	/* 0x0020 */
+	u16 reserved_3[9];	/* 0x002e */
+	struct ihs_i2c i2c0;	/* 0x0040 */
+	u16 reserved_4[10];	/* 0x004c */
+	u16 mc_int;		/* 0x0060 */
+	u16 mc_int_en;		/* 0x0062 */
+	u16 mc_status;		/* 0x0064 */
+	u16 mc_control;		/* 0x0066 */
+	u16 mc_tx_data;		/* 0x0068 */
+	u16 mc_tx_address;	/* 0x006a */
+	u16 mc_tx_cmd;		/* 0x006c */
+	u16 mc_res;		/* 0x006e */
+	u16 mc_rx_cmd_status;	/* 0x0070 */
+	u16 mc_rx_data;		/* 0x0072 */
+	u16 reserved_5[69];	/* 0x0074 */
+	u16 reflection_high;	/* 0x00fe */
+	struct ihs_osd osd0;	/* 0x0100 */
+#ifdef CONFIG_SYS_OSD_DH
+	u16 reserved_6[57];	/* 0x010e */
+	struct ihs_osd osd1;	/* 0x0180 */
+	u16 reserved_7[9];	/* 0x018e */
+	struct ihs_i2c i2c1;	/* 0x01a0 */
+	u16 reserved_8[1834];	/* 0x01ac */
+	u16 videomem0[2048];	/* 0x1000 */
+	u16 videomem1[2048];	/* 0x2000 */
+#else
+	u16 reserved_6[889];	/* 0x010e */
+	u16 videomem0[2048];	/* 0x0800 */
+#endif
+};
+#endif
+
+#ifdef CONFIG_STRIDER_CPU
+struct ihs_fpga {
+	u16 reflection_low;	/* 0x0000 */
+	u16 versions;		/* 0x0002 */
+	u16 fpga_version;	/* 0x0004 */
+	u16 fpga_features;	/* 0x0006 */
+	u16 reserved_0[1];	/* 0x0008 */
+	u16 top_interrupt;	/* 0x000a */
+	u16 reserved_1[3];	/* 0x000c */
+	u16 extended_control;	/* 0x0012 */
+	struct ihs_gpio gpio;	/* 0x0014 */
+	u16 mpc3w_control;	/* 0x001a */
+	u16 reserved_2[2];	/* 0x001c */
+	struct ihs_io_ep ep;	/* 0x0020 */
+	u16 reserved_3[9];	/* 0x002e */
+	u16 mc_int;		/* 0x0040 */
+	u16 mc_int_en;		/* 0x0042 */
+	u16 mc_status;		/* 0x0044 */
+	u16 mc_control;		/* 0x0046 */
+	u16 mc_tx_data;		/* 0x0048 */
+	u16 mc_tx_address;	/* 0x004a */
+	u16 mc_tx_cmd;		/* 0x004c */
+	u16 mc_res;		/* 0x004e */
+	u16 mc_rx_cmd_status;	/* 0x0050 */
+	u16 mc_rx_data;		/* 0x0052 */
+	u16 reserved_4[62];	/* 0x0054 */
+	struct ihs_i2c i2c0;	/* 0x00d0 */
+};
+#endif
+
+#ifdef CONFIG_STRIDER_CON
+struct ihs_fpga {
+	u16 reflection_low;	/* 0x0000 */
+	u16 versions;		/* 0x0002 */
+	u16 fpga_version;	/* 0x0004 */
+	u16 fpga_features;	/* 0x0006 */
+	u16 reserved_0[1];	/* 0x0008 */
+	u16 top_interrupt;	/* 0x000a */
 	u16 reserved_1[4];	/* 0x000c */
 	struct ihs_gpio gpio;	/* 0x0014 */
 	u16 mpc3w_control;	/* 0x001a */
 	u16 reserved_2[2];	/* 0x001c */
 	struct ihs_io_ep ep;	/* 0x0020 */
 	u16 reserved_3[9];	/* 0x002e */
-	struct ihs_i2c i2c;	/* 0x0040 */
+	struct ihs_i2c i2c0;	/* 0x0040 */
 	u16 reserved_4[10];	/* 0x004c */
 	u16 mc_int;		/* 0x0060 */
 	u16 mc_int_en;		/* 0x0062 */
@@ -189,11 +265,10 @@
 	u16 mc_res;		/* 0x006e */
 	u16 mc_rx_cmd_status;	/* 0x0070 */
 	u16 mc_rx_data;		/* 0x0072 */
-	u16 reserved_5[69];	/* 0x0074 */
-	u16 reflection_high;	/* 0x00fe */
-	struct ihs_osd osd;	/* 0x0100 */
+	u16 reserved_5[70];	/* 0x0074 */
+	struct ihs_osd osd0;	/* 0x0100 */
 	u16 reserved_6[889];	/* 0x010e */
-	u16 videomem[31736];	/* 0x0800 */
+	u16 videomem0[2048];	/* 0x0800 */
 };
 #endif
 
@@ -208,11 +283,13 @@
 	u16 reserved_1[29];	/* 0x001e */
 	u16 mpc3w_control;	/* 0x0058 */
 	u16 reserved_2[3];	/* 0x005a */
-	struct ihs_i2c i2c;	/* 0x0060 */
-	u16 reserved_3[205];	/* 0x0066 */
-	struct ihs_osd osd;	/* 0x0200 */
-	u16 reserved_4[761];	/* 0x020e */
-	u16 videomem[31736];	/* 0x0800 */
+	struct ihs_i2c i2c0;	/* 0x0060 */
+	u16 reserved_3[2];	/* 0x006c */
+	struct ihs_i2c i2c1;	/* 0x0070 */
+	u16 reserved_4[194];	/* 0x007c */
+	struct ihs_osd osd0;	/* 0x0200 */
+	u16 reserved_5[761];	/* 0x020e */
+	u16 videomem0[2048];	/* 0x0800 */
 };
 #endif
 
diff --git a/include/grlib/apbuart.h b/include/grlib/apbuart.h
new file mode 100644
index 0000000..1e1eb9a
--- /dev/null
+++ b/include/grlib/apbuart.h
@@ -0,0 +1,47 @@
+/* GRLIB APBUART definitions
+ *
+ * (C) Copyright 2010, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __GRLIB_APBUART_H__
+#define __GRLIB_APBUART_H__
+
+/* APBUART Register map */
+typedef struct {
+	volatile unsigned int data;
+	volatile unsigned int status;
+	volatile unsigned int ctrl;
+	volatile unsigned int scaler;
+} ambapp_dev_apbuart;
+
+/*
+ *  The following defines the bits in the LEON UART Status Registers.
+ */
+
+#define APBUART_STATUS_DR   0x00000001	/* Data Ready */
+#define APBUART_STATUS_TSE  0x00000002	/* TX Send Register Empty */
+#define APBUART_STATUS_THE  0x00000004	/* TX Hold Register Empty */
+#define APBUART_STATUS_BR   0x00000008	/* Break Error */
+#define APBUART_STATUS_OE   0x00000010	/* RX Overrun Error */
+#define APBUART_STATUS_PE   0x00000020	/* RX Parity Error */
+#define APBUART_STATUS_FE   0x00000040	/* RX Framing Error */
+#define APBUART_STATUS_ERR  0x00000078	/* Error Mask */
+
+/*
+ *  The following defines the bits in the LEON UART Ctrl Registers.
+ */
+
+#define APBUART_CTRL_RE     0x00000001	/* Receiver enable */
+#define APBUART_CTRL_TE     0x00000002	/* Transmitter enable */
+#define APBUART_CTRL_RI     0x00000004	/* Receiver interrupt enable */
+#define APBUART_CTRL_TI     0x00000008	/* Transmitter interrupt enable */
+#define APBUART_CTRL_PS     0x00000010	/* Parity select */
+#define APBUART_CTRL_PE     0x00000020	/* Parity enable */
+#define APBUART_CTRL_FL     0x00000040	/* Flow control enable */
+#define APBUART_CTRL_LB     0x00000080	/* Loop Back enable */
+#define APBUART_CTRL_DBG    (1<<11)	/* Debug Bit used by GRMON */
+
+#endif
diff --git a/include/grlib/gptimer.h b/include/grlib/gptimer.h
new file mode 100644
index 0000000..8b2b165
--- /dev/null
+++ b/include/grlib/gptimer.h
@@ -0,0 +1,34 @@
+/* GRLIB GPTIMER (General Purpose Timer) definitions
+ *
+ * (C) Copyright 2010, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __GRLIB_GPTIMER_H__
+#define __GRLIB_GPTIMER_H__
+
+typedef struct {
+	volatile unsigned int val;
+	volatile unsigned int rld;
+	volatile unsigned int ctrl;
+	volatile unsigned int unused;
+} ambapp_dev_gptimer_element;
+
+#define GPTIMER_CTRL_EN	0x1	/* Timer enable */
+#define GPTIMER_CTRL_RS	0x2	/* Timer reStart  */
+#define GPTIMER_CTRL_LD	0x4	/* Timer reLoad */
+#define GPTIMER_CTRL_IE	0x8	/* interrupt enable */
+#define GPTIMER_CTRL_IP	0x10	/* interrupt flag/pending */
+#define GPTIMER_CTRL_CH	0x20	/* Chain with previous timer */
+
+typedef struct {
+	volatile unsigned int scalar;
+	volatile unsigned int scalar_reload;
+	volatile unsigned int config;
+	volatile unsigned int unused;
+	volatile ambapp_dev_gptimer_element e[8];
+} ambapp_dev_gptimer;
+
+#endif
diff --git a/include/grlib/greth.h b/include/grlib/greth.h
new file mode 100644
index 0000000..89c1e49
--- /dev/null
+++ b/include/grlib/greth.h
@@ -0,0 +1,87 @@
+/* Gaisler.com GRETH 10/100/1000 Ethernet MAC definitions
+ *
+ * (C) Copyright 2010, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __GRLIB_GRETH_H__
+#define __GRLIB_GRETH_H__
+
+#define GRETH_FD 0x10
+#define GRETH_RESET 0x40
+#define GRETH_MII_BUSY 0x8
+#define GRETH_MII_NVALID 0x10
+
+/* MII registers */
+#define GRETH_MII_EXTADV_1000FD 0x00000200
+#define GRETH_MII_EXTADV_1000HD 0x00000100
+#define GRETH_MII_EXTPRT_1000FD 0x00000800
+#define GRETH_MII_EXTPRT_1000HD 0x00000400
+
+#define GRETH_MII_100T4 0x00000200
+#define GRETH_MII_100TXFD 0x00000100
+#define GRETH_MII_100TXHD 0x00000080
+#define GRETH_MII_10FD 0x00000040
+#define GRETH_MII_10HD 0x00000020
+
+#define GRETH_BD_EN 0x800
+#define GRETH_BD_WR 0x1000
+#define GRETH_BD_IE 0x2000
+#define GRETH_BD_LEN 0x7FF
+
+#define GRETH_TXEN 0x1
+#define GRETH_INT_TX 0x8
+#define GRETH_TXI 0x4
+#define GRETH_TXBD_STATUS 0x0001C000
+#define GRETH_TXBD_MORE 0x20000
+#define GRETH_TXBD_IPCS 0x40000
+#define GRETH_TXBD_TCPCS 0x80000
+#define GRETH_TXBD_UDPCS 0x100000
+#define GRETH_TXBD_ERR_LC 0x10000
+#define GRETH_TXBD_ERR_UE 0x4000
+#define GRETH_TXBD_ERR_AL 0x8000
+#define GRETH_TXBD_NUM 128
+#define GRETH_TXBD_NUM_MASK (GRETH_TXBD_NUM-1)
+#define GRETH_TX_BUF_SIZE 2048
+
+#define GRETH_INT_RX         0x4
+#define GRETH_RXEN           0x2
+#define GRETH_RXI            0x8
+#define GRETH_RXBD_STATUS    0xFFFFC000
+#define GRETH_RXBD_ERR_AE    0x4000
+#define GRETH_RXBD_ERR_FT    0x8000
+#define GRETH_RXBD_ERR_CRC   0x10000
+#define GRETH_RXBD_ERR_OE    0x20000
+#define GRETH_RXBD_ERR_LE    0x40000
+#define GRETH_RXBD_IP_DEC    0x80000
+#define GRETH_RXBD_IP_CSERR  0x100000
+#define GRETH_RXBD_UDP_DEC   0x200000
+#define GRETH_RXBD_UDP_CSERR 0x400000
+#define GRETH_RXBD_TCP_DEC   0x800000
+#define GRETH_RXBD_TCP_CSERR 0x1000000
+
+#define GRETH_RXBD_NUM 128
+#define GRETH_RXBD_NUM_MASK (GRETH_RXBD_NUM-1)
+#define GRETH_RX_BUF_SIZE 2048
+
+/* Ethernet configuration registers */
+typedef struct _greth_regs {
+	volatile unsigned int control;
+	volatile unsigned int status;
+	volatile unsigned int esa_msb;
+	volatile unsigned int esa_lsb;
+	volatile unsigned int mdio;
+	volatile unsigned int tx_desc_p;
+	volatile unsigned int rx_desc_p;
+	volatile unsigned int edcl_ip;
+} greth_regs;
+
+/* Ethernet buffer descriptor */
+typedef struct _greth_bd {
+	volatile unsigned int stat;
+	unsigned int addr;	/* Buffer address not changed by HW */
+} greth_bd;
+
+#endif
diff --git a/include/grlib/irqmp.h b/include/grlib/irqmp.h
new file mode 100644
index 0000000..0354d5c
--- /dev/null
+++ b/include/grlib/irqmp.h
@@ -0,0 +1,23 @@
+/* GRLIB IRQMP (IRQ Multi-processor controller) definitions
+ *
+ * (C) Copyright 2010, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __GRLIB_IRQMP_H__
+#define __GRLIB_IRQMP_H__
+
+typedef struct {
+	volatile unsigned int ilevel;
+	volatile unsigned int ipend;
+	volatile unsigned int iforce;
+	volatile unsigned int iclear;
+	volatile unsigned int mstatus;
+	volatile unsigned int notused[11];
+	volatile unsigned int cpu_mask[16];
+	volatile unsigned int cpu_force[16];
+} ambapp_dev_irqmp;
+
+#endif
diff --git a/include/image-sparse.h b/include/image-sparse.h
new file mode 100644
index 0000000..0382f5b
--- /dev/null
+++ b/include/image-sparse.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2014 Broadcom Corporation.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <part.h>
+#include <sparse_format.h>
+
+#define ROUNDUP(x, y)	(((x) + ((y) - 1)) & ~((y) - 1))
+
+typedef struct sparse_storage {
+	unsigned int	block_sz;
+	unsigned int	start;
+	unsigned int	size;
+	const char	*name;
+
+	int	(*write)(struct sparse_storage *storage, void *priv,
+			 unsigned int offset, unsigned int size,
+			 char *data);
+} sparse_storage_t;
+
+static inline int is_sparse_image(void *buf)
+{
+	sparse_header_t *s_header = (sparse_header_t *)buf;
+
+	if ((le32_to_cpu(s_header->magic) == SPARSE_HEADER_MAGIC) &&
+	    (le16_to_cpu(s_header->major_version) == 1))
+		return 1;
+
+	return 0;
+}
+
+int store_sparse_image(sparse_storage_t *storage, void *storage_priv,
+		       unsigned int session_id, void *data);
diff --git a/include/linux/mtd/concat.h b/include/linux/mtd/concat.h
index 195a4a5..a374ca9 100644
--- a/include/linux/mtd/concat.h
+++ b/include/linux/mtd/concat.h
@@ -1,9 +1,10 @@
 /*
  * MTD device concatenation layer definitions
  *
- * (C) 2002 Robert Kaiser <rkaiser@sysgo.de>
+ * Copyright © 2002      Robert Kaiser <rkaiser@sysgo.de>
  *
- * This code is GPL
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
  */
 
 #ifndef MTD_CONCAT_H
diff --git a/include/linux/mtd/doc2000.h b/include/linux/mtd/doc2000.h
index ba29d53..a3cfe6b 100644
--- a/include/linux/mtd/doc2000.h
+++ b/include/linux/mtd/doc2000.h
@@ -1,12 +1,13 @@
 /*
  * Linux driver for Disk-On-Chip devices
  *
- * Copyright (C) 1999 Machine Vision Holdings, Inc.
- * Copyright (C) 2001-2003 David Woodhouse <dwmw2@infradead.org>
- * Copyright (C) 2002-2003 Greg Ungerer <gerg@snapgear.com>
- * Copyright (C) 2002-2003 SnapGear Inc
+ * Copyright © 1999 Machine Vision Holdings, Inc.
+ * Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org>
+ * Copyright © 2002-2003 Greg Ungerer <gerg@snapgear.com>
+ * Copyright © 2002-2003 SnapGear Inc
  *
- * Released under GPL
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
  */
 
 #ifndef __MTD_DOC2000_H__
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index c2cd3df..9da77ec 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -1,7 +1,7 @@
 /*
  * Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org> et al.
  *
- * Released under GPL
+ * SPDX-License-Identifier:	GPL-2.0+
  *
  */
 
diff --git a/include/linux/mtd/nand_ecc.h b/include/linux/mtd/nand_ecc.h
index 090da50..02ba9f7 100644
--- a/include/linux/mtd/nand_ecc.h
+++ b/include/linux/mtd/nand_ecc.h
@@ -1,11 +1,11 @@
 /*
  *  drivers/mtd/nand_ecc.h
  *
- *  Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
+ *  Copyright (C) 2000-2010 Steven J. Hill <sjhill@realitydiluted.com>
+ *			    David Woodhouse <dwmw2@infradead.org>
+ *			    Thomas Gleixner <tglx@linutronix.de>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * SPDX-License-Identifier:	GPL-2.0
  *
  * This file is the header for the ECC algorithm.
  */
diff --git a/include/part.h b/include/part.h
index 8ea9b30..8b5ac12 100644
--- a/include/part.h
+++ b/include/part.h
@@ -93,6 +93,9 @@
 #ifdef CONFIG_PARTITION_UUIDS
 	char	uuid[37];	/* filesystem UUID as string, if exists	*/
 #endif
+#ifdef CONFIG_PARTITION_TYPE_GUID
+	char	type_guid[37];	/* type GUID as string, if exists	*/
+#endif
 } disk_partition_t;
 
 /* Misc _get_dev functions */
diff --git a/include/part_efi.h b/include/part_efi.h
index 3012b91..c8fc873 100644
--- a/include/part_efi.h
+++ b/include/part_efi.h
@@ -43,6 +43,9 @@
 #define PARTITION_BASIC_DATA_GUID \
 	EFI_GUID( 0xEBD0A0A2, 0xB9E5, 0x4433, \
 		0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7)
+#define PARTITION_LINUX_FILE_SYSTEM_DATA_GUID \
+	EFI_GUID(0x0FC63DAF, 0x8483, 0x4772, \
+		0x8E, 0x79, 0x3D, 0x69, 0xD8, 0x47, 0x7D, 0xE4)
 #define PARTITION_LINUX_RAID_GUID \
 	EFI_GUID( 0xa19d880f, 0x05fc, 0x4d3b, \
 		0xa0, 0x06, 0x74, 0x3f, 0x0f, 0x84, 0x91, 0x1e)
diff --git a/include/spi_flash.h b/include/spi_flash.h
index 0ae0062..f25b3e7 100644
--- a/include/spi_flash.h
+++ b/include/spi_flash.h
@@ -237,7 +237,7 @@
 static inline int spi_flash_protect(struct spi_flash *flash, u32 ofs, u32 len,
 					bool prot)
 {
-	if (!flash->flash_lock)
+	if (!flash->flash_lock || !flash->flash_unlock)
 		return -EOPNOTSUPP;
 
 	if (prot)
diff --git a/include/uuid.h b/include/uuid.h
index 93027c1..c3f423f 100644
--- a/include/uuid.h
+++ b/include/uuid.h
@@ -36,6 +36,10 @@
 int uuid_str_valid(const char *uuid);
 int uuid_str_to_bin(char *uuid_str, unsigned char *uuid_bin, int str_format);
 void uuid_bin_to_str(unsigned char *uuid_bin, char *uuid_str, int str_format);
+#ifdef CONFIG_PARTITION_TYPE_GUID
+int uuid_guid_get_bin(const char *guid_str, unsigned char *guid_bin);
+int uuid_guid_get_str(unsigned char *guid_bin, char *guid_str);
+#endif
 void gen_rand_uuid(unsigned char *uuid_bin);
 void gen_rand_uuid_str(char *uuid_str, int str_format);
 #endif
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index c1b5177..f1849bc 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -36,6 +36,7 @@
 	COMPAT(NVIDIA_TEGRA30_SDMMC, "nvidia,tegra30-sdhci"),
 	COMPAT(NVIDIA_TEGRA20_SDMMC, "nvidia,tegra20-sdhci"),
 	COMPAT(NVIDIA_TEGRA124_PCIE, "nvidia,tegra124-pcie"),
+	COMPAT(NVIDIA_TEGRA210_PCIE, "nvidia,tegra210-pcie"),
 	COMPAT(NVIDIA_TEGRA30_PCIE, "nvidia,tegra30-pcie"),
 	COMPAT(NVIDIA_TEGRA20_PCIE, "nvidia,tegra20-pcie"),
 	COMPAT(NVIDIA_TEGRA124_XUSB_PADCTL, "nvidia,tegra124-xusb-padctl"),
diff --git a/lib/uuid.c b/lib/uuid.c
index f6b4423..c8584ed 100644
--- a/lib/uuid.c
+++ b/lib/uuid.c
@@ -80,10 +80,65 @@
 	return 1;
 }
 
+#ifdef CONFIG_PARTITION_TYPE_GUID
+static const struct {
+	const char *string;
+	efi_guid_t guid;
+} list_guid[] = {
+	{"system",	PARTITION_SYSTEM_GUID},
+	{"mbr",		LEGACY_MBR_PARTITION_GUID},
+	{"msft",	PARTITION_MSFT_RESERVED_GUID},
+	{"data",	PARTITION_BASIC_DATA_GUID},
+	{"linux",	PARTITION_LINUX_FILE_SYSTEM_DATA_GUID},
+	{"raid",	PARTITION_LINUX_RAID_GUID},
+	{"swap",	PARTITION_LINUX_SWAP_GUID},
+	{"lvm",		PARTITION_LINUX_LVM_GUID}
+};
+
+/*
+ * uuid_guid_get_bin() - this function get GUID bin for string
+ *
+ * @param guid_str - pointer to partition type string
+ * @param guid_bin - pointer to allocated array for big endian output [16B]
+ */
+int uuid_guid_get_bin(const char *guid_str, unsigned char *guid_bin)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(list_guid); i++) {
+		if (!strcmp(list_guid[i].string, guid_str)) {
+			memcpy(guid_bin, &list_guid[i].guid, 16);
+			return 0;
+		}
+	}
+	return -ENODEV;
+}
+
+/*
+ * uuid_guid_get_str() - this function get string for GUID.
+ *
+ * @param guid_bin - pointer to string with partition type guid [16B]
+ * @param guid_str - pointer to allocated partition type string [7B]
+ */
+int uuid_guid_get_str(unsigned char *guid_bin, char *guid_str)
+{
+	int i;
+
+	*guid_str = 0;
+	for (i = 0; i < ARRAY_SIZE(list_guid); i++) {
+		if (!memcmp(list_guid[i].guid.b, guid_bin, 16)) {
+			strcpy(guid_str, list_guid[i].string);
+			return 0;
+		}
+	}
+	return -ENODEV;
+}
+#endif
+
 /*
  * uuid_str_to_bin() - convert string UUID or GUID to big endian binary data.
  *
- * @param uuid_str - pointer to UUID or GUID string [37B]
+ * @param uuid_str - pointer to UUID or GUID string [37B] or GUID shorcut
  * @param uuid_bin - pointer to allocated array for big endian output [16B]
  * @str_format     - UUID string format: 0 - UUID; 1 - GUID
  */
@@ -93,8 +148,13 @@
 	uint32_t tmp32;
 	uint64_t tmp64;
 
-	if (!uuid_str_valid(uuid_str))
+	if (!uuid_str_valid(uuid_str)) {
+#ifdef CONFIG_PARTITION_TYPE_GUID
+		if (!uuid_guid_get_bin(uuid_str, uuid_bin))
+			return 0;
+#endif
 		return -EINVAL;
+	}
 
 	if (str_format == UUID_STR_FORMAT_STD) {
 		tmp32 = cpu_to_be32(simple_strtoul(uuid_str, NULL, 16));
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
index dd235b9..8f690eb 100644
--- a/scripts/Makefile.spl
+++ b/scripts/Makefile.spl
@@ -56,6 +56,7 @@
 libs-$(CONFIG_SPL_LIBCOMMON_SUPPORT) += common/
 libs-$(CONFIG_SPL_LIBDISK_SUPPORT) += disk/
 libs-y += drivers/
+libs-y += dts/
 libs-y += fs/
 libs-$(CONFIG_SPL_LIBGENERIC_SUPPORT) += lib/
 libs-$(CONFIG_SPL_POST_MEM_SUPPORT) += post/drivers/
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl
index 368a20e..4707dfd 100755
--- a/scripts/get_maintainer.pl
+++ b/scripts/get_maintainer.pl
@@ -62,7 +62,7 @@
 my %commit_signer_hash;
 
 my @penguin_chief = ();
-push(@penguin_chief, "Tom Rini:trini\@ti.com");
+push(@penguin_chief, "Tom Rini:trini\@konsulko.com");
 
 my @penguin_chief_names = ();
 foreach my $chief (@penguin_chief) {