diff --git a/Makefile b/Makefile
index 600a4d623a993f96fcfb44dd0823db9b4980dca4..57fa6ec359ad05dd16352e9e45b3ccae14d1a6b6 100644
--- a/Makefile
+++ b/Makefile
@@ -747,6 +747,9 @@ BOARD_SIZE_CHECK =
 endif
 
 # Statically apply RELA-style relocations (currently arm64 only)
+# This is useful for arm64 where static relocation needs to be performed on
+# the raw binary, but certain simulators only accept an ELF file (but don't
+# do the relocation).
 ifneq ($(CONFIG_STATIC_RELA),)
 # $(1) is u-boot ELF, $(2) is u-boot bin, $(3) is text base
 DO_STATIC_RELA = \
@@ -1180,17 +1183,17 @@ OBJCOPYFLAGS_u-boot-img-spl-at-end.bin := -I binary -O binary \
 u-boot-img-spl-at-end.bin: u-boot.img spl/u-boot-spl.bin FORCE
 	$(call if_changed,pad_cat)
 
-# Create a new ELF from a raw binary file.  This is useful for arm64
-# where static relocation needs to be performed on the raw binary,
-# but certain simulators only accept an ELF file (but don't do the
-# relocation).
-# FIXME refactor dts/Makefile to share target/arch detection
+# Create a new ELF from a raw binary file.
+ifndef PLATFORM_ELFENTRY
+  PLATFORM_ELFENTRY = "_start"
+endif
+quiet_cmd_u-boot-elf ?= LD      $@
+	cmd_u-boot-elf ?= $(LD) u-boot-elf.o -o $@ \
+	--defsym=$(PLATFORM_ELFENTRY)=$(CONFIG_SYS_TEXT_BASE) \
+	-Ttext=$(CONFIG_SYS_TEXT_BASE)
 u-boot.elf: u-boot.bin
-	@$(OBJCOPY)  -B aarch64 -I binary -O elf64-littleaarch64 \
-		$< u-boot-elf.o
-	@$(LD) u-boot-elf.o -o $@ \
-		--defsym=_start=$(CONFIG_SYS_TEXT_BASE) \
-		-Ttext=$(CONFIG_SYS_TEXT_BASE)
+	$(Q)$(OBJCOPY) -I binary $(PLATFORM_ELFFLAGS) $< u-boot-elf.o
+	$(call if_changed,u-boot-elf)
 
 # Rule to link u-boot
 # May be overridden by arch/$(ARCH)/config.mk
diff --git a/arch/arm/config.mk b/arch/arm/config.mk
index 2143633fe440985c5c732d436ee97a5b94598bc1..a5eebb95e5c6d58188c21da27cf56f8c61f1da8e 100644
--- a/arch/arm/config.mk
+++ b/arch/arm/config.mk
@@ -30,6 +30,12 @@ PLATFORM_RELFLAGS	+= $(LLVM_RELFLAGS)
 
 PLATFORM_CPPFLAGS += -D__ARM__
 
+ifdef CONFIG_ARM64
+PLATFORM_ELFFLAGS += -B aarch64 -O elf64-littleaarch64
+else
+PLATFORM_ELFFLAGS += -B arm -O elf32-littlearm
+endif
+
 # Choose between ARM/Thumb instruction sets
 ifeq ($(CONFIG_$(SPL_)SYS_THUMB_BUILD),y)
 AFLAGS_IMPLICIT_IT	:= $(call as-option,-Wa$(comma)-mimplicit-it=always)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index d97930e577bb057a45ce62249871244440c9bdcf..c97ea4156b49a78f474b1bf62ea1c16f4c5a2a81 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -75,6 +75,15 @@ config ARCH_ATH79
 	select OF_CONTROL
 	select DM
 
+config ARCH_BMIPS
+	bool "Support BMIPS SoCs"
+	select OF_CONTROL
+	select DM
+	select CLK
+	select CPU
+	select RAM
+	select SYSRESET
+
 config MACH_PIC32
 	bool "Support Microchip PIC32"
 	select OF_CONTROL
@@ -123,6 +132,7 @@ source "board/micronas/vct/Kconfig"
 source "board/pb1x00/Kconfig"
 source "board/qemu-mips/Kconfig"
 source "arch/mips/mach-ath79/Kconfig"
+source "arch/mips/mach-bmips/Kconfig"
 source "arch/mips/mach-pic32/Kconfig"
 
 if MIPS
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index efe7e44236b9bd0b5f34129b64db09fdd1b09af0..c30d4ef39db0b79840fcdf9ff64e789cf4085067 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -15,6 +15,7 @@ libs-y += arch/mips/lib/
 
 machine-$(CONFIG_SOC_AU1X00) += au1x00
 machine-$(CONFIG_ARCH_ATH79) += ath79
+machine-$(CONFIG_ARCH_BMIPS) += bmips
 machine-$(CONFIG_MACH_PIC32) += pic32
 
 machdirs := $(patsubst %,arch/mips/mach-%/,$(machine-y))
diff --git a/arch/mips/config.mk b/arch/mips/config.mk
index dcd346002cab9ce63dff390260190015480ba96c..2c72c1553d64826af0c2216d34550546946804b8 100644
--- a/arch/mips/config.mk
+++ b/arch/mips/config.mk
@@ -36,6 +36,8 @@ OBJCOPYFLAGS		+= -O $(64bit-bfd)
 endif
 
 PLATFORM_CPPFLAGS += -D__MIPS__
+PLATFORM_ELFENTRY = "__start"
+PLATFORM_ELFFLAGS += -B mips $(OBJCOPYFLAGS)
 
 #
 # From Linux arch/mips/Makefile
diff --git a/arch/mips/cpu/cpu.c b/arch/mips/cpu/cpu.c
index 1b919ed82289d1d4d30e4daccf057c8c4e89e9ed..55e6498b6557c75b265328b3eb3958ded4d5d758 100644
--- a/arch/mips/cpu/cpu.c
+++ b/arch/mips/cpu/cpu.c
@@ -12,6 +12,7 @@
 #include <asm/mipsregs.h>
 #include <asm/reboot.h>
 
+#ifndef CONFIG_SYSRESET
 void __weak _machine_restart(void)
 {
 	fprintf(stderr, "*** reset failed ***\n");
@@ -26,6 +27,7 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
 	return 0;
 }
