This target supports some of the xDSL Broadcom MIPS SoCs for now.
However, support for other SoCs could be added in the future.

Signed-off-by: Álvaro Fernández Rojas <nolt...@gmail.com>
---
 arch/mips/Kconfig                       |  10 ++
 arch/mips/Makefile                      |   1 +
 arch/mips/dts/Makefile                  |   3 +
 arch/mips/dts/brcm,bcm63268.dtsi        |  87 +++++++++++
 arch/mips/dts/brcm,bcm6328.dtsi         |  87 +++++++++++
 arch/mips/dts/brcm,bcm6358.dtsi         |  97 ++++++++++++
 arch/mips/dts/comtrend,ar-5387un.dts    |  27 ++++
 arch/mips/dts/comtrend,vr-3032u.dts     |  27 ++++
 arch/mips/dts/huawei,hg556a.dts         |  31 ++++
 arch/mips/mach-bmips/Kconfig            |  86 ++++++++++
 arch/mips/mach-bmips/Makefile           |   5 +
 arch/mips/mach-bmips/dram.c             |  37 +++++
 board/comtrend/ar5387un/Kconfig         |  24 +++
 board/comtrend/ar5387un/MAINTAINERS     |   6 +
 board/comtrend/ar5387un/Makefile        |   5 +
 board/comtrend/ar5387un/ar-5387un.c     |  22 +++
 board/comtrend/vr3032u/Kconfig          |  24 +++
 board/comtrend/vr3032u/MAINTAINERS      |   6 +
 board/comtrend/vr3032u/Makefile         |   5 +
 board/comtrend/vr3032u/vr-3032u.c       |  22 +++
 board/huawei/hg556a/Kconfig             |  24 +++
 board/huawei/hg556a/MAINTAINERS         |   6 +
 board/huawei/hg556a/Makefile            |   5 +
 board/huawei/hg556a/hg556a.c            |  22 +++
 configs/comtrend_ar5387un_ram_defconfig |  47 ++++++
 configs/comtrend_vr3032u_ram_defconfig  |  47 ++++++
 configs/huawei_hg556a_ram_defconfig     |  47 ++++++
 drivers/cpu/Makefile                    |   2 +
 drivers/cpu/bmips_cpu.c                 | 268 ++++++++++++++++++++++++++++++++
 drivers/ram/Makefile                    |   2 +
 drivers/ram/bmips_ram.c                 | 126 +++++++++++++++
 include/configs/bmips_bcm63268.h        |  25 +++
 include/configs/bmips_bcm6328.h         |  25 +++
 include/configs/bmips_bcm6358.h         |  27 ++++
 include/configs/bmips_common.h          |  26 ++++
 include/configs/comtrend_ar5387un.h     |  15 ++
 include/configs/comtrend_vr3032u.h      |  15 ++
 include/configs/huawei_hg556a.h         |  15 ++
 38 files changed, 1356 insertions(+)
 create mode 100644 arch/mips/dts/brcm,bcm63268.dtsi
 create mode 100644 arch/mips/dts/brcm,bcm6328.dtsi
 create mode 100644 arch/mips/dts/brcm,bcm6358.dtsi
 create mode 100644 arch/mips/dts/comtrend,ar-5387un.dts
 create mode 100644 arch/mips/dts/comtrend,vr-3032u.dts
 create mode 100644 arch/mips/dts/huawei,hg556a.dts
 create mode 100644 arch/mips/mach-bmips/Kconfig
 create mode 100644 arch/mips/mach-bmips/Makefile
 create mode 100644 arch/mips/mach-bmips/dram.c
 create mode 100644 board/comtrend/ar5387un/Kconfig
 create mode 100644 board/comtrend/ar5387un/MAINTAINERS
 create mode 100644 board/comtrend/ar5387un/Makefile
 create mode 100644 board/comtrend/ar5387un/ar-5387un.c
 create mode 100644 board/comtrend/vr3032u/Kconfig
 create mode 100644 board/comtrend/vr3032u/MAINTAINERS
 create mode 100644 board/comtrend/vr3032u/Makefile
 create mode 100644 board/comtrend/vr3032u/vr-3032u.c
 create mode 100644 board/huawei/hg556a/Kconfig
 create mode 100644 board/huawei/hg556a/MAINTAINERS
 create mode 100644 board/huawei/hg556a/Makefile
 create mode 100644 board/huawei/hg556a/hg556a.c
 create mode 100644 configs/comtrend_ar5387un_ram_defconfig
 create mode 100644 configs/comtrend_vr3032u_ram_defconfig
 create mode 100644 configs/huawei_hg556a_ram_defconfig
 create mode 100644 drivers/cpu/bmips_cpu.c
 create mode 100644 drivers/ram/bmips_ram.c
 create mode 100644 include/configs/bmips_bcm63268.h
 create mode 100644 include/configs/bmips_bcm6328.h
 create mode 100644 include/configs/bmips_bcm6358.h
 create mode 100644 include/configs/bmips_common.h
 create mode 100644 include/configs/comtrend_ar5387un.h
 create mode 100644 include/configs/comtrend_vr3032u.h
 create mode 100644 include/configs/huawei_hg556a.h

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index d97930e..c97ea41 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 efe7e44..c30d4ef 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/dts/Makefile b/arch/mips/dts/Makefile
index 30fcc2b..4c02c48 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 0000000..d02472d
--- /dev/null
+++ b/arch/mips/dts/brcm,bcm63268.dtsi
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <nolt...@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include "skeleton.dtsi"
+
+/ {
+       compatible = "brcm,bcm63268";
+
+       cpus {
+               #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;
+               };
+       };
+
+       ubus {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               u-boot,dm-pre-reloc;
+
+               periph_cntl: syscon@10000000 {
+                       compatible = "syscon";
+                       reg = <0x10000000 0x14>;
+               };
+
+               reboot: syscon-reboot {
+                       compatible = "syscon-reboot";
+                       regmap = <&periph_cntl>;
+                       offset = <0x8>;
+                       mask = <0x1>;
+               };
+
+               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";
+               };
+
+               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 0000000..f7f4793
--- /dev/null
+++ b/arch/mips/dts/brcm,bcm6328.dtsi
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <nolt...@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include "skeleton.dtsi"
+
+/ {
+       compatible = "brcm,bcm6328";
+
+       cpus {
+               #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;
+               };
+       };
+
+       ubus {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               u-boot,dm-pre-reloc;
+
+               reset_cntl: syscon@10000068 {
+                       compatible = "syscon";
+                       reg = <0x10000068 0x4>;
+               };
+
+               reboot: syscon-reboot {
+                       compatible = "syscon-reboot";
+                       regmap = <&reset_cntl>;
+                       offset = <0>;
+                       mask = <0x1>;
+               };
+
+               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";
+               };
+
+               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 0000000..4b015d3
--- /dev/null
+++ b/arch/mips/dts/brcm,bcm6358.dtsi
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <nolt...@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include "skeleton.dtsi"
+
+/ {
+       compatible = "brcm,bcm6358";
+
+       cpus {
+               #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;
+               };
+       };
+
+       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;
+
+               periph_cntl: syscon@fffe0000 {
+                       compatible = "syscon";
+                       reg = <0xfffe0000 0xc>;
+               };
+
+               reboot: syscon-reboot {
+                       compatible = "syscon-reboot";
+                       regmap = <&periph_cntl>;
+                       offset = <0x8>;
+                       mask = <0x1>;
+               };
+
+               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 0000000..f9c4a1c
--- /dev/null
+++ b/arch/mips/dts/comtrend,ar-5387un.dts
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <nolt...@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+/dts-v1/;
+
+#include "brcm,bcm6328.dtsi"
+
+/ {
+       model = "Comtrend AR-5387un Board";
+       compatible = "comtrend,ar5387-un", "brcm,bcm6328";
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+};
+
+&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 0000000..c0fdb28
--- /dev/null
+++ b/arch/mips/dts/comtrend,vr-3032u.dts
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <nolt...@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+/dts-v1/;
+
+#include "brcm,bcm63268.dtsi"
+
+/ {
+       model = "Comtrend VR-3032u Board";
+       compatible = "comtrend,vr-3032u", "brcm,bcm63268";
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+};
+
+&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 0000000..08ef2c1
--- /dev/null
+++ b/arch/mips/dts/huawei,hg556a.dts
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <nolt...@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+/dts-v1/;
+
+#include "brcm,bcm6358.dtsi"
+
+/ {
+       model = "Huawei HG556a Board";
+       compatible = "huawei,hg556a", "brcm,bcm6358";
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+};
+
+&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 0000000..2996087
--- /dev/null
+++ b/arch/mips/mach-bmips/Kconfig
@@ -0,0 +1,86 @@
+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 board"
+       depends on SOC_BMIPS_BCM6328
+       select BMIPS_SUPPORTS_BOOT_RAM
+
+config BOARD_HUAWEI_HG556A
+       bool "Huawei HG556a board"
+       depends on SOC_BMIPS_BCM6358
+       select BMIPS_SUPPORTS_BOOT_RAM
+
+config BOARD_COMTREND_VR3032U
+       bool "Comtrend VR-3032u board"
+       depends on SOC_BMIPS_BCM63268
+       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. Caches are
+         disabled and environment is built in.
+
+endchoice
+
+config BMIPS_SUPPORTS_BOOT_RAM
+       bool
+
+source "board/comtrend/ar5387un/Kconfig"
+source "board/huawei/hg556a/Kconfig"
+source "board/comtrend/vr3032u/Kconfig"
+
+endmenu
diff --git a/arch/mips/mach-bmips/Makefile b/arch/mips/mach-bmips/Makefile
new file mode 100644
index 0000000..f432acc
--- /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 0000000..931aa5d
--- /dev/null
+++ b/arch/mips/mach-bmips/dram.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2016 Daniel Schwierzeck <daniel.schwierz...@gmail.com>
+ * Copyright (C) 2017 Álvaro Fernández Rojas <nolt...@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <ram.h>
+#include <dm.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int initdram(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/board/comtrend/ar5387un/Kconfig b/board/comtrend/ar5387un/Kconfig
new file mode 100644
index 0000000..32a69da
--- /dev/null
+++ b/board/comtrend/ar5387un/Kconfig
@@ -0,0 +1,24 @@
+if BOARD_COMTREND_AR5387UN
+
+config SYS_BOARD
+       default "ar5387un"
+
+config SYS_VENDOR
+       default "comtrend"
+
+config SYS_CONFIG_NAME
+       default "comtrend_ar5387un"
+
+config SYS_DCACHE_SIZE
+       default 32768
+
+config SYS_DCACHE_LINE_SIZE
+       default 16
+
+config SYS_ICACHE_SIZE
+       default 32768
+
+config SYS_ICACHE_LINE_SIZE
+       default 16
+
+endif
diff --git a/board/comtrend/ar5387un/MAINTAINERS 
b/board/comtrend/ar5387un/MAINTAINERS
new file mode 100644
index 0000000..bcaac64
--- /dev/null
+++ b/board/comtrend/ar5387un/MAINTAINERS
@@ -0,0 +1,6 @@
+COMTREND AR-5387UN BOARD
+M:     Álvaro Fernández Rojas <nolt...@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 0000000..9de1cd2
--- /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 0000000..429117a
--- /dev/null
+++ b/board/comtrend/ar5387un/ar-5387un.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <nolt...@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/types.h>
+
+#ifdef CONFIG_BOARD_EARLY_INIT_F
+int board_early_init_f(void)
+{
+# ifdef CONFIG_DEBUG_UART
+       debug_uart_init();
+# endif
+
+       return 0;
+}
+#endif
diff --git a/board/comtrend/vr3032u/Kconfig b/board/comtrend/vr3032u/Kconfig
new file mode 100644
index 0000000..1cba219
--- /dev/null
+++ b/board/comtrend/vr3032u/Kconfig
@@ -0,0 +1,24 @@
+if BOARD_COMTREND_VR3032U
+
+config SYS_BOARD
+       default "vr3032u"
+
+config SYS_VENDOR
+       default "comtrend"
+
+config SYS_CONFIG_NAME
+       default "comtrend_vr3032u"
+
+config SYS_DCACHE_SIZE
+       default 32768
+
+config SYS_DCACHE_LINE_SIZE
+       default 16
+
+config SYS_ICACHE_SIZE
+       default 65536
+
+config SYS_ICACHE_LINE_SIZE
+       default 16
+
+endif
diff --git a/board/comtrend/vr3032u/MAINTAINERS 
b/board/comtrend/vr3032u/MAINTAINERS
new file mode 100644
index 0000000..833d7da
--- /dev/null
+++ b/board/comtrend/vr3032u/MAINTAINERS
@@ -0,0 +1,6 @@
+COMTREND VR-3032U BOARD
+M:     Álvaro Fernández Rojas <nolt...@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 0000000..9e62031
--- /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 0000000..429117a
--- /dev/null
+++ b/board/comtrend/vr3032u/vr-3032u.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <nolt...@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/types.h>
+
+#ifdef CONFIG_BOARD_EARLY_INIT_F
+int board_early_init_f(void)
+{
+# ifdef CONFIG_DEBUG_UART
+       debug_uart_init();
+# endif
+
+       return 0;
+}
+#endif
diff --git a/board/huawei/hg556a/Kconfig b/board/huawei/hg556a/Kconfig
new file mode 100644
index 0000000..59f65b1
--- /dev/null
+++ b/board/huawei/hg556a/Kconfig
@@ -0,0 +1,24 @@
+if BOARD_HUAWEI_HG556A
+
+config SYS_BOARD
+       default "hg556a"
+
+config SYS_VENDOR
+       default "huawei"
+
+config SYS_CONFIG_NAME
+       default "huawei_hg556a"
+
+config SYS_DCACHE_SIZE
+       default 16384
+
+config SYS_DCACHE_LINE_SIZE
+       default 16
+
+config SYS_ICACHE_SIZE
+       default 16384
+
+config SYS_ICACHE_LINE_SIZE
+       default 16
+
+endif
diff --git a/board/huawei/hg556a/MAINTAINERS b/board/huawei/hg556a/MAINTAINERS
new file mode 100644
index 0000000..3ead7e4
--- /dev/null
+++ b/board/huawei/hg556a/MAINTAINERS
@@ -0,0 +1,6 @@
+HUAWEI HG556A BOARD
+M:     Álvaro Fernández Rojas <nolt...@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 0000000..ace0ed3
--- /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 0000000..429117a
--- /dev/null
+++ b/board/huawei/hg556a/hg556a.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <nolt...@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/types.h>
+
+#ifdef CONFIG_BOARD_EARLY_INIT_F
+int board_early_init_f(void)
+{
+# ifdef CONFIG_DEBUG_UART
+       debug_uart_init();
+# endif
+
+       return 0;
+}
+#endif
diff --git a/configs/comtrend_ar5387un_ram_defconfig 
b/configs/comtrend_ar5387un_ram_defconfig
new file mode 100644
index 0000000..cd99ca3
--- /dev/null
+++ b/configs/comtrend_ar5387un_ram_defconfig
@@ -0,0 +1,47 @@
+CONFIG_ARCH_BMIPS=y
+CONFIG_BCM6345_SERIAL=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_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_DEBUG_UART=y
+CONFIG_DEBUG_UART_BCM6345=y
+CONFIG_DEBUG_UART_BASE=0xb0000100
+CONFIG_DEBUG_UART_CLOCK=25000000
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_DEFAULT_DEVICE_TREE="comtrend,ar-5387un"
+CONFIG_DISPLAY_CPUINFO=y
+# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_DM_GPIO=y
+CONFIG_DM_SERIAL=y
+CONFIG_HUSH_PARSER=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_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 0000000..d8b1d38
--- /dev/null
+++ b/configs/comtrend_vr3032u_ram_defconfig
@@ -0,0 +1,47 @@
+CONFIG_ARCH_BMIPS=y
+CONFIG_BCM6345_SERIAL=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_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_DEBUG_UART=y
+CONFIG_DEBUG_UART_BCM6345=y
+CONFIG_DEBUG_UART_BASE=0xb0000100
+CONFIG_DEBUG_UART_CLOCK=25000000
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_DEFAULT_DEVICE_TREE="comtrend,vr-3032u"
+CONFIG_DISPLAY_CPUINFO=y
+# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_DM_GPIO=y
+CONFIG_DM_SERIAL=y
+CONFIG_HUSH_PARSER=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_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 0000000..9994a4d
--- /dev/null
+++ b/configs/huawei_hg556a_ram_defconfig
@@ -0,0 +1,47 @@
+CONFIG_ARCH_BMIPS=y
+CONFIG_BCM6345_SERIAL=y
+CONFIG_BOARD_HUAWEI_HG556A=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_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_DEBUG_UART=y
+CONFIG_DEBUG_UART_BCM6345=y
+CONFIG_DEBUG_UART_BASE=0xfffe0100
+CONFIG_DEBUG_UART_CLOCK=25000000
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_DEFAULT_DEVICE_TREE="huawei,hg556a"
+CONFIG_DISPLAY_CPUINFO=y
+# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_DM_GPIO=y
+CONFIG_DM_SERIAL=y
+CONFIG_HUSH_PARSER=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_SOC_BMIPS_BCM6358=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="HG556a # "
+CONFIG_SYS_TEXT_BASE=0x80010000
diff --git a/drivers/cpu/Makefile b/drivers/cpu/Makefile
index 8710160..db515f6 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 0000000..8ca4899
--- /dev/null
+++ b/drivers/cpu/bmips_cpu.c
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <nolt...@gmail.com>
+ *
+ * Derived from linux/arch/mips/bcm63xx/cpu.c:
+ *     Copyright (C) 2008 Maxime Bizon <mbi...@freebox.fr>
+ *     Copyright (C) 2009 Florian Fainelli <flor...@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_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 {
+       void __iomem *regs;
+       ulong (*get_cpu_freq)(const struct bmips_cpu_hw *);
+       int (*get_cpu_count)(const struct bmips_cpu_hw *);
+};
+
+struct bmips_cpu_priv {
+       const struct bmips_cpu_hw *hw;
+};
+
+/* Specific CPU Ops */
+static ulong bcm6328_get_cpu_freq(const struct bmips_cpu_hw *hw)
+{
+       unsigned int mips_pll_fcvo;
+
+       mips_pll_fcvo = __raw_readl(hw->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(const struct bmips_cpu_hw *hw)
+{
+       unsigned int tmp, n1, n2, m1;
+
+       tmp = __raw_readl(hw->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(const struct bmips_cpu_hw *hw)
+{
+       unsigned mips_pll_fcvo;
+
+       mips_pll_fcvo = __raw_readl(hw->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(const struct bmips_cpu_hw *hw)
+{
+       u32 val = __raw_readl(hw->regs + REG_BCM6328_OTP);
+
+       if (val & BCM6328_TP1_DISABLED)
+               return 1;
+       else
+               return 2;
+}
+
+static int bcm6358_get_cpu_count(const struct bmips_cpu_hw *hw)
+{
+       return 2;
+}
+
+static const struct bmips_cpu_hw bmips_cpu_bcm6328 = {
+       .regs = (void __iomem *)0xb0000000,
+       .get_cpu_freq = bcm6328_get_cpu_freq,
+       .get_cpu_count = bcm6328_get_cpu_count,
+};
+
+static const struct bmips_cpu_hw bmips_cpu_bcm6358 = {
+       .regs = (void __iomem *)0xfffe0000,
+       .get_cpu_freq = bcm6358_get_cpu_freq,
+       .get_cpu_count = bcm6358_get_cpu_count,
+};
+
+static const struct bmips_cpu_hw bmips_cpu_bcm63268 = {
+       .regs = (void __iomem *)0xb0000000,
+       .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;
+       u32 cpu_revid;
+       u16 cpu_id;
+       u8 cpu_rev;
+
+       cpu_revid = __raw_readl(hw->regs);
+       cpu_id = (cpu_revid & REV_CHIPID_MASK) >> REV_CHIPID_SHIFT;
+       cpu_rev = (cpu_revid & REV_REVID_MASK) >> REV_REVID_SHIFT;
+
+       snprintf(buf, size, "BCM%04X%02X", cpu_id, cpu_rev);
+
+       return 0;
+}
+
+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(hw);
+       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(hw);
+}
+
+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);
+       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);
+
+       priv->hw = hw;
+
+       plat->cpu_id = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+               "reg", -1);
+       plat->device_id = read_c0_prid();
+
+       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,
+       .ops            = &bmips_cpu_ops,
+};
+
+#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/ram/Makefile b/drivers/ram/Makefile
index 0e10249..818dd9f 100644
--- a/drivers/ram/Makefile
+++ b/drivers/ram/Makefile
@@ -6,3 +6,5 @@
 #
 obj-$(CONFIG_RAM) += ram-uclass.o
 obj-$(CONFIG_SANDBOX) += sandbox_ram.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 0000000..7c7da88
--- /dev/null
+++ b/drivers/ram/bmips_ram.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <nolt...@gmail.com>
+ *
+ * Derived from linux/arch/mips/bcm63xx/cpu.c:
+ *     Copyright (C) 2008 Maxime Bizon <mbi...@freebox.fr>
+ *     Copyright (C) 2009 Florian Fainelli <flor...@openwrt.org>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <errno.h>
+#include <common.h>
+#include <dm/device.h>
+#include <ram.h>
+#include <asm/io.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 __raw_readl(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 = __raw_readl(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_of_match[] = {
+       {
+               .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_of_match,
+       .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/include/configs/bmips_bcm63268.h b/include/configs/bmips_bcm63268.h
new file mode 100644
index 0000000..91f42e9
--- /dev/null
+++ b/include/configs/bmips_bcm63268.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <nolt...@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_SYS_INIT_SP_OFFSET      0x2000
+#define CONFIG_SKIP_LOWLEVEL_INIT
+#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 0000000..a5c9a2e
--- /dev/null
+++ b/include/configs/bmips_bcm6328.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <nolt...@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_SYS_INIT_SP_OFFSET      0x2000
+#define CONFIG_SKIP_LOWLEVEL_INIT
+#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 0000000..efac11d
--- /dev/null
+++ b/include/configs/bmips_bcm6358.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <nolt...@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_SYS_INIT_SP_OFFSET      0x2000
+#define CONFIG_SKIP_LOWLEVEL_INIT
+#endif
+
+#define CONFIG_SYS_MAX_FLASH_BANKS      2
+
+#endif /* __CONFIG_BMIPS_BCM6358_H */
diff --git a/include/configs/bmips_common.h b/include/configs/bmips_common.h
new file mode 100644
index 0000000..0640d21
--- /dev/null
+++ b/include/configs/bmips_common.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <nolt...@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
+
+/* Serial */
+#define CONFIG_BAUDRATE                        115200
+
+/* 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 0000000..8803506
--- /dev/null
+++ b/include/configs/comtrend_ar5387un.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <nolt...@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <configs/bmips_common.h>
+#include <configs/bmips_bcm6328.h>
+
+#define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_SIZE                        (8 * 1024)
+
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_AUTO_COMPLETE
+#define CONFIG_CMDLINE_EDITING
diff --git a/include/configs/comtrend_vr3032u.h 
b/include/configs/comtrend_vr3032u.h
new file mode 100644
index 0000000..066b4c7
--- /dev/null
+++ b/include/configs/comtrend_vr3032u.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <nolt...@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <configs/bmips_common.h>
+#include <configs/bmips_bcm63268.h>
+
+#define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_SIZE                        (8 * 1024)
+
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_AUTO_COMPLETE
+#define CONFIG_CMDLINE_EDITING
diff --git a/include/configs/huawei_hg556a.h b/include/configs/huawei_hg556a.h
new file mode 100644
index 0000000..4856ee7
--- /dev/null
+++ b/include/configs/huawei_hg556a.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <nolt...@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <configs/bmips_common.h>
+#include <configs/bmips_bcm6358.h>
+
+#define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_SIZE                        (8 * 1024)
+
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_AUTO_COMPLETE
+#define CONFIG_CMDLINE_EDITING
-- 
2.1.4

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to