+#endif
 
 void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1)
 {
diff --git a/arch/mips/cpu/start.S b/arch/mips/cpu/start.S
index 6740fdf9ed272eda6bc7213ad02db57fc68f7d7b..d01ee9f9bddd3095ffcf754dcc9e6176aacf33ef 100644
--- a/arch/mips/cpu/start.S
+++ b/arch/mips/cpu/start.S
@@ -151,8 +151,13 @@ reset:
 	 mfc0	t0, CP0_GLOBALNUMBER
 #endif
 
+#ifdef CONFIG_ARCH_BMIPS
+1:	mfc0	t0, CP0_DIAGNOSTIC, 3
+	and	t0, t0, (1 << 31)
+#else
 1:	mfc0	t0, CP0_EBASE
 	and	t0, t0, EBASE_CPUNUM
+#endif
 
 	/* Hang if this isn't the first CPU in the system */
 2:	beqz	t0, 4f
@@ -237,6 +242,13 @@ wr_done:
 #ifdef CONFIG_MIPS_INIT_STACK_IN_SRAM
 	/* Set up initial stack and global data */
 	setup_stack_gd
+
+# ifdef CONFIG_DEBUG_UART
+	/* Earliest point to set up debug uart */
+	PTR_LA	t9, debug_uart_init
+	jalr	t9
+	 nop
+# endif
 #endif
 
 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
@@ -263,6 +275,13 @@ wr_done:
 #ifndef CONFIG_MIPS_INIT_STACK_IN_SRAM
 	/* Set up initial stack and global data */
 	setup_stack_gd
+
+# ifdef CONFIG_DEBUG_UART
+	/* Earliest point to set up debug uart */
+	PTR_LA	t9, debug_uart_init
+	jalr	t9
+	 nop
+# endif
 #endif
 
 	move	a0, zero		# a0 <-- boot_flags = 0
diff --git a/arch/mips/dts/Makefile b/arch/mips/dts/Makefile
index 30fcc2b91e6a9113fbbc76e62782a68ca3b909fd..4c02c48c11168ca5288433d9f0abd51ea6d21ac7 100644
--- a/arch/mips/dts/Makefile
+++ b/arch/mips/dts/Makefile
@@ -8,6 +8,9 @@ dtb-$(CONFIG_TARGET_BOSTON) += img,boston.dtb
 dtb-$(CONFIG_TARGET_MALTA) += mti,malta.dtb
 dtb-$(CONFIG_TARGET_PIC32MZDASK) += pic32mzda_sk.dtb
 dtb-$(CONFIG_TARGET_XILFPGA) += nexys4ddr.dtb
+dtb-$(CONFIG_BOARD_COMTREND_AR5387UN) += comtrend,ar-5387un.dtb
+dtb-$(CONFIG_BOARD_COMTREND_VR3032U) += comtrend,vr-3032u.dtb
+dtb-$(CONFIG_BOARD_HUAWEI_HG556A) += huawei,hg556a.dtb
 dtb-$(CONFIG_BOARD_TPLINK_WDR4300) += tplink_wdr4300.dtb
 
 targets += $(dtb-y)
diff --git a/arch/mips/dts/brcm,bcm63268.dtsi b/arch/mips/dts/brcm,bcm63268.dtsi
new file mode 100644
index 0000000000000000000000000000000000000000..3d0f8e0ea14c2c9d3ab72330d8a6e09c5d4badbf
--- /dev/null
+++ b/arch/mips/dts/brcm,bcm63268.dtsi
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <dt-bindings/clock/bcm63268-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/power-domain/bcm63268-power-domain.h>
+#include <dt-bindings/reset/bcm63268-reset.h>
+#include "skeleton.dtsi"
+
+/ {
+	compatible = "brcm,bcm63268";
+
+	cpus {
+		reg = <0x10000000 0x4>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		u-boot,dm-pre-reloc;
+
+		cpu@0 {
+			compatible = "brcm,bcm63268-cpu", "mips,mips4Kc";
+			device_type = "cpu";
+			reg = <0>;
+			u-boot,dm-pre-reloc;
+		};
+
+		cpu@1 {
+			compatible = "brcm,bcm63268-cpu", "mips,mips4Kc";
+			device_type = "cpu";
+			reg = <1>;
+			u-boot,dm-pre-reloc;
+		};
+	};
+
+	clocks {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		u-boot,dm-pre-reloc;
+
+		periph_osc: periph-osc {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <50000000>;
+			u-boot,dm-pre-reloc;
+		};
+
+		periph_clk: periph-clk {
+			compatible = "brcm,bcm6345-clk";
+			reg = <0x10000004 0x4>;
+			#clock-cells = <1>;
+		};
+
+		timer_clk: timer-clk {
+			compatible = "brcm,bcm6345-clk";
+			reg = <0x100000ac 0x4>;
+			#clock-cells = <1>;
+		};
+	};
+
+	ubus {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		u-boot,dm-pre-reloc;
+
+		pll_cntl: syscon@10000008 {
+			compatible = "syscon";
+			reg = <0x10000008 0x4>;
+		};
+
+		syscon-reboot {
+			compatible = "syscon-reboot";
+			regmap = <&pll_cntl>;
+			offset = <0x0>;
+			mask = <0x1>;
+		};
+
+		periph_rst: reset-controller@10000010 {
+			compatible = "brcm,bcm6345-reset";
+			reg = <0x10000010 0x4>;
+			#reset-cells = <1>;
+		};
+
+		gpio1: gpio-controller@100000c0 {
+			compatible = "brcm,bcm6345-gpio";
+			reg = <0x100000c0 0x4>, <0x100000c8 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			ngpios = <20>;
+
+			status = "disabled";
+		};
+
+		gpio0: gpio-controller@100000c4 {
+			compatible = "brcm,bcm6345-gpio";
+			reg = <0x100000c4 0x4>, <0x100000cc 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			status = "disabled";
+		};
+
+		uart0: serial@10000180 {
+			compatible = "brcm,bcm6345-uart";
+			reg = <0x10000180 0x18>;
+			clocks = <&periph_osc>;
+
+			status = "disabled";
+		};
+
+		uart1: serial@100001a0 {
+			compatible = "brcm,bcm6345-uart";
+			reg = <0x100001a0 0x18>;
+			clocks = <&periph_osc>;
+
+			status = "disabled";
+		};
+
+		periph_pwr: power-controller@1000184c {
+			compatible = "brcm,bcm6328-power-domain";
+			reg = <0x1000184c 0x4>;
+			#power-domain-cells = <1>;
+		};
+
+		leds: led-controller@10001900 {
+			compatible = "brcm,bcm6328-leds";
+			reg = <0x10001900 0x24>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			status = "disabled";
+		};
+
+		memory-controller@10003000 {
+			compatible = "brcm,bcm6328-mc";
+			reg = <0x10003000 0x1000>;
+			u-boot,dm-pre-reloc;
+		};
+	};
+};
diff --git a/arch/mips/dts/brcm,bcm6328.dtsi b/arch/mips/dts/brcm,bcm6328.dtsi
new file mode 100644
index 0000000000000000000000000000000000000000..4adc83fcb43713bebb9cabf624edd600862c9cd9
--- /dev/null
+++ b/arch/mips/dts/brcm,bcm6328.dtsi
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <dt-bindings/clock/bcm6328-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/power-domain/bcm6328-power-domain.h>
+#include <dt-bindings/reset/bcm6328-reset.h>
+#include "skeleton.dtsi"
+
+/ {
+	compatible = "brcm,bcm6328";
+
+	cpus {
+		reg = <0x10000000 0x4>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		u-boot,dm-pre-reloc;
+
+		cpu@0 {
+			compatible = "brcm,bcm6328-cpu", "mips,mips4Kc";
+			device_type = "cpu";
+			reg = <0>;
+			u-boot,dm-pre-reloc;
+		};
+
+		cpu@1 {
+			compatible = "brcm,bcm6328-cpu", "mips,mips4Kc";
+			device_type = "cpu";
+			reg = <1>;
+			u-boot,dm-pre-reloc;
+		};
+	};
+
+	clocks {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		u-boot,dm-pre-reloc;
+
+		periph_osc: periph-osc {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <50000000>;
+			u-boot,dm-pre-reloc;
+		};
+
+		periph_clk: periph-clk {
+			compatible = "brcm,bcm6345-clk";
+			reg = <0x10000004 0x4>;
+			#clock-cells = <1>;
+		};
+	};
+
+	ubus {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		u-boot,dm-pre-reloc;
+
+		periph_rst: reset-controller@10000010 {
+			compatible = "brcm,bcm6345-reset";
+			reg = <0x10000010 0x4>;
+			#reset-cells = <1>;
+		};
+
+		pll_cntl: syscon@10000068 {
+			compatible = "syscon";
+			reg = <0x10000068 0x4>;
+		};
+
+		syscon-reboot {
+			compatible = "syscon-reboot";
+			regmap = <&pll_cntl>;
+			offset = <0x0>;
+			mask = <0x1>;
+		};
+
+		gpio: gpio-controller@10000084 {
+			compatible = "brcm,bcm6345-gpio";
+			reg = <0x10000084 0x4>, <0x1000008c 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			status = "disabled";
+		};
+
+		uart0: serial@10000100 {
+			compatible = "brcm,bcm6345-uart";
+			reg = <0x10000100 0x18>;
+			clocks = <&periph_osc>;
+
+			status = "disabled";
+		};
+
+		uart1: serial@10000120 {
+			compatible = "brcm,bcm6345-uart";
+			reg = <0x10000120 0x18>;
+			clocks = <&periph_osc>;
+
+			status = "disabled";
+		};
+
+		leds: led-controller@10000800 {
+			compatible = "brcm,bcm6328-leds";
+			reg = <0x10000800 0x24>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			status = "disabled";
+		};
+
+		periph_pwr: power-controller@10001848 {
+			compatible = "brcm,bcm6328-power-domain";
+			reg = <0x10001848 0x4>;
+			#power-domain-cells = <1>;
+		};
+
+		memory-controller@10003000 {
+			compatible = "brcm,bcm6328-mc";
+			reg = <0x10003000 0x1000>;
+			u-boot,dm-pre-reloc;
+		};
+	};
+};
diff --git a/arch/mips/dts/brcm,bcm6358.dtsi b/arch/mips/dts/brcm,bcm6358.dtsi
new file mode 100644
index 0000000000000000000000000000000000000000..df75988c82316905783b07e67deba3260987cf1e
--- /dev/null
+++ b/arch/mips/dts/brcm,bcm6358.dtsi
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <dt-bindings/clock/bcm6358-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/reset/bcm6358-reset.h>
+#include "skeleton.dtsi"
+
+/ {
+	compatible = "brcm,bcm6358";
+
+	cpus {
+		reg = <0xfffe0000 0x4>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		u-boot,dm-pre-reloc;
+
+		cpu@0 {
+			compatible = "brcm,bcm6358-cpu", "mips,mips4Kc";
+			device_type = "cpu";
+			reg = <0>;
+			u-boot,dm-pre-reloc;
+		};
+
+		cpu@1 {
+			compatible = "brcm,bcm6358-cpu", "mips,mips4Kc";
+			device_type = "cpu";
+			reg = <1>;
+			u-boot,dm-pre-reloc;
+		};
+	};
+
+	clocks {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		u-boot,dm-pre-reloc;
+
+		periph_osc: periph-osc {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <50000000>;
+			u-boot,dm-pre-reloc;
+		};
+
+		periph_clk: periph-clk {
+			compatible = "brcm,bcm6345-clk";
+			reg = <0xfffe0004 0x4>;
+			#clock-cells = <1>;
+		};
+	};
+
+	pflash: nor@1e000000 {
+		compatible = "cfi-flash";
+		reg = <0x1e000000 0x2000000>;
+		bank-width = <2>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		status = "disabled";
+	};
+
+	ubus {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		u-boot,dm-pre-reloc;
+
+		pll_cntl: syscon@fffe0008 {
+			compatible = "syscon";
+			reg = <0xfffe0008 0x4>;
+		};
+
+		syscon-reboot {
+			compatible = "syscon-reboot";
+			regmap = <&pll_cntl>;
+			offset = <0x0>;
+			mask = <0x1>;
+		};
+
+		periph_rst: reset-controller@fffe0034 {
+			compatible = "brcm,bcm6345-reset";
+			reg = <0xfffe0034 0x4>;
+			#reset-cells = <1>;
+		};
+
+		gpio1: gpio-controller@fffe0080 {
+			compatible = "brcm,bcm6345-gpio";
+			reg = <0xfffe0080 0x4>, <0xfffe0088 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			ngpios = <8>;
+
+			status = "disabled";
+		};
+
+		gpio0: gpio-controller@fffe0084 {
+			compatible = "brcm,bcm6345-gpio";
+			reg = <0xfffe0084 0x4>, <0xfffe008c 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			status = "disabled";
+		};
+
+		leds: led-controller@fffe00d0 {
+			compatible = "brcm,bcm6358-leds";
+			reg = <0xfffe00d0 0x8>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			status = "disabled";
+		};
+
+		uart0: serial@fffe0100 {
+			compatible = "brcm,bcm6345-uart";
+			reg = <0xfffe0100 0x18>;
+			clocks = <&periph_osc>;
+
+			status = "disabled";
+		};
+
+		uart1: serial@fffe0120 {
+			compatible = "brcm,bcm6345-uart";
+			reg = <0xfffe0120 0x18>;
+			clocks = <&periph_osc>;
+
+			status = "disabled";
+		};
+
+		memory-controller@fffe1200 {
+			compatible = "brcm,bcm6358-mc";
+			reg = <0xfffe1200 0x1000>;
+			u-boot,dm-pre-reloc;
+		};
+	};
+};
diff --git a/arch/mips/dts/comtrend,ar-5387un.dts b/arch/mips/dts/comtrend,ar-5387un.dts
new file mode 100644
index 0000000000000000000000000000000000000000..73f2b49b76c6607e5022b07476f341a008274a51
--- /dev/null
+++ b/arch/mips/dts/comtrend,ar-5387un.dts
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/dts-v1/;
+
+#include "brcm,bcm6328.dtsi"
+
+/ {
+	model = "Comtrend AR-5387un";
+	compatible = "comtrend,ar5387-un", "brcm,bcm6328";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&leds {
+	status = "okay";
+
+	led@1 {
+		reg = <1>;
+		label = "AR-5387un:red:inet";
+	};
+
+	led@4 {
+		reg = <4>;
+		label = "AR-5387un:red:power";
+	};
+
+	led@7 {
+		reg = <7>;
+		label = "AR-5387un:green:inet";
+	};
+
+	led@8 {
+		reg = <8>;
+		label = "AR-5387un:green:power";
+	};
+
+	led@11 {
+		reg = <11>;
+		active-low;
+		label = "AR-5387un:green:dsl";
+	};
+};
+
+&uart0 {
+	u-boot,dm-pre-reloc;
+	status = "okay";
+};
diff --git a/arch/mips/dts/comtrend,vr-3032u.dts b/arch/mips/dts/comtrend,vr-3032u.dts
new file mode 100644
index 0000000000000000000000000000000000000000..54e738c8210fd469e79bc59517ee7eb1b8785d69
--- /dev/null
+++ b/arch/mips/dts/comtrend,vr-3032u.dts
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/dts-v1/;
+
+#include "brcm,bcm63268.dtsi"
+
+/ {
+	model = "Comtrend VR-3032u";
+	compatible = "comtrend,vr-3032u", "brcm,bcm63268";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&leds {
+	status = "okay";
+	brcm,serial-leds;
+	brcm,serial-dat-low;
+	brcm,serial-shift-inv;
+
+	led@2 {
+		reg = <2>;
+		active-low;
+		label = "VR-3032u:red:inet";
+	};
+
+	led@3 {
+		reg = <3>;
+		active-low;
+		label = "VR-3032u:green:dsl";
+	};
+
+	led@4 {
+		reg = <4>;
+		active-low;
+		label = "VR-3032u:green:usb";
+	};
+
+	led@7 {
+		reg = <7>;
+		active-low;
+		label = "VR-3032u:green:wps";
+	};
+
+	led@8 {
+		reg = <8>;
+		active-low;
+		label = "VR-3032u:green:inet";
+	};
+
+	led@20 {
+		reg = <20>;
+		active-low;
+		label = "VR-3032u:green:power";
+	};
+};
+
+&uart0 {
+	u-boot,dm-pre-reloc;
+	status = "okay";
+};
diff --git a/arch/mips/dts/huawei,hg556a.dts b/arch/mips/dts/huawei,hg556a.dts
new file mode 100644
index 0000000000000000000000000000000000000000..31c7d7ed5ce5c1c286a331b772db0cd169709212
--- /dev/null
+++ b/arch/mips/dts/huawei,hg556a.dts
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/dts-v1/;
+
+#include "brcm,bcm6358.dtsi"
+
+/ {
+	model = "Huawei EchoLife HG556a";
+	compatible = "huawei,hg556a", "brcm,bcm6358";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+
+		message_red {
+			label = "HG556a:red:message";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+		};
+
+		hspa_red {
+			label = "HG556a:red:hspa";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+		};
+
+		dsl_red {
+			label = "HG556a:red:dsl";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+		};
+
+		power_red {
+			label = "HG556a:red:power";
+			gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
+		};
+
+		all_red {
+			label = "HG556a:red:all";
+			gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
+		};
+
+		lan1_green {
+			label = "HG556a:green:lan1";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		lan1_red {
+			label = "HG556a:red:lan1";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+
+		lan2_green {
+			label = "HG556a:green:lan2";
+			gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
+		};
+
+		lan2_red {
+			label = "HG556a:red:lan2";
+			gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
+		};
+
+		lan3_green {
+			label = "HG556a:green:lan3";
+			gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
+		};
+
+		lan3_red {
+			label = "HG556a:red:lan3";
+			gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
+		};
+
+		lan4_green {
+			label = "HG556a:green:lan4";
+			gpios = <&gpio0 27 GPIO_ACTIVE_LOW>;
+		};
+
+		lan4_red {
+			label = "HG556a:red:lan4";
+			gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&gpio0 {
+	status = "okay";
+};
+
+&pflash {
+	status = "okay";
+};
+
+&uart0 {
+	u-boot,dm-pre-reloc;
+	status = "okay";
+};
diff --git a/arch/mips/dts/sfr,nb4-ser.dts b/arch/mips/dts/sfr,nb4-ser.dts
new file mode 100644
index 0000000000000000000000000000000000000000..f2092e9f999f56480175227308b11dd95bf0dc13
--- /dev/null
+++ b/arch/mips/dts/sfr,nb4-ser.dts
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/dts-v1/;
+
+#include "brcm,bcm6358.dtsi"
+
+/ {
+	model = "SFR NeufBox 4 (Sercomm) Board";
+	compatible = "sfr,nb4-ser", "brcm,bcm6358";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+
+		traffic_white {
+			label = "NB4-SER:white:traffic";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+		};
+
+		service_blue {
+			label = "NB4-SER:blue:service";
+			gpios = <&gpio0 4 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi_white {
+			label = "NB4-SER:white:wifi";
+			gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
+		};
+
+		service_red {
+			label = "NB4-SER:red:service";
+			gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
+		};
+
+		service_green {
+			label = "NB4-SER:green:service";
+			gpios = <&gpio0 30 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&gpio0 {
+	status = "okay";
+};
+
+&leds {
+	status = "okay";
+	brcm,clk-div = <1>;
+
+	led@0 {
+		reg = <0>;
+		active-low;
+		label = "NB4-SER:white:alarm";
+	};
+
+	led@2 {
+		reg = <2>;
+		active-low;
+		label = "NB4-SER:white:tv";
+	};
+
+	led@3 {
+		reg = <3>;
+		active-low;
+		label = "NB4-SER:white:tel";
+	};
+
+	led@4 {
+		reg = <4>;
+		active-low;
+		label = "NB4-SER:white:adsl";
+	};
+};
+
+&pflash {
+	status = "okay";
+};
+
+&uart0 {
+	u-boot,dm-pre-reloc;
+	status = "okay";
+};
diff --git a/arch/mips/mach-bmips/Kconfig b/arch/mips/mach-bmips/Kconfig
new file mode 100644
index 0000000000000000000000000000000000000000..d1684486a85f7cb23ba217b12b74c22bc11a6536
--- /dev/null
+++ b/arch/mips/mach-bmips/Kconfig
@@ -0,0 +1,88 @@
+menu "Broadcom MIPS platforms"
+	depends on ARCH_BMIPS
+
+config SYS_SOC
+	default "bcm6328" if SOC_BMIPS_BCM6328
+	default "bcm6358" if SOC_BMIPS_BCM6358
+	default "bcm63268" if SOC_BMIPS_BCM63268
+
+choice
+	prompt "Broadcom MIPS SoC select"
+
+config SOC_BMIPS_BCM6328
+	bool "BMIPS BCM6328 family"
+	select SUPPORTS_BIG_ENDIAN
+	select SUPPORTS_CPU_MIPS32_R1
+	select MIPS_TUNE_4KC
+	select MIPS_L1_CACHE_SHIFT_4
+	select SWAP_IO_SPACE
+	select SYSRESET_SYSCON
+	help
+	  This supports BMIPS BCM6328 family including BCM63281 and BCM63283.
+
+config SOC_BMIPS_BCM6358
+	bool "BMIPS BCM6358 family"
+	select SUPPORTS_BIG_ENDIAN
+	select SUPPORTS_CPU_MIPS32_R1
+	select MIPS_TUNE_4KC
+	select MIPS_L1_CACHE_SHIFT_4
+	select SWAP_IO_SPACE
+	select SYSRESET_SYSCON
+	help
+	  This supports BMIPS BCM6358 family including BCM6358 and BCM6359.
+
+config SOC_BMIPS_BCM63268
+	bool "BMIPS BCM63268 family"
+	select SUPPORTS_BIG_ENDIAN
+	select SUPPORTS_CPU_MIPS32_R1
+	select MIPS_TUNE_4KC
+	select MIPS_L1_CACHE_SHIFT_4
+	select SWAP_IO_SPACE
+	select SYSRESET_SYSCON
+	help
+	  This supports BMIPS BCM63268 family including BCM63168, BCM63169,
+	  BCM63268 and BCM63269.
+
+endchoice
+
+choice
+	prompt "Board select"
+
+config BOARD_COMTREND_AR5387UN
+	bool "Comtrend AR-5387un"
+	depends on SOC_BMIPS_BCM6328
+	select BMIPS_SUPPORTS_BOOT_RAM
+
+config BOARD_COMTREND_VR3032U
+	bool "Comtrend VR-3032u board"
+	depends on SOC_BMIPS_BCM63268
+	select BMIPS_SUPPORTS_BOOT_RAM
+
+config BOARD_HUAWEI_HG556A
+	bool "Huawei EchoLife HG556a"
+	depends on SOC_BMIPS_BCM6358
+	select BMIPS_SUPPORTS_BOOT_RAM
+
+endchoice
+
+choice
+	prompt "Boot mode"
+
+config BMIPS_BOOT_RAM
+	bool "RAM boot"
+	depends on BMIPS_SUPPORTS_BOOT_RAM
+	help
+	  This builds an image that is linked to a RAM address. It can be used
+	  for booting from CFE via TFTP using an ELF image, but it can also be
+	  booted from RAM by other bootloaders using a BIN image.
+
+endchoice
+
+config BMIPS_SUPPORTS_BOOT_RAM
+	bool
+
+source "board/comtrend/ar5387un/Kconfig"
+source "board/comtrend/vr3032u/Kconfig"
+source "board/huawei/hg556a/Kconfig"
+
+endmenu
diff --git a/arch/mips/mach-bmips/Makefile b/arch/mips/mach-bmips/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..f432accb8288eeed6540cc5c629f4702a0f1afd4
--- /dev/null
+++ b/arch/mips/mach-bmips/Makefile
@@ -0,0 +1,5 @@
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y += dram.o
diff --git a/arch/mips/mach-bmips/dram.c b/arch/mips/mach-bmips/dram.c
new file mode 100644
index 0000000000000000000000000000000000000000..b19b28a91022cb13e266d18a19ab46b6af927584
--- /dev/null
+++ b/arch/mips/mach-bmips/dram.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2016 Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <ram.h>
+#include <dm.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+	struct ram_info ram;
+	struct udevice *dev;
+	int err;
+
+	err = uclass_get_device(UCLASS_RAM, 0, &dev);
+	if (err) {
+		debug("DRAM init failed: %d\n", err);
+		return 0;
+	}
+
+	err = ram_get_info(dev, &ram);
+	if (err) {
+		debug("Cannot get DRAM size: %d\n", err);
+		return 0;
+	}
+
+	debug("SDRAM base=%zx, size=%x\n", ram.base, ram.size);
+
+	gd->ram_size = ram.size;
+
+	return 0;
+}
diff --git a/arch/mips/mach-bmips/include/ioremap.h b/arch/mips/mach-bmips/include/ioremap.h
new file mode 100644
index 0000000000000000000000000000000000000000..404690e4db3ccd4838658573a06e8c821b9d7617
--- /dev/null
+++ b/arch/mips/mach-bmips/include/ioremap.h
@@ -0,0 +1,45 @@
+/*
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+#ifndef __ASM_MACH_BMIPS_IOREMAP_H
+#define __ASM_MACH_BMIPS_IOREMAP_H
+
+#include <linux/types.h>
+
+/*
+ * Allow physical addresses to be fixed up to help peripherals located
+ * outside the low 32-bit range -- generic pass-through version.
+ */
+static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr,
+						phys_addr_t size)
+{
+	return phys_addr;
+}
+
+static inline int is_bmips_internal_registers(phys_addr_t offset)
+{
+#if defined(CONFIG_SOC_BMIPS_BCM6358)
+	if (offset >= 0xfffe0000)
+		return 1;
+#endif
+
+	return 0;
+}
+
+static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size,
+						unsigned long flags)
+{
+	if (is_bmips_internal_registers(offset))
+		return (void __iomem *)offset;
+
+	return NULL;
+}
+
+static inline int plat_iounmap(const volatile void __iomem *addr)
+{
+	return is_bmips_internal_registers((unsigned long)addr);
+}
+
+#define _page_cachable_default	_CACHE_CACHABLE_NONCOHERENT
+
+#endif /* __ASM_MACH_BMIPS_IOREMAP_H */
diff --git a/board/comtrend/ar5387un/Kconfig b/board/comtrend/ar5387un/Kconfig
new file mode 100644
index 0000000000000000000000000000000000000000..45ab7e2844a12a37a0c32f5bd7177ba0e6c05093
--- /dev/null
+++ b/board/comtrend/ar5387un/Kconfig
@@ -0,0 +1,12 @@
+if BOARD_COMTREND_AR5387UN
+
+config SYS_BOARD
+	default "ar5387un"
+
+config SYS_VENDOR
+	default "comtrend"
+
+config SYS_CONFIG_NAME
+	default "comtrend_ar5387un"
+
+endif
diff --git a/board/comtrend/ar5387un/MAINTAINERS b/board/comtrend/ar5387un/MAINTAINERS
new file mode 100644
index 0000000000000000000000000000000000000000..bcaac64db09ba6c0e2255febe3aa58d46a333a55
--- /dev/null
+++ b/board/comtrend/ar5387un/MAINTAINERS
@@ -0,0 +1,6 @@
+COMTREND AR-5387UN BOARD
+M:	Álvaro Fernández Rojas <noltari@gmail.com>
+S:	Maintained
+F:	board/comtrend/ar-5387un/
+F:	include/configs/comtrend_ar5387un.h
+F:	configs/comtrend_ar5387un_ram_defconfig
diff --git a/board/comtrend/ar5387un/Makefile b/board/comtrend/ar5387un/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..9de1cd2ba2d42e19ac140a9a3bd8e58711cf2288
--- /dev/null
+++ b/board/comtrend/ar5387un/Makefile
@@ -0,0 +1,5 @@
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y += ar-5387un.o
diff --git a/board/comtrend/ar5387un/ar-5387un.c b/board/comtrend/ar5387un/ar-5387un.c
new file mode 100644
index 0000000000000000000000000000000000000000..d181ca68a04cc3a9d400605124acd7b3c273c512
--- /dev/null
+++ b/board/comtrend/ar5387un/ar-5387un.c
@@ -0,0 +1,7 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
diff --git a/board/comtrend/vr3032u/Kconfig b/board/comtrend/vr3032u/Kconfig
new file mode 100644
index 0000000000000000000000000000000000000000..6f552cf22a0e40490c6797655b7485959298ef63
--- /dev/null
+++ b/board/comtrend/vr3032u/Kconfig
@@ -0,0 +1,12 @@
+if BOARD_COMTREND_VR3032U
+
+config SYS_BOARD
+	default "vr3032u"
+
+config SYS_VENDOR
+	default "comtrend"
+
+config SYS_CONFIG_NAME
+	default "comtrend_vr3032u"
+
+endif
diff --git a/board/comtrend/vr3032u/MAINTAINERS b/board/comtrend/vr3032u/MAINTAINERS
new file mode 100644
index 0000000000000000000000000000000000000000..833d7da4afa7d11508d07a83fc2b1ff573e97176
--- /dev/null
+++ b/board/comtrend/vr3032u/MAINTAINERS
@@ -0,0 +1,6 @@
+COMTREND VR-3032U BOARD
+M:	Álvaro Fernández Rojas <noltari@gmail.com>
+S:	Maintained
+F:	board/comtrend/vr-3032u/
+F:	include/configs/comtrend_vr-3032u.h
+F:	configs/comtrend_vr3032u_ram_defconfig
diff --git a/board/comtrend/vr3032u/Makefile b/board/comtrend/vr3032u/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..9e6203132f5120c9f2f7f1416c81d4311f3f5706
--- /dev/null
+++ b/board/comtrend/vr3032u/Makefile
@@ -0,0 +1,5 @@
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y += vr-3032u.o
diff --git a/board/comtrend/vr3032u/vr-3032u.c b/board/comtrend/vr3032u/vr-3032u.c
new file mode 100644
index 0000000000000000000000000000000000000000..d181ca68a04cc3a9d400605124acd7b3c273c512
--- /dev/null
+++ b/board/comtrend/vr3032u/vr-3032u.c
@@ -0,0 +1,7 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
diff --git a/board/huawei/hg556a/Kconfig b/board/huawei/hg556a/Kconfig
new file mode 100644
index 0000000000000000000000000000000000000000..88622d0e681e1ebce3e8cf63e2b0668b6f38f491
--- /dev/null
+++ b/board/huawei/hg556a/Kconfig
@@ -0,0 +1,12 @@
+if BOARD_HUAWEI_HG556A
+
+config SYS_BOARD
+	default "hg556a"
+
+config SYS_VENDOR
+	default "huawei"
+
+config SYS_CONFIG_NAME
+	default "huawei_hg556a"
+
+endif
diff --git a/board/huawei/hg556a/MAINTAINERS b/board/huawei/hg556a/MAINTAINERS
new file mode 100644
index 0000000000000000000000000000000000000000..3ead7e4dd8a04a7a119afa46c39bc87f8caa1d9a
--- /dev/null
+++ b/board/huawei/hg556a/MAINTAINERS
@@ -0,0 +1,6 @@
+HUAWEI HG556A BOARD
+M:	Álvaro Fernández Rojas <noltari@gmail.com>
+S:	Maintained
+F:	board/huawei/hg556a/
+F:	include/configs/huawei_hg556a.h
+F:	configs/huawei_hg556a_ram_defconfig
diff --git a/board/huawei/hg556a/Makefile b/board/huawei/hg556a/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..ace0ed3efd9c54248bf203a14e29948ccd3b8ef5
--- /dev/null
+++ b/board/huawei/hg556a/Makefile
@@ -0,0 +1,5 @@
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y += hg556a.o
diff --git a/board/huawei/hg556a/hg556a.c b/board/huawei/hg556a/hg556a.c
new file mode 100644
index 0000000000000000000000000000000000000000..d181ca68a04cc3a9d400605124acd7b3c273c512
--- /dev/null
+++ b/board/huawei/hg556a/hg556a.c
@@ -0,0 +1,7 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
diff --git a/board/qca/ap121/ap121.c b/board/qca/ap121/ap121.c
index e245faa5cf86039c0843be9411c52e55bc310920..ac9be35dd9b9ba4926a1379d0d8bba2a03c45a6f 100644
--- a/board/qca/ap121/ap121.c
+++ b/board/qca/ap121/ap121.c
@@ -43,9 +43,6 @@ void board_debug_uart_init(void)
 
 int board_early_init_f(void)
 {
-#ifdef CONFIG_DEBUG_UART
-	debug_uart_init();
-#endif
 	ddr_init();
 	ath79_eth_reset();
 	return 0;
diff --git a/board/qca/ap143/ap143.c b/board/qca/ap143/ap143.c
index e921ea53f340c73d61c9795b58e5946b7bbbfa9b..19b55acbf2d0b90b5bcaee91de11dab35b53df29 100644
--- a/board/qca/ap143/ap143.c
+++ b/board/qca/ap143/ap143.c
@@ -59,9 +59,6 @@ void board_debug_uart_init(void)
 
 int board_early_init_f(void)
 {
-#ifdef CONFIG_DEBUG_UART
-	debug_uart_init();
-#endif
 	ddr_init();
 	ath79_eth_reset();
 	return 0;
diff --git a/board/sfr/nb4_ser/Kconfig b/board/sfr/nb4_ser/Kconfig
new file mode 100644
index 0000000000000000000000000000000000000000..78aefb547f049542e02a498814b25f090b862396
--- /dev/null
+++ b/board/sfr/nb4_ser/Kconfig
@@ -0,0 +1,12 @@
+if BOARD_SFR_NB4_SER
+
+config SYS_BOARD
+	default "nb4_ser"
+
+config SYS_VENDOR
+	default "sfr"
+
+config SYS_CONFIG_NAME
+	default "sfr_nb4_ser"
+
+endif
diff --git a/board/sfr/nb4_ser/MAINTAINERS b/board/sfr/nb4_ser/MAINTAINERS
new file mode 100644
index 0000000000000000000000000000000000000000..bf80267f046b64cfb171770de33e32057c041583
--- /dev/null
+++ b/board/sfr/nb4_ser/MAINTAINERS
@@ -0,0 +1,6 @@
+SFR NEUFBOX 4 SERCOMM BOARD
+M:	Álvaro Fernández Rojas <noltari@gmail.com>
+S:	Maintained
+F:	board/sfr/nb4_ser/
+F:	include/configs/sfr_nb4_ser.h
+F:	configs/sfr_nb4-ser_ram_defconfig
diff --git a/board/sfr/nb4_ser/Makefile b/board/sfr/nb4_ser/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..f3b1404f7c5029bd4a775ed7468e4f445450dc2a
--- /dev/null
+++ b/board/sfr/nb4_ser/Makefile
@@ -0,0 +1,5 @@
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y += nb4-ser.o
diff --git a/board/sfr/nb4_ser/nb4-ser.c b/board/sfr/nb4_ser/nb4-ser.c
new file mode 100644
index 0000000000000000000000000000000000000000..d181ca68a04cc3a9d400605124acd7b3c273c512
--- /dev/null
+++ b/board/sfr/nb4_ser/nb4-ser.c
@@ -0,0 +1,7 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
diff --git a/board/tplink/wdr4300/wdr4300.c b/board/tplink/wdr4300/wdr4300.c
index 6e070fd55803bea739c006f9e50d3949d789cab6..0f59648b1fed192a2b1f70ead69df663f58d6556 100644
--- a/board/tplink/wdr4300/wdr4300.c
+++ b/board/tplink/wdr4300/wdr4300.c
@@ -34,8 +34,7 @@ static void wdr4300_usb_start(void)
 static inline void wdr4300_usb_start(void) {}
 #endif
 
-#ifdef CONFIG_BOARD_EARLY_INIT_F
-int board_early_init_f(void)
+void wdr4300_pinmux_config(void)
 {
 	void __iomem *regs;
 
@@ -56,9 +55,20 @@ int board_early_init_f(void)
 	writel(0x00000000, regs + AR934X_GPIO_REG_OUT_FUNC3);
 	writel(0x0000004d, regs + AR934X_GPIO_REG_OUT_FUNC4);
 	writel(0x00000000, regs + AR934X_GPIO_REG_OUT_FUNC5);
+}
+
+#ifdef CONFIG_DEBUG_UART_BOARD_INIT
+void board_debug_uart_init(void)
+{
+	wdr4300_pinmux_config();
+}
+#endif
 
-#ifdef CONFIG_DEBUG_UART
-	debug_uart_init();
+#ifdef CONFIG_BOARD_EARLY_INIT_F
+int board_early_init_f(void)
+{
+#ifndef CONFIG_DEBUG_UART_BOARD_INIT
+	wdr4300_pinmux_config();
 #endif
 
 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
diff --git a/cmd/cpu.c b/cmd/cpu.c
index bc4dc5c529b87565c36c7d289e47a7e9533edfd4..6213c720cbf472371fd722f5e56673291f84693d 100644
--- a/cmd/cpu.c
+++ b/cmd/cpu.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2015 Google, Inc
  * Written by Simon Glass <sjg@chromium.org>
+ * Copyright (c) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
@@ -15,25 +16,21 @@ static const char *cpu_feature_name[CPU_FEAT_COUNT] = {
 	"L1 cache",
 	"MMU",
 	"Microcode",
+	"Device ID",
 };
 
 static int print_cpu_list(bool detail)
 {
 	struct udevice *dev;
-	struct uclass *uc;
 	char buf[100];
-	int ret;
 
-	ret = uclass_get(UCLASS_CPU, &uc);
-	if (ret) {
-		printf("Cannot find CPU uclass\n");
-		return ret;
-	}
-	uclass_foreach_dev(dev, uc) {
+	for (uclass_first_device(UCLASS_CPU, &dev);
+		     dev;
+		     uclass_next_device(&dev)) {
 		struct cpu_platdata *plat = dev_get_parent_platdata(dev);
 		struct cpu_info info;
-		bool first;
-		int i;
+		bool first = true;
+		int ret, i;
 
 		ret = cpu_get_desc(dev, buf, sizeof(buf));
 		printf("%3d: %-10s %s\n", dev->seq, dev->name,
@@ -44,13 +41,12 @@ static int print_cpu_list(bool detail)
 		if (ret) {
 			printf("\t(no detail available");
 			if (ret != -ENOSYS)
-				printf(": err=%d\n", ret);
+				printf(": err=%d", ret);
 			printf(")\n");
 			continue;
 		}
 		printf("\tID = %d, freq = ", plat->cpu_id);
 		print_freq(info.cpu_freq, "");
-		first = true;
 		for (i = 0; i < CPU_FEAT_COUNT; i++) {
 			if (info.features & (1 << i)) {
 				printf("%s%s", first ? ": " : ", ",
@@ -59,10 +55,9 @@ static int print_cpu_list(bool detail)
 			}
 		}
 		printf("\n");
-		if (info.features & (1 << CPU_FEAT_UCODE)) {
+		if (info.features & (1 << CPU_FEAT_UCODE))
 			printf("\tMicrocode version %#x\n",
 			       plat->ucode_version);
-		}
 		if (info.features & (1 << CPU_FEAT_DEVICE_ID))
 			printf("\tDevice ID %#lx\n", plat->device_id);
 	}
@@ -70,7 +65,8 @@ static int print_cpu_list(bool detail)
 	return 0;
 }
 
-static int do_cpu_list(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+static int do_cpu_list(cmd_tbl_t *cmdtp, int flag, int argc,
+		       char *const argv[])
 {
 	if (print_cpu_list(false))
 		return CMD_RET_FAILURE;
@@ -96,7 +92,7 @@ static cmd_tbl_t cmd_cpu_sub[] = {
  * Process a cpu sub-command
  */
 static int do_cpu(cmd_tbl_t *cmdtp, int flag, int argc,
-		       char * const argv[])
+		  char * const argv[])
 {
 	cmd_tbl_t *c = NULL;
 
@@ -105,7 +101,8 @@ static int do_cpu(cmd_tbl_t *cmdtp, int flag, int argc,
 	argv++;
 
 	if (argc)
-		c = find_cmd_tbl(argv[0], cmd_cpu_sub, ARRAY_SIZE(cmd_cpu_sub));
+		c = find_cmd_tbl(argv[0], cmd_cpu_sub,
+				 ARRAY_SIZE(cmd_cpu_sub));
 
 	if (c)
 		return c->cmd(cmdtp, flag, argc, argv);
diff --git a/configs/comtrend_ar5387un_ram_defconfig b/configs/comtrend_ar5387un_ram_defconfig
new file mode 100644
index 0000000000000000000000000000000000000000..5b05fd20d78a9fbdebee30fbe7a2072f9077698e
--- /dev/null
+++ b/configs/comtrend_ar5387un_ram_defconfig
@@ -0,0 +1,54 @@
+CONFIG_ARCH_BMIPS=y
+CONFIG_BAUDRATE=115200
+CONFIG_BCM6328_POWER_DOMAIN=y
+CONFIG_BCM6345_CLK=y
+CONFIG_BCM6345_SERIAL=y
+CONFIG_BMIPS_BOOT_RAM=y
+CONFIG_BOARD_COMTREND_AR5387UN=y
+# CONFIG_CMD_BOOTD is not set
+CONFIG_CMD_BOOTM=y
+CONFIG_CMD_CPU=y
+# CONFIG_CMD_CRC32 is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_ENV_EXISTS is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set
+# CONFIG_CMD_GPIO is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_IMPORTENV is not set
+CONFIG_CMD_LED=y
+CONFIG_CMD_LICENSE=y
+CONFIG_CMD_LOADB=y
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MEMINFO=y
+# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_NET is not set
+# CONFIG_CMD_NFS is not set
+# CONFIG_CMD_SAVEENV is not set
+# CONFIG_CMD_XIMG is not set
+CONFIG_DEFAULT_DEVICE_TREE="comtrend,ar-5387un"
+CONFIG_DISPLAY_CPUINFO=y
+# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_DM_GPIO=y
+CONFIG_DM_RESET=y
+CONFIG_DM_SERIAL=y
+CONFIG_HUSH_PARSER=y
+CONFIG_LED=y
+CONFIG_LED_BCM6328=y
+CONFIG_LED_BLINK=y
+CONFIG_MIPS=y
+# CONFIG_MIPS_BOOT_CMDLINE_LEGACY is not set
+# CONFIG_MIPS_BOOT_ENV_LEGACY is not set
+CONFIG_MIPS_BOOT_FDT=y
+CONFIG_OF_STDOUT_VIA_ALIAS=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_RESET=y
+CONFIG_RESET_BCM6345=y
+CONFIG_SOC_BMIPS_BCM6328=y
+# CONFIG_SPL_SERIAL_PRESENT is not set
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SYS_NO_FLASH=y
+CONFIG_SYS_PROMPT="AR-5387un # "
+CONFIG_SYS_TEXT_BASE=0x80010000
diff --git a/configs/comtrend_vr3032u_ram_defconfig b/configs/comtrend_vr3032u_ram_defconfig
new file mode 100644
index 0000000000000000000000000000000000000000..c056d73f18b5d5db646d7081e724e98aea9fb84e
--- /dev/null
+++ b/configs/comtrend_vr3032u_ram_defconfig
@@ -0,0 +1,54 @@
+CONFIG_ARCH_BMIPS=y
+CONFIG_BAUDRATE=115200
+CONFIG_BCM6328_POWER_DOMAIN=y
+CONFIG_BCM6345_CLK=y
+CONFIG_BCM6345_SERIAL=y
+CONFIG_BMIPS_BOOT_RAM=y
+CONFIG_BOARD_COMTREND_VR3032U=y
+# CONFIG_CMD_BOOTD is not set
+CONFIG_CMD_BOOTM=y
+CONFIG_CMD_CPU=y
+# CONFIG_CMD_CRC32 is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_ENV_EXISTS is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set
+# CONFIG_CMD_GPIO is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_IMPORTENV is not set
+CONFIG_CMD_LED=y
+CONFIG_CMD_LICENSE=y
+CONFIG_CMD_LOADB=y
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MEMINFO=y
+# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_NET is not set
+# CONFIG_CMD_NFS is not set
+# CONFIG_CMD_SAVEENV is not set
+# CONFIG_CMD_XIMG is not set
+CONFIG_DEFAULT_DEVICE_TREE="comtrend,vr-3032u"
+CONFIG_DISPLAY_CPUINFO=y
+# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_DM_GPIO=y
+CONFIG_DM_RESET=y
+CONFIG_DM_SERIAL=y
+CONFIG_HUSH_PARSER=y
+CONFIG_LED=y
+CONFIG_LED_BCM6328=y
+CONFIG_LED_BLINK=y
+CONFIG_MIPS=y
+# CONFIG_MIPS_BOOT_CMDLINE_LEGACY is not set
+# CONFIG_MIPS_BOOT_ENV_LEGACY is not set
+CONFIG_MIPS_BOOT_FDT=y
+CONFIG_OF_STDOUT_VIA_ALIAS=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_RESET=y
+CONFIG_RESET_BCM6345=y
+CONFIG_SOC_BMIPS_BCM63268=y
+# CONFIG_SPL_SERIAL_PRESENT is not set
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SYS_NO_FLASH=y
+CONFIG_SYS_PROMPT="VR-3032u # "
+CONFIG_SYS_TEXT_BASE=0x80010000
diff --git a/configs/huawei_hg556a_ram_defconfig b/configs/huawei_hg556a_ram_defconfig
new file mode 100644
index 0000000000000000000000000000000000000000..c2e64723c326f645b8504a25c3c073d503780813
--- /dev/null
+++ b/configs/huawei_hg556a_ram_defconfig
@@ -0,0 +1,55 @@
+CONFIG_ARCH_BMIPS=y
+CONFIG_BAUDRATE=115200
+CONFIG_BCM6345_CLK=y
+CONFIG_BCM6345_GPIO=y
+CONFIG_BCM6345_SERIAL=y
+CONFIG_BMIPS_BOOT_RAM=y
+CONFIG_BOARD_HUAWEI_HG556A=y
+CONFIG_CFI_FLASH=y
+# CONFIG_CMD_BOOTD is not set
+CONFIG_CMD_BOOTM=y
+CONFIG_CMD_CPU=y
+# CONFIG_CMD_CRC32 is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_ENV_EXISTS is not set
+# CONFIG_CMD_EXPORTENV is not set
+CONFIG_CMD_FLASH=y
+# CONFIG_CMD_FPGA is not set
+# CONFIG_CMD_GPIO is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_IMPORTENV is not set
+CONFIG_CMD_LED=y
+CONFIG_CMD_LICENSE=y
+CONFIG_CMD_LOADB=y
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MEMINFO=y
+# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_NET is not set
+# CONFIG_CMD_NFS is not set
+# CONFIG_CMD_SAVEENV is not set
+# CONFIG_CMD_XIMG is not set
+CONFIG_DEFAULT_DEVICE_TREE="huawei,hg556a"
+CONFIG_DISPLAY_CPUINFO=y
+# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_DM_GPIO=y
+CONFIG_DM_RESET=y
+CONFIG_DM_SERIAL=y
+CONFIG_HUSH_PARSER=y
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_MIPS=y
+# CONFIG_MIPS_BOOT_CMDLINE_LEGACY is not set
+# CONFIG_MIPS_BOOT_ENV_LEGACY is not set
+CONFIG_MIPS_BOOT_FDT=y
+CONFIG_MTD=y
+CONFIG_MTD_DEVICE=y
+CONFIG_MTD_NOR_FLASH=y
+CONFIG_OF_STDOUT_VIA_ALIAS=y
+CONFIG_RESET=y
+CONFIG_RESET_BCM6345=y
+CONFIG_SOC_BMIPS_BCM6358=y
+# CONFIG_SPL_SERIAL_PRESENT is not set
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SYS_PROMPT="HG556a # "
+CONFIG_SYS_TEXT_BASE=0x80010000
diff --git a/configs/sfr_nb4-ser_ram_defconfig b/configs/sfr_nb4-ser_ram_defconfig
new file mode 100644
index 0000000000000000000000000000000000000000..d7c83297317d5abc8a786127230eaca05a64662e
--- /dev/null
+++ b/configs/sfr_nb4-ser_ram_defconfig
@@ -0,0 +1,56 @@
+CONFIG_ARCH_BMIPS=y
+CONFIG_BAUDRATE=115200
+CONFIG_BCM6345_CLK=y
+CONFIG_BCM6345_GPIO=y
+CONFIG_BCM6345_SERIAL=y
+CONFIG_BMIPS_BOOT_RAM=y
+CONFIG_BOARD_SFR_NB4_SER=y
+CONFIG_CFI_FLASH=y
+# CONFIG_CMD_BOOTD is not set
+CONFIG_CMD_BOOTM=y
+CONFIG_CMD_CPU=y
+# CONFIG_CMD_CRC32 is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_ENV_EXISTS is not set
+# CONFIG_CMD_EXPORTENV is not set
+CONFIG_CMD_FLASH=y
+# CONFIG_CMD_FPGA is not set
+# CONFIG_CMD_GPIO is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_IMPORTENV is not set
+CONFIG_CMD_LED=y
+CONFIG_CMD_LICENSE=y
+CONFIG_CMD_LOADB=y
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MEMINFO=y
+# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_NET is not set
+# CONFIG_CMD_NFS is not set
+# CONFIG_CMD_SAVEENV is not set
+# CONFIG_CMD_XIMG is not set
+CONFIG_DEFAULT_DEVICE_TREE="sfr,nb4-ser"
+CONFIG_DISPLAY_CPUINFO=y
+# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_DM_GPIO=y
+CONFIG_DM_RESET=y
+CONFIG_DM_SERIAL=y
+CONFIG_HUSH_PARSER=y
+CONFIG_LED=y
+CONFIG_LED_BCM6358=y
+CONFIG_LED_GPIO=y
+CONFIG_MIPS=y
+# CONFIG_MIPS_BOOT_CMDLINE_LEGACY is not set
+# CONFIG_MIPS_BOOT_ENV_LEGACY is not set
+CONFIG_MIPS_BOOT_FDT=y
+CONFIG_MTD=y
+CONFIG_MTD_DEVICE=y
+CONFIG_MTD_NOR_FLASH=y
+CONFIG_OF_STDOUT_VIA_ALIAS=y
+CONFIG_RESET=y
+CONFIG_RESET_BCM6345=y
+CONFIG_SOC_BMIPS_BCM6358=y
+# CONFIG_SPL_SERIAL_PRESENT is not set
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SYS_PROMPT="NB4-SER # "
+CONFIG_SYS_TEXT_BASE=0x80010000
diff --git a/doc/device-tree-bindings/leds/leds-bcm6328.txt b/doc/device-tree-bindings/leds/leds-bcm6328.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7f5597b73731ea97ef4a459b86c653d47b427e7a
--- /dev/null
+++ b/doc/device-tree-bindings/leds/leds-bcm6328.txt
@@ -0,0 +1,106 @@
+LEDs connected to Broadcom BCM6328 controller
+
+This controller is present on BCM6318, BCM6328, BCM6362 and BCM63268.
+In these SoCs it's possible to control LEDs both as GPIOs or by hardware.
+However, on some devices there are Serial LEDs (LEDs connected to a 74x164
+controller), which can either be controlled by software (exporting the 74x164
+as spi-gpio. See Documentation/devicetree/bindings/gpio/gpio-74x164.txt), or
+by hardware using this driver.
+Some of these Serial LEDs are hardware controlled (e.g. ethernet LEDs) and
+exporting the 74x164 as spi-gpio prevents those LEDs to be hardware
+controlled, so the only chance to keep them working is by using this driver.
+
+Required properties:
+  - compatible : should be "brcm,bcm6328-leds".
+  - #address-cells : must be 1.
+  - #size-cells : must be 0.
+  - reg : BCM6328 LED controller address and size.
+
+Optional properties:
+  - brcm,serial-leds : Boolean, enables Serial LEDs.
+    Default : false
+  - brcm,serial-mux : Boolean, enables Serial LEDs multiplexing.
+    Default : false
+  - brcm,serial-clk-low : Boolean, makes clock signal active low.
+    Default : false
+  - brcm,serial-dat-low : Boolean, makes data signal active low.
+    Default : false
+  - brcm,serial-shift-inv : Boolean, inverts Serial LEDs shift direction.
+    Default : false
+
+Each LED is represented as a sub-node of the brcm,bcm6328-leds device.
+
+LED sub-node required properties:
+  - reg : LED pin number (only LEDs 0 to 23 are valid).
+
+LED sub-node optional properties:
+  - label : see Documentation/devicetree/bindings/leds/common.txt
+  - active-low : Boolean, makes LED active low.
+    Default : false
+
+Examples:
+Scenario 1 : BCM6328 with 4 GPIO LEDs
+	leds0: led-controller@10000800 {
+		compatible = "brcm,bcm6328-leds";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x10000800 0x24>;
+
+		alarm_red@2 {
+			reg = <2>;
+			active-low;
+			label = "red:alarm";
+		};
+		inet_green@3 {
+			reg = <3>;
+			active-low;
+			label = "green:inet";
+		};
+		power_green@4 {
+			reg = <4>;
+			active-low;
+			label = "green:power";
+		};
+	};
+
+Scenario 2 : BCM63268 with Serial LEDs
+	leds0: led-controller@10001900 {
+		compatible = "brcm,bcm6328-leds";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x10001900 0x24>;
+		brcm,serial-leds;
+		brcm,serial-dat-low;
+		brcm,serial-shift-inv;
+
+		inet_red@2 {
+			reg = <2>;
+			active-low;
+			label = "red:inet";
+		};
+		dsl_green@3 {
+			reg = <3>;
+			active-low;
+			label = "green:dsl";
+		};
+		usb_green@4 {
+			reg = <4>;
+			active-low;
+			label = "green:usb";
+		};
+		wps_green@7 {
+			reg = <7>;
+			active-low;
+			label = "green:wps";
+		};
+		inet_green@8 {
+			reg = <8>;
+			active-low;
+			label = "green:inet";
+		};
+		power_green@20 {
+			reg = <20>;
+			active-low;
+			label = "green:power";
+		};
+	};
diff --git a/doc/device-tree-bindings/leds/leds-bcm6358.txt b/doc/device-tree-bindings/leds/leds-bcm6358.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e394d9ebb40d64e49a157791fd8e1ada233aada3
--- /dev/null
+++ b/doc/device-tree-bindings/leds/leds-bcm6358.txt
@@ -0,0 +1,141 @@
+LEDs connected to Broadcom BCM6358 controller
+
+This controller is present on BCM6358 and BCM6368.
+In these SoCs there are Serial LEDs (LEDs connected to a 74x164 controller),
+which can either be controlled by software (exporting the 74x164 as spi-gpio.
+See Documentation/devicetree/bindings/gpio/gpio-74x164.txt), or
+by hardware using this driver.
+
+Required properties:
+  - compatible : should be "brcm,bcm6358-leds".
+  - #address-cells : must be 1.
+  - #size-cells : must be 0.
+  - reg : BCM6358 LED controller address and size.
+
+Optional properties:
+  - brcm,clk-div : SCK signal divider. Possible values are 1, 2, 4 and 8.
+    Default : 1
+  - brcm,clk-dat-low : Boolean, makes clock and data signals active low.
+    Default : false
+
+Each LED is represented as a sub-node of the brcm,bcm6358-leds device.
+
+LED sub-node required properties:
+  - reg : LED pin number (only LEDs 0 to 31 are valid).
+
+LED sub-node optional properties:
+  - label : see Documentation/devicetree/bindings/leds/common.txt
+  - active-low : Boolean, makes LED active low.
+    Default : false
+
+Examples:
+Scenario 1 : BCM6358
+	leds0: led-controller@fffe00d0 {
+		compatible = "brcm,bcm6358-leds";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0xfffe00d0 0x8>;
+
+		alarm_white {
+			reg = <0>;
+			active-low;
+			label = "white:alarm";
+		};
+		tv_white {
+			reg = <2>;
+			active-low;
+			label = "white:tv";
+		};
+		tel_white {
+			reg = <3>;
+			active-low;
+			label = "white:tel";
+		};
+		adsl_white {
+			reg = <4>;
+			active-low;
+			label = "white:adsl";
+		};
+	};
+
+Scenario 2 : BCM6368
+	leds0: led-controller@100000d0 {
+		compatible = "brcm,bcm6358-leds";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x100000d0 0x8>;
+		brcm,pol-low;
+		brcm,clk-div = <4>;
+
+		power_red {
+			reg = <0>;
+			active-low;
+			label = "red:power";
+		};
+		power_green {
+			reg = <1>;
+			active-low;
+			label = "green:power";
+			default-state = "on";
+		};
+		power_blue {
+			reg = <2>;
+			label = "blue:power";
+		};
+		broadband_red {
+			reg = <3>;
+			active-low;
+			label = "red:broadband";
+		};
+		broadband_green {
+			reg = <4>;
+			label = "green:broadband";
+		};
+		broadband_blue {
+			reg = <5>;
+			active-low;
+			label = "blue:broadband";
+		};
+		wireless_red {
+			reg = <6>;
+			active-low;
+			label = "red:wireless";
+		};
+		wireless_green {
+			reg = <7>;
+			active-low;
+			label = "green:wireless";
+		};
+		wireless_blue {
+			reg = <8>;
+			label = "blue:wireless";
+		};
+		phone_red {
+			reg = <9>;
+			active-low;
+			label = "red:phone";
+		};
+		phone_green {
+			reg = <10>;
+			active-low;
+			label = "green:phone";
+		};
+		phone_blue {
+			reg = <11>;
+			label = "blue:phone";
+		};
+		upgrading_red {
+			reg = <12>;
+			active-low;
+			label = "red:upgrading";
+		};
+		upgrading_green {
+			reg = <13>;
+			active-low;
+			label = "green:upgrading";
+		};
+		upgrading_blue {
+			reg = <14>;
+			label = "blue:upgrading";
+		};
+	};
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 5ca958c0075db9ca235786c0d06ca3173cfd8bf3..44da716b2679246555d1684b02590effa9d5cde5 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -20,6 +20,14 @@ config SPL_CLK
 	  setting up clocks within SPL, and allows the same drivers to be
 	  used as U-Boot proper.
 
+config CLK_BCM6345
+	bool "Clock controller driver for BCM6345"
+	depends on CLK && ARCH_BMIPS
+	default y
+	help
+	  This clock driver adds support for enabling and disabling peripheral
+	  clocks on BCM6345 SoCs. HW has no rate changing capabilities.
+
 config CLK_BOSTON
 	def_bool y if TARGET_BOSTON
 	depends on CLK
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 01a8cd641e7f5b129917f7ca6cacf23be3b24da7..2746a8016abdde2a770b813a3ed022279f302c19 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -17,6 +17,7 @@ obj-y += tegra/
 obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
 obj-$(CONFIG_CLK_EXYNOS) += exynos/
 obj-$(CONFIG_CLK_AT91) += at91/
+obj-$(CONFIG_CLK_BCM6345) += clk_bcm6345.o
 obj-$(CONFIG_CLK_BOSTON) += clk_boston.o
 obj-$(CONFIG_ARCH_ASPEED) += aspeed/
 obj-$(CONFIG_STM32F7) += clk_stm32f7.o
diff --git a/drivers/clk/clk_bcm6345.c b/drivers/clk/clk_bcm6345.c
new file mode 100644
index 0000000000000000000000000000000000000000..4c7a2dfb70b380a6f28e1bdb96c64f253429cf8b
--- /dev/null
+++ b/drivers/clk/clk_bcm6345.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/arch/mips/bcm63xx/clk.c:
+ *	Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/io.h>
+
+#define MAX_CLKS	32
+
+struct bcm6345_clk_priv {
+	void __iomem *regs;
+};
+
+static int bcm6345_clk_enable(struct clk *clk)
+{
+	struct bcm6345_clk_priv *priv = dev_get_priv(clk->dev);
+
+	if (clk->id >= MAX_CLKS)
+		return -EINVAL;
+
+	setbits_be32(priv->regs, BIT(clk->id));
+
+	return 0;
+}
+
+static int bcm6345_clk_disable(struct clk *clk)
+{
+	struct bcm6345_clk_priv *priv = dev_get_priv(clk->dev);
+
+	if (clk->id >= MAX_CLKS)
+		return -EINVAL;
+
+	clrbits_be32(priv->regs, BIT(clk->id));
+
+	return 0;
+}
+
+static struct clk_ops bcm6345_clk_ops = {
+	.disable = bcm6345_clk_disable,
+	.enable = bcm6345_clk_enable,
+};
+
+static const struct udevice_id bcm6345_clk_ids[] = {
+	{ .compatible = "brcm,bcm6345-clk" },
+	{ /* sentinel */ }
+};
+
+static int bcm63xx_clk_probe(struct udevice *dev)
+{
+	struct bcm6345_clk_priv *priv = dev_get_priv(dev);
+	fdt_addr_t addr;
+	fdt_size_t size;
+
+	addr = dev_get_addr_size_index(dev, 0, &size);
+	if (addr == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	priv->regs = ioremap(addr, size);
+
+	return 0;
+}
+
+U_BOOT_DRIVER(clk_bcm6345) = {
+	.name = "clk_bcm6345",
+	.id = UCLASS_CLK,
+	.of_match = bcm6345_clk_ids,
+	.ops = &bcm6345_clk_ops,
+	.probe = bcm63xx_clk_probe,
+	.priv_auto_alloc_size = sizeof(struct bcm6345_clk_priv),
+};
diff --git a/drivers/cpu/Makefile b/drivers/cpu/Makefile
index 871016030f8826c6ca6fb35f2228fe542c049ad7..db515f6f177c886096631d48f3f29c10070a9a83 100644
--- a/drivers/cpu/Makefile
+++ b/drivers/cpu/Makefile
@@ -5,3 +5,5 @@
 # SPDX-License-Identifier:      GPL-2.0+
 #
 obj-$(CONFIG_CPU) += cpu-uclass.o
+
+obj-$(CONFIG_ARCH_BMIPS) += bmips_cpu.o
diff --git a/drivers/cpu/bmips_cpu.c b/drivers/cpu/bmips_cpu.c
new file mode 100644
index 0000000000000000000000000000000000000000..379acf2d5560fd7326d09c0fb366db86dc5c430d
--- /dev/null
+++ b/drivers/cpu/bmips_cpu.c
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/arch/mips/bcm63xx/cpu.c:
+ *	Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ *	Copyright (C) 2009 Florian Fainelli <florian@openwrt.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <cpu.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/io.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define REV_CHIPID_SHIFT		16
+#define REV_CHIPID_MASK			(0xffff << REV_CHIPID_SHIFT)
+#define REV_LONG_CHIPID_SHIFT		12
+#define REV_LONG_CHIPID_MASK		(0xfffff << REV_LONG_CHIPID_SHIFT)
+#define REV_REVID_SHIFT			0
+#define REV_REVID_MASK			(0xff << REV_REVID_SHIFT)
+
+#define REG_BCM6328_OTP			0x62c
+#define BCM6328_TP1_DISABLED		BIT(9)
+
+#define REG_BCM6328_MISC_STRAPBUS	0x1a40
+#define STRAPBUS_6328_FCVO_SHIFT	7
+#define STRAPBUS_6328_FCVO_MASK		(0x1f << STRAPBUS_6328_FCVO_SHIFT)
+
+#define REG_BCM6358_DDR_DMIPSPLLCFG	0x12b8
+#define DMIPSPLLCFG_6358_M1_SHIFT	0
+#define DMIPSPLLCFG_6358_M1_MASK	(0xff << DMIPSPLLCFG_6358_M1_SHIFT)
+#define DMIPSPLLCFG_6358_N1_SHIFT	23
+#define DMIPSPLLCFG_6358_N1_MASK	(0x3f << DMIPSPLLCFG_6358_N1_SHIFT)
+#define DMIPSPLLCFG_6358_N2_SHIFT	29
+#define DMIPSPLLCFG_6358_N2_MASK	(0x7 << DMIPSPLLCFG_6358_N2_SHIFT)
+
+#define REG_BCM63268_MISC_STRAPBUS	0x1814
+#define STRAPBUS_63268_FCVO_SHIFT	21
+#define STRAPBUS_63268_FCVO_MASK	(0xf << STRAPBUS_63268_FCVO_SHIFT)
+
+struct bmips_cpu_priv;
+
+struct bmips_cpu_hw {
+	int (*get_cpu_desc)(struct bmips_cpu_priv *priv, char *buf, int size);
+	ulong (*get_cpu_freq)(struct bmips_cpu_priv *);
+	int (*get_cpu_count)(struct bmips_cpu_priv *);
+};
+
+struct bmips_cpu_priv {
+	void __iomem *regs;
+	const struct bmips_cpu_hw *hw;
+};
+
+/* Specific CPU Ops */
+static int bcm6358_get_cpu_desc(struct bmips_cpu_priv *priv, char *buf,
+				int size)
+{
+	unsigned short cpu_id;
+	unsigned char cpu_rev;
+	u32 val;
+
+	val = readl_be(priv->regs);
+	cpu_id = (val & REV_CHIPID_MASK) >> REV_CHIPID_SHIFT;
+	cpu_rev = (val & REV_REVID_MASK) >> REV_REVID_SHIFT;
+
+	snprintf(buf, size, "BCM%04X%02X", cpu_id, cpu_rev);
+
+	return 0;
+}
+
+static int bcm6328_get_cpu_desc(struct bmips_cpu_priv *priv, char *buf,
+				int size)
+{
+	unsigned int cpu_id;
+	unsigned char cpu_rev;
+	u32 val;
+
+	val = readl_be(priv->regs);
+	cpu_id = (val & REV_LONG_CHIPID_MASK) >> REV_LONG_CHIPID_SHIFT;
+	cpu_rev = (val & REV_REVID_MASK) >> REV_REVID_SHIFT;
+
+	snprintf(buf, size, "BCM%05X%02X", cpu_id, cpu_rev);
+
+	return 0;
+}
+
+static ulong bcm6328_get_cpu_freq(struct bmips_cpu_priv *priv)
+{
+	unsigned int mips_pll_fcvo;
+
+	mips_pll_fcvo = readl_be(priv->regs + REG_BCM6328_MISC_STRAPBUS);
+	mips_pll_fcvo = (mips_pll_fcvo & STRAPBUS_6328_FCVO_MASK)
+			>> STRAPBUS_6328_FCVO_SHIFT;
+
+	switch (mips_pll_fcvo) {
+	case 0x12:
+	case 0x14:
+	case 0x19:
+		return 160000000;
+	case 0x1c:
+		return 192000000;
+	case 0x13:
+	case 0x15:
+		return 200000000;
+	case 0x1a:
+		return 384000000;
+	case 0x16:
+		return 400000000;
+	default:
+		return 320000000;
+	}
+}
+
+static ulong bcm6358_get_cpu_freq(struct bmips_cpu_priv *priv)
+{
+	unsigned int tmp, n1, n2, m1;
+
+	tmp = readl_be(priv->regs + REG_BCM6358_DDR_DMIPSPLLCFG);
+	n1 = (tmp & DMIPSPLLCFG_6358_N1_MASK) >> DMIPSPLLCFG_6358_N1_SHIFT;
+	n2 = (tmp & DMIPSPLLCFG_6358_N2_MASK) >> DMIPSPLLCFG_6358_N2_SHIFT;
+	m1 = (tmp & DMIPSPLLCFG_6358_M1_MASK) >> DMIPSPLLCFG_6358_M1_SHIFT;
+
+	return (16 * 1000000 * n1 * n2) / m1;
+}
+
+static ulong bcm63268_get_cpu_freq(struct bmips_cpu_priv *priv)
+{
+	unsigned int mips_pll_fcvo;
+
+	mips_pll_fcvo = readl_be(priv->regs + REG_BCM63268_MISC_STRAPBUS);
+	mips_pll_fcvo = (mips_pll_fcvo & STRAPBUS_63268_FCVO_MASK)
+			>> STRAPBUS_63268_FCVO_SHIFT;
+
+	switch (mips_pll_fcvo) {
+	case 0x3:
+	case 0xe:
+		return 320000000;
+	case 0xa:
+		return 333000000;
+	case 0x2:
+	case 0xb:
+	case 0xf:
+		return 400000000;
+	default:
+		return 0;
+	}
+}
+
+static int bcm6328_get_cpu_count(struct bmips_cpu_priv *priv)
+{
+	u32 val = readl_be(priv->regs + REG_BCM6328_OTP);
+
+	if (val & BCM6328_TP1_DISABLED)
+		return 1;
+	else
+		return 2;
+}
+
+static int bcm6358_get_cpu_count(struct bmips_cpu_priv *priv)
+{
+	return 2;
+}
+
+static const struct bmips_cpu_hw bmips_cpu_bcm6328 = {
+	.get_cpu_desc = bcm6328_get_cpu_desc,
+	.get_cpu_freq = bcm6328_get_cpu_freq,
+	.get_cpu_count = bcm6328_get_cpu_count,
+};
+
+static const struct bmips_cpu_hw bmips_cpu_bcm6358 = {
+	.get_cpu_desc = bcm6358_get_cpu_desc,
+	.get_cpu_freq = bcm6358_get_cpu_freq,
+	.get_cpu_count = bcm6358_get_cpu_count,
+};
+
+static const struct bmips_cpu_hw bmips_cpu_bcm63268 = {
+	.get_cpu_desc = bcm6328_get_cpu_desc,
+	.get_cpu_freq = bcm63268_get_cpu_freq,
+	.get_cpu_count = bcm6358_get_cpu_count,
+};
+
+/* Generic CPU Ops */
+static int bmips_cpu_get_desc(struct udevice *dev, char *buf, int size)
+{
+	struct bmips_cpu_priv *priv = dev_get_priv(dev);
+	const struct bmips_cpu_hw *hw = priv->hw;
+
+	return hw->get_cpu_desc(priv, buf, size);
+}
+
+static int bmips_cpu_get_info(struct udevice *dev, struct cpu_info *info)
+{
+	struct bmips_cpu_priv *priv = dev_get_priv(dev);
+	const struct bmips_cpu_hw *hw = priv->hw;
+
+	info->cpu_freq = hw->get_cpu_freq(priv);
+	info->features = BIT(CPU_FEAT_L1_CACHE);
+	info->features |= BIT(CPU_FEAT_MMU);
+	info->features |= BIT(CPU_FEAT_DEVICE_ID);
+
+	return 0;
+}
+
+static int bmips_cpu_get_count(struct udevice *dev)
+{
+	struct bmips_cpu_priv *priv = dev_get_priv(dev);
+	const struct bmips_cpu_hw *hw = priv->hw;
+
+	return hw->get_cpu_count(priv);
+}
+
+static int bmips_cpu_get_vendor(struct udevice *dev, char *buf, int size)
+{
+	snprintf(buf, size, "Broadcom");
+
+	return 0;
+}
+
+static const struct cpu_ops bmips_cpu_ops = {
+	.get_desc = bmips_cpu_get_desc,
+	.get_info = bmips_cpu_get_info,
+	.get_count = bmips_cpu_get_count,
+	.get_vendor = bmips_cpu_get_vendor,
+};
+
+/* BMIPS CPU driver */
+int bmips_cpu_bind(struct udevice *dev)
+{
+	struct cpu_platdata *plat = dev_get_parent_platdata(dev);
+
+	plat->cpu_id = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+		"reg", -1);
+	plat->device_id = read_c0_prid();
+
+	return 0;
+}
+
+int bmips_cpu_probe(struct udevice *dev)
+{
+	struct bmips_cpu_priv *priv = dev_get_priv(dev);
+	const struct bmips_cpu_hw *hw =
+		(const struct bmips_cpu_hw *)dev_get_driver_data(dev);
+	fdt_addr_t addr;
+	fdt_size_t size;
+
+	addr = dev_get_addr_size_index(dev_get_parent(dev), 0, &size);
+	if (addr == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	priv->regs = ioremap(addr, size);
+	priv->hw = hw;
+
+	return 0;
+}
+
+static const struct udevice_id bmips_cpu_ids[] = {
+	{
+		.compatible = "brcm,bcm6328-cpu",
+		.data = (ulong)&bmips_cpu_bcm6328,
+	}, {
+		.compatible = "brcm,bcm6358-cpu",
+		.data = (ulong)&bmips_cpu_bcm6358,
+	}, {
+		.compatible = "brcm,bcm63268-cpu",
+		.data = (ulong)&bmips_cpu_bcm63268,
+	},
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(bmips_cpu_drv) = {
+	.name = "bmips_cpu",
+	.id = UCLASS_CPU,
+	.of_match = bmips_cpu_ids,
+	.bind = bmips_cpu_bind,
+	.probe = bmips_cpu_probe,
+	.priv_auto_alloc_size = sizeof(struct bmips_cpu_priv),
+	.ops = &bmips_cpu_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
+
+#ifdef CONFIG_DISPLAY_CPUINFO
+int print_cpuinfo(void)
+{
+	struct cpu_info cpu;
+	struct udevice *dev;
+	int err;
+	char desc[100];
+
+	err = uclass_get_device(UCLASS_CPU, 0, &dev);
+	if (err)
+		return 0;
+
+	err = cpu_get_info(dev, &cpu);
+	if (err)
+		return 0;
+
+	err = cpu_get_desc(dev, desc, sizeof(desc));
+	if (err)
+		return 0;
+
+	printf("Chip ID: %s, MIPS: ", desc);
+	print_freq(cpu.cpu_freq, "\n");
+
+	return 0;
+}
+#endif
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 99516119ff1d2486c1ef902d7a060aa35a004bfc..325d053931f73decd19aa8a2e1cae81793617a7f 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -21,6 +21,12 @@ config ALTERA_PIO
 	  Select this to enable PIO for Altera devices. Please find
 	  details on the "Embedded Peripherals IP User Guide" of Altera.
 
+config BCM6345_GPIO
+	bool "BCM6345 GPIO driver"
+	depends on DM_GPIO && ARCH_BMIPS
+	help
+	  This driver supports the GPIO banks on BCM6345 SoCs.
+
 config DWAPB_GPIO
 	bool "DWAPB GPIO driver"
 	depends on DM && DM_GPIO
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 0ca845f54caa6bcc1111e44ad591eb7016de9429..03df558879b00963d9a6614fd0a96a06094e012f 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_DM_74X164)		+= 74x164_gpio.o
 
 obj-$(CONFIG_AT91_GPIO)	+= at91_gpio.o
 obj-$(CONFIG_ATMEL_PIO4)	+= atmel_pio4.o
+obj-$(CONFIG_BCM6345_GPIO)	+= bcm6345_gpio.o
 obj-$(CONFIG_INTEL_ICH6_GPIO)	+= intel_ich6_gpio.o
 obj-$(CONFIG_INTEL_BROADWELL_GPIO)	+= intel_broadwell_gpio.o
 obj-$(CONFIG_KIRKWOOD_GPIO)	+= kw_gpio.o
diff --git a/drivers/gpio/bcm6345_gpio.c b/drivers/gpio/bcm6345_gpio.c
new file mode 100644
index 0000000000000000000000000000000000000000..1c46020aa4d6ca3ba12bd6aaea6ba379d1f9c0a3
--- /dev/null
+++ b/drivers/gpio/bcm6345_gpio.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/arch/mips/bcm63xx/gpio.c:
+ *	Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ *	Copyright (C) 2008-2011 Florian Fainelli <florian@openwrt.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <dm/device.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct bcm6345_gpio_priv {
+	void __iomem *reg_dirout;
+	void __iomem *reg_data;
+};
+
+static int bcm6345_gpio_get_value(struct udevice *dev, unsigned offset)
+{
+	struct bcm6345_gpio_priv *priv = dev_get_priv(dev);
+
+	return !!(readl_be(priv->reg_data) & BIT(offset));
+}
+
+static int bcm6345_gpio_set_value(struct udevice *dev, unsigned offset,
+				  int value)
+{
+	struct bcm6345_gpio_priv *priv = dev_get_priv(dev);
+
+	if (value)
+		setbits_be32(priv->reg_data, BIT(offset));
+	else
+		clrbits_be32(priv->reg_data, BIT(offset));
+
+	return 0;
+}
+
+static int bcm6345_gpio_set_direction(void __iomem *dirout, unsigned offset,
+				      bool input)
+{
+	if (input)
+		clrbits_be32(dirout, BIT(offset));
+	else
+		setbits_be32(dirout, BIT(offset));
+
+	return 0;
+}
+
+static int bcm6345_gpio_direction_input(struct udevice *dev, unsigned offset)
+{
+	struct bcm6345_gpio_priv *priv = dev_get_priv(dev);
+
+	return bcm6345_gpio_set_direction(priv->reg_dirout, offset, 1);
+}
+
+static int bcm6345_gpio_direction_output(struct udevice *dev, unsigned offset,
+					 int value)
+{
+	struct bcm6345_gpio_priv *priv = dev_get_priv(dev);
+
+	return bcm6345_gpio_set_direction(priv->reg_dirout, offset, 0);
+}
+
+static int bcm6345_gpio_get_function(struct udevice *dev, unsigned offset)
+{
+	struct bcm6345_gpio_priv *priv = dev_get_priv(dev);
+
+	if (readl_be(priv->reg_dirout) & BIT(offset))
+		return GPIOF_OUTPUT;
+	else
+		return GPIOF_INPUT;
+}
+
+static const struct dm_gpio_ops bcm6345_gpio_ops = {
+	.direction_input = bcm6345_gpio_direction_input,
+	.direction_output = bcm6345_gpio_direction_output,
+	.get_value = bcm6345_gpio_get_value,
+	.set_value = bcm6345_gpio_set_value,
+	.get_function = bcm6345_gpio_get_function,
+};
+
+static int bcm6345_gpio_probe(struct udevice *dev)
+{
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+	struct bcm6345_gpio_priv *priv = dev_get_priv(dev);
+	fdt_addr_t data_addr, dirout_addr;
+	fdt_size_t data_size, dirout_size;
+
+	dirout_addr = dev_get_addr_size_index(dev, 0, &dirout_size);
+	if (dirout_addr == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	data_addr = dev_get_addr_size_index(dev, 1, &data_size);
+	if (data_addr == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	priv->reg_data = ioremap(data_addr, data_size);
+	priv->reg_dirout = ioremap(dirout_addr, dirout_size);
+
+	uc_priv->gpio_count = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
+					      "ngpios", 32);
+	uc_priv->bank_name = dev->name;
+
+	return 0;
+}
+
+static const struct udevice_id bcm6345_gpio_ids[] = {
+	{ .compatible = "brcm,bcm6345-gpio" },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(bcm6345_gpio) = {
+	.name = "bcm6345-gpio",
+	.id = UCLASS_GPIO,
+	.of_match = bcm6345_gpio_ids,
+	.ops = &bcm6345_gpio_ops,
+	.priv_auto_alloc_size = sizeof(struct bcm6345_gpio_priv),
+	.probe = bcm6345_gpio_probe,
+};
diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig
index 309372ab56484509694d3f5401c73a8053b53a67..5da5c4af3925804a31e0606c96a8572d87b59564 100644
--- a/drivers/led/Kconfig
+++ b/drivers/led/Kconfig
@@ -9,6 +9,25 @@ config LED
 	  can provide access to board-specific LEDs. Use of the device tree
 	  for configuration is encouraged.
 
+config LED_BCM6328
+	bool "LED Support for BCM6328"
+	depends on LED && ARCH_BMIPS
+	help
+	  This option enables support for LEDs connected to the BCM6328
+	  LED HW controller accessed via MMIO registers.
+	  HW blinking is supported and up to 24 LEDs can be controlled.
+	  All LEDs can blink at the same time but the delay is shared, which
+	  means that if one LED is set to blink at 100ms and then a different
+	  LED is set to blink at 200ms, both will blink at 200ms.
+
+config LED_BCM6358
+	bool "LED Support for BCM6358"
+	depends on LED && ARCH_BMIPS
+	help
+	  This option enables support for LEDs connected to the BCM6358
+	  LED HW controller accessed via MMIO registers.
+	  HW has no blinking capabilities and up to 32 LEDs can be controlled.
+
 config LED_BLINK
 	bool "Support LED blinking"
 	depends on LED
diff --git a/drivers/led/Makefile b/drivers/led/Makefile
index 02367fdacbc10e77abbe51979b2a40bc1fa2bc56..9d079f8336e15ba67ec2ce09a32e797e84d7588b 100644
--- a/drivers/led/Makefile
+++ b/drivers/led/Makefile
@@ -6,4 +6,6 @@
 #
 
 obj-y += led-uclass.o
+obj-$(CONFIG_LED_BCM6328) += led_bcm6328.o
+obj-$(CONFIG_LED_BCM6358) += led_bcm6358.o
 obj-$(CONFIG_$(SPL_)LED_GPIO) += led_gpio.o
diff --git a/drivers/led/led_bcm6328.c b/drivers/led/led_bcm6328.c
new file mode 100644
index 0000000000000000000000000000000000000000..ef8c6a70617e9170632b0445e8996a4ecaaec666
--- /dev/null
+++ b/drivers/led/led_bcm6328.c
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <led.h>
+#include <asm/io.h>
+#include <dm/lists.h>
+
+#define LEDS_MAX			24
+
+/* LED Init register */
+#define LED_INIT_REG			0x00
+#define LED_INIT_FASTINTV_MS		20
+#define LED_INIT_FASTINTV_SHIFT		6
+#define LED_INIT_FASTINTV_MASK		(0x3f << LED_INIT_FASTINTV_SHIFT)
+#define LED_INIT_SLEDEN_SHIFT		12
+#define LED_INIT_SLEDEN_MASK		(1 << LED_INIT_SLEDEN_SHIFT)
+#define LED_INIT_SLEDMUX_SHIFT		13
+#define LED_INIT_SLEDMUX_MASK		(1 << LED_INIT_SLEDMUX_SHIFT)
+#define LED_INIT_SLEDCLKNPOL_SHIFT	14
+#define LED_INIT_SLEDCLKNPOL_MASK	(1 << LED_INIT_SLEDCLKNPOL_SHIFT)
+#define LED_INIT_SLEDDATAPPOL_SHIFT	15
+#define LED_INIT_SLEDDATANPOL_MASK	(1 << LED_INIT_SLEDDATAPPOL_SHIFT)
+#define LED_INIT_SLEDSHIFTDIR_SHIFT	16
+#define LED_INIT_SLEDSHIFTDIR_MASK	(1 << LED_INIT_SLEDSHIFTDIR_SHIFT)
+
+/* LED Mode registers */
+#define LED_MODE_REG_HI			0x04
+#define LED_MODE_REG_LO			0x08
+#define LED_MODE_ON			0
+#define LED_MODE_FAST			1
+#define LED_MODE_BLINK			2
+#define LED_MODE_OFF			3
+#define LED_MODE_MASK			0x3
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct bcm6328_led_priv {
+	void __iomem *regs;
+	void __iomem *mode;
+	uint8_t shift;
+	bool active_low;
+};
+
+static unsigned long bcm6328_led_get_mode(struct bcm6328_led_priv *priv)
+{
+	return ((readl_be(priv->mode) >> priv->shift) & LED_MODE_MASK);
+}
+
+static int bcm6328_led_set_mode(struct bcm6328_led_priv *priv, uint8_t mode)
+{
+	clrsetbits_be32(priv->mode, (LED_MODE_MASK << priv->shift),
+			(mode << priv->shift));
+
+	return 0;
+}
+
+static enum led_state_t bcm6328_led_get_state(struct udevice *dev)
+{
+	struct bcm6328_led_priv *priv = dev_get_priv(dev);
+	enum led_state_t state = LEDST_OFF;
+
+	switch (bcm6328_led_get_mode(priv)) {
+#ifdef CONFIG_LED_BLINK
+	case LED_MODE_BLINK:
+	case LED_MODE_FAST:
+		state = LEDST_BLINK;
+		break;
+#endif
+	case LED_MODE_OFF:
+		state = (priv->active_low ? LEDST_ON : LEDST_OFF);
+		break;
+	case LED_MODE_ON:
+		state = (priv->active_low ? LEDST_OFF : LEDST_ON);
+		break;
+	}
+
+	return state;
+}
+
+static int bcm6328_led_set_state(struct udevice *dev, enum led_state_t state)
+{
+	struct bcm6328_led_priv *priv = dev_get_priv(dev);
+	unsigned long mode;
+
+	switch (state) {
+#ifdef CONFIG_LED_BLINK
+	case LEDST_BLINK:
+		mode = LED_MODE_BLINK;
+		break;
+#endif
+	case LEDST_OFF:
+		mode = (priv->active_low ? LED_MODE_ON : LED_MODE_OFF);
+		break;
+	case LEDST_ON:
+		mode = (priv->active_low ? LED_MODE_OFF : LED_MODE_ON);
+		break;
+	case LEDST_TOGGLE:
+		if (bcm6328_led_get_state(dev) == LEDST_OFF)
+			return bcm6328_led_set_state(dev, LEDST_ON);
+		else
+			return bcm6328_led_set_state(dev, LEDST_OFF);
+		break;
+	default:
+		return -ENOSYS;
+	}
+
+	return bcm6328_led_set_mode(priv, mode);
+}
+
+#ifdef CONFIG_LED_BLINK
+static unsigned long bcm6328_blink_delay(int delay)
+{
+	unsigned long bcm6328_delay = delay;
+
+	bcm6328_delay += (LED_INIT_FASTINTV_MS / 2);
+	bcm6328_delay /= LED_INIT_FASTINTV_MS;
+	bcm6328_delay <<= LED_INIT_FASTINTV_SHIFT;
+
+	if (bcm6328_delay > LED_INIT_FASTINTV_MASK)
+		return LED_INIT_FASTINTV_MASK;
+	else
+		return bcm6328_delay;
+}
+
+static int bcm6328_led_set_period(struct udevice *dev, int period_ms)
+{
+	struct bcm6328_led_priv *priv = dev_get_priv(dev);
+
+	clrsetbits_be32(priv->regs + LED_INIT_REG, LED_INIT_FASTINTV_MASK,
+			bcm6328_blink_delay(period_ms));
+
+	return 0;
+}
+#endif
+
+static const struct led_ops bcm6328_led_ops = {
+	.get_state = bcm6328_led_get_state,
+	.set_state = bcm6328_led_set_state,
+#ifdef CONFIG_LED_BLINK
+	.set_period = bcm6328_led_set_period,
+#endif
+};
+
+static int bcm6328_led_probe(struct udevice *dev)
+{
+	struct led_uc_plat *uc_plat = dev_get_uclass_platdata(dev);
+	fdt_addr_t addr;
+	fdt_size_t size;
+
+	/* Top-level LED node */
+	if (!uc_plat->label) {
+		void __iomem *regs;
+		u32 set_bits = 0;
+
+		addr = dev_get_addr_size_index(dev, 0, &size);
+		if (addr == FDT_ADDR_T_NONE)
+			return -EINVAL;
+
+		regs = ioremap(addr, size);
+
+		if (fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
+				    "brcm,serial-leds"))
+			set_bits |= LED_INIT_SLEDEN_MASK;
+		if (fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
+				    "brcm,serial-mux"))
+			set_bits |= LED_INIT_SLEDMUX_MASK;
+		if (fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
+				    "brcm,serial-clk-low"))
+			set_bits |= LED_INIT_SLEDCLKNPOL_MASK;
+		if (!fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
+				     "brcm,serial-dat-low"))
+			set_bits |= LED_INIT_SLEDDATANPOL_MASK;
+		if (!fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
+				     "brcm,serial-shift-inv"))
+			set_bits |= LED_INIT_SLEDSHIFTDIR_MASK;
+
+		clrsetbits_be32(regs + LED_INIT_REG, ~0, set_bits);
+	} else {
+		struct bcm6328_led_priv *priv = dev_get_priv(dev);
+		unsigned int pin;
+
+		addr = dev_get_addr_size_index(dev_get_parent(dev), 0, &size);
+		if (addr == FDT_ADDR_T_NONE)
+			return -EINVAL;
+
+		pin = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev), "reg",
+				      LEDS_MAX);
+		if (pin >= LEDS_MAX)
+			return -EINVAL;
+
+		priv->regs = ioremap(addr, size);
+		if (pin < 8) {
+			/* LEDs 0-7 (bits 47:32) */
+			priv->mode = priv->regs + LED_MODE_REG_HI;
+			priv->shift = (pin << 1);
+		} else {
+			/* LEDs 8-23 (bits 31:0) */
+			priv->mode = priv->regs + LED_MODE_REG_LO;
+			priv->shift = ((pin - 8) << 1);
+		}
+
+		if (fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
+				    "active-low"))
+			priv->active_low = true;
+	}
+
+	return 0;
+}
+
+static int bcm6328_led_bind(struct udevice *parent)
+{
+	const void *blob = gd->fdt_blob;
+	int node;
+
+	for (node = fdt_first_subnode(blob, dev_of_offset(parent));
+	     node > 0;
+	     node = fdt_next_subnode(blob, node)) {
+		struct led_uc_plat *uc_plat;
+		struct udevice *dev;
+		const char *label;
+		int ret;
+
+		label = fdt_getprop(blob, node, "label", NULL);
+		if (!label) {
+			debug("%s: node %s has no label\n", __func__,
+			      fdt_get_name(blob, node, NULL));
+			return -EINVAL;
+		}
+
+		ret = device_bind_driver_to_node(parent, "bcm6328-led",
+						 fdt_get_name(blob, node, NULL),
+						 node, &dev);
+		if (ret)
+			return ret;
+
+		uc_plat = dev_get_uclass_platdata(dev);
+		uc_plat->label = label;
+	}
+
+	return 0;
+}
+
+static const struct udevice_id bcm6328_led_ids[] = {
+	{ .compatible = "brcm,bcm6328-leds" },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(bcm6328_led) = {
+	.name = "bcm6328-led",
+	.id = UCLASS_LED,
+	.of_match = bcm6328_led_ids,
+	.ops = &bcm6328_led_ops,
+	.bind = bcm6328_led_bind,
+	.probe = bcm6328_led_probe,
+	.priv_auto_alloc_size = sizeof(struct bcm6328_led_priv),
+};
diff --git a/drivers/led/led_bcm6358.c b/drivers/led/led_bcm6358.c
new file mode 100644
index 0000000000000000000000000000000000000000..11caecdc26b141769e89060f09dd8c143ca23070
--- /dev/null
+++ b/drivers/led/led_bcm6358.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <led.h>
+#include <asm/io.h>
+#include <dm/lists.h>
+
+#define LEDS_MAX		32
+#define LEDS_WAIT		100
+
+/* LED Mode register */
+#define LED_MODE_REG		0x0
+#define LED_MODE_OFF		0
+#define LED_MODE_ON		1
+#define LED_MODE_MASK		1
+
+/* LED Control register */
+#define LED_CTRL_REG		0x4
+#define LED_CTRL_CLK_MASK	0x3
+#define LED_CTRL_CLK_1		0
+#define LED_CTRL_CLK_2		1
+#define LED_CTRL_CLK_4		2
+#define LED_CTRL_CLK_8		3
+#define LED_CTRL_POL_SHIFT	2
+#define LED_CTRL_POL_MASK	(1 << LED_CTRL_POL_SHIFT)
+#define LED_CTRL_BUSY_SHIFT	3
+#define LED_CTRL_BUSY_MASK	(1 << LED_CTRL_BUSY_SHIFT)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct bcm6358_led_priv {
+	void __iomem *regs;
+	uint8_t pin;
+	bool active_low;
+};
+
+static void bcm6358_led_busy(void __iomem *regs)
+{
+	while (readl_be(regs + LED_CTRL_REG) & LED_CTRL_BUSY_MASK)
+		udelay(LEDS_WAIT);
+}
+
+static unsigned long bcm6358_led_get_mode(struct bcm6358_led_priv *priv)
+{
+	bcm6358_led_busy(priv->regs);
+
+	return (readl_be(priv->regs + LED_MODE_REG) >> priv->pin) &
+	       LED_MODE_MASK;
+}
+
+static int bcm6358_led_set_mode(struct bcm6358_led_priv *priv, uint8_t mode)
+{
+	bcm6358_led_busy(priv->regs);
+
+	clrsetbits_be32(priv->regs + LED_MODE_REG,
+			(LED_MODE_MASK << priv->pin),
+			(mode << priv->pin));
+
+	return 0;
+}
+
+static enum led_state_t bcm6358_led_get_state(struct udevice *dev)
+{
+	struct bcm6358_led_priv *priv = dev_get_priv(dev);
+	enum led_state_t state = LEDST_OFF;
+
+	switch (bcm6358_led_get_mode(priv)) {
+	case LED_MODE_OFF:
+		state = (priv->active_low ? LEDST_ON : LEDST_OFF);
+		break;
+	case LED_MODE_ON:
+		state = (priv->active_low ? LEDST_OFF : LEDST_ON);
+		break;
+	}
+
+	return state;
+}
+
+static int bcm6358_led_set_state(struct udevice *dev, enum led_state_t state)
+{
+	struct bcm6358_led_priv *priv = dev_get_priv(dev);
+	unsigned long mode;
+
+	switch (state) {
+	case LEDST_OFF:
+		mode = (priv->active_low ? LED_MODE_ON : LED_MODE_OFF);
+		break;
+	case LEDST_ON:
+		mode = (priv->active_low ? LED_MODE_OFF : LED_MODE_ON);
+		break;
+	case LEDST_TOGGLE:
+		if (bcm6358_led_get_state(dev) == LEDST_OFF)
+			return bcm6358_led_set_state(dev, LEDST_ON);
+		else
+			return bcm6358_led_set_state(dev, LEDST_OFF);
+		break;
+	default:
+		return -ENOSYS;
+	}
+
+	return bcm6358_led_set_mode(priv, mode);
+}
+
+static const struct led_ops bcm6358_led_ops = {
+	.get_state = bcm6358_led_get_state,
+	.set_state = bcm6358_led_set_state,
+};
+
+static int bcm6358_led_probe(struct udevice *dev)
+{
+	struct led_uc_plat *uc_plat = dev_get_uclass_platdata(dev);
+	fdt_addr_t addr;
+	fdt_size_t size;
+
+	/* Top-level LED node */
+	if (!uc_plat->label) {
+		void __iomem *regs;
+		unsigned int clk_div;
+		u32 set_bits = 0;
+
+		addr = dev_get_addr_size_index(dev, 0, &size);
+		if (addr == FDT_ADDR_T_NONE)
+			return -EINVAL;
+
+		regs = ioremap(addr, size);
+
+		if (fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
+				    "brcm,clk-dat-low"))
+			set_bits |= LED_CTRL_POL_MASK;
+		clk_div = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
+					  "brcm,clk-div", LED_CTRL_CLK_1);
+		switch (clk_div) {
+		case 8:
+			set_bits |= LED_CTRL_CLK_8;
+			break;
+		case 4:
+			set_bits |= LED_CTRL_CLK_4;
+			break;
+		case 2:
+			set_bits |= LED_CTRL_CLK_2;
+			break;
+		default:
+			set_bits |= LED_CTRL_CLK_1;
+			break;
+		}
+
+		bcm6358_led_busy(regs);
+		clrsetbits_be32(regs + LED_CTRL_REG,
+				LED_CTRL_POL_MASK | LED_CTRL_CLK_MASK,
+				set_bits);
+	} else {
+		struct bcm6358_led_priv *priv = dev_get_priv(dev);
+		unsigned int pin;
+
+		addr = dev_get_addr_size_index(dev_get_parent(dev), 0, &size);
+		if (addr == FDT_ADDR_T_NONE)
+			return -EINVAL;
+
+		pin = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev), "reg",
+				      LEDS_MAX);
+		if (pin >= LEDS_MAX)
+			return -EINVAL;
+
+		priv->regs = ioremap(addr, size);
+		priv->pin = pin;
+
+		if (fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
+				    "active-low"))
+			priv->active_low = true;
+	}
+
+	return 0;
+}
+
+static int bcm6358_led_bind(struct udevice *parent)
+{
+	const void *blob = gd->fdt_blob;
+	int node;
+
+	for (node = fdt_first_subnode(blob, dev_of_offset(parent));
+	     node > 0;
+	     node = fdt_next_subnode(blob, node)) {
+		struct led_uc_plat *uc_plat;
+		struct udevice *dev;
+		const char *label;
+		int ret;
+
+		label = fdt_getprop(blob, node, "label", NULL);
+		if (!label) {
+			debug("%s: node %s has no label\n", __func__,
+			      fdt_get_name(blob, node, NULL));
+			return -EINVAL;
+		}
+
+		ret = device_bind_driver_to_node(parent, "bcm6358-led",
+						 fdt_get_name(blob, node, NULL),
+						 node, &dev);
+		if (ret)
+			return ret;
+
+		uc_plat = dev_get_uclass_platdata(dev);
+		uc_plat->label = label;
+	}
+
+	return 0;
+}
+
+static const struct udevice_id bcm6358_led_ids[] = {
+	{ .compatible = "brcm,bcm6358-leds" },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(bcm6358_led) = {
+	.name = "bcm6358-led",
+	.id = UCLASS_LED,
+	.of_match = bcm6358_led_ids,
+	.bind = bcm6358_led_bind,
+	.probe = bcm6358_led_probe,
+	.priv_auto_alloc_size = sizeof(struct bcm6358_led_priv),
+	.ops = &bcm6358_led_ops,
+};
diff --git a/drivers/power/domain/Kconfig b/drivers/power/domain/Kconfig
index 132e33250e8c2d3a8f95edf007d359f51703b0a3..7cfa76149876e72a08f0bca62006995d051dcb3e 100644
--- a/drivers/power/domain/Kconfig
+++ b/drivers/power/domain/Kconfig
@@ -9,6 +9,13 @@ config POWER_DOMAIN
 	  domains). This may be used to save power. This API provides the
 	  means to control such power management hardware.
 
+config BCM6328_POWER_DOMAIN
+	bool "Enable the BCM6328 power domain driver"
+	depends on POWER_DOMAIN && ARCH_BMIPS
+	help
+	  Enable support for manipulating BCM6345 power domains via MMIO
+	  mapped registers.
+
 config SANDBOX_POWER_DOMAIN
 	bool "Enable the sandbox power domain test driver"
 	depends on POWER_DOMAIN && SANDBOX
diff --git a/drivers/power/domain/Makefile b/drivers/power/domain/Makefile
index 2c3d92638fbee3002aae593b41353de1d6b76d8c..c7d764440205c9a5b9e99d959cf138a58e9efb36 100644
--- a/drivers/power/domain/Makefile
+++ b/drivers/power/domain/Makefile
@@ -3,6 +3,7 @@
 # SPDX-License-Identifier: GPL-2.0
 
 obj-$(CONFIG_POWER_DOMAIN) += power-domain-uclass.o
+obj-$(CONFIG_BCM6328_POWER_DOMAIN) += bcm6328-power-domain.o
 obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain.o
 obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain-test.o
 obj-$(CONFIG_TEGRA186_POWER_DOMAIN) += tegra186-power-domain.o
diff --git a/drivers/power/domain/bcm6328-power-domain.c b/drivers/power/domain/bcm6328-power-domain.c
new file mode 100644
index 0000000000000000000000000000000000000000..15638bf3bad27e4a9f1412f1717acd3ef1013781
--- /dev/null
+++ b/drivers/power/domain/bcm6328-power-domain.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <power-domain-uclass.h>
+#include <asm/io.h>
+
+#define MAX_DOMAINS	32
+
+struct bcm6328_power_domain {
+	void __iomem *regs;
+};
+
+static int bcm6328_power_domain_request(struct power_domain *power_domain)
+{
+	if (power_domain->id >= MAX_DOMAINS)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int bcm6328_power_domain_free(struct power_domain *power_domain)
+{
+	return 0;
+}
+
+static int bcm6328_power_domain_on(struct power_domain *power_domain)
+{
+	struct bcm6328_power_domain *priv = dev_get_priv(power_domain->dev);
+
+	clrbits_be32(priv->regs, BIT(power_domain->id));
+
+	return 0;
+}
+
+static int bcm6328_power_domain_off(struct power_domain *power_domain)
+{
+	struct bcm6328_power_domain *priv = dev_get_priv(power_domain->dev);
+
+	setbits_be32(priv->regs, BIT(power_domain->id));
+
+	return 0;
+}
+
+static int bcm6328_power_domain_probe(struct udevice *dev)
+{
+	struct bcm6328_power_domain *priv = dev_get_priv(dev);
+	fdt_addr_t addr;
+	fdt_size_t size;
+
+	addr = dev_get_addr_size_index(dev, 0, &size);
+	if (addr == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	priv->regs = ioremap(addr, size);
+
+	return 0;
+}
+
+static const struct udevice_id bcm6328_power_domain_ids[] = {
+	{ .compatible = "brcm,bcm6328-power-domain" },
+	{ /* sentinel */ }
+};
+
+struct power_domain_ops bcm6328_power_domain_ops = {
+	.free = bcm6328_power_domain_free,
+	.off = bcm6328_power_domain_off,
+	.on = bcm6328_power_domain_on,
+	.request = bcm6328_power_domain_request,
+};
+
+U_BOOT_DRIVER(bcm6328_power_domain) = {
+	.name = "bcm6328_power_domain",
+	.id = UCLASS_POWER_DOMAIN,
+	.of_match = bcm6328_power_domain_ids,
+	.ops = &bcm6328_power_domain_ops,
+	.priv_auto_alloc_size = sizeof(struct bcm6328_power_domain),
+	.probe = bcm6328_power_domain_probe,
+};
diff --git a/drivers/ram/Makefile b/drivers/ram/Makefile
index ecb036dfbab9d858da10d77e65abeb582b9b5a6f..c409c480fc779e95b3199cf6a76e2f7c3325b57e 100644
--- a/drivers/ram/Makefile
+++ b/drivers/ram/Makefile
@@ -7,3 +7,4 @@
 obj-$(CONFIG_RAM) += ram-uclass.o
 obj-$(CONFIG_SANDBOX) += sandbox_ram.o
 obj-$(CONFIG_STM32_SDRAM) += stm32_sdram.o
+obj-$(CONFIG_ARCH_BMIPS) += bmips_ram.o
diff --git a/drivers/ram/bmips_ram.c b/drivers/ram/bmips_ram.c
new file mode 100644
index 0000000000000000000000000000000000000000..9c0b23b914e2f350735ee325889edea083260489
--- /dev/null
+++ b/drivers/ram/bmips_ram.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/arch/mips/bcm63xx/cpu.c:
+ *	Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ *	Copyright (C) 2009 Florian Fainelli <florian@openwrt.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <ram.h>
+#include <asm/io.h>
+#include <dm/device.h>
+
+#define MEMC_CFG_REG		0x4
+#define MEMC_CFG_32B_SHIFT	1
+#define MEMC_CFG_32B_MASK	(1 << MEMC_CFG_32B_SHIFT)
+#define MEMC_CFG_COL_SHIFT	3
+#define MEMC_CFG_COL_MASK	(0x3 << MEMC_CFG_COL_SHIFT)
+#define MEMC_CFG_ROW_SHIFT	6
+#define MEMC_CFG_ROW_MASK	(0x3 << MEMC_CFG_ROW_SHIFT)
+
+#define DDR_CSEND_REG		0x8
+
+struct bmips_ram_priv;
+
+struct bmips_ram_hw {
+	ulong (*get_ram_size)(struct bmips_ram_priv *);
+};
+
+struct bmips_ram_priv {
+	void __iomem *regs;
+	const struct bmips_ram_hw *hw;
+};
+
+static ulong bcm6328_get_ram_size(struct bmips_ram_priv *priv)
+{
+	return readl_be(priv->regs + DDR_CSEND_REG) << 24;
+}
+
+static ulong bcm6358_get_ram_size(struct bmips_ram_priv *priv)
+{
+	unsigned int cols = 0, rows = 0, is_32bits = 0, banks = 0;
+	u32 val;
+
+	val = readl_be(priv->regs + MEMC_CFG_REG);
+	rows = (val & MEMC_CFG_ROW_MASK) >> MEMC_CFG_ROW_SHIFT;
+	cols = (val & MEMC_CFG_COL_MASK) >> MEMC_CFG_COL_SHIFT;
+	is_32bits = (val & MEMC_CFG_32B_MASK) ? 0 : 1;
+	banks = 2;
+
+	/* 0 => 11 address bits ... 2 => 13 address bits */
+	rows += 11;
+
+	/* 0 => 8 address bits ... 2 => 10 address bits */
+	cols += 8;
+
+	return 1 << (cols + rows + (is_32bits + 1) + banks);
+}
+
+static int bmips_ram_get_info(struct udevice *dev, struct ram_info *info)
+{
+	struct bmips_ram_priv *priv = dev_get_priv(dev);
+	const struct bmips_ram_hw *hw = priv->hw;
+
+	info->base = 0x80000000;
+	info->size = hw->get_ram_size(priv);
+
+	return 0;
+}
+
+static const struct ram_ops bmips_ram_ops = {
+	.get_info = bmips_ram_get_info,
+};
+
+static const struct bmips_ram_hw bmips_ram_bcm6328 = {
+	.get_ram_size = bcm6328_get_ram_size,
+};
+
+static const struct bmips_ram_hw bmips_ram_bcm6358 = {
+	.get_ram_size = bcm6358_get_ram_size,
+};
+
+static const struct udevice_id bmips_ram_ids[] = {
+	{
+		.compatible = "brcm,bcm6328-mc",
+		.data = (ulong)&bmips_ram_bcm6328,
+	}, {
+		.compatible = "brcm,bcm6358-mc",
+		.data = (ulong)&bmips_ram_bcm6358,
+	}, {
+		.compatible = "brcm,bcm63268-mc",
+		.data = (ulong)&bmips_ram_bcm6328,
+	},
+	{ /* sentinel */ }
+};
+
+static int bmips_ram_probe(struct udevice *dev)
+{
+	struct bmips_ram_priv *priv = dev_get_priv(dev);
+	const struct bmips_ram_hw *hw =
+		(const struct bmips_ram_hw *)dev_get_driver_data(dev);
+	fdt_addr_t addr;
+	fdt_size_t size;
+
+	addr = dev_get_addr_size_index(dev, 0, &size);
+	if (addr == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	priv->regs = ioremap(addr, size);
+	priv->hw = hw;
+
+	return 0;
+}
+
+U_BOOT_DRIVER(bmips_ram) = {
+	.name = "bmips-mc",
+	.id = UCLASS_RAM,
+	.of_match = bmips_ram_ids,
+	.probe = bmips_ram_probe,
+	.priv_auto_alloc_size = sizeof(struct bmips_ram_priv),
+	.ops = &bmips_ram_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 80f4646a79c5e6bd5470b00f17fb723b67b3e1b1..e6af7da8fe59292f4238e23b3ccef29b9c72986c 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -42,6 +42,12 @@ config TEGRA186_RESET
 	  Enable support for manipulating Tegra's on-SoC reset signals via IPC
 	  requests to the BPMP (Boot and Power Management Processor).
 
+config RESET_BCM6345
+	bool "Reset controller driver for BCM6345"
+	depends on DM_RESET && ARCH_BMIPS
+	help
+	  Support reset controller on BCM6345.
+
 config RESET_UNIPHIER
 	bool "Reset controller driver for UniPhier SoCs"
 	depends on ARCH_UNIPHIER
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 630b4b4e541c1ef2e1ab7382454b1f401d64e470..d5e06c2241d7648ac0d812ff5e9719e03f961467 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -8,5 +8,6 @@ obj-$(CONFIG_SANDBOX_MBOX) += sandbox-reset-test.o
 obj-$(CONFIG_STI_RESET) += sti-reset.o
 obj-$(CONFIG_TEGRA_CAR_RESET) += tegra-car-reset.o
 obj-$(CONFIG_TEGRA186_RESET) += tegra186-reset.o
+obj-$(CONFIG_RESET_BCM6345) += reset-bcm6345.o
 obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o
 obj-$(CONFIG_AST2500_RESET) += ast2500-reset.o
diff --git a/drivers/reset/reset-bcm6345.c b/drivers/reset/reset-bcm6345.c
new file mode 100644
index 0000000000000000000000000000000000000000..774c2a7538d47da58cd7171b2ccd0f0291fad80d
--- /dev/null
+++ b/drivers/reset/reset-bcm6345.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/arch/mips/bcm63xx/reset.c:
+ *	Copyright (C) 2012 Jonas Gorski <jonas.gorski@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <reset-uclass.h>
+#include <asm/io.h>
+
+#define MAX_RESETS	32
+
+struct bcm6345_reset_priv {
+	void __iomem *regs;
+};
+
+static int bcm6345_reset_assert(struct reset_ctl *rst)
+{
+	struct bcm6345_reset_priv *priv = dev_get_priv(rst->dev);
+
+	clrbits_be32(priv->regs, BIT(rst->id));
+	mdelay(20);
+
+	return 0;
+}
+
+static int bcm6345_reset_deassert(struct reset_ctl *rst)
+{
+	struct bcm6345_reset_priv *priv = dev_get_priv(rst->dev);
+
+	setbits_be32(priv->regs, BIT(rst->id));
+	mdelay(20);
+
+	return 0;
+}
+
+static int bcm6345_reset_free(struct reset_ctl *rst)
+{
+	return 0;
+}
+
+static int bcm6345_reset_request(struct reset_ctl *rst)
+{
+	if (rst->id >= MAX_RESETS)
+		return -EINVAL;
+
+	return bcm6345_reset_assert(rst);
+}
+
+struct reset_ops bcm6345_reset_reset_ops = {
+	.free = bcm6345_reset_free,
+	.request = bcm6345_reset_request,
+	.rst_assert = bcm6345_reset_assert,
+	.rst_deassert = bcm6345_reset_deassert,
+};
+
+static const struct udevice_id bcm6345_reset_ids[] = {
+	{ .compatible = "brcm,bcm6345-reset" },
+	{ /* sentinel */ }
+};
+
+static int bcm6345_reset_probe(struct udevice *dev)
+{
+	struct bcm6345_reset_priv *priv = dev_get_priv(dev);
+	fdt_addr_t addr;
+	fdt_size_t size;
+
+	addr = dev_get_addr_size_index(dev, 0, &size);
+	if (addr == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	priv->regs = ioremap(addr, size);
+
+	return 0;
+}
+
+U_BOOT_DRIVER(bcm6345_reset) = {
+	.name = "bcm6345-reset",
+	.id = UCLASS_RESET,
+	.of_match = bcm6345_reset_ids,
+	.ops = &bcm6345_reset_reset_ops,
+	.probe = bcm6345_reset_probe,
+	.priv_auto_alloc_size = sizeof(struct bcm6345_reset_priv),
+};
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 58320666b7d427710c5783c4e1d53936813e8a0e..724994568dfce711a6b5891205ec2c7cfb9163d0 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -145,6 +145,14 @@ config DEBUG_UART_ATMEL
 	  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_BCM6345
+	bool "BCM6345 UART"
+	depends on BCM6345_SERIAL
+	help
+	  Select this to enable a debug UART on BCM6345 SoCs. You
+	  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_NS16550
 	bool "ns16550"
 	help
@@ -350,6 +358,12 @@ config ATMEL_USART
 	  configured in the device tree, and input clock frequency can
 	  be got from the clk node.
 
+config BCM6345_SERIAL
+	bool "Support for BCM6345 UART"
+	depends on DM_SERIAL && ARCH_BMIPS
+	help
+	  Select this to enable UART on BCM6345 SoCs.
+
 config FSL_LPUART
 	bool "Freescale LPUART support"
 	help
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 4382cf93297b25a4ae35044bbd1dd31e813f795c..dca31b295c14acb2aa326d74daa29122dfa93428 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_ALTERA_JTAG_UART) += altera_jtag_uart.o
 obj-$(CONFIG_AR933X_UART) += serial_ar933x.o
 obj-$(CONFIG_ARM_DCC) += arm_dcc.o
 obj-$(CONFIG_ATMEL_USART) += atmel_usart.o
+obj-$(CONFIG_BCM6345_SERIAL) += serial_bcm6345.o
 obj-$(CONFIG_EFI_APP) += serial_efi.o
 obj-$(CONFIG_LPC32XX_HSUART) += lpc32xx_hsuart.o
 obj-$(CONFIG_MCFUART) += mcfuart.o
diff --git a/drivers/serial/serial_bcm6345.c b/drivers/serial/serial_bcm6345.c
new file mode 100644
index 0000000000000000000000000000000000000000..db270e3b21bd1cdc76b3fa9dad98b878ddc9f3f5
--- /dev/null
+++ b/drivers/serial/serial_bcm6345.c
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/tty/serial/bcm63xx_uart.c:
+ *	Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <clk.h>
+#include <debug_uart.h>
+#include <errno.h>
+#include <serial.h>
+#include <asm/io.h>
+#include <asm/types.h>
+#include <dm/device.h>
+
+/* UART Control register */
+#define UART_CTL_REG			0x0
+#define UART_CTL_RXTIMEOUT_MASK		0x1f
+#define UART_CTL_RXTIMEOUT_5		0x5
+#define UART_CTL_RSTRXFIFO_SHIFT	6
+#define UART_CTL_RSTRXFIFO_MASK		(1 << UART_CTL_RSTRXFIFO_SHIFT)
+#define UART_CTL_RSTTXFIFO_SHIFT	7
+#define UART_CTL_RSTTXFIFO_MASK		(1 << UART_CTL_RSTTXFIFO_SHIFT)
+#define UART_CTL_STOPBITS_SHIFT		8
+#define UART_CTL_STOPBITS_MASK		(0xf << UART_CTL_STOPBITS_SHIFT)
+#define UART_CTL_STOPBITS_1		(0x7 << UART_CTL_STOPBITS_SHIFT)
+#define UART_CTL_BITSPERSYM_SHIFT	12
+#define UART_CTL_BITSPERSYM_MASK	(0x3 << UART_CTL_BITSPERSYM_SHIFT)
+#define UART_CTL_BITSPERSYM_8		(0x3 << UART_CTL_BITSPERSYM_SHIFT)
+#define UART_CTL_XMITBRK_SHIFT		14
+#define UART_CTL_XMITBRK_MASK		(1 << UART_CTL_XMITBRK_SHIFT)
+#define UART_CTL_RSVD_SHIFT		15
+#define UART_CTL_RSVD_MASK		(1 << UART_CTL_RSVD_SHIFT)
+#define UART_CTL_RXPAREVEN_SHIFT	16
+#define UART_CTL_RXPAREVEN_MASK		(1 << UART_CTL_RXPAREVEN_SHIFT)
+#define UART_CTL_RXPAREN_SHIFT		17
+#define UART_CTL_RXPAREN_MASK		(1 << UART_CTL_RXPAREN_SHIFT)
+#define UART_CTL_TXPAREVEN_SHIFT	18
+#define UART_CTL_TXPAREVEN_MASK		(1 << UART_CTL_TXPAREVEN_SHIFT)
+#define UART_CTL_TXPAREN_SHIFT		19
+#define UART_CTL_TXPAREN_MASK		(1 << UART_CTL_TXPAREN_SHIFT)
+#define UART_CTL_LOOPBACK_SHIFT		20
+#define UART_CTL_LOOPBACK_MASK		(1 << UART_CTL_LOOPBACK_SHIFT)
+#define UART_CTL_RXEN_SHIFT		21
+#define UART_CTL_RXEN_MASK		(1 << UART_CTL_RXEN_SHIFT)
+#define UART_CTL_TXEN_SHIFT		22
+#define UART_CTL_TXEN_MASK		(1 << UART_CTL_TXEN_SHIFT)
+#define UART_CTL_BRGEN_SHIFT		23
+#define UART_CTL_BRGEN_MASK		(1 << UART_CTL_BRGEN_SHIFT)
+
+/* UART Baudword register */
+#define UART_BAUD_REG			0x4
+
+/* UART FIFO Config register */
+#define UART_FIFO_CFG_REG		0x8
+#define UART_FIFO_CFG_RX_SHIFT		8
+#define UART_FIFO_CFG_RX_MASK		(0xf << UART_FIFO_CFG_RX_SHIFT)
+#define UART_FIFO_CFG_RX_4		(0x4 << UART_FIFO_CFG_RX_SHIFT)
+#define UART_FIFO_CFG_TX_SHIFT		12
+#define UART_FIFO_CFG_TX_MASK		(0xf << UART_FIFO_CFG_TX_SHIFT)
+#define UART_FIFO_CFG_TX_4		(0x4 << UART_FIFO_CFG_TX_SHIFT)
+
+/* UART Interrupt register */
+#define UART_IR_REG			0x10
+#define UART_IR_STAT(x)			(1 << (x))
+#define UART_IR_TXEMPTY			5
+#define UART_IR_RXOVER			7
+#define UART_IR_RXNOTEMPTY		11
+
+/* UART FIFO register */
+#define UART_FIFO_REG			0x14
+#define UART_FIFO_VALID_MASK		0xff
+#define UART_FIFO_FRAMEERR_SHIFT	8
+#define UART_FIFO_FRAMEERR_MASK		(1 << UART_FIFO_FRAMEERR_SHIFT)
+#define UART_FIFO_PARERR_SHIFT		9
+#define UART_FIFO_PARERR_MASK		(1 << UART_FIFO_PARERR_SHIFT)
+#define UART_FIFO_BRKDET_SHIFT		10
+#define UART_FIFO_BRKDET_MASK		(1 << UART_FIFO_BRKDET_SHIFT)
+#define UART_FIFO_ANYERR_MASK		(UART_FIFO_FRAMEERR_MASK |	\
+					UART_FIFO_PARERR_MASK |		\
+					UART_FIFO_BRKDET_MASK)
+
+struct bcm6345_serial_priv {
+	void __iomem *base;
+	ulong uartclk;
+};
+
+/* enable rx & tx operation on uart */
+static void bcm6345_serial_enable(void __iomem *base)
+{
+	setbits_be32(base + UART_CTL_REG, UART_CTL_BRGEN_MASK |
+		     UART_CTL_TXEN_MASK | UART_CTL_RXEN_MASK);
+}
+
+/* disable rx & tx operation on uart */
+static void bcm6345_serial_disable(void __iomem *base)
+{
+	clrbits_be32(base + UART_CTL_REG, UART_CTL_BRGEN_MASK |
+		     UART_CTL_TXEN_MASK | UART_CTL_RXEN_MASK);
+}
+
+/* clear all unread data in rx fifo and unsent data in tx fifo */
+static void bcm6345_serial_flush(void __iomem *base)
+{
+	/* empty rx and tx fifo */
+	setbits_be32(base + UART_CTL_REG, UART_CTL_RSTRXFIFO_MASK |
+		     UART_CTL_RSTTXFIFO_MASK);
+
+	/* read any pending char to make sure all irq status are cleared */
+	readl_be(base + UART_FIFO_REG);
+}
+
+static int bcm6345_serial_init(void __iomem *base, ulong clk, u32 baudrate)
+{
+	u32 val;
+
+	/* mask all irq and flush port */
+	bcm6345_serial_disable(base);
+	bcm6345_serial_flush(base);
+
+	/* set uart control config */
+	clrsetbits_be32(base + UART_CTL_REG,
+			/* clear rx timeout */
+			UART_CTL_RXTIMEOUT_MASK |
+			/* clear stop bits */
+			UART_CTL_STOPBITS_MASK |
+			/* clear bits per symbol */
+			UART_CTL_BITSPERSYM_MASK |
+			/* clear xmit break */
+			UART_CTL_XMITBRK_MASK |
+			/* clear reserved bit */
+			UART_CTL_RSVD_MASK |
+			/* disable parity */
+			UART_CTL_RXPAREN_MASK |
+			UART_CTL_TXPAREN_MASK |
+			/* disable loopback */
+			UART_CTL_LOOPBACK_MASK,
+			/* set timeout to 5 */
+			UART_CTL_RXTIMEOUT_5 |
+			/* set 8 bits/symbol */
+			UART_CTL_BITSPERSYM_8 |
+			/* set parity to even */
+			UART_CTL_RXPAREVEN_MASK |
+			UART_CTL_TXPAREVEN_MASK);
+
+	/* set uart fifo config */
+	clrsetbits_be32(base + UART_FIFO_CFG_REG,
+			/* clear fifo config */
+			UART_FIFO_CFG_RX_MASK |
+			UART_FIFO_CFG_TX_MASK,
+			/* set fifo config to 4 */
+			UART_FIFO_CFG_RX_4 |
+			UART_FIFO_CFG_TX_4);
+
+	/* set baud rate */
+	val = (clk / baudrate) / 16;
+	if (val & 0x1)
+		val = val;
+	else
+		val = val / 2 - 1;
+	writel_be(val, base + UART_BAUD_REG);
+
+	/* clear interrupts */
+	writel_be(0, base + UART_IR_REG);
+
+	/* enable uart */
+	bcm6345_serial_enable(base);
+
+	return 0;
+}
+
+static int bcm6345_serial_pending(struct udevice *dev, bool input)
+{
+	struct bcm6345_serial_priv *priv = dev_get_priv(dev);
+	u32 val = readl_be(priv->base + UART_IR_REG);
+
+	if (input)
+		return !!(val & UART_IR_STAT(UART_IR_RXNOTEMPTY));
+	else
+		return !(val & UART_IR_STAT(UART_IR_TXEMPTY));
+}
+
+static int bcm6345_serial_setbrg(struct udevice *dev, int baudrate)
+{
+	struct bcm6345_serial_priv *priv = dev_get_priv(dev);
+
+	return bcm6345_serial_init(priv->base, priv->uartclk, baudrate);
+}
+
+static int bcm6345_serial_putc(struct udevice *dev, const char ch)
+{
+	struct bcm6345_serial_priv *priv = dev_get_priv(dev);
+	u32 val;
+
+	val = readl_be(priv->base + UART_IR_REG);
+	if (!(val & UART_IR_STAT(UART_IR_TXEMPTY)))
+		return -EAGAIN;
+
+	writel_be(ch, priv->base + UART_FIFO_REG);
+
+	return 0;
+}
+
+static int bcm6345_serial_getc(struct udevice *dev)
+{
+	struct bcm6345_serial_priv *priv = dev_get_priv(dev);
+	u32 val;
+
+	val = readl_be(priv->base + UART_IR_REG);
+	if (val & UART_IR_STAT(UART_IR_RXOVER))
+		setbits_be32(priv->base + UART_CTL_REG,
+			     UART_CTL_RSTRXFIFO_MASK);
+	if (!(val & UART_IR_STAT(UART_IR_RXNOTEMPTY)))
+		return -EAGAIN;
+
+	val = readl_be(priv->base + UART_FIFO_REG);
+	if (val & UART_FIFO_ANYERR_MASK)
+		return -EAGAIN;
+
+	return val & UART_FIFO_VALID_MASK;
+}
+
+static int bcm6345_serial_probe(struct udevice *dev)
+{
+	struct bcm6345_serial_priv *priv = dev_get_priv(dev);
+	struct clk clk;
+	fdt_addr_t addr;
+	fdt_size_t size;
+	int ret;
+
+	/* get address */
+	addr = dev_get_addr_size_index(dev, 0, &size);
+	if (addr == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	priv->base = ioremap(addr, size);
+
+	/* get clock rate */
+	ret = clk_get_by_index(dev, 0, &clk);
+	if (ret < 0)
+		return ret;
+	priv->uartclk = clk_get_rate(&clk) / 2;
+	clk_free(&clk);
+
+	/* initialize serial */
+	return bcm6345_serial_init(priv->base, priv->uartclk, CONFIG_BAUDRATE);
+}
+
+static const struct dm_serial_ops bcm6345_serial_ops = {
+	.putc = bcm6345_serial_putc,
+	.pending = bcm6345_serial_pending,
+	.getc = bcm6345_serial_getc,
+	.setbrg = bcm6345_serial_setbrg,
+};
+
+static const struct udevice_id bcm6345_serial_ids[] = {
+	{ .compatible = "brcm,bcm6345-uart" },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(bcm6345_serial) = {
+	.name = "bcm6345-uart",
+	.id = UCLASS_SERIAL,
+	.of_match = bcm6345_serial_ids,
+	.probe = bcm6345_serial_probe,
+	.priv_auto_alloc_size = sizeof(struct bcm6345_serial_priv),
+	.ops = &bcm6345_serial_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
+
+#ifdef CONFIG_DEBUG_UART_BCM6345
+static inline void _debug_uart_init(void)
+{
+	void __iomem *base = (void __iomem *)CONFIG_DEBUG_UART_BASE;
+
+	bcm6345_serial_init(base, CONFIG_DEBUG_UART_CLOCK, CONFIG_BAUDRATE);
+}
+
+static inline void wait_xfered(void __iomem *base)
+{
+	do {
+		u32 val = readl_be(base + UART_IR_REG);
+		if (val & UART_IR_STAT(UART_IR_TXEMPTY))
+			break;
+	} while (1);
+}
+
+static inline void _debug_uart_putc(int ch)
+{
+	void __iomem *base = (void __iomem *)CONFIG_DEBUG_UART_BASE;
+
+	wait_xfered(base);
+	writel_be(ch, base + UART_FIFO_REG);
+	wait_xfered(base);
+}
+
+DEBUG_UART_FUNCS
+#endif
diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig
index 966463036f1175cd26b0cc6aeaba32a2fb8a370a..b2f746494d29520bee1eb1fa1269ddb9639b257a 100644
--- a/drivers/sysreset/Kconfig
+++ b/drivers/sysreset/Kconfig
@@ -23,4 +23,12 @@ config SYSRESET_PSCI
 	  must be running on your system.
 
 endif
+
+config SYSRESET_SYSCON
+	bool "Enable support for mfd syscon reboot driver"
+	select REGMAP
+	select SYSCON
+	help
+	  Reboot support for generic SYSCON mapped register reset.
+
 endmenu
diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile
index 7bb840649ff95655183d796c62af29f6b691a6ea..bd352e754150456c3a5ab6acc352256abc8d34d9 100644
--- a/drivers/sysreset/Makefile
+++ b/drivers/sysreset/Makefile
@@ -6,6 +6,7 @@
 
 obj-$(CONFIG_SYSRESET) += sysreset-uclass.o
 obj-$(CONFIG_SYSRESET_PSCI) += sysreset_psci.o
+obj-$(CONFIG_SYSRESET_SYSCON) += sysreset_syscon.o
 
 ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_ROCKCHIP_RK3036) += sysreset_rk3036.o
diff --git a/drivers/sysreset/sysreset_syscon.c b/drivers/sysreset/sysreset_syscon.c
new file mode 100644
index 0000000000000000000000000000000000000000..3818faeb462fe7761c20c8b42e2e90f3dad2167c
--- /dev/null
+++ b/drivers/sysreset/sysreset_syscon.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/power/reset/syscon-reboot.c:
+ *	Copyright (C) 2013, Applied Micro Circuits Corporation
+ *	Author: Feng Kan <fkan@apm.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <regmap.h>
+#include <sysreset.h>
+#include <syscon.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct syscon_reboot_priv {
+	struct regmap *regmap;
+	unsigned int offset;
+	unsigned int mask;
+};
+
+static int syscon_reboot_request(struct udevice *dev, enum sysreset_t type)
+{
+	struct syscon_reboot_priv *priv = dev_get_priv(dev);
+
+	regmap_write(priv->regmap, priv->offset, priv->mask);
+
+	return -EINPROGRESS;
+}
+
+static struct sysreset_ops syscon_reboot_ops = {
+	.request = syscon_reboot_request,
+};
+
+int syscon_reboot_probe(struct udevice *dev)
+{
+	struct udevice *syscon;
+	struct syscon_reboot_priv *priv = dev_get_priv(dev);
+	int err;
+
+	err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
+					   "regmap", &syscon);
+	if (err) {
+		error("unable to find syscon device\n");
+		return err;
+	}
+
+	priv->regmap = syscon_get_regmap(syscon);
+	if (!priv->regmap) {
+		error("unable to find regmap\n");
+		return -ENODEV;
+	}
+
+	priv->offset = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
+				       "offset", 0);
+	priv->mask = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
+				       "mask", 0);
+
+	return 0;
+}
+
+static const struct udevice_id syscon_reboot_ids[] = {
+	{ .compatible = "syscon-reboot" },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(syscon_reboot) = {
+	.name = "syscon_reboot",
+	.id = UCLASS_SYSRESET,
+	.of_match = syscon_reboot_ids,
+	.probe = syscon_reboot_probe,
+	.priv_auto_alloc_size = sizeof(struct syscon_reboot_priv),
+	.ops = &syscon_reboot_ops,
+};
diff --git a/include/configs/bmips_bcm63268.h b/include/configs/bmips_bcm63268.h
new file mode 100644
index 0000000000000000000000000000000000000000..ac0a6700f7c18f08272803909234f3d1fe586829
--- /dev/null
+++ b/include/configs/bmips_bcm63268.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __CONFIG_BMIPS_BCM63268_H
+#define __CONFIG_BMIPS_BCM63268_H
+
+/* CPU */
+#define CONFIG_SYS_MIPS_TIMER_FREQ	200000000
+
+/* RAM */
+#define CONFIG_NR_DRAM_BANKS		1
+#define CONFIG_SYS_SDRAM_BASE		0x80000000
+
+/* U-Boot */
+#define CONFIG_SYS_LOAD_ADDR		CONFIG_SYS_SDRAM_BASE + 0x100000
+
+#if defined(CONFIG_BMIPS_BOOT_RAM)
+#define CONFIG_SKIP_LOWLEVEL_INIT
+#define CONFIG_SYS_INIT_SP_OFFSET	0x2000
+#endif
+
+#endif /* __CONFIG_BMIPS_BCM63268_H */
diff --git a/include/configs/bmips_bcm6328.h b/include/configs/bmips_bcm6328.h
new file mode 100644
index 0000000000000000000000000000000000000000..41c7838a232eba79eb138704fe49e72490988b42
--- /dev/null
+++ b/include/configs/bmips_bcm6328.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __CONFIG_BMIPS_BCM6328_H
+#define __CONFIG_BMIPS_BCM6328_H
+
+/* CPU */
+#define CONFIG_SYS_MIPS_TIMER_FREQ	160000000
+
+/* RAM */
+#define CONFIG_NR_DRAM_BANKS		1
+#define CONFIG_SYS_SDRAM_BASE		0x80000000
+
+/* U-Boot */
+#define CONFIG_SYS_LOAD_ADDR		CONFIG_SYS_SDRAM_BASE + 0x100000
+
+#if defined(CONFIG_BMIPS_BOOT_RAM)
+#define CONFIG_SKIP_LOWLEVEL_INIT
+#define CONFIG_SYS_INIT_SP_OFFSET	0x2000
+#endif
+
+#endif /* __CONFIG_BMIPS_BCM6328_H */
diff --git a/include/configs/bmips_bcm6358.h b/include/configs/bmips_bcm6358.h
new file mode 100644
index 0000000000000000000000000000000000000000..5d018a348140f0ffad71def1406d34625f961030
--- /dev/null
+++ b/include/configs/bmips_bcm6358.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __CONFIG_BMIPS_BCM6358_H
+#define __CONFIG_BMIPS_BCM6358_H
+
+/* CPU */
+#define CONFIG_SYS_MIPS_TIMER_FREQ	150000000
+
+/* RAM */
+#define CONFIG_NR_DRAM_BANKS		1
+#define CONFIG_SYS_SDRAM_BASE		0x80000000
+
+/* U-Boot */
+#define CONFIG_SYS_LOAD_ADDR		CONFIG_SYS_SDRAM_BASE + 0x100000
+
+#if defined(CONFIG_BMIPS_BOOT_RAM)
+#define CONFIG_SKIP_LOWLEVEL_INIT
+#define CONFIG_SYS_INIT_SP_OFFSET	0x2000
+#endif
+
+#define CONFIG_SYS_FLASH_BASE			0xbe000000
+#define CONFIG_SYS_FLASH_EMPTY_INFO
+#define CONFIG_SYS_FLASH_PROTECTION
+#define CONFIG_SYS_MAX_FLASH_BANKS_DETECT	1
+
+#endif /* __CONFIG_BMIPS_BCM6358_H */
diff --git a/include/configs/bmips_common.h b/include/configs/bmips_common.h
new file mode 100644
index 0000000000000000000000000000000000000000..d2b05d44c8b86f073dbe686d83d3934309011737
--- /dev/null
+++ b/include/configs/bmips_common.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __CONFIG_BMIPS_COMMON_H
+#define __CONFIG_BMIPS_COMMON_H
+
+/* RAM */
+#define CONFIG_SYS_MEMTEST_START	0xa0000000
+#define CONFIG_SYS_MEMTEST_END		0xa2000000
+
+/* Memory usage */
+#define CONFIG_SYS_MAXARGS		24
+#define CONFIG_SYS_MALLOC_LEN		(1024 * 1024)
+#define CONFIG_SYS_BOOTPARAMS_LEN	(128 * 1024)
+#define CONFIG_SYS_CBSIZE		512
+
+/* U-Boot */
+#define CONFIG_SYS_MONITOR_BASE		CONFIG_SYS_TEXT_BASE
+
+#endif /* __CONFIG_BMIPS_COMMON_H */
diff --git a/include/configs/comtrend_ar5387un.h b/include/configs/comtrend_ar5387un.h
new file mode 100644
index 0000000000000000000000000000000000000000..5d8f968c4d8f8a4baa97b8f450d60d0e46ce855e
--- /dev/null
+++ b/include/configs/comtrend_ar5387un.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <configs/bmips_common.h>
+#include <configs/bmips_bcm6328.h>
+
+#define CONFIG_REMAKE_ELF
+
+#define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_SIZE			(8 * 1024)
+
+#define CONFIG_AUTO_COMPLETE
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_SYS_LONGHELP
diff --git a/include/configs/comtrend_vr3032u.h b/include/configs/comtrend_vr3032u.h
new file mode 100644
index 0000000000000000000000000000000000000000..d45f8b32dafe125e97ca71b49a24cfe5eee301d9
--- /dev/null
+++ b/include/configs/comtrend_vr3032u.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <configs/bmips_common.h>
+#include <configs/bmips_bcm63268.h>
+
+#define CONFIG_REMAKE_ELF
+
+#define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_SIZE			(8 * 1024)
+
+#define CONFIG_AUTO_COMPLETE
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_SYS_LONGHELP
diff --git a/include/configs/huawei_hg556a.h b/include/configs/huawei_hg556a.h
new file mode 100644
index 0000000000000000000000000000000000000000..ab64518e0b1514ee58b9d86cf098631012196292
--- /dev/null
+++ b/include/configs/huawei_hg556a.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <configs/bmips_common.h>
+#include <configs/bmips_bcm6358.h>
+
+#define CONFIG_REMAKE_ELF
+
+#define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_SIZE			(8 * 1024)
+
+#define CONFIG_AUTO_COMPLETE
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_SYS_LONGHELP
+
+#define CONFIG_SYS_FLASH_CFI		1
+#define CONFIG_FLASH_CFI_DRIVER		1
diff --git a/include/configs/sfr_nb4_ser.h b/include/configs/sfr_nb4_ser.h
new file mode 100644
index 0000000000000000000000000000000000000000..ab64518e0b1514ee58b9d86cf098631012196292
--- /dev/null
+++ b/include/configs/sfr_nb4_ser.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <configs/bmips_common.h>
+#include <configs/bmips_bcm6358.h>
+
+#define CONFIG_REMAKE_ELF
+
+#define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_SIZE			(8 * 1024)
+
+#define CONFIG_AUTO_COMPLETE
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_SYS_LONGHELP
+
+#define CONFIG_SYS_FLASH_CFI		1
+#define CONFIG_FLASH_CFI_DRIVER		1
diff --git a/include/dt-bindings/clock/bcm63268-clock.h b/include/dt-bindings/clock/bcm63268-clock.h
new file mode 100644
index 0000000000000000000000000000000000000000..23818da1a0e295f192363fb2e93789d117c5d41b
--- /dev/null
+++ b/include/dt-bindings/clock/bcm63268-clock.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_BCM63268_H
+#define __DT_BINDINGS_CLOCK_BCM63268_H
+
+#define BCM63268_CLK_GLESS	0
+#define BCM63268_CLK_VDSL_QPROC	1
+#define BCM63268_CLK_VDSL_AFE	2
+#define BCM63268_CLK_VDSL	3
+#define BCM63268_CLK_MIPS	4
+#define BCM63268_CLK_WLAN_OCP	5
+#define BCM63268_CLK_DECT	6
+#define BCM63268_CLK_FAP0	7
+#define BCM63268_CLK_FAP1	8
+#define BCM63268_CLK_SAR	9
+#define BCM63268_CLK_ROBOSW	10
+#define BCM63268_CLK_PCM	11
+#define BCM63268_CLK_USBD	12
+#define BCM63268_CLK_USBH	13
+#define BCM63268_CLK_IPSEC	14
+#define BCM63268_CLK_SPI	15
+#define BCM63268_CLK_HSSPI	16
+#define BCM63268_CLK_PCIE	17
+#define BCM63268_CLK_PHYMIPS	18
+#define BCM63268_CLK_GMAC	19
+#define BCM63268_CLK_NAND	20
+#define BCM63268_CLK_TBUS	27
+#define BCM63268_CLK_ROBOSW250	31
+
+#define BCM63268_TCLK_EPHY1	0
+#define BCM63268_TCLK_EPHY2	1
+#define BCM63268_TCLK_EPHY3	2
+#define BCM63268_TCLK_GPHY	3
+#define BCM63268_TCLK_DSL	4
+#define BCM63268_TCLK_WO_EPHY	5
+#define BCM63268_TCLK_WO_DSL	6
+#define BCM63268_TCLK_FAP1	11
+#define BCM63268_TCLK_FAP2	15
+#define BCM63268_TCLK_UTO_50	16
+#define BCM63268_TCLK_UTO_EXT	17
+#define BCM63268_TCLK_USB_REF	18
+#define BCM63268_TCLK_SW_RST	29
+#define BCM63268_TCLK_HW_RST	30
+#define BCM63268_TCLK_POR_RST	31
+
+#endif /* __DT_BINDINGS_CLOCK_BCM63268_H */
diff --git a/include/dt-bindings/clock/bcm6328-clock.h b/include/dt-bindings/clock/bcm6328-clock.h
new file mode 100644
index 0000000000000000000000000000000000000000..5d0fc115e7eb6f88d9477b667e3b442ff4c59c94
--- /dev/null
+++ b/include/dt-bindings/clock/bcm6328-clock.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_BCM6328_H
+#define __DT_BINDINGS_CLOCK_BCM6328_H
+
+#define BCM6328_CLK_PHYMIPS	0
+#define BCM6328_CLK_ADSL_QPROC	1
+#define BCM6328_CLK_ADSL_AFE	2
+#define BCM6328_CLK_ADSL	3
+#define BCM6328_CLK_MIPS	4
+#define BCM6328_CLK_SAR		5
+#define BCM6328_CLK_PCM		6
+#define BCM6328_CLK_USBD	7
+#define BCM6328_CLK_USBH	8
+#define BCM6328_CLK_HSSPI	9
+#define BCM6328_CLK_PCIE	10
+#define BCM6328_CLK_ROBOSW	11
+
+#endif /* __DT_BINDINGS_CLOCK_BCM6328_H */
diff --git a/include/dt-bindings/clock/bcm6358-clock.h b/include/dt-bindings/clock/bcm6358-clock.h
new file mode 100644
index 0000000000000000000000000000000000000000..ff2232123b9e3e8293fd9d1e74a1585ec7563402
--- /dev/null
+++ b/include/dt-bindings/clock/bcm6358-clock.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_BCM6358_H
+#define __DT_BINDINGS_CLOCK_BCM6358_H
+
+#define BCM6358_CLK_ENET	4
+#define BCM6358_CLK_ADSL	5
+#define BCM6358_CLK_PCM		8
+#define BCM6358_CLK_SPI		9
+#define BCM6358_CLK_USBS	10
+#define BCM6358_CLK_SAR		11
+#define BCM6358_CLK_EMUSB	17
+#define BCM6358_CLK_ENET0	18
+#define BCM6358_CLK_ENET1	19
+#define BCM6358_CLK_USBSU	20
+#define BCM6358_CLK_EPHY	21
+
+#endif /* __DT_BINDINGS_CLOCK_BCM6358_H */
diff --git a/include/dt-bindings/power-domain/bcm63268-power-domain.h b/include/dt-bindings/power-domain/bcm63268-power-domain.h
new file mode 100644
index 0000000000000000000000000000000000000000..d9eba4418e5a59063761824564ad4dd3a6b138c5
--- /dev/null
+++ b/include/dt-bindings/power-domain/bcm63268-power-domain.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __DT_BINDINGS_POWER_DOMAIN_BCM63268_H
+#define __DT_BINDINGS_POWER_DOMAIN_BCM63268_H
+
+#define BCM63268_PWR_SAR	0
+#define BCM63268_PWR_IPSEC	1
+#define BCM63268_PWR_MIPS	2
+#define BCM63268_PWR_DECT	3
+#define BCM63268_PWR_USBH	4
+#define BCM63268_PWR_USBD	5
+#define BCM63268_PWR_ROBOSW	6
+#define BCM63268_PWR_PCM	7
+#define BCM63268_PWR_PERIPH	8
+#define BCM63268_PWR_VDSL_PHY	9
+#define BCM63268_PWR_VDSL_MIPS	10
+#define BCM63268_PWR_FAP	11
+#define BCM63268_PWR_PCIE	12
+#define BCM63268_PWR_WLAN_PADS	13
+
+#endif /* __DT_BINDINGS_POWER_DOMAIN_BCM63268_H */
diff --git a/include/dt-bindings/power-domain/bcm6328-power-domain.h b/include/dt-bindings/power-domain/bcm6328-power-domain.h
new file mode 100644
index 0000000000000000000000000000000000000000..006806c9358657cfa85f30aae204b24474af84c7
--- /dev/null
+++ b/include/dt-bindings/power-domain/bcm6328-power-domain.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __DT_BINDINGS_POWER_DOMAIN_BCM6328_H
+#define __DT_BINDINGS_POWER_DOMAIN_BCM6328_H
+
+#define BCM6328_PWR_ADSL2_MIPS	0
+#define BCM6328_PWR_ADSL2_PHY	1
+#define BCM6328_PWR_ADSL2_AFE	2
+#define BCM6328_PWR_SAR		3
+#define BCM6328_PWR_PCM		4
+#define BCM6328_PWR_USBD	5
+#define BCM6328_PWR_USBH	6
+#define BCM6328_PWR_PCIE	7
+#define BCM6328_PWR_ROBOSW	8
+#define BCM6328_PWR_EPHY	9
+
+#endif /* __DT_BINDINGS_POWER_DOMAIN_BCM6328_H */
diff --git a/include/dt-bindings/reset/bcm63268-reset.h b/include/dt-bindings/reset/bcm63268-reset.h
new file mode 100644
index 0000000000000000000000000000000000000000..1373884b361c9ae8ba246e0cada12781a6f97438
--- /dev/null
+++ b/include/dt-bindings/reset/bcm63268-reset.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __DT_BINDINGS_RESET_BCM63268_H
+#define __DT_BINDINGS_RESET_BCM63268_H
+
+#define BCM63268_RST_SPI	0
+#define BCM63268_RST_IPSEC	1
+#define BCM63268_RST_EPHY	2
+#define BCM63268_RST_SAR	3
+#define BCM63268_RST_ENETSW	4
+#define BCM63268_RST_USBS	5
+#define BCM63268_RST_USBH	6
+#define BCM63268_RST_PCM	7
+#define BCM63268_RST_PCIE_CORE	8
+#define BCM63268_RST_PCIE	9
+#define BCM63268_RST_PCIE_EXT	10
+#define BCM63268_RST_WLAN_SHIM	11
+#define BCM63268_RST_DDR_PHY	12
+#define BCM63268_RST_FAP0	13
+#define BCM63268_RST_WLAN_UBUS	14
+#define BCM63268_RST_DECT	15
+#define BCM63268_RST_FAP1	16
+#define BCM63268_RST_PCIE_HARD	17
+#define BCM63268_RST_GPHY	18
+
+#endif /* __DT_BINDINGS_RESET_BCM63268_H */
diff --git a/include/dt-bindings/reset/bcm6328-reset.h b/include/dt-bindings/reset/bcm6328-reset.h
new file mode 100644
index 0000000000000000000000000000000000000000..c144ad2a787b0729a11c0d462bddb53be695930f
--- /dev/null
+++ b/include/dt-bindings/reset/bcm6328-reset.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __DT_BINDINGS_RESET_BCM6328_H
+#define __DT_BINDINGS_RESET_BCM6328_H
+
+#define BCM6328_RST_SPI		0
+#define BCM6328_RST_EPHY	1
+#define BCM6328_RST_SAR		2
+#define BCM6328_RST_ENETSW	3
+#define BCM6328_RST_USBS	4
+#define BCM6328_RST_USBH	5
+#define BCM6328_RST_PCM		6
+#define BCM6328_RST_PCIE_CORE	7
+#define BCM6328_RST_PCIE	8
+#define BCM6328_RST_PCIE_EXT	9
+#define BCM6328_RST_PCIE_HARD	10
+
+#endif /* __DT_BINDINGS_RESET_BCM6328_H */
diff --git a/include/dt-bindings/reset/bcm6358-reset.h b/include/dt-bindings/reset/bcm6358-reset.h
new file mode 100644
index 0000000000000000000000000000000000000000..4b3cff3e491bb2fcce75db48d673328aca66781c
--- /dev/null
+++ b/include/dt-bindings/reset/bcm6358-reset.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __DT_BINDINGS_RESET_BCM6358_H
+#define __DT_BINDINGS_RESET_BCM6358_H
+
+#define BCM6358_RST_SPI		0
+#define BCM6358_RST_ENET	2
+#define BCM6358_RST_MPI		3
+#define BCM6358_RST_EPHY	6
+#define BCM6358_RST_SAR		7
+#define BCM6358_RST_USBH	12
+#define BCM6358_RST_PCM		13
+#define BCM6358_RST_ADSL	14
+
+#endif /* __DT_BINDINGS_RESET_BCM6358_H */