Pārlūkot izejas kodu

Merge tag 'mips-updates-for-2019.11' of git://git.denx.de/u-boot-mips

- mips: fix some DTC warnings
- bmips: bcm6348: add DMA driver
- bmips: bcm5348: add ethernet driver
- bmips: bcm6368: add ethernet driver
- mips: mt76xx: fix DMA problems, disable CONFIG_OF_EMBED
- mips: mscc: add support for Microsemi Ocelot and Luton SoCs
- mips: mscc: add support for Ocelot and Luton evaluation boards
- mips: jz47xx: add basic support for Ingenic JZ4780 SoC
- mips: jz47xx: add support for Imgtec Creator CI20 board
Tom Rini 5 gadi atpakaļ
vecāks
revīzija
fd0135e3c5
100 mainītis faili ar 6585 papildinājumiem un 39 dzēšanām
  1. 18 0
      MAINTAINERS
  2. 14 1
      arch/mips/Kconfig
  3. 2 0
      arch/mips/Makefile
  4. 0 10
      arch/mips/cpu/cpu.c
  5. 1 0
      arch/mips/dts/Makefile
  6. 0 3
      arch/mips/dts/ar933x.dtsi
  7. 38 0
      arch/mips/dts/brcm,bcm6318.dtsi
  8. 38 0
      arch/mips/dts/brcm,bcm63268.dtsi
  9. 30 0
      arch/mips/dts/brcm,bcm6328.dtsi
  10. 29 0
      arch/mips/dts/brcm,bcm6338.dtsi
  11. 42 0
      arch/mips/dts/brcm,bcm6348.dtsi
  12. 46 0
      arch/mips/dts/brcm,bcm6358.dtsi
  13. 32 0
      arch/mips/dts/brcm,bcm6362.dtsi
  14. 32 0
      arch/mips/dts/brcm,bcm6368.dtsi
  15. 122 0
      arch/mips/dts/ci20.dts
  16. 32 0
      arch/mips/dts/comtrend,ar-5315u.dts
  17. 32 0
      arch/mips/dts/comtrend,ar-5387un.dts
  18. 12 0
      arch/mips/dts/comtrend,ct-5361.dts
  19. 32 0
      arch/mips/dts/comtrend,vr-3032u.dts
  20. 14 0
      arch/mips/dts/comtrend,wap-5813n.dts
  21. 12 0
      arch/mips/dts/huawei,hg556a.dts
  22. 164 0
      arch/mips/dts/jz4780.dtsi
  23. 36 0
      arch/mips/dts/luton_pcb091.dts
  24. 87 0
      arch/mips/dts/mscc,luton.dtsi
  25. 152 0
      arch/mips/dts/mscc,ocelot.dtsi
  26. 42 0
      arch/mips/dts/mscc,ocelot_pcb.dtsi
  27. 14 0
      arch/mips/dts/netgear,dgnd3700v2.dts
  28. 0 1
      arch/mips/dts/nexys4ddr.dts
  29. 12 0
      arch/mips/dts/ocelot_pcb120.dts
  30. 12 0
      arch/mips/dts/ocelot_pcb123.dts
  31. 0 3
      arch/mips/dts/qca953x.dtsi
  32. 12 0
      arch/mips/dts/sagem,f@st1704.dts
  33. 24 0
      arch/mips/dts/sfr,nb4-ser.dts
  34. 19 0
      arch/mips/include/asm/cacheops.h
  35. 11 7
      arch/mips/include/asm/mipsregs.h
  36. 33 0
      arch/mips/include/asm/spl.h
  37. 26 0
      arch/mips/mach-jz47xx/Kconfig
  38. 5 0
      arch/mips/mach-jz47xx/Makefile
  39. 103 0
      arch/mips/mach-jz47xx/include/mach/jz4780.h
  40. 456 0
      arch/mips/mach-jz47xx/include/mach/jz4780_dram.h
  41. 12 0
      arch/mips/mach-jz47xx/include/mach/jz4780_gpio.h
  42. 3 0
      arch/mips/mach-jz47xx/jz4780/Makefile
  43. 4 0
      arch/mips/mach-jz47xx/jz4780/TODO
  44. 39 0
      arch/mips/mach-jz47xx/jz4780/gpio.c
  45. 83 0
      arch/mips/mach-jz47xx/jz4780/jz4780.c
  46. 530 0
      arch/mips/mach-jz47xx/jz4780/pll.c
  47. 53 0
      arch/mips/mach-jz47xx/jz4780/reset.c
  48. 270 0
      arch/mips/mach-jz47xx/jz4780/sdram.c
  49. 239 0
      arch/mips/mach-jz47xx/jz4780/timer.c
  50. 50 0
      arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds
  51. 98 0
      arch/mips/mach-jz47xx/start.S
  52. 86 0
      arch/mips/mach-mscc/Kconfig
  53. 6 0
      arch/mips/mach-mscc/Makefile
  54. 102 0
      arch/mips/mach-mscc/cpu.c
  55. 73 0
      arch/mips/mach-mscc/dram.c
  56. 49 0
      arch/mips/mach-mscc/include/ioremap.h
  57. 28 0
      arch/mips/mach-mscc/include/mach/common.h
  58. 814 0
      arch/mips/mach-mscc/include/mach/ddr.h
  59. 24 0
      arch/mips/mach-mscc/include/mach/luton/luton.h
  60. 14 0
      arch/mips/mach-mscc/include/mach/luton/luton_devcpu_gcb.h
  61. 245 0
      arch/mips/mach-mscc/include/mach/luton/luton_icpu_cfg.h
  62. 24 0
      arch/mips/mach-mscc/include/mach/ocelot/ocelot.h
  63. 21 0
      arch/mips/mach-mscc/include/mach/ocelot/ocelot_devcpu_gcb.h
  64. 274 0
      arch/mips/mach-mscc/include/mach/ocelot/ocelot_icpu_cfg.h
  65. 55 0
      arch/mips/mach-mscc/include/mach/tlb.h
  66. 30 0
      arch/mips/mach-mscc/lowlevel_init.S
  67. 62 0
      arch/mips/mach-mscc/lowlevel_init_luton.S
  68. 30 0
      arch/mips/mach-mscc/reset.c
  69. 13 1
      arch/mips/mach-mt7620/cpu.c
  70. 15 0
      board/imgtec/ci20/Kconfig
  71. 6 0
      board/imgtec/ci20/MAINTAINERS
  72. 3 0
      board/imgtec/ci20/Makefile
  73. 10 0
      board/imgtec/ci20/README
  74. 362 0
      board/imgtec/ci20/ci20.c
  75. 14 0
      board/mscc/luton/Kconfig
  76. 3 0
      board/mscc/luton/Makefile
  77. 28 0
      board/mscc/luton/luton.c
  78. 14 0
      board/mscc/ocelot/Kconfig
  79. 4 0
      board/mscc/ocelot/Makefile
  80. 58 0
      board/mscc/ocelot/ocelot.c
  81. 48 0
      configs/ci20_mmc_defconfig
  82. 6 1
      configs/comtrend_ar5315u_ram_defconfig
  83. 6 1
      configs/comtrend_ar5387un_ram_defconfig
  84. 7 1
      configs/comtrend_ct5361_ram_defconfig
  85. 6 1
      configs/comtrend_vr3032u_ram_defconfig
  86. 7 1
      configs/comtrend_wap5813n_ram_defconfig
  87. 0 1
      configs/gardena-smart-gateway-mt7688-ram_defconfig
  88. 0 1
      configs/gardena-smart-gateway-mt7688_defconfig
  89. 7 1
      configs/huawei_hg556a_ram_defconfig
  90. 0 1
      configs/linkit-smart-7688-ram_defconfig
  91. 0 1
      configs/linkit-smart-7688_defconfig
  92. 64 0
      configs/mscc_luton_defconfig
  93. 67 0
      configs/mscc_ocelot_defconfig
  94. 60 0
      configs/mscc_ocelot_pcb120_defconfig
  95. 7 1
      configs/netgear_dgnd3700v2_ram_defconfig
  96. 7 1
      configs/sagem_f@st1704_ram_defconfig
  97. 7 1
      configs/sfr_nb4-ser_ram_defconfig
  98. 9 0
      drivers/dma/Kconfig
  99. 1 0
      drivers/dma/Makefile
  100. 642 0
      drivers/dma/bcm6348-iudma.c

+ 18 - 0
MAINTAINERS

@@ -512,6 +512,24 @@ S:	Maintained
 T:	git git://git.denx.de/u-boot-mips.git
 F:	arch/mips/
 
+MIPS MSCC
+M:	Gregory CLEMENT <gregory.clement@bootlin.com>
+M:	Lars Povlsen <lars.povlsen@microchip.com>
+M:	Horatiu Vultur <horatiu.vultur@microchip.com>
+S:	Maintained
+F:	arch/mips/mach-mscc/
+F:	arch/mips/dts/luton*
+F:	arch/mips/dts/mscc*
+F:	arch/mips/dts/ocelot*
+F:	board/mscc/
+F:	configs/mscc*
+F:	include/configs/vcoreiii.h
+
+MIPS JZ4780
+M:	Ezequiel Garcia <ezequiel@collabora.com>
+S:	Maintained
+F:	arch/mips/mach-jz47xx/
+
 MMC
 M:	Jaehoon Chung <jh80.chung@samsung.com>
 S:	Maintained

+ 14 - 1
arch/mips/Kconfig

@@ -59,6 +59,11 @@ config ARCH_ATH79
 	select OF_CONTROL
 	imply CMD_DM
 
+config ARCH_MSCC
+	bool "Support MSCC VCore-III"
+	select OF_CONTROL
+	select DM
+
 config ARCH_BMIPS
 	bool "Support BMIPS SoCs"
 	select CLK
@@ -79,7 +84,7 @@ config ARCH_MT7620
 	select DM_SERIAL
 	imply DM_SPI
 	imply DM_SPI_FLASH
-	select ARCH_MISC_INIT if WATCHDOG
+	select ARCH_MISC_INIT
 	select MIPS_TUNE_24KC
 	select OF_CONTROL
 	select ROM_EXCEPTION_VECTORS
@@ -88,6 +93,12 @@ config ARCH_MT7620
 	select SUPPORTS_LITTLE_ENDIAN
 	select SYSRESET
 
+config ARCH_JZ47XX
+	bool "Support Ingenic JZ47xx"
+	select SUPPORT_SPL
+	select OF_CONTROL
+	select DM
+
 config MACH_PIC32
 	bool "Support Microchip PIC32"
 	select DM
@@ -138,7 +149,9 @@ source "board/imgtec/xilfpga/Kconfig"
 source "board/micronas/vct/Kconfig"
 source "board/qemu-mips/Kconfig"
 source "arch/mips/mach-ath79/Kconfig"
+source "arch/mips/mach-mscc/Kconfig"
 source "arch/mips/mach-bmips/Kconfig"
+source "arch/mips/mach-jz47xx/Kconfig"
 source "arch/mips/mach-pic32/Kconfig"
 source "arch/mips/mach-mt7620/Kconfig"
 

+ 2 - 0
arch/mips/Makefile

@@ -13,8 +13,10 @@ libs-y += arch/mips/lib/
 
 machine-$(CONFIG_ARCH_ATH79) += ath79
 machine-$(CONFIG_ARCH_BMIPS) += bmips
+machine-$(CONFIG_ARCH_JZ47XX) += jz47xx
 machine-$(CONFIG_MACH_PIC32) += pic32
 machine-$(CONFIG_ARCH_MT7620) += mt7620
+machine-$(CONFIG_ARCH_MSCC) += mscc
 
 machdirs := $(patsubst %,arch/mips/mach-%/,$(machine-y))
 libs-y += $(machdirs)

+ 0 - 10
arch/mips/cpu/cpu.c

@@ -28,16 +28,6 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 }
 #endif
 
-void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1)
-{
-	write_c0_entrylo0(low0);
-	write_c0_pagemask(pagemask);
-	write_c0_entrylo1(low1);
-	write_c0_entryhi(hi);
-	write_c0_index(index);
-	tlb_write_indexed();
-}
-
 int arch_cpu_init(void)
 {
 	mips_cache_probe();

+ 1 - 0
arch/mips/dts/Makefile

@@ -16,6 +16,7 @@ dtb-$(CONFIG_BOARD_NETGEAR_CG3100D) += netgear,cg3100d.dtb
 dtb-$(CONFIG_BOARD_NETGEAR_DGND3700V2) += netgear,dgnd3700v2.dtb
 dtb-$(CONFIG_BOARD_SAGEM_FAST1704) += sagem,f@st1704.dtb
 dtb-$(CONFIG_BOARD_TPLINK_WDR4300) += tplink_wdr4300.dtb
+dtb-$(CONFIG_TARGET_JZ4780_CI20) += ci20.dtb
 
 targets += $(dtb-y)
 

+ 0 - 3
arch/mips/dts/ar933x.dtsi

@@ -3,7 +3,6 @@
  * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
  */
 
-#include <dt-bindings/interrupt-controller/irq.h>
 #include "skeleton.dtsi"
 
 / {
@@ -68,7 +67,6 @@
 			uart0: uart@18020000 {
 				compatible = "qca,ar9330-uart";
 				reg = <0x18020000 0x20>;
-				interrupts = <128 IRQ_TYPE_LEVEL_HIGH>;
 
 				status = "disabled";
 			};
@@ -103,7 +101,6 @@
 		spi0: spi@1f000000 {
 			compatible = "qca,ar7100-spi";
 			reg = <0x1f000000 0x10>;
-			interrupts = <129 IRQ_TYPE_LEVEL_HIGH>;
 
 			status = "disabled";
 

+ 38 - 0
arch/mips/dts/brcm,bcm6318.dtsi

@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/clock/bcm6318-clock.h>
+#include <dt-bindings/dma/bcm6318-dma.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/power-domain/bcm6318-power-domain.h>
 #include <dt-bindings/reset/bcm6318-reset.h>
@@ -54,6 +55,12 @@
 			reg = <0x10000004 0x4>;
 			#clock-cells = <1>;
 		};
+
+		ubus_clk: ubus-clk {
+			compatible = "brcm,bcm6345-clk";
+			reg = <0x10000008 0x4>;
+			#clock-cells = <1>;
+		};
 	};
 
 	ubus {
@@ -182,5 +189,36 @@
 
 			status = "disabled";
 		};
+
+		enet: ethernet@10080000 {
+			compatible = "brcm,bcm6368-enet";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x10080000 0x8000>;
+			clocks = <&periph_clk BCM6318_CLK_ROBOSW250>,
+				 <&periph_clk BCM6318_CLK_ROBOSW025>,
+				 <&ubus_clk BCM6318_UCLK_ROBOSW>;
+			resets = <&periph_rst BCM6318_RST_ENETSW>,
+				 <&periph_rst BCM6318_RST_EPHY>;
+			dmas = <&iudma BCM6318_DMA_ENETSW_RX>,
+			       <&iudma BCM6318_DMA_ENETSW_TX>;
+			dma-names = "rx",
+				    "tx";
+			brcm,num-ports = <5>;
+
+			status = "disabled";
+		};
+
+		iudma: dma-controller@10088000 {
+			compatible = "brcm,bcm6368-iudma";
+			reg = <0x10088000 0x80>,
+			      <0x10088200 0x80>,
+			      <0x10088400 0x80>;
+			reg-names = "dma",
+				    "dma-channels",
+				    "dma-sram";
+			#dma-cells = <1>;
+			dma-channels = <8>;
+		};
 	};
 };

+ 38 - 0
arch/mips/dts/brcm,bcm63268.dtsi

@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/clock/bcm63268-clock.h>
+#include <dt-bindings/dma/bcm63268-dma.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/power-domain/bcm63268-power-domain.h>
 #include <dt-bindings/reset/bcm63268-reset.h>
@@ -217,5 +218,42 @@
 			reg = <0x10003000 0x894>;
 			u-boot,dm-pre-reloc;
 		};
+
+		iudma: dma-controller@1000d800 {
+			compatible = "brcm,bcm6368-iudma";
+			reg = <0x1000d800 0x80>,
+			      <0x1000da00 0x80>,
+			      <0x1000dc00 0x80>;
+			reg-names = "dma",
+				    "dma-channels",
+				    "dma-sram";
+			#dma-cells = <1>;
+			dma-channels = <8>;
+		};
+
+		enet: ethernet@10700000 {
+			compatible = "brcm,bcm6368-enet";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x10700000 0x10000>;
+			clocks = <&periph_clk BCM63268_CLK_GMAC>,
+				 <&periph_clk BCM63268_CLK_ROBOSW>,
+				 <&periph_clk BCM63268_CLK_ROBOSW250>,
+				 <&timer_clk BCM63268_TCLK_EPHY1>,
+				 <&timer_clk BCM63268_TCLK_EPHY2>,
+				 <&timer_clk BCM63268_TCLK_EPHY3>,
+				 <&timer_clk BCM63268_TCLK_GPHY>;
+			resets = <&periph_rst BCM63268_RST_ENETSW>,
+				 <&periph_rst BCM63268_RST_EPHY>,
+				 <&periph_rst BCM63268_RST_GPHY>;
+			dmas = <&iudma BCM63268_DMA_ENETSW_RX>,
+			       <&iudma BCM63268_DMA_ENETSW_TX>;
+			dma-names = "rx",
+				    "tx";
+			brcm,rgmii-override;
+			brcm,rgmii-timing;
+
+			status = "disabled";
+		};
 	};
 };

+ 30 - 0
arch/mips/dts/brcm,bcm6328.dtsi

@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/clock/bcm6328-clock.h>
+#include <dt-bindings/dma/bcm6328-dma.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/power-domain/bcm6328-power-domain.h>
 #include <dt-bindings/reset/bcm6328-reset.h>
@@ -187,5 +188,34 @@
 			reg = <0x10003000 0x864>;
 			u-boot,dm-pre-reloc;
 		};
+
+		iudma: dma-controller@1000d800 {
+			compatible = "brcm,bcm6368-iudma";
+			reg = <0x1000d800 0x80>,
+			      <0x1000da00 0x80>,
+			      <0x1000dc00 0x80>;
+			reg-names = "dma",
+				    "dma-channels",
+				    "dma-sram";
+			#dma-cells = <1>;
+			dma-channels = <8>;
+		};
+
+		enet: ethernet@10e00000 {
+			compatible = "brcm,bcm6368-enet";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x10e00000 0x10000>;
+			clocks = <&periph_clk BCM6328_CLK_ROBOSW>;
+			resets = <&periph_rst BCM6328_RST_ENETSW>,
+				 <&periph_rst BCM6328_RST_EPHY>;
+			dmas = <&iudma BCM6328_DMA_ENETSW_RX>,
+			       <&iudma BCM6328_DMA_ENETSW_TX>;
+			dma-names = "rx",
+				    "tx";
+			brcm,num-ports = <5>;
+
+			status = "disabled";
+		};
 	};
 };

+ 29 - 0
arch/mips/dts/brcm,bcm6338.dtsi

@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/clock/bcm6338-clock.h>
+#include <dt-bindings/dma/bcm6338-dma.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/reset/bcm6338-reset.h>
 #include "skeleton.dtsi"
@@ -130,5 +131,33 @@
 			reg = <0xfffe3100 0x38>;
 			u-boot,dm-pre-reloc;
 		};
+
+		iudma: dma-controller@fffe2400 {
+			compatible = "brcm,bcm6348-iudma";
+			reg = <0xfffe2400 0x1c>,
+			      <0xfffe2500 0x60>,
+			      <0xfffe2600 0x60>;
+			reg-names = "dma",
+				    "dma-channels",
+				    "dma-sram";
+			#dma-cells = <1>;
+			dma-channels = <6>;
+			resets = <&periph_rst BCM6338_RST_DMAMEM>;
+		};
+
+		enet: ethernet@fffe2800 {
+			compatible = "brcm,bcm6348-enet";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0xfffe2800 0x2dc>;
+			clocks = <&periph_clk BCM6338_CLK_ENET>;
+			resets = <&periph_rst BCM6338_RST_ENET>;
+			dmas = <&iudma BCM6338_DMA_ENET_RX>,
+			       <&iudma BCM6338_DMA_ENET_TX>;
+			dma-names = "rx",
+				    "tx";
+
+			status = "disabled";
+		};
 	};
 };

+ 42 - 0
arch/mips/dts/brcm,bcm6348.dtsi

@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/clock/bcm6348-clock.h>
+#include <dt-bindings/dma/bcm6348-dma.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/reset/bcm6348-reset.h>
 #include "skeleton.dtsi"
@@ -159,5 +160,46 @@
 			reg = <0xfffe2300 0x38>;
 			u-boot,dm-pre-reloc;
 		};
+
+		enet0: ethernet@fffe6000 {
+			compatible = "brcm,bcm6348-enet";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0xfffe6000 0x2dc>;
+			dmas = <&iudma BCM6348_DMA_ENET0_RX>,
+			       <&iudma BCM6348_DMA_ENET0_TX>;
+			dma-names = "rx",
+				    "tx";
+
+			status = "disabled";
+		};
+
+		enet1: ethernet@fffe6800 {
+			compatible = "brcm,bcm6348-enet";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0xfffe6800 0x2dc>;
+			dmas = <&iudma BCM6348_DMA_ENET1_RX>,
+			       <&iudma BCM6348_DMA_ENET1_TX>;
+			dma-names = "rx",
+				    "tx";
+
+			status = "disabled";
+		};
+
+		iudma: dma-controller@fffe7000 {
+			compatible = "brcm,bcm6348-iudma";
+			reg = <0xfffe7000 0x1c>,
+			      <0xfffe7100 0x40>,
+			      <0xfffe7200 0x40>;
+			reg-names = "dma",
+				    "dma-channels",
+				    "dma-sram";
+			#dma-cells = <1>;
+			dma-channels = <4>;
+			clocks = <&periph_clk BCM6348_CLK_ENET>;
+			resets = <&periph_rst BCM6348_RST_ENET>,
+				 <&periph_rst BCM6348_RST_DMAMEM>;
+		};
 	};
 };

+ 46 - 0
arch/mips/dts/brcm,bcm6358.dtsi

@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/clock/bcm6358-clock.h>
+#include <dt-bindings/dma/bcm6358-dma.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/reset/bcm6358-reset.h>
 #include "skeleton.dtsi"
@@ -190,5 +191,50 @@
 
 			status = "disabled";
 		};
+
+		enet0: ethernet@fffe4000 {
+			compatible = "brcm,bcm6348-enet";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0xfffe4000 0x2dc>;
+			clocks = <&periph_clk BCM6358_CLK_ENET0>;
+			dmas = <&iudma BCM6358_DMA_ENET0_RX>,
+			       <&iudma BCM6358_DMA_ENET0_TX>;
+			dma-names = "rx",
+				    "tx";
+
+			status = "disabled";
+		};
+
+		enet1: ethernet@fffe4800 {
+			compatible = "brcm,bcm6348-enet";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0xfffe4800 0x2dc>;
+			clocks = <&periph_clk BCM6358_CLK_ENET1>;
+			dmas = <&iudma BCM6358_DMA_ENET1_RX>,
+			       <&iudma BCM6358_DMA_ENET1_TX>;
+			dma-names = "rx",
+				    "tx";
+
+			status = "disabled";
+		};
+
+		iudma: dma-controller@fffe5000 {
+			compatible = "brcm,bcm6348-iudma";
+			reg = <0xfffe5000 0x24>,
+			      <0xfffe5100 0x80>,
+			      <0xfffe5200 0x80>;
+			reg-names = "dma",
+				    "dma-channels",
+				    "dma-sram";
+			#dma-cells = <1>;
+			dma-channels = <8>;
+			clocks = <&periph_clk BCM6358_CLK_EMUSB>,
+				 <&periph_clk BCM6358_CLK_USBSU>,
+				 <&periph_clk BCM6358_CLK_EPHY>;
+			resets = <&periph_rst BCM6358_RST_ENET>,
+				 <&periph_rst BCM6358_RST_EPHY>;
+		};
 	};
 };

+ 32 - 0
arch/mips/dts/brcm,bcm6362.dtsi

@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/clock/bcm6362-clock.h>
+#include <dt-bindings/dma/bcm6362-dma.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/power-domain/bcm6362-power-domain.h>
 #include <dt-bindings/reset/bcm6362-reset.h>
@@ -211,5 +212,36 @@
 			reg = <0x10003000 0x864>;
 			u-boot,dm-pre-reloc;
 		};
+
+		iudma: dma-controller@1000d800 {
+			compatible = "brcm,bcm6368-iudma";
+			reg = <0x1000d800 0x80>,
+			      <0x1000da00 0x80>,
+			      <0x1000dc00 0x80>;
+			reg-names = "dma",
+				    "dma-channels",
+				    "dma-sram";
+			#dma-cells = <1>;
+			dma-channels = <8>;
+		};
+
+		enet: ethernet@10e00000 {
+			compatible = "brcm,bcm6368-enet";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x10e00000 0x10000>;
+			clocks = <&periph_clk BCM6362_CLK_SWPKT_USB>,
+				 <&periph_clk BCM6362_CLK_SWPKT_SAR>,
+				 <&periph_clk BCM6362_CLK_ROBOSW>;
+			resets = <&periph_rst BCM6362_RST_ENETSW>,
+				 <&periph_rst BCM6362_RST_EPHY>;
+			dmas = <&iudma BCM6362_DMA_ENETSW_RX>,
+			       <&iudma BCM6362_DMA_ENETSW_TX>;
+			dma-names = "rx",
+				    "tx";
+			brcm,num-ports = <6>;
+
+			status = "disabled";
+		};
 	};
 };

+ 32 - 0
arch/mips/dts/brcm,bcm6368.dtsi

@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/clock/bcm6368-clock.h>
+#include <dt-bindings/dma/bcm6368-dma.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/reset/bcm6368-reset.h>
 #include "skeleton.dtsi"
@@ -192,5 +193,36 @@
 
 			status = "disabled";
 		};
+
+		iudma: dma-controller@10006800 {
+			compatible = "brcm,bcm6368-iudma";
+			reg = <0x10006800 0x80>,
+			      <0x10006a00 0x80>,
+			      <0x10006c00 0x80>;
+			reg-names = "dma",
+				    "dma-channels",
+				    "dma-sram";
+			#dma-cells = <1>;
+			dma-channels = <8>;
+		};
+
+		enet: ethernet@10f00000 {
+			compatible = "brcm,bcm6368-enet";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x10f00000 0x10000>;
+			clocks = <&periph_clk BCM6368_CLK_SWPKT_USB>,
+				 <&periph_clk BCM6368_CLK_SWPKT_SAR>,
+				 <&periph_clk BCM6368_CLK_ROBOSW>;
+			resets = <&periph_rst BCM6368_RST_SWITCH>,
+				 <&periph_rst BCM6368_RST_EPHY>;
+			dmas = <&iudma BCM6368_DMA_ENETSW_RX>,
+			       <&iudma BCM6368_DMA_ENETSW_TX>;
+			dma-names = "rx",
+				    "tx";
+			brcm,num-ports = <6>;
+
+			status = "disabled";
+		};
 	};
 };

+ 122 - 0
arch/mips/dts/ci20.dts

@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+#include "jz4780.dtsi"
+
+/ {
+	compatible = "img,ci20", "ingenic,jz4780";
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial3 = &uart3;
+		serial4 = &uart4;
+	};
+
+	chosen {
+		stdout-path = "serial4:115200n8";
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x0 0x10000000
+		       0x30000000 0x30000000>;
+	};
+};
+
+&ext {
+	clock-frequency = <48000000>;
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&uart3 {
+	status = "okay";
+};
+
+&uart4 {
+	status = "okay";
+};
+
+&nemc {
+	status = "okay";
+
+	nandc: nand-controller@1 {
+		compatible = "ingenic,jz4780-nand";
+		reg = <1 0 0x1000000>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ingenic,bch-controller = <&bch>;
+
+		ingenic,nemc-tAS = <10>;
+		ingenic,nemc-tAH = <5>;
+		ingenic,nemc-tBP = <10>;
+		ingenic,nemc-tAW = <15>;
+		ingenic,nemc-tSTRV = <100>;
+
+		nand@1 {
+			reg = <1>;
+
+			nand-ecc-step-size = <1024>;
+			nand-ecc-strength = <24>;
+			nand-ecc-mode = "hw";
+			nand-on-flash-bbt;
+
+			partitions {
+				compatible = "fixed-partitions";
+				#address-cells = <2>;
+				#size-cells = <2>;
+
+				partition@0 {
+					label = "u-boot-spl";
+					reg = <0x0 0x0 0x0 0x800000>;
+				};
+
+				partition@0x800000 {
+					label = "u-boot";
+					reg = <0x0 0x800000 0x0 0x200000>;
+				};
+
+				partition@0xa00000 {
+					label = "u-boot-env";
+					reg = <0x0 0xa00000 0x0 0x200000>;
+				};
+
+				partition@0xc00000 {
+					label = "boot";
+					reg = <0x0 0xc00000 0x0 0x4000000>;
+				};
+
+				partition@0x8c00000 {
+					label = "system";
+					reg = <0x0 0x4c00000 0x1 0xfb400000>;
+				};
+			};
+		};
+	};
+};
+
+&bch {
+	status = "okay";
+};
+
+&mmc0 {
+	bus-width = <4>;
+	max-frequency = <50000000>;
+	status = "okay";
+};
+
+&mmc1 {
+	bus-width = <4>;
+	max-frequency = <50000000>;
+	status = "okay";
+};

+ 32 - 0
arch/mips/dts/comtrend,ar-5315u.dts

@@ -24,6 +24,38 @@
 	status = "okay";
 };
 
+&enet {
+	status = "okay";
+
+	port@0 {
+		compatible = "brcm,enetsw-port";
+		reg = <0>;
+		label = "fe4";
+		brcm,phy-id = <1>;
+	};
+
+	port@1 {
+		compatible = "brcm,enetsw-port";
+		reg = <1>;
+		label = "fe3";
+		brcm,phy-id = <2>;
+	};
+
+	port@2 {
+		compatible = "brcm,enetsw-port";
+		reg = <2>;
+		label = "fe2";
+		brcm,phy-id = <3>;
+	};
+
+	port@3 {
+		compatible = "brcm,enetsw-port";
+		reg = <3>;
+		label = "fe1";
+		brcm,phy-id = <4>;
+	};
+};
+
 &leds {
 	status = "okay";
 

+ 32 - 0
arch/mips/dts/comtrend,ar-5387un.dts

@@ -24,6 +24,38 @@
 	status = "okay";
 };
 
+&enet {
+	status = "okay";
+
+	port@0 {
+		compatible = "brcm,enetsw-port";
+		reg = <0>;
+		label = "fe1";
+		brcm,phy-id = <1>;
+	};
+
+	port@1 {
+		compatible = "brcm,enetsw-port";
+		reg = <1>;
+		label = "fe2";
+		brcm,phy-id = <2>;
+	};
+
+	port@2 {
+		compatible = "brcm,enetsw-port";
+		reg = <2>;
+		label = "fe3";
+		brcm,phy-id = <3>;
+	};
+
+	port@3 {
+		compatible = "brcm,enetsw-port";
+		reg = <3>;
+		label = "fe4";
+		brcm,phy-id = <4>;
+	};
+};
+
 &leds {
 	status = "okay";
 

+ 12 - 0
arch/mips/dts/comtrend,ct-5361.dts

@@ -34,6 +34,18 @@
 	};
 };
 
+&enet1 {
+	status = "okay";
+	phy = <&enet1phy>;
+	phy-mode = "mii";
+
+	enet1phy: fixed-link {
+		reg = <1>;
+		speed = <100>;
+		full-duplex;
+	};
+};
+
 &gpio0 {
 	status = "okay";
 };

+ 32 - 0
arch/mips/dts/comtrend,vr-3032u.dts

@@ -24,6 +24,38 @@
 	status = "okay";
 };
 
+&enet {
+	status = "okay";
+
+	port@0 {
+		compatible = "brcm,enetsw-port";
+		reg = <0>;
+		label = "fe2";
+		brcm,phy-id = <1>;
+	};
+
+	port@1 {
+		compatible = "brcm,enetsw-port";
+		reg = <1>;
+		label = "fe3";
+		brcm,phy-id = <2>;
+	};
+
+	port@2 {
+		compatible = "brcm,enetsw-port";
+		reg = <2>;
+		label = "fe4";
+		brcm,phy-id = <3>;
+	};
+
+	port@3 {
+		compatible = "brcm,enetsw-port";
+		reg = <3>;
+		label = "fe1";
+		brcm,phy-id = <4>;
+	};
+};
+
 &leds {
 	status = "okay";
 	brcm,serial-leds;

+ 14 - 0
arch/mips/dts/comtrend,wap-5813n.dts

@@ -54,6 +54,20 @@
 	status = "okay";
 };
 
+&enet {
+	status = "okay";
+
+	port@4 {
+		compatible = "brcm,enetsw-port";
+		reg = <4>;
+		label = "rgmii";
+		brcm,phy-id = <0xff>;
+		speed = <1000>;
+		full-duplex;
+		bypass-link;
+	};
+};
+
 &gpio0 {
 	status = "okay";
 };

+ 12 - 0
arch/mips/dts/huawei,hg556a.dts

@@ -93,6 +93,18 @@
 	status = "okay";
 };
 
+&enet1 {
+	status = "okay";
+	phy = <&enet1phy>;
+	phy-mode = "mii";
+
+	enet1phy: fixed-link {
+		reg = <1>;
+		speed = <100>;
+		full-duplex;
+	};
+};
+
 &gpio0 {
 	status = "okay";
 };

+ 164 - 0
arch/mips/dts/jz4780.dtsi

@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <dt-bindings/clock/jz4780-cgu.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "ingenic,jz4780";
+
+	cpuintc: interrupt-controller {
+		#address-cells = <0>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+		compatible = "mti,cpu-interrupt-controller";
+	};
+
+	intc: interrupt-controller@10001000 {
+		compatible = "ingenic,jz4780-intc";
+		reg = <0x10001000 0x50>;
+
+		interrupt-controller;
+		#interrupt-cells = <1>;
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <2>;
+	};
+
+	ext: ext {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+	};
+
+	rtc: rtc {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+	};
+
+	cgu: jz4780-cgu@10000000 {
+		compatible = "ingenic,jz4780-cgu";
+		reg = <0x10000000 0x100>;
+
+		clocks = <&ext>, <&rtc>;
+		clock-names = "ext", "rtc";
+
+		#clock-cells = <1>;
+	};
+
+	mmc0: mmc@13450000 {
+		compatible = "ingenic,jz4780-mmc";
+		reg = <0x13450000 0x1000>;
+
+		status = "disabled";
+
+		clocks = <&cgu JZ4780_CLK_MSC0>;
+		clock-names = "mmc";
+	};
+
+	mmc1: mmc@13460000 {
+		compatible = "ingenic,jz4780-mmc";
+		reg = <0x13460000 0x1000>;
+
+		clocks = <&cgu JZ4780_CLK_MSC1>;
+		clock-names = "mmc";
+
+		status = "disabled";
+	};
+
+	uart0: serial@10030000 {
+		compatible = "ingenic,jz4780-uart";
+		reg = <0x10030000 0x100>;
+		reg-shift = <2>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <51>;
+
+		clocks = <&ext>, <&cgu JZ4780_CLK_UART0>;
+		clock-names = "baud", "module";
+
+		status = "disabled";
+	};
+
+	uart1: serial@10031000 {
+		compatible = "ingenic,jz4780-uart";
+		reg = <0x10031000 0x100>;
+		reg-shift = <2>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <50>;
+
+		clocks = <&ext>, <&cgu JZ4780_CLK_UART1>;
+		clock-names = "baud", "module";
+
+		status = "disabled";
+	};
+
+	uart2: serial@10032000 {
+		compatible = "ingenic,jz4780-uart";
+		reg = <0x10032000 0x100>;
+		reg-shift = <2>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <49>;
+
+		clocks = <&ext>, <&cgu JZ4780_CLK_UART2>;
+		clock-names = "baud", "module";
+
+		status = "disabled";
+	};
+
+	uart3: serial@10033000 {
+		compatible = "ingenic,jz4780-uart";
+		reg = <0x10033000 0x100>;
+		reg-shift = <2>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <48>;
+
+		clocks = <&ext>, <&cgu JZ4780_CLK_UART3>;
+		clock-names = "baud", "module";
+
+		status = "disabled";
+	};
+
+	uart4: serial@10034000 {
+		compatible = "ingenic,jz4780-uart";
+		reg = <0x10034000 0x100>;
+		reg-shift = <2>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <34>;
+
+		clocks = <&ext>, <&cgu JZ4780_CLK_UART4>;
+		clock-names = "baud", "module";
+
+		status = "disabled";
+	};
+
+	nemc: nemc@13410000 {
+		compatible = "ingenic,jz4780-nemc";
+		reg = <0x13410000 0x10000>;
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <1 0 0x1b000000 0x1000000
+			  2 0 0x1a000000 0x1000000
+			  3 0 0x19000000 0x1000000
+			  4 0 0x18000000 0x1000000
+			  5 0 0x17000000 0x1000000
+			  6 0 0x16000000 0x1000000>;
+
+		clocks = <&cgu JZ4780_CLK_NEMC>;
+
+		status = "disabled";
+	};
+
+	bch: bch@134d0000 {
+		compatible = "ingenic,jz4780-bch";
+		reg = <0x134d0000 0x10000>;
+
+		clocks = <&cgu JZ4780_CLK_BCH>;
+
+		status = "disabled";
+	};
+};

+ 36 - 0
arch/mips/dts/luton_pcb091.dts

@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+/dts-v1/;
+#include "mscc,luton.dtsi"
+
+/ {
+	model = "Luton10 PCB091 Reference Board";
+	compatible = "mscc,luton-pcb091", "mscc,luton";
+
+	aliases {
+		serial0 = &uart0;
+		spi0 = &spi0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+	spi-flash@0 {
+		compatible = "spi-flash";
+		spi-max-frequency = <18000000>; /* input clock */
+		reg = <0>; /* CS0 */
+		spi-cs-high;
+	};
+};
+

+ 87 - 0
arch/mips/dts/mscc,luton.dtsi

@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "mscc,luton";
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			compatible = "mips,mips24KEc";
+			device_type = "cpu";
+			reg = <0>;
+		};
+	};
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	ahb_clk: ahb-clk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <208333333>;
+	};
+
+	ahb {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0 0x60000000 0x10200000>;
+
+		uart0: serial@10100000 {
+			pinctrl-0 = <&uart_pins>;
+			pinctrl-names = "default";
+
+			compatible = "ns16550a";
+			reg = <0x10100000 0x20>;
+			clocks = <&ahb_clk>;
+			reg-io-width = <4>;
+			reg-shift = <2>;
+
+			status = "disabled";
+		};
+
+		gpio: pinctrl@70068 {
+			compatible = "mscc,luton-pinctrl";
+			reg = <0x70068 0x68>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&gpio 0 0 32>;
+
+			uart_pins: uart-pins {
+				pins = "GPIO_30", "GPIO_31";
+				function = "uart";
+			};
+
+		};
+
+		gpio_spi_bitbang: gpio@10000064 {
+			compatible = "mscc,spi-bitbang-gpio";
+			reg = <0x10000064 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+
+		};
+
+		spi0: spi-bitbang {
+			compatible = "spi-gpio";
+			status = "okay";
+			gpio-sck = <&gpio_spi_bitbang 6 0>;
+			gpio-miso = <&gpio_spi_bitbang 0 0>;
+			gpio-mosi = <&gpio_spi_bitbang 5 0>;
+			cs-gpios = <&gpio_spi_bitbang 1 0>;
+			num-chipselects = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+};

+ 152 - 0
arch/mips/dts/mscc,ocelot.dtsi

@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "mscc,ocelot";
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			compatible = "mips,mips24KEc";
+			device_type = "cpu";
+			clocks = <&cpu_clk>;
+			reg = <0>;
+		};
+	};
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	cpuintc: interrupt-controller@0 {
+		#address-cells = <0>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+		compatible = "mti,cpu-interrupt-controller";
+	};
+
+	cpu_clk: cpu-clock {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <500000000>;
+	};
+
+	ahb_clk: ahb-clk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <250000000>;
+	};
+
+	ahb {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0 0x70000000 0x2000000>;
+
+		interrupt-parent = <&intc>;
+
+		cpu_ctrl: syscon@0 {
+			compatible = "mscc,ocelot-cpu-syscon", "syscon";
+			reg = <0x0 0x2c>;
+		};
+
+		intc: interrupt-controller@70 {
+			compatible = "mscc,ocelot-icpu-intr";
+			reg = <0x70 0x70>;
+			#interrupt-cells = <1>;
+			interrupt-controller;
+			interrupt-parent = <&cpuintc>;
+			interrupts = <2>;
+		};
+
+		uart0: serial@100000 {
+			pinctrl-0 = <&uart_pins>;
+			pinctrl-names = "default";
+			compatible = "ns16550a";
+			reg = <0x100000 0x20>;
+			interrupts = <6>;
+			clocks = <&ahb_clk>;
+			reg-io-width = <4>;
+			reg-shift = <2>;
+
+			status = "disabled";
+		};
+
+		uart2: serial@100800 {
+			pinctrl-0 = <&uart2_pins>;
+			pinctrl-names = "default";
+			compatible = "ns16550a";
+			reg = <0x100800 0x20>;
+			interrupts = <7>;
+			clocks = <&ahb_clk>;
+			reg-io-width = <4>;
+			reg-shift = <2>;
+
+			status = "disabled";
+		};
+
+		spi0: spi-master@101000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "snps,dw-apb-ssi";
+			reg = <0x101000 0x40>;
+			num-chipselect = <4>;
+			bus-num = <0>;
+			reg-io-width = <4>;
+			reg-shift = <2>;
+			spi-max-frequency = <18000000>; /* input clock */
+			clocks = <&ahb_clk>;
+
+			status = "disabled";
+		};
+
+		reset@1070008 {
+			compatible = "mscc,ocelot-chip-reset";
+			reg = <0x1070008 0x4>;
+		};
+
+		gpio: pinctrl@1070034 {
+			compatible = "mscc,ocelot-pinctrl";
+			reg = <0x1070034 0x68>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&gpio 0 0 22>;
+
+			uart_pins: uart-pins {
+				pins = "GPIO_6", "GPIO_7";
+				function = "uart";
+			};
+
+			uart2_pins: uart2-pins {
+				pins = "GPIO_12", "GPIO_13";
+				function = "uart2";
+			};
+
+			spi_cs1_pin: spi-cs1-pin {
+				pins = "GPIO_8";
+				function = "si";
+			};
+
+			spi_cs2_pin: spi-cs2-pin {
+				pins = "GPIO_9";
+				function = "si";
+			};
+
+			spi_cs3_pin: spi-cs3-pin {
+				pins = "GPIO_16";
+				function = "si";
+			};
+
+			spi_cs4_pin: spi-cs4-pin {
+				pins = "GPIO_17";
+				function = "si";
+			};
+		};
+	};
+};

+ 42 - 0
arch/mips/dts/mscc,ocelot_pcb.dtsi

@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+/dts-v1/;
+#include "mscc,ocelot.dtsi"
+
+/ {
+	compatible = "mscc,ocelot";
+
+	aliases {
+		spi0 = &spi0;
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+	pinctrl-0 = <&spi_cs1_pin>;
+	pinctrl-names = "default";
+
+	spi-flash@0 {
+		compatible = "spi-flash";
+		spi-max-frequency = <18000000>; /* input clock */
+		reg = <0>; /* CS0 */
+	};
+
+	spi-nand@1 {
+		compatible = "spi-nand";
+		spi-max-frequency = <18000000>; /* input clock */
+		reg = <1>; /* CS1 */
+	};
+};

+ 14 - 0
arch/mips/dts/netgear,dgnd3700v2.dts

@@ -43,6 +43,20 @@
 	status = "okay";
 };
 
+&enet {
+	status = "okay";
+
+	port@4 {
+		compatible = "brcm,enetsw-port";
+		reg = <4>;
+		label = "rgmii";
+		brcm,phy-id = <0xff>;
+		speed = <1000>;
+		full-duplex;
+		bypass-link;
+	};
+};
+
 &gpio0 {
 	status = "okay";
 };

+ 0 - 1
arch/mips/dts/nexys4ddr.dts

@@ -40,7 +40,6 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 			phy0: phy@1 {
-				compatible = <0x0007c0f0 0xfffffff0>;
 				device_type = "ethernet-phy";
 				reg = <1>;
 			} ;

+ 12 - 0
arch/mips/dts/ocelot_pcb120.dts

@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+/dts-v1/;
+#include "mscc,ocelot_pcb.dtsi"
+
+/ {
+	model = "Ocelot PCB120 Reference Board";
+	compatible = "mscc,ocelot-pcb120", "mscc,ocelot";
+};

+ 12 - 0
arch/mips/dts/ocelot_pcb123.dts

@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+/dts-v1/;
+#include "mscc,ocelot_pcb.dtsi"
+
+/ {
+	model = "Ocelot PCB123 Reference Board";
+	compatible = "mscc,ocelot-pcb123", "mscc,ocelot";
+};

+ 0 - 3
arch/mips/dts/qca953x.dtsi

@@ -3,7 +3,6 @@
  * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
  */
 
-#include <dt-bindings/interrupt-controller/irq.h>
 #include "skeleton.dtsi"
 
 / {
@@ -63,7 +62,6 @@
 				reg = <0x18020000 0x20>;
 				reg-shift = <2>;
 				clock-frequency = <25000000>;
-				interrupts = <128 IRQ_TYPE_LEVEL_HIGH>;
 
 				status = "disabled";
 			};
@@ -72,7 +70,6 @@
 		spi0: spi@1f000000 {
 			compatible = "qca,ar7100-spi";
 			reg = <0x1f000000 0x10>;
-			interrupts = <129 IRQ_TYPE_LEVEL_HIGH>;
 
 			status = "disabled";
 

+ 12 - 0
arch/mips/dts/sagem,f@st1704.dts

@@ -39,6 +39,18 @@
 	};
 };
 
+&enet {
+	status = "okay";
+	phy = <&enetphy>;
+	phy-mode = "mii";
+
+	enetphy: fixed-link {
+		reg = <1>;
+		speed = <100>;
+		full-duplex;
+	};
+};
+
 &gpio {
 	status = "okay";
 };

+ 24 - 0
arch/mips/dts/sfr,nb4-ser.dts

@@ -53,6 +53,30 @@
 	status = "okay";
 };
 
+&enet0 {
+	status = "okay";
+	phy = <&enet0phy>;
+	phy-mode = "internal";
+
+	enet0phy: fixed-link {
+		reg = <1>;
+		speed = <100>;
+		full-duplex;
+	};
+};
+
+&enet1 {
+	status = "okay";
+	phy = <&enet1phy>;
+	phy-mode = "mii";
+
+	enet1phy: fixed-link {
+		reg = <1>;
+		speed = <100>;
+		full-duplex;
+	};
+};
+
 &gpio0 {
 	status = "okay";
 };

+ 19 - 0
arch/mips/include/asm/cacheops.h

@@ -19,6 +19,25 @@ static inline void mips_cache(int op, const volatile void *addr)
 #endif
 }
 
+#define MIPS32_WHICH_ICACHE                    0x0
+#define MIPS32_FETCH_AND_LOCK                  0x7
+
+#define ICACHE_LOAD_LOCK (MIPS32_WHICH_ICACHE | (MIPS32_FETCH_AND_LOCK << 2))
+
+/* Prefetch and lock instructions into cache */
+static inline void icache_lock(void *func, size_t len)
+{
+	int i, lines = ((len - 1) / ARCH_DMA_MINALIGN) + 1;
+
+	for (i = 0; i < lines; i++) {
+		asm volatile (" cache %0, %1(%2)"
+			      : /* No Output */
+			      : "I" ICACHE_LOAD_LOCK,
+				"n" (i * ARCH_DMA_MINALIGN),
+				"r" (func)
+			      : /* No Clobbers */);
+	}
+}
 #endif /* !__ASSEMBLY__ */
 
 /*

+ 11 - 7
arch/mips/include/asm/mipsregs.h

@@ -1013,9 +1013,7 @@ do {									\
 #define __read_64bit_c0_split(source, sel)				\
 ({									\
 	unsigned long long __val;					\
-	unsigned long __flags;						\
 									\
-	local_irq_save(__flags);					\
 	if (sel == 0)							\
 		__asm__ __volatile__(					\
 			".set\tmips64\n\t"				\
@@ -1034,16 +1032,12 @@ do {									\
 			"dsra\t%L0, %L0, 32\n\t"			\
 			".set\tmips0"					\
 			: "=r" (__val));				\
-	local_irq_restore(__flags);					\
 									\
 	__val;								\
 })
 
 #define __write_64bit_c0_split(source, sel, val)			\
 do {									\
-	unsigned long __flags;						\
-									\
-	local_irq_save(__flags);					\
 	if (sel == 0)							\
 		__asm__ __volatile__(					\
 			".set\tmips64\n\t"				\
@@ -1064,7 +1058,6 @@ do {									\
 			"dmtc0\t%L0, " #source ", " #sel "\n\t"		\
 			".set\tmips0"					\
 			: : "r" (val));					\
-	local_irq_restore(__flags);					\
 } while (0)
 
 #define __readx_32bit_c0_register(source)				\
@@ -2005,6 +1998,17 @@ static inline unsigned int get_ebase_cpunum(void)
 	return read_c0_ebase() & 0x3ff;
 }
 
+static inline void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0,
+				 u32 low1)
+{
+	write_c0_entrylo0(low0);
+	write_c0_pagemask(pagemask);
+	write_c0_entrylo1(low1);
+	write_c0_entryhi(hi);
+	write_c0_index(index);
+	tlb_write_indexed();
+}
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* _ASM_MIPSREGS_H */

+ 33 - 0
arch/mips/include/asm/spl.h

@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2012
+ * Texas Instruments, <www.ti.com>
+ */
+#ifndef	_ASM_SPL_H_
+#define	_ASM_SPL_H_
+
+enum {
+	BOOT_DEVICE_RAM,
+	BOOT_DEVICE_MMC1,
+	BOOT_DEVICE_MMC2,
+	BOOT_DEVICE_MMC2_2,
+	BOOT_DEVICE_NAND,
+	BOOT_DEVICE_ONENAND,
+	BOOT_DEVICE_NOR,
+	BOOT_DEVICE_UART,
+	BOOT_DEVICE_SPI,
+	BOOT_DEVICE_USB,
+	BOOT_DEVICE_SATA,
+	BOOT_DEVICE_I2C,
+	BOOT_DEVICE_BOARD,
+	BOOT_DEVICE_DFU,
+	BOOT_DEVICE_XIP,
+	BOOT_DEVICE_BOOTROM,
+	BOOT_DEVICE_NONE
+};
+
+#ifndef CONFIG_DM
+extern gd_t gdata;
+#endif
+
+#endif

+ 26 - 0
arch/mips/mach-jz47xx/Kconfig

@@ -0,0 +1,26 @@
+menu "Ingenic JZ47xx platforms"
+	depends on ARCH_JZ47XX
+
+config SYS_SOC
+	default "jz47xx"
+
+config SOC_JZ4780
+	bool
+	select SUPPORTS_LITTLE_ENDIAN
+	select SUPPORTS_CPU_MIPS32_R1
+	select SUPPORTS_CPU_MIPS32_R2
+	help
+	  Support for Ingenic JZ4780 family SoCs.
+
+choice
+	prompt "Board select"
+
+config TARGET_JZ4780_CI20
+	bool "Creator CI20 Reference Board"
+	select SOC_JZ4780
+
+endchoice
+
+source "board/imgtec/ci20/Kconfig"
+
+endmenu

+ 5 - 0
arch/mips/mach-jz47xx/Makefile

@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+extra-$(CONFIG_SPL_BUILD)	:= start.o
+
+obj-$(CONFIG_SOC_JZ4780)	+= jz4780/

+ 103 - 0
arch/mips/mach-jz47xx/include/mach/jz4780.h

@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * JZ4780 definitions
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ */
+
+#ifndef __JZ4780_H__
+#define __JZ4780_H__
+
+/* AHB0 BUS Devices */
+#define DDRC_BASE	0xb3010000
+
+/* AHB2 BUS Devices */
+#define NEMC_BASE	0xb3410000
+#define BCH_BASE	0xb34d0000
+
+/* APB BUS Devices */
+#define CPM_BASE	0xb0000000
+#define TCU_BASE	0xb0002000
+#define WDT_BASE	0xb0002000
+#define GPIO_BASE	0xb0010000
+#define UART0_BASE	0xb0030000
+#define UART1_BASE	0xb0031000
+#define UART2_BASE	0xb0032000
+#define UART3_BASE	0xb0033000
+#define MSC0_BASE	0xb3450000
+#define MSC1_BASE	0xb3460000
+#define MSC2_BASE	0xb3470000
+
+/*
+ * GPIO
+ */
+/* n = 0,1,2,3,4,5 */
+#define GPIO_PXPIN(n)	(0x00 + (n) * 0x100)
+#define GPIO_PXINT(n)	(0x10 + (n) * 0x100)
+#define GPIO_PXINTS(n)	(0x14 + (n) * 0x100)
+#define GPIO_PXINTC(n)	(0x18 + (n) * 0x100)
+#define GPIO_PXMASK(n)	(0x20 + (n) * 0x100)
+#define GPIO_PXMASKS(n)	(0x24 + (n) * 0x100)
+#define GPIO_PXMASKC(n)	(0x28 + (n) * 0x100)
+#define GPIO_PXPAT1(n)	(0x30 + (n) * 0x100)
+#define GPIO_PXPAT1S(n)	(0x34 + (n) * 0x100)
+#define GPIO_PXPAT1C(n)	(0x38 + (n) * 0x100)
+#define GPIO_PXPAT0(n)	(0x40 + (n) * 0x100)
+#define GPIO_PXPAT0S(n)	(0x44 + (n) * 0x100)
+#define GPIO_PXPAT0C(n)	(0x48 + (n) * 0x100)
+#define GPIO_PXFLG(n)	(0x50 + (n) * 0x100)
+#define GPIO_PXFLGC(n)	(0x54 + (n) * 0x100)
+#define GPIO_PXOEN(n)	(0x60 + (n) * 0x100)
+#define GPIO_PXOENS(n)	(0x64 + (n) * 0x100)
+#define GPIO_PXOENC(n)	(0x68 + (n) * 0x100)
+#define GPIO_PXPEN(n)	(0x70 + (n) * 0x100)
+#define GPIO_PXPENS(n)	(0x74 + (n) * 0x100)
+#define GPIO_PXPENC(n)	(0x78 + (n) * 0x100)
+#define GPIO_PXDS(n)	(0x80 + (n) * 0x100)
+#define GPIO_PXDSS(n)	(0x84 + (n) * 0x100)
+#define GPIO_PXDSC(n)	(0x88 + (n) * 0x100)
+
+/* PLL setup */
+#define JZ4780_SYS_EXTAL	48000000
+#define JZ4780_SYS_MEM_SPEED	(CONFIG_SYS_MHZ * 1000000)
+#define JZ4780_SYS_MEM_DIV	3
+#define JZ4780_SYS_AUDIO_SPEED	(768 * 1000000)
+
+#define JZ4780_APLL_M	1
+#define JZ4780_APLL_N	1
+#define JZ4780_APLL_OD	1
+
+#define JZ4780_MPLL_M	(JZ4780_SYS_MEM_SPEED / JZ4780_SYS_EXTAL * 2)
+#define JZ4780_MPLL_N	2
+#define JZ4780_MPLL_OD	1
+
+#define JZ4780_EPLL_M	(JZ4780_SYS_AUDIO_SPEED * 2 / JZ4780_SYS_EXTAL)
+#define JZ4780_EPLL_N	1
+#define JZ4780_EPLL_OD	2
+
+#define JZ4780_VPLL_M	((888 * 1000000) * 2 / JZ4780_SYS_EXTAL)
+#define JZ4780_VPLL_N	1
+#define JZ4780_VPLL_OD	2
+
+#ifndef __ASSEMBLY__
+
+u32 sdram_size(int bank);
+
+const u32 jz4780_clk_get_efuse_clk(void);
+void jz4780_clk_ungate_ethernet(void);
+void jz4780_clk_ungate_mmc(void);
+void jz4780_clk_ungate_uart(const unsigned int uart);
+
+void jz4780_efuse_read(size_t addr, size_t count, u8 *buf);
+void jz4780_efuse_init(u32 ahb2_rate);
+
+void jz4780_tcu_wdt_start(void);
+
+#ifdef CONFIG_SPL_BUILD
+int jz_mmc_init(void __iomem *base);
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif	/* __JZ4780_H__ */

+ 456 - 0
arch/mips/mach-jz47xx/include/mach/jz4780_dram.h

@@ -0,0 +1,456 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * JZ4780 DDR initialization - parameters definitions
+ *
+ * Copyright (c) 2015 Imagination Technologies
+ * Author: Matt Redfearn <matt.redfearn.com>
+ */
+
+#ifndef __JZ4780_DRAM_H__
+#define __JZ4780_DRAM_H__
+
+/*
+ * DDR
+ */
+#define DDRC_ST				0x0
+#define DDRC_CFG			0x4
+#define DDRC_CTRL			0x8
+#define DDRC_LMR			0xc
+#define DDRC_REFCNT			0x18
+#define DDRC_DQS			0x1c
+#define DDRC_DQS_ADJ			0x20
+#define DDRC_MMAP0			0x24
+#define DDRC_MMAP1			0x28
+#define DDRC_MDELAY			0x2c
+#define DDRC_CKEL			0x30
+#define DDRC_PMEMCTRL0			0x54
+#define DDRC_PMEMCTRL1			0x50
+#define DDRC_PMEMCTRL2			0x58
+#define DDRC_PMEMCTRL3			0x5c
+
+#define DDRC_TIMING(n)			(0x60 + 4 * (n))
+#define DDRC_REMMAP(n)			(0x9c + 4 * (n))
+
+/*
+ * DDR PHY
+ */
+#define DDR_MEM_PHY_BASE		0x20000000
+#define DDR_PHY_OFFSET			0x1000
+
+#define DDRP_PIR			0x4
+#define DDRP_PGCR			0x8
+#define DDRP_PGSR			0xc
+
+#define DDRP_PTR0			0x18
+#define DDRP_PTR1			0x1c
+#define DDRP_PTR2			0x20
+
+#define DDRP_ACIOCR			0x24
+#define DDRP_DXCCR			0x28
+#define DDRP_DSGCR			0x2c
+#define DDRP_DCR			0x30
+
+#define DDRP_DTPR0			0x34
+#define DDRP_DTPR1			0x38
+#define DDRP_DTPR2			0x3c
+#define DDRP_MR0			0x40
+#define DDRP_MR1			0x44
+#define DDRP_MR2			0x48
+#define DDRP_MR3			0x4c
+
+#define DDRP_ODTCR			0x50
+#define DDRP_DTAR			0x54
+#define DDRP_DTDR0			0x58
+#define DDRP_DTDR1			0x5c
+
+#define DDRP_DCUAR			0xc0
+#define DDRP_DCUDR			0xc4
+#define DDRP_DCURR			0xc8
+#define DDRP_DCULR			0xcc
+#define DDRP_DCUGCR			0xd0
+#define DDRP_DCUTPR			0xd4
+#define DDRP_DCUSR0			0xd8
+#define DDRP_DCUSR1			0xdc
+
+#define DDRP_ZQXCR0(n)			(0x180 + ((n) * 0x10))
+#define DDRP_ZQXCR1(n)			(0x184 + ((n) * 0x10))
+#define DDRP_ZQXSR0(n)			(0x188 + ((n) * 0x10))
+#define DDRP_ZQXSR1(n)			(0x18c + ((n) * 0x10))
+
+#define DDRP_DXGCR(n)			(0x1c0 + ((n) * 0x40))
+#define DDRP_DXGSR0(n)			(0x1c4 + ((n) * 0x40))
+#define DDRP_DXGSR1(n)			(0x1c8 + ((n) * 0x40))
+#define DDRP_DXDQSTR(n)			(0x1d4 + ((n) * 0x40))
+
+/* DDRC Status Register */
+#define DDRC_ST_ENDIAN			BIT(7)
+#define DDRC_ST_DPDN			BIT(5)
+#define DDRC_ST_PDN			BIT(4)
+#define DDRC_ST_AREF			BIT(3)
+#define DDRC_ST_SREF			BIT(2)
+#define DDRC_ST_CKE1			BIT(1)
+#define DDRC_ST_CKE0			BIT(0)
+
+/* DDRC Configure Register */
+#define DDRC_CFG_ROW1_BIT		27
+#define DDRC_CFG_ROW1_MASK		(0x7 << DDRC_CFG_ROW1_BIT)
+#define DDRC_CFG_COL1_BIT		24
+#define DDRC_CFG_COL1_MASK		(0x7 << DDRC_CFG_COL1_BIT)
+#define DDRC_CFG_BA1			BIT(23)
+#define DDRC_CFG_IMBA			BIT(22)
+#define DDRC_CFG_BL_8			BIT(21)
+
+#define DDRC_CFG_TYPE_BIT		17
+#define DDRC_CFG_TYPE_MASK		(0x7 << DDRC_CFG_TYPE_BIT)
+#define DDRC_CFG_TYPE_DDR1		(2 << DDRC_CFG_TYPE_BIT)
+#define DDRC_CFG_TYPE_MDDR		(3 << DDRC_CFG_TYPE_BIT)
+#define DDRC_CFG_TYPE_DDR2		(4 << DDRC_CFG_TYPE_BIT)
+#define DDRC_CFG_TYPE_LPDDR2		(5 << DDRC_CFG_TYPE_BIT)
+#define DDRC_CFG_TYPE_DDR3		(6 << DDRC_CFG_TYPE_BIT)
+
+#define DDRC_CFG_ODT_EN			BIT(16)
+
+#define DDRC_CFG_MPRT			BIT(15)
+
+#define DDRC_CFG_ROW_BIT		11
+#define DDRC_CFG_ROW_MASK		(0x7 << DDRC_CFG_ROW_BIT)
+#define DDRC_CFG_ROW_12			(0 << DDRC_CFG_ROW_BIT)
+#define DDRC_CFG_ROW_13			(1 << DDRC_CFG_ROW_BIT)
+#define DDRC_CFG_ROW_14			(2 << DDRC_CFG_ROW_BIT)
+
+#define DDRC_CFG_COL_BIT		8
+#define DDRC_CFG_COL_MASK		(0x7 << DDRC_CFG_COL_BIT)
+#define DDRC_CFG_COL_8			(0 << DDRC_CFG_COL_BIT)
+#define DDRC_CFG_COL_9			(1 << DDRC_CFG_COL_BIT)
+#define DDRC_CFG_COL_10			(2 << DDRC_CFG_COL_BIT)
+#define DDRC_CFG_COL_11			(3 << DDRC_CFG_COL_BIT)
+
+#define DDRC_CFG_CS1EN			BIT(7)
+#define DDRC_CFG_CS0EN			BIT(6)
+#define DDRC_CFG_CL_BIT			2
+#define DDRC_CFG_CL_MASK		(0xf << DDRC_CFG_CL_BIT)
+#define DDRC_CFG_CL_3			(0 << DDRC_CFG_CL_BIT)
+#define DDRC_CFG_CL_4			(1 << DDRC_CFG_CL_BIT)
+#define DDRC_CFG_CL_5			(2 << DDRC_CFG_CL_BIT)
+#define DDRC_CFG_CL_6			(3 << DDRC_CFG_CL_BIT)
+
+#define DDRC_CFG_BA			BIT(1)
+#define DDRC_CFG_DW			BIT(0)
+
+/* DDRC Control Register */
+#define DDRC_CTRL_DFI_RST		BIT(23)
+#define DDRC_CTRL_DLL_RST		BIT(22)
+#define DDRC_CTRL_CTL_RST		BIT(21)
+#define DDRC_CTRL_CFG_RST		BIT(20)
+#define DDRC_CTRL_ACTPD			BIT(15)
+#define DDRC_CTRL_PDT_BIT		12
+#define DDRC_CTRL_PDT_MASK		(0x7 << DDRC_CTRL_PDT_BIT)
+#define DDRC_CTRL_PDT_DIS		(0 << DDRC_CTRL_PDT_BIT)
+#define DDRC_CTRL_PDT_8			(1 << DDRC_CTRL_PDT_BIT)
+#define DDRC_CTRL_PDT_16		(2 << DDRC_CTRL_PDT_BIT)
+#define DDRC_CTRL_PDT_32		(3 << DDRC_CTRL_PDT_BIT)
+#define DDRC_CTRL_PDT_64		(4 << DDRC_CTRL_PDT_BIT)
+#define DDRC_CTRL_PDT_128		(5 << DDRC_CTRL_PDT_BIT)
+
+#define DDRC_CTRL_PRET_BIT		8
+#define DDRC_CTRL_PRET_MASK		(0x7 << DDRC_CTRL_PRET_BIT)
+#define DDRC_CTRL_PRET_DIS		(0 << DDRC_CTRL_PRET_BIT)
+#define DDRC_CTRL_PRET_8		(1 << DDRC_CTRL_PRET_BIT)
+#define DDRC_CTRL_PRET_16		(2 << DDRC_CTRL_PRET_BIT)
+#define DDRC_CTRL_PRET_32		(3 << DDRC_CTRL_PRET_BIT)
+#define DDRC_CTRL_PRET_64		(4 << DDRC_CTRL_PRET_BIT)
+#define DDRC_CTRL_PRET_128		(5 << DDRC_CTRL_PRET_BIT)
+
+#define DDRC_CTRL_DPD			BIT(6)
+#define DDRC_CTRL_SR			BIT(5)
+#define DDRC_CTRL_UNALIGN		BIT(4)
+#define DDRC_CTRL_ALH			BIT(3)
+#define DDRC_CTRL_RDC			BIT(2)
+#define DDRC_CTRL_CKE			BIT(1)
+#define DDRC_CTRL_RESET			BIT(0)
+
+/* DDRC Load-Mode-Register */
+#define DDRC_LMR_DDR_ADDR_BIT		16
+#define DDRC_LMR_DDR_ADDR_MASK		(0x3fff << DDRC_LMR_DDR_ADDR_BIT)
+
+#define DDRC_LMR_BA_BIT			8
+#define DDRC_LMR_BA_MASK		(0x7 << DDRC_LMR_BA_BIT)
+/* For DDR2 */
+#define DDRC_LMR_BA_MRS			(0 << DDRC_LMR_BA_BIT)
+#define DDRC_LMR_BA_EMRS1		(1 << DDRC_LMR_BA_BIT)
+#define DDRC_LMR_BA_EMRS2		(2 << DDRC_LMR_BA_BIT)
+#define DDRC_LMR_BA_EMRS3		(3 << DDRC_LMR_BA_BIT)
+/* For mobile DDR */
+#define DDRC_LMR_BA_M_MRS		(0 << DDRC_LMR_BA_BIT)
+#define DDRC_LMR_BA_M_EMRS		(2 << DDRC_LMR_BA_BIT)
+#define DDRC_LMR_BA_M_SR		(1 << DDRC_LMR_BA_BIT)
+/* For Normal DDR1 */
+#define DDRC_LMR_BA_N_MRS		(0 << DDRC_LMR_BA_BIT)
+#define DDRC_LMR_BA_N_EMRS		(1 << DDRC_LMR_BA_BIT)
+
+#define DDRC_LMR_CMD_BIT		4
+#define DDRC_LMR_CMD_MASK		(0x3 << DDRC_LMR_CMD_BIT)
+#define DDRC_LMR_CMD_PREC		(0 << DDRC_LMR_CMD_BIT)
+#define DDRC_LMR_CMD_AUREF		(1 << DDRC_LMR_CMD_BIT)
+#define DDRC_LMR_CMD_LMR		(2 << DDRC_LMR_CMD_BIT)
+
+#define DDRC_LMR_START			BIT(0)
+
+/* DDRC Timing Config Register 1 */
+#define DDRC_TIMING1_TRTP_BIT		24
+#define DDRC_TIMING1_TRTP_MASK		(0x3f << DDRC_TIMING1_TRTP_BIT)
+#define DDRC_TIMING1_TWTR_BIT		16
+#define DDRC_TIMING1_TWTR_MASK		(0x3f << DDRC_TIMING1_TWTR_BIT)
+#define DDRC_TIMING1_TWTR_1		(0 << DDRC_TIMING1_TWTR_BIT)
+#define DDRC_TIMING1_TWTR_2		(1 << DDRC_TIMING1_TWTR_BIT)
+#define DDRC_TIMING1_TWTR_3		(2 << DDRC_TIMING1_TWTR_BIT)
+#define DDRC_TIMING1_TWTR_4		(3 << DDRC_TIMING1_TWTR_BIT)
+#define DDRC_TIMING1_TWR_BIT		8
+#define DDRC_TIMING1_TWR_MASK		(0x3f << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWR_1		(0 << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWR_2		(1 << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWR_3		(2 << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWR_4		(3 << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWR_5		(4 << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWR_6		(5 << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWL_BIT		0
+#define DDRC_TIMING1_TWL_MASK		(0x3f << DDRC_TIMING1_TWL_BIT)
+
+/* DDRC Timing Config Register 2 */
+#define DDRC_TIMING2_TCCD_BIT		24
+#define DDRC_TIMING2_TCCD_MASK		(0x3f << DDRC_TIMING2_TCCD_BIT)
+#define DDRC_TIMING2_TRAS_BIT		16
+#define DDRC_TIMING2_TRAS_MASK		(0x3f << DDRC_TIMING2_TRAS_BIT)
+#define DDRC_TIMING2_TRCD_BIT		8
+#define DDRC_TIMING2_TRCD_MASK		(0x3f << DDRC_TIMING2_TRCD_BIT)
+#define DDRC_TIMING2_TRL_BIT		0
+#define DDRC_TIMING2_TRL_MASK		(0x3f << DDRC_TIMING2_TRL_BIT)
+
+/* DDRC Timing Config Register 3 */
+#define DDRC_TIMING3_ONUM		27
+#define DDRC_TIMING3_TCKSRE_BIT		24
+#define DDRC_TIMING3_TCKSRE_MASK	(0x3f << DDRC_TIMING3_TCKSRE_BIT)
+#define DDRC_TIMING3_TRP_BIT		16
+#define DDRC_TIMING3_TRP_MASK		(0x3f << DDRC_TIMING3_TRP_BIT)
+#define DDRC_TIMING3_TRRD_BIT		8
+#define DDRC_TIMING3_TRRD_MASK		(0x3f << DDRC_TIMING3_TRRD_BIT)
+#define DDRC_TIMING3_TRRD_DISABLE	(0 << DDRC_TIMING3_TRRD_BIT)
+#define DDRC_TIMING3_TRRD_2		(1 << DDRC_TIMING3_TRRD_BIT)
+#define DDRC_TIMING3_TRRD_3		(2 << DDRC_TIMING3_TRRD_BIT)
+#define DDRC_TIMING3_TRRD_4		(3 << DDRC_TIMING3_TRRD_BIT)
+#define DDRC_TIMING3_TRC_BIT		0
+#define DDRC_TIMING3_TRC_MASK		(0x3f << DDRC_TIMING3_TRC_BIT)
+
+/* DDRC Timing Config Register 4 */
+#define DDRC_TIMING4_TRFC_BIT		24
+#define DDRC_TIMING4_TRFC_MASK		(0x3f << DDRC_TIMING4_TRFC_BIT)
+#define DDRC_TIMING4_TEXTRW_BIT		21
+#define DDRC_TIMING4_TEXTRW_MASK	(0x7 << DDRC_TIMING4_TEXTRW_BIT)
+#define DDRC_TIMING4_TRWCOV_BIT		19
+#define DDRC_TIMING4_TRWCOV_MASK	(0x3 << DDRC_TIMING4_TRWCOV_BIT)
+#define DDRC_TIMING4_TCKE_BIT		16
+#define DDRC_TIMING4_TCKE_MASK		(0x7 << DDRC_TIMING4_TCKE_BIT)
+#define DDRC_TIMING4_TMINSR_BIT		8
+#define DDRC_TIMING4_TMINSR_MASK	(0xf << DDRC_TIMING4_TMINSR_BIT)
+#define DDRC_TIMING4_TXP_BIT		4
+#define DDRC_TIMING4_TXP_MASK		(0x7 << DDRC_TIMING4_TXP_BIT)
+#define DDRC_TIMING4_TMRD_BIT		0
+#define DDRC_TIMING4_TMRD_MASK		(0x3 << DDRC_TIMING4_TMRD_BIT)
+
+/* DDRC Timing Config Register 5 */
+#define DDRC_TIMING5_TCTLUPD_BIT	24
+#define DDRC_TIMING4_TCTLUPD_MASK	(0x3f << DDRC_TIMING5_TCTLUDP_BIT)
+#define DDRC_TIMING5_TRTW_BIT		16
+#define DDRC_TIMING5_TRTW_MASK		(0x3f << DDRC_TIMING5_TRTW_BIT)
+#define DDRC_TIMING5_TRDLAT_BIT		8
+#define DDRC_TIMING5_TRDLAT_MASK	(0x3f << DDRC_TIMING5_TRDLAT_BIT)
+#define DDRC_TIMING5_TWDLAT_BIT		0
+#define DDRC_TIMING5_TWDLAT_MASK	(0x3f << DDRC_TIMING5_TWDLAT_BIT)
+
+/* DDRC Timing Config Register 6 */
+#define DDRC_TIMING6_TXSRD_BIT		24
+#define DDRC_TIMING6_TXSRD_MASK		(0x3f << DDRC_TIMING6_TXSRD_BIT)
+#define DDRC_TIMING6_TFAW_BIT		16
+#define DDRC_TIMING6_TFAW_MASK		(0x3f << DDRC_TIMING6_TFAW_BIT)
+#define DDRC_TIMING6_TCFGW_BIT		8
+#define DDRC_TIMING6_TCFGW_MASK		(0x3f << DDRC_TIMING6_TCFGW_BIT)
+#define DDRC_TIMING6_TCFGR_BIT		0
+#define DDRC_TIMING6_TCFGR_MASK		(0x3f << DDRC_TIMING6_TCFGR_BIT)
+
+/* DDRC  Auto-Refresh Counter */
+#define DDRC_REFCNT_CON_BIT		16
+#define DDRC_REFCNT_CON_MASK		(0xff << DDRC_REFCNT_CON_BIT)
+#define DDRC_REFCNT_CNT_BIT		8
+#define DDRC_REFCNT_CNT_MASK		(0xff << DDRC_REFCNT_CNT_BIT)
+#define DDRC_REFCNT_CLKDIV_BIT		1
+#define DDRC_REFCNT_CLKDIV_MASK		(0x7 << DDRC_REFCNT_CLKDIV_BIT)
+#define DDRC_REFCNT_REF_EN		BIT(0)
+
+/* DDRC DQS Delay Control Register */
+#define DDRC_DQS_ERROR			BIT(29)
+#define DDRC_DQS_READY			BIT(28)
+#define DDRC_DQS_AUTO			BIT(23)
+#define DDRC_DQS_DET			BIT(24)
+#define DDRC_DQS_SRDET			BIT(25)
+#define DDRC_DQS_CLKD_BIT		16
+#define DDRC_DQS_CLKD_MASK		(0x3f << DDRC_DQS_CLKD_BIT)
+#define DDRC_DQS_WDQS_BIT		8
+#define DDRC_DQS_WDQS_MASK		(0x3f << DDRC_DQS_WDQS_BIT)
+#define DDRC_DQS_RDQS_BIT		0
+#define DDRC_DQS_RDQS_MASK		(0x3f << DDRC_DQS_RDQS_BIT)
+
+/* DDRC DQS Delay Adjust Register */
+#define DDRC_DQS_ADJWDQS_BIT		8
+#define DDRC_DQS_ADJWDQS_MASK		(0x1f << DDRC_DQS_ADJWDQS_BIT)
+#define DDRC_DQS_ADJRDQS_BIT		0
+#define DDRC_DQS_ADJRDQS_MASK		(0x1f << DDRC_DQS_ADJRDQS_BIT)
+
+/* DDRC Memory Map Config Register */
+#define DDRC_MMAP_BASE_BIT		8
+#define DDRC_MMAP_BASE_MASK		(0xff << DDRC_MMAP_BASE_BIT)
+#define DDRC_MMAP_MASK_BIT		0
+#define DDRC_MMAP_MASK_MASK		(0xff << DDRC_MMAP_MASK_BIT)
+
+#define DDRC_MMAP0_BASE			(0x20 << DDRC_MMAP_BASE_BIT)
+#define DDRC_MMAP1_BASE_64M		(0x24 << DDRC_MMAP_BASE_BIT)
+#define DDRC_MMAP1_BASE_128M		(0x28 << DDRC_MMAP_BASE_BIT)
+#define DDRC_MMAP1_BASE_256M		(0x30 << DDRC_MMAP_BASE_BIT)
+
+#define DDRC_MMAP_MASK_64_64		(0xfc << DDRC_MMAP_MASK_BIT)
+#define DDRC_MMAP_MASK_128_128		(0xf8 << DDRC_MMAP_MASK_BIT)
+#define DDRC_MMAP_MASK_256_256		(0xf0 << DDRC_MMAP_MASK_BIT)
+
+/* DDRP PHY Initialization Register */
+#define DDRP_PIR_INIT			BIT(0)
+#define DDRP_PIR_DLLSRST		BIT(1)
+#define DDRP_PIR_DLLLOCK		BIT(2)
+#define DDRP_PIR_ZCAL			BIT(3)
+#define DDRP_PIR_ITMSRST		BIT(4)
+#define DDRP_PIR_DRAMRST		BIT(5)
+#define DDRP_PIR_DRAMINT		BIT(6)
+#define DDRP_PIR_QSTRN			BIT(7)
+#define DDRP_PIR_EYETRN			BIT(8)
+#define DDRP_PIR_DLLBYP			BIT(17)
+/* DDRP PHY General Configurate Register */
+#define DDRP_PGCR_ITMDMD		BIT(0)
+#define DDRP_PGCR_DQSCFG		BIT(1)
+#define DDRP_PGCR_DFTCMP		BIT(2)
+#define DDRP_PGCR_DFTLMT_BIT		3
+#define DDRP_PGCR_DTOSEL_BIT		5
+#define DDRP_PGCR_CKEN_BIT		9
+#define DDRP_PGCR_CKDV_BIT		12
+#define DDRP_PGCR_CKINV			BIT(14)
+#define DDRP_PGCR_RANKEN_BIT		18
+#define DDRP_PGCR_ZCKSEL_32		(2 << 22)
+#define DDRP_PGCR_PDDISDX		BIT(24)
+/* DDRP PHY General Status Register */
+#define DDRP_PGSR_IDONE			BIT(0)
+#define DDRP_PGSR_DLDONE		BIT(1)
+#define DDRP_PGSR_ZCDONE		BIT(2)
+#define DDRP_PGSR_DIDONE		BIT(3)
+#define DDRP_PGSR_DTDONE		BIT(4)
+#define DDRP_PGSR_DTERR			BIT(5)
+#define DDRP_PGSR_DTIERR		BIT(6)
+#define DDRP_PGSR_DFTEERR		BIT(7)
+/* DDRP DRAM Configuration Register */
+#define DDRP_DCR_TYPE_BIT		0
+#define DDRP_DCR_TYPE_MASK		(0x7 << DDRP_DCR_TYPE_BIT)
+#define DDRP_DCR_TYPE_MDDR		(0 << DDRP_DCR_TYPE_BIT)
+#define DDRP_DCR_TYPE_DDR		(1 << DDRP_DCR_TYPE_BIT)
+#define DDRP_DCR_TYPE_DDR2		(2 << DDRP_DCR_TYPE_BIT)
+#define DDRP_DCR_TYPE_DDR3		(3 << DDRP_DCR_TYPE_BIT)
+#define DDRP_DCR_TYPE_LPDDR2		(4 << DDRP_DCR_TYPE_BIT)
+#define DDRP_DCR_DDR8BNK_BIT		3
+#define DDRP_DCR_DDR8BNK_MASK		(1 << DDRP_DCR_DDR8BNK_BIT)
+#define DDRP_DCR_DDR8BNK		(1 << DDRP_DCR_DDR8BNK_BIT)
+#define DDRP_DCR_DDR8BNK_DIS		(0 << DDRP_DCR_DDR8BNK_BIT)
+
+#define DRP_DTRP1_RTODT			BIT(11)
+
+#define DDRP_DXGCR_DXEN			BIT(0)
+
+#define DDRP_ZQXCR_ZDEN_BIT		28
+#define DDRP_ZQXCR_ZDEN			(1 << DDRP_ZQXCR_ZDEN_BIT)
+#define DDRP_ZQXCR_PULLUP_IMPE_BIT	5
+#define DDRP_ZQXCR_PULLDOWN_IMPE_BIT	0
+
+/* DDR3 Mode Register Set */
+#define DDR3_MR0_BL_BIT			0
+#define DDR3_MR0_BL_MASK		(3 << DDR3_MR0_BL_BIT)
+#define DDR3_MR0_BL_8			(0 << DDR3_MR0_BL_BIT)
+#define DDR3_MR0_BL_fly			(1 << DDR3_MR0_BL_BIT)
+#define DDR3_MR0_BL_4			(2 << DDR3_MR0_BL_BIT)
+#define DDR3_MR0_BT_BIT			3
+#define DDR3_MR0_BT_MASK		(1 << DDR3_MR0_BT_BIT)
+#define DDR3_MR0_BT_SEQ			(0 << DDR3_MR0_BT_BIT)
+#define DDR3_MR0_BT_INTER		(1 << DDR3_MR0_BT_BIT)
+#define DDR3_MR0_WR_BIT			9
+
+#define DDR3_MR1_DLL_DISABLE		1
+#define DDR3_MR1_DIC_6			(0 << 5 | 0 << 1)
+#define DDR3_MR1_DIC_7			(0 << 5 | BIT(1))
+#define DDR3_MR1_RTT_DIS		(0 << 9 | 0 << 6 | 0 << 2)
+#define DDR3_MR1_RTT_4			(0 << 9 | 0 << 6 | BIT(2))
+#define DDR3_MR1_RTT_2			(0 << 9 | BIT(6) | 0 << 2)
+#define DDR3_MR1_RTT_6			(0 << 9 | BIT(6) | BIT(2))
+#define DDR3_MR1_RTT_12			(BIT(9) | 0 << 6 | 0 << 2)
+#define DDR3_MR1_RTT_8			(BIT(9) | 0 << 6 | BIT(2))
+
+#define DDR3_MR2_CWL_BIT		3
+
+/* Parameters common to all RAM devices used */
+
+/* Chip Select */
+/* CSEN : whether a ddr chip exists 0 - un-used, 1 - used */
+#define DDR_CS0EN	1
+/* CSEN : whether a ddr chip exists 0 - un-used, 1 - used */
+#define DDR_CS1EN	0
+
+/* ROW : 12 to 18 row address, 1G only 512MB */
+#define DDR_ROW		15
+/* COL :  8 to 14 column address */
+#define DDR_COL		10
+/* Banks each chip: 0-4bank, 1-8bank */
+#define DDR_BANK8	1
+/* 0 - 16-bit data width, 1 - 32-bit data width */
+#define DDR_DW32	1
+
+/* Refresh period: 64ms / 32768 = 1.95 us , 2 ^ 15 = 32768 */
+#define DDR_tREFI	7800
+/* Clock Divider */
+#define DDR_CLK_DIV	1
+
+/* DDR3 Burst length: 0 - 8 burst, 2 - 4 burst , 1 - 4 or 8 (on the fly) */
+#define DDR_BL		8
+
+/* CAS latency: 5 to 14, tCK */
+#define DDR_CL		6
+/* DDR3 only: CAS Write Latency, 5 to 8 */
+#define DDR_tCWL	(DDR_CL - 1)
+
+/* Structure representing per-RAM type configuration */
+
+struct jz4780_ddr_config {
+	u32	timing[6];	/* Timing1..6 register value */
+
+	/* DDR PHY control */
+	u16	mr0;	/* Mode Register 0 */
+	u16	mr1;	/* Mode Register 1 */
+
+	u32	ptr0;	/* PHY Timing Register 0 */
+	u32	ptr1;	/* PHY Timing Register 1 */
+	u32	ptr2;	/* PHY Timing Register 1 */
+
+	u32	dtpr0;	/* DRAM Timing Parameters Register 0 */
+	u32	dtpr1;	/* DRAM Timing Parameters Register 1 */
+	u32	dtpr2;	/* DRAM Timing Parameters Register 2 */
+
+	u8	pullup;	/* PHY pullup impedance */
+	u8	pulldn;	/* PHY pulldown impedance */
+};
+
+void pll_init(void);
+void sdram_init(void);
+
+#endif	/* __JZ4780_DRAM_H__ */
+

+ 12 - 0
arch/mips/mach-jz47xx/include/mach/jz4780_gpio.h

@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef __JZ4780_GPIO_H__
+#define __JZ4780_GPIO_H__
+
+#define JZ_GPIO(bank, pin) ((32 * (bank)) + (pin))
+
+int jz47xx_gpio_get_value(unsigned int gpio);
+void jz47xx_gpio_direction_input(unsigned int gpio);
+void jz47xx_gpio_direction_output(unsigned int gpio, int value);
+
+#endif

+ 3 - 0
arch/mips/mach-jz47xx/jz4780/Makefile

@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y := gpio.o jz4780.o pll.o reset.o sdram.o timer.o

+ 4 - 0
arch/mips/mach-jz47xx/jz4780/TODO

@@ -0,0 +1,4 @@
+- dm gpio driver
+- ethernet driver for the dm9000
+- reduce the hundreds of definitions of register addresses to the ones really needed in assembly or SPL.
+- define the remaining register base addresses as physical addresses and establish a mapping with ioremap_nocache()

+ 39 - 0
arch/mips/mach-jz47xx/jz4780/gpio.c

@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <config.h>
+#include <common.h>
+#include <asm/io.h>
+#include <mach/jz4780.h>
+
+int jz47xx_gpio_get_value(unsigned int gpio)
+{
+	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+	int port = gpio / 32;
+	int pin = gpio % 32;
+
+	return readl(gpio_regs + GPIO_PXPIN(port)) & BIT(pin);
+}
+
+void jz47xx_gpio_direction_input(unsigned int gpio)
+{
+	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+	int port = gpio / 32;
+	int pin = gpio % 32;
+
+	writel(BIT(pin), gpio_regs + GPIO_PXINTC(port));
+	writel(BIT(pin), gpio_regs + GPIO_PXMASKS(port));
+	writel(BIT(pin), gpio_regs + GPIO_PXPAT1S(port));
+}
+
+void jz47xx_gpio_direction_output(unsigned int gpio, int value)
+{
+	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+	int port = gpio / 32;
+	int pin = gpio % 32;
+
+	writel(BIT(pin), gpio_regs + GPIO_PXINTC(port));
+	writel(BIT(pin), gpio_regs + GPIO_PXMASKS(port));
+	writel(BIT(pin), gpio_regs + GPIO_PXPAT1C(port));
+	writel(BIT(pin), gpio_regs +
+			 (value ? GPIO_PXPAT0S(port) : GPIO_PXPAT0C(port)));
+}

+ 83 - 0
arch/mips/mach-jz47xx/jz4780/jz4780.c

@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * JZ4780 common routines
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ */
+
+#include <config.h>
+#include <common.h>
+#include <asm/io.h>
+#include <asm/sections.h>
+#include <mach/jz4780.h>
+#include <mach/jz4780_dram.h>
+#include <mmc.h>
+#include <spl.h>
+
+#ifdef CONFIG_SPL_BUILD
+/* Pointer to the global data structure for SPL */
+DECLARE_GLOBAL_DATA_PTR;
+gd_t gdata __attribute__ ((section(".bss")));
+
+void board_init_f(ulong dummy)
+{
+	typedef void __noreturn (*image_entry_noargs_t)(void);
+	struct mmc *mmc;
+	unsigned long count;
+	struct image_header *header;
+	int ret;
+
+	/* Set global data pointer */
+	gd = &gdata;
+
+	timer_init();
+	pll_init();
+	sdram_init();
+	enable_caches();
+
+	/* Clear the BSS */
+	memset(__bss_start, 0, (char *)&__bss_end - __bss_start);
+
+	gd->flags |= GD_FLG_SPL_INIT;
+
+	ret = mmc_initialize(NULL);
+	if (ret)
+		hang();
+
+	mmc = find_mmc_device(BOOT_DEVICE_MMC1);
+	if (ret)
+		hang();
+
+	ret = mmc_init(mmc);
+	if (ret)
+		hang();
+
+	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
+					 sizeof(struct image_header));
+
+	count = blk_dread(mmc_get_blk_desc(mmc),
+			  CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR,
+		0x800, header);
+	if (count == 0)
+		hang();
+
+	image_entry_noargs_t image_entry =
+		(image_entry_noargs_t)CONFIG_SYS_TEXT_BASE;
+
+	image_entry();
+
+	hang();
+}
+#endif /* CONFIG_SPL_BUILD */
+
+ulong board_get_usable_ram_top(ulong total_size)
+{
+	return CONFIG_SYS_SDRAM_BASE + (256 * 1024 * 1024);
+}
+
+int print_cpuinfo(void)
+{
+	printf("CPU:   Ingenic JZ4780\n");
+	return 0;
+}

+ 530 - 0
arch/mips/mach-jz47xx/jz4780/pll.c

@@ -0,0 +1,530 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * JZ4780 PLL setup
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ */
+
+#include <config.h>
+#include <common.h>
+#include <asm/io.h>
+#include <mach/jz4780.h>
+
+#define CPM_CPCCR		0x00
+#define CPM_LCR			0x04
+#define CPM_RSR			0x08
+#define CPM_CPPCR		0x0c
+#define CPM_CPAPCR		0x10
+#define CPM_CPMPCR		0x14
+#define CPM_CPEPCR		0x18
+#define CPM_CPVPCR		0x1c
+#define CPM_CLKGR0		0x20
+#define CPM_OPCR		0x24
+#define CPM_CLKGR1		0x28
+#define CPM_DDCDR		0x2c
+#define CPM_VPUCDR		0x30
+#define CPM_CPSPR		0x34
+#define CPM_CPSPPR		0x38
+#define CPM_USBPCR		0x3c
+#define CPM_USBRDT		0x40
+#define CPM_USBVBFIL		0x44
+#define CPM_USBPCR1		0x48
+#define CPM_USBCDR		0x50
+#define CPM_LPCDR		0x54
+#define CPM_I2SCDR		0x60
+#define CPM_LPCDR1		0x64
+#define CPM_MSCCDR		0x68
+#define CPM_UHCCDR		0x6c
+#define CPM_SSICDR		0x74
+#define CPM_CIMCDR		0x7c
+#define CPM_PCMCDR		0x84
+#define CPM_GPUCDR		0x88
+#define CPM_HDMICDR		0x8c
+#define CPM_I2S1CDR		0xa0
+#define CPM_MSCCDR1		0xa4
+#define CPM_MSCCDR2		0xa8
+#define CPM_BCHCDR		0xac
+#define CPM_SPCR0		0xb8
+#define CPM_SPCR1		0xbc
+#define CPM_CPCSR		0xd4
+#define CPM_PSWCST(n)		((0x4 * (n)) + 0x90)
+
+/* Clock control register */
+#define CPM_CPCCR_SEL_SRC_BIT		30
+#define CPM_CPCCR_SEL_SRC_MASK		(0x3 << CPM_CPCCR_SEL_SRC_BIT)
+#define CPM_SRC_SEL_STOP		0
+#define CPM_SRC_SEL_APLL		1
+#define CPM_SRC_SEL_EXCLK		2
+#define CPM_SRC_SEL_RTCLK		3
+#define CPM_CPCCR_SEL_CPLL_BIT		28
+#define CPM_CPCCR_SEL_CPLL_MASK		(0x3 << CPM_CPCCR_SEL_CPLL_BIT)
+#define CPM_CPCCR_SEL_H0PLL_BIT		26
+#define CPM_CPCCR_SEL_H0PLL_MASK	(0x3 << CPM_CPCCR_SEL_H0PLL_BIT)
+#define CPM_CPCCR_SEL_H2PLL_BIT		24
+#define CPM_CPCCR_SEL_H2PLL_MASK	(0x3 << CPM_CPCCR_SEL_H2PLL_BIT)
+#define CPM_PLL_SEL_STOP		0
+#define CPM_PLL_SEL_SRC			1
+#define CPM_PLL_SEL_MPLL		2
+#define CPM_PLL_SEL_EPLL		3
+#define CPM_CPCCR_CE_CPU		(0x1 << 22)
+#define CPM_CPCCR_CE_AHB0		(0x1 << 21)
+#define CPM_CPCCR_CE_AHB2		(0x1 << 20)
+#define CPM_CPCCR_PDIV_BIT		16
+#define CPM_CPCCR_PDIV_MASK		(0xf << CPM_CPCCR_PDIV_BIT)
+#define CPM_CPCCR_H2DIV_BIT		12
+#define CPM_CPCCR_H2DIV_MASK		(0xf << CPM_CPCCR_H2DIV_BIT)
+#define CPM_CPCCR_H0DIV_BIT		8
+#define CPM_CPCCR_H0DIV_MASK		(0x0f << CPM_CPCCR_H0DIV_BIT)
+#define CPM_CPCCR_L2DIV_BIT		4
+#define CPM_CPCCR_L2DIV_MASK		(0x0f << CPM_CPCCR_L2DIV_BIT)
+#define CPM_CPCCR_CDIV_BIT		0
+#define CPM_CPCCR_CDIV_MASK		(0x0f << CPM_CPCCR_CDIV_BIT)
+
+/* Clock Status register */
+#define CPM_CPCSR_H2DIV_BUSY		BIT(2)
+#define CPM_CPCSR_H0DIV_BUSY		BIT(1)
+#define CPM_CPCSR_CDIV_BUSY		BIT(0)
+
+/* PLL control register */
+#define CPM_CPPCR_PLLST_BIT		0
+#define CPM_CPPCR_PLLST_MASK		(0xff << CPM_CPPCR_PLLST_BIT)
+
+/* XPLL control register */
+#define CPM_CPXPCR_XPLLM_BIT		19
+#define CPM_CPXPCR_XPLLM_MASK		(0x1fff << CPM_CPXPCR_XPLLM_BIT)
+#define CPM_CPXPCR_XPLLN_BIT		13
+#define CPM_CPXPCR_XPLLN_MASK		(0x3f << CPM_CPXPCR_XPLLN_BIT)
+#define CPM_CPXPCR_XPLLOD_BIT		9
+#define CPM_CPXPCR_XPLLOD_MASK		(0xf << CPM_CPXPCR_XPLLOD_BIT)
+#define CPM_CPXPCR_XLOCK		BIT(6)
+#define CPM_CPXPCR_XPLL_ON		BIT(4)
+#define CPM_CPXPCR_XF_MODE		BIT(3)
+#define CPM_CPXPCR_XPLLBP		BIT(1)
+#define CPM_CPXPCR_XPLLEN		BIT(0)
+
+/* CPM scratch protected register */
+#define CPM_CPSPPR_BIT			0
+#define CPM_CPSPPR_MASK			(0xffff << CPM_CPSPPR_BIT)
+
+/* USB parameter control register */
+#define CPM_USBPCR_USB_MODE		BIT(31)  /* 1: OTG, 0: UDC*/
+#define CPM_USBPCR_AVLD_REG		BIT(30)
+#define CPM_USBPCR_IDPULLUP_MASK_BIT	28
+#define CPM_USBPCR_IDPULLUP_MASK_MASK	(0x02 << IDPULLUP_MASK_BIT)
+#define CPM_USBPCR_INCR_MASK		BIT(27)
+#define CPM_USBPCR_CLK12_EN		BIT(26)
+#define CPM_USBPCR_COMMONONN		BIT(25)
+#define CPM_USBPCR_VBUSVLDEXT		BIT(24)
+#define CPM_USBPCR_VBUSVLDEXTSEL	BIT(23)
+#define CPM_USBPCR_POR			BIT(22)
+#define CPM_USBPCR_SIDDQ		BIT(21)
+#define CPM_USBPCR_OTG_DISABLE		BIT(20)
+#define CPM_USBPCR_COMPDISTUNE_BIT	17
+#define CPM_USBPCR_COMPDISTUNE_MASK	(0x07 << COMPDISTUNE_BIT)
+#define CPM_USBPCR_OTGTUNE_BIT		14
+#define CPM_USBPCR_OTGTUNE_MASK		(0x07 << OTGTUNE_BIT)
+#define CPM_USBPCR_SQRXTUNE_BIT		11
+#define CPM_USBPCR_SQRXTUNE_MASK	(0x7x << SQRXTUNE_BIT)
+#define CPM_USBPCR_TXFSLSTUNE_BIT	7
+#define CPM_USBPCR_TXFSLSTUNE_MASK	(0x0f << TXFSLSTUNE_BIT)
+#define CPM_USBPCR_TXPREEMPHTUNE	BIT(6)
+#define CPM_USBPCR_TXRISETUNE_BIT	4
+#define CPM_USBPCR_TXRISETUNE_MASK	(0x03 << TXRISETUNE_BIT)
+#define CPM_USBPCR_TXVREFTUNE_BIT	0
+#define CPM_USBPCR_TXVREFTUNE_MASK	(0x0f << TXVREFTUNE_BIT)
+
+/* DDR memory clock divider register */
+#define CPM_DDRCDR_DCS_BIT		30
+#define CPM_DDRCDR_DCS_MASK		(0x3 << CPM_DDRCDR_DCS_BIT)
+#define CPM_DDRCDR_DCS_STOP		(0x0 << CPM_DDRCDR_DCS_BIT)
+#define CPM_DDRCDR_DCS_SRC		(0x1 << CPM_DDRCDR_DCS_BIT)
+#define CPM_DDRCDR_DCS_MPLL		(0x2 << CPM_DDRCDR_DCS_BIT)
+#define CPM_DDRCDR_CE_DDR		BIT(29)
+#define CPM_DDRCDR_DDR_BUSY		BIT(28)
+#define CPM_DDRCDR_DDR_STOP		BIT(27)
+#define CPM_DDRCDR_DDRDIV_BIT		0
+#define CPM_DDRCDR_DDRDIV_MASK		(0xf << CPM_DDRCDR_DDRDIV_BIT)
+
+/* USB reset detect timer register */
+#define CPM_USBRDT_VBFIL_LD_EN		BIT(25)
+#define CPM_USBRDT_IDDIG_EN		BIT(24)
+#define CPM_USBRDT_IDDIG_REG		BIT(23)
+#define CPM_USBRDT_USBRDT_BIT		0
+#define CPM_USBRDT_USBRDT_MASK		(0x7fffff << CPM_USBRDT_USBRDT_BIT)
+
+/* USB OTG PHY clock divider register */
+#define CPM_USBCDR_UCS			BIT(31)
+#define CPM_USBCDR_UPCS			BIT(30)
+#define CPM_USBCDR_CEUSB		BIT(29)
+#define CPM_USBCDR_USB_BUSY		BIT(28)
+#define CPM_USBCDR_OTGDIV_BIT		0
+#define CPM_USBCDR_OTGDIV_MASK		(0xff << CPM_USBCDR_OTGDIV_BIT)
+
+/* I2S device clock divider register */
+#define CPM_I2SCDR_I2CS			BIT(31)
+#define CPM_I2SCDR_I2PCS		BIT(30)
+#define CPM_I2SCDR_I2SDIV_BIT		0
+#define CPM_I2SCDR_I2SDIV_MASK		(0x1ff << CPM_I2SCDR_I2SDIV_BIT)
+
+/* LCD0 pix clock divider register */
+#define CPM_LPCDR_LPCS_BIT		30
+#define CPM_LPCDR_LPCS_MASK		(0x3 << CPM_LPCDR_LPCS_BIT)
+#define CPM_LPCDR_CELCD			BIT(28)
+#define CPM_LPCDR_LCD_BUSY		BIT(27)
+#define CPM_LPCDR_LCD_STOP		BIT(26)
+#define CPM_LPCDR_PIXDIV_BIT		0
+#define CPM_LPCDR_PIXDIV_MASK		(0xff << CPM_LPCDR_PIXDIV_BIT)
+
+/* MSC clock divider register */
+#define CPM_MSCCDR_MPCS_BIT		30
+#define CPM_MSCCDR_MPCS_MASK		(3 << CPM_MSCCDR_MPCS_BIT)
+#define CPM_MSCCDR_MPCS_STOP		(0x0 << CPM_MSCCDR_MPCS_BIT)
+#define CPM_MSCCDR_MPCS_SRC		(0x1 << CPM_MSCCDR_MPCS_BIT)
+#define CPM_MSCCDR_MPCS_MPLL		(0x2 << CPM_MSCCDR_MPCS_BIT)
+#define CPM_MSCCDR_CE			BIT(29)
+#define CPM_MSCCDR_MSC_BUSY		BIT(28)
+#define CPM_MSCCDR_MSC_STOP		BIT(27)
+#define CPM_MSCCDR_MSC_CLK0_SEL		BIT(15)
+#define CPM_MSCCDR_MSCDIV_BIT		0
+#define CPM_MSCCDR_MSCDIV_MASK		(0xff << CPM_MSCCDR_MSCDIV_BIT)
+
+/* UHC 48M clock divider register */
+#define CPM_UHCCDR_UHCS_BIT		30
+#define CPM_UHCCDR_UHCS_MASK		(0x3 << CPM_UHCCDR_UHCS_BIT)
+#define CPM_UHCCDR_UHCS_SRC		(0x0 << CPM_UHCCDR_UHCS_BIT)
+#define CPM_UHCCDR_UHCS_MPLL		(0x1 << CPM_UHCCDR_UHCS_BIT)
+#define CPM_UHCCDR_UHCS_EPLL		(0x2 << CPM_UHCCDR_UHCS_BIT)
+#define CPM_UHCCDR_UHCS_OTG		(0x3 << CPM_UHCCDR_UHCS_BIT)
+#define CPM_UHCCDR_CE_UHC		BIT(29)
+#define CPM_UHCCDR_UHC_BUSY		BIT(28)
+#define CPM_UHCCDR_UHC_STOP		BIT(27)
+#define CPM_UHCCDR_UHCDIV_BIT		0
+#define CPM_UHCCDR_UHCDIV_MASK		(0xff << CPM_UHCCDR_UHCDIV_BIT)
+
+/* SSI clock divider register */
+#define CPM_SSICDR_SCS			BIT(31)
+#define CPM_SSICDR_SSIDIV_BIT		0
+#define CPM_SSICDR_SSIDIV_MASK		(0x3f << CPM_SSICDR_SSIDIV_BIT)
+
+/* CIM MCLK clock divider register */
+#define CPM_CIMCDR_CIMDIV_BIT		0
+#define CPM_CIMCDR_CIMDIV_MASK		(0xff << CPM_CIMCDR_CIMDIV_BIT)
+
+/* GPS clock divider register */
+#define CPM_GPSCDR_GPCS			BIT(31)
+#define CPM_GPSCDR_GPSDIV_BIT		0
+#define CPM_GSPCDR_GPSDIV_MASK		(0xf << CPM_GPSCDR_GPSDIV_BIT)
+
+/* PCM device clock divider register */
+#define CPM_PCMCDR_PCMS			BIT(31)
+#define CPM_PCMCDR_PCMPCS		BIT(30)
+#define CPM_PCMCDR_PCMDIV_BIT		0
+#define CPM_PCMCDR_PCMDIV_MASK		(0x1ff << CPM_PCMCDR_PCMDIV_BIT)
+
+/* GPU clock divider register */
+#define CPM_GPUCDR_GPCS			BIT(31)
+#define CPM_GPUCDR_GPUDIV_BIT		0
+#define CPM_GPUCDR_GPUDIV_MASK		(0x7 << CPM_GPUCDR_GPUDIV_BIT)
+
+/* HDMI clock divider register */
+#define CPM_HDMICDR_HPCS_BIT		30
+#define CPM_HDMICDR_HPCS_MASK		(0x3 << CPM_HDMICDR_HPCS_BIT)
+#define CPM_HDMICDR_CEHDMI		BIT(29)
+#define CPM_HDMICDR_HDMI_BUSY		BIT(28)
+#define CPM_HDMICDR_HDMI_STOP		BIT(26)
+#define CPM_HDMICDR_HDMIDIV_BIT		0
+#define CPM_HDMICDR_HDMIDIV_MASK	(0xff << CPM_HDMICDR_HDMIDIV_BIT)
+
+/* Low Power Control Register */
+#define CPM_LCR_PD_SCPU			BIT(31)
+#define CPM_LCR_PD_VPU			BIT(30)
+#define CPM_LCR_PD_GPU			BIT(29)
+#define CPM_LCR_PD_GPS			BIT(28)
+#define CPM_LCR_SCPUS			BIT(27)
+#define CPM_LCR_VPUS			BIT(26)
+#define CPM_LCR_GPUS			BIT(25)
+#define CPM_LCR_GPSS			BIT(24)
+#define CPM_LCR_GPU_IDLE		BIT(20)
+#define CPM_LCR_PST_BIT			8
+#define CPM_LCR_PST_MASK		(0xfff << CPM_LCR_PST_BIT)
+#define CPM_LCR_DOZE_DUTY_BIT		3
+#define CPM_LCR_DOZE_DUTY_MASK		(0x1f << CPM_LCR_DOZE_DUTY_BIT)
+#define CPM_LCR_DOZE_ON			BIT(2)
+#define CPM_LCR_LPM_BIT			0
+#define CPM_LCR_LPM_MASK		(0x3 << CPM_LCR_LPM_BIT)
+#define CPM_LCR_LPM_IDLE		(0x0 << CPM_LCR_LPM_BIT)
+#define CPM_LCR_LPM_SLEEP		(0x1 << CPM_LCR_LPM_BIT)
+
+/* Clock Gate Register0 */
+#define CPM_CLKGR0_DDR1			BIT(31)
+#define CPM_CLKGR0_DDR0			BIT(30)
+#define CPM_CLKGR0_IPU			BIT(29)
+#define CPM_CLKGR0_LCD1			BIT(28)
+#define CPM_CLKGR0_LCD			BIT(27)
+#define CPM_CLKGR0_CIM			BIT(26)
+#define CPM_CLKGR0_I2C2			BIT(25)
+#define CPM_CLKGR0_UHC			BIT(24)
+#define CPM_CLKGR0_MAC			BIT(23)
+#define CPM_CLKGR0_GPS			BIT(22)
+#define CPM_CLKGR0_PDMAC		BIT(21)
+#define CPM_CLKGR0_SSI2			BIT(20)
+#define CPM_CLKGR0_SSI1			BIT(19)
+#define CPM_CLKGR0_UART3		BIT(18)
+#define CPM_CLKGR0_UART2		BIT(17)
+#define CPM_CLKGR0_UART1		BIT(16)
+#define CPM_CLKGR0_UART0		BIT(15)
+#define CPM_CLKGR0_SADC			BIT(14)
+#define CPM_CLKGR0_KBC			BIT(13)
+#define CPM_CLKGR0_MSC2			BIT(12)
+#define CPM_CLKGR0_MSC1			BIT(11)
+#define CPM_CLKGR0_OWI			BIT(10)
+#define CPM_CLKGR0_TSSI			BIT(9)
+#define CPM_CLKGR0_AIC			BIT(8)
+#define CPM_CLKGR0_SCC			BIT(7)
+#define CPM_CLKGR0_I2C1			BIT(6)
+#define CPM_CLKGR0_I2C0			BIT(5)
+#define CPM_CLKGR0_SSI0			BIT(4)
+#define CPM_CLKGR0_MSC0			BIT(3)
+#define CPM_CLKGR0_OTG			BIT(2)
+#define CPM_CLKGR0_BCH			BIT(1)
+#define CPM_CLKGR0_NEMC			BIT(0)
+
+/* Clock Gate Register1 */
+#define CPM_CLKGR1_P1			BIT(15)
+#define CPM_CLKGR1_X2D			BIT(14)
+#define CPM_CLKGR1_DES			BIT(13)
+#define CPM_CLKGR1_I2C4			BIT(12)
+#define CPM_CLKGR1_AHB			BIT(11)
+#define CPM_CLKGR1_UART4		BIT(10)
+#define CPM_CLKGR1_HDMI			BIT(9)
+#define CPM_CLKGR1_OTG1			BIT(8)
+#define CPM_CLKGR1_GPVLC		BIT(7)
+#define CPM_CLKGR1_AIC1			BIT(6)
+#define CPM_CLKGR1_COMPRES		BIT(5)
+#define CPM_CLKGR1_GPU			BIT(4)
+#define CPM_CLKGR1_PCM			BIT(3)
+#define CPM_CLKGR1_VPU			BIT(2)
+#define CPM_CLKGR1_TSSI1		BIT(1)
+#define CPM_CLKGR1_I2C3			BIT(0)
+
+/* Oscillator and Power Control Register */
+#define CPM_OPCR_O1ST_BIT		8
+#define CPM_OPCR_O1ST_MASK		(0xff << CPM_OPCR_O1ST_BIT)
+#define CPM_OPCR_SPENDN			BIT(7)
+#define CPM_OPCR_GPSEN			BIT(6)
+#define CPM_OPCR_SPENDH			BIT(5)
+#define CPM_OPCR_O1SE			BIT(4)
+#define CPM_OPCR_ERCS			BIT(2) /* 0: select EXCLK/512 clock, 1: RTCLK clock */
+#define CPM_OPCR_USBM			BIT(0) /* 0: select EXCLK/512 clock, 1: RTCLK clock */
+
+/* Reset Status Register */
+#define CPM_RSR_P0R			BIT(2)
+#define CPM_RSR_WR			BIT(1)
+#define CPM_RSR_PR			BIT(0)
+
+/* BCH clock divider register */
+#define CPM_BCHCDR_BPCS_BIT		30
+#define CPM_BCHCDR_BPCS_MASK		(0x3 << CPM_BCHCDR_BPCS_BIT)
+#define CPM_BCHCDR_BPCS_STOP		(0X0 << CPM_BCHCDR_BPCS_BIT)
+#define CPM_BCHCDR_BPCS_SRC_CLK		(0x1 << CPM_BCHCDR_BPCS_BIT)
+#define CPM_BCHCDR_BPCS_MPLL		(0x2 << CPM_BCHCDR_BPCS_BIT)
+#define CPM_BCHCDR_BPCS_EPLL		(0x3 << CPM_BCHCDR_BPCS_BIT)
+#define CPM_BCHCDR_CE_BCH		BIT(29)
+#define CPM_BCHCDR_BCH_BUSY		BIT(28)
+#define CPM_BCHCDR_BCH_STOP		BIT(27)
+#define CPM_BCHCDR_BCHCDR_BIT		0
+#define CPM_BCHCDR_BCHCDR_MASK		(0x7 << CPM_BCHCDR_BCHCDR_BIT)
+
+/* CPM scratch pad protected register(CPSPPR) */
+#define CPSPPR_CPSPR_WRITABLE		0x00005a5a
+#define RECOVERY_SIGNATURE		0x1a1a	/* means "RECY" */
+#define RECOVERY_SIGNATURE_SEC		0x800	/* means "RECY" */
+
+#define REBOOT_SIGNATURE		0x3535	/* means reboot */
+
+/* XPLL control register */
+#define XLOCK		(1 << 6)
+#define XPLL_ON		(1 << 4)
+#define XF_MODE		(1 << 3)
+#define XPLLBP		(1 << 1)
+#define XPLLEN		(1 << 0)
+
+enum PLLS {
+	EXTCLK = 0,
+	APLL,
+	MPLL,
+	EPLL,
+	VPLL,
+};
+
+#define M_N_OD(m, n, od)		\
+		((((m) - 1) << 19) | (((n) - 1) << 13) | (((od) - 1) << 9))
+
+struct cgu_pll_select {
+	u8	reg;
+	u8	pll;
+	u8	pll_shift;
+};
+
+static void pll_init_one(int pll, int m, int n, int od)
+{
+	void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+	void __iomem *pll_reg = cpm_regs + CPM_CPAPCR + ((pll - 1) * 4);
+
+	setbits_le32(pll_reg, M_N_OD(m, n, od) | XPLLEN);
+
+	/* FIXME */
+	while (!(readl(pll_reg) & XPLL_ON))
+		;
+}
+
+static void cpu_mux_select(int pll)
+{
+	void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+	u32 clk_ctrl;
+	unsigned int selectplls[] = {
+		CPM_PLL_SEL_STOP,
+		CPM_PLL_SEL_SRC,
+		CPM_PLL_SEL_MPLL,
+		CPM_PLL_SEL_EPLL
+	};
+
+	/* Init CPU, L2CACHE, AHB0, AHB2, APB clock */
+	clk_ctrl = CPM_CPCCR_CE_CPU | CPM_CPCCR_CE_AHB0 | CPM_CPCCR_CE_AHB2 |
+			((6 - 1) << CPM_CPCCR_H2DIV_BIT) |
+			((3 - 1) << CPM_CPCCR_H0DIV_BIT) |
+			((2 - 1) << CPM_CPCCR_L2DIV_BIT) |
+			((1 - 1) << CPM_CPCCR_CDIV_BIT);
+
+	if (CONFIG_SYS_MHZ >= 1000)
+		clk_ctrl |= (12 - 1) << CPM_CPCCR_PDIV_BIT;
+	else
+		clk_ctrl |= (6 - 1) << CPM_CPCCR_PDIV_BIT;
+
+	clrsetbits_le32(cpm_regs + CPM_CPCCR, 0x00ffffff, clk_ctrl);
+
+	while (readl(cpm_regs + CPM_CPCSR) & (CPM_CPCSR_CDIV_BUSY |
+	       CPM_CPCSR_H0DIV_BUSY | CPM_CPCSR_H2DIV_BUSY))
+		;
+
+	clk_ctrl = (selectplls[pll] << CPM_CPCCR_SEL_CPLL_BIT) |
+		   (selectplls[MPLL] << CPM_CPCCR_SEL_H0PLL_BIT) |
+		   (selectplls[MPLL] << CPM_CPCCR_SEL_H2PLL_BIT);
+	if (pll == APLL)
+		clk_ctrl |= CPM_PLL_SEL_SRC << CPM_CPCCR_SEL_SRC_BIT;
+	else
+		clk_ctrl |= CPM_SRC_SEL_EXCLK << CPM_CPCCR_SEL_SRC_BIT;
+
+	clrsetbits_le32(cpm_regs + CPM_CPCCR, 0xff << 24, clk_ctrl);
+}
+
+static void ddr_mux_select(int pll)
+{
+	void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+	int selectplls[] = { CPM_DDRCDR_DCS_STOP,
+			     CPM_DDRCDR_DCS_SRC,
+			     CPM_DDRCDR_DCS_MPLL};
+
+	writel(selectplls[pll] | CPM_DDRCDR_CE_DDR | (JZ4780_SYS_MEM_DIV - 1),
+	       cpm_regs + CPM_DDCDR);
+
+	while (readl(cpm_regs + CPM_DDCDR) & CPM_DDRCDR_DDR_BUSY)
+		;
+
+	clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_DDR0);
+
+	mdelay(200);
+}
+
+static void cgu_mux_init(struct cgu_pll_select *cgu, unsigned int num)
+{
+	void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+	unsigned int selectplls[] = {0, 1, 2, 3, 2, 6};
+	int i;
+
+	for (i = 0; i < num; i++)
+		writel(selectplls[cgu[i].pll] << cgu[i].pll_shift,
+		       cpm_regs + cgu[i].reg);
+}
+
+void pll_init(void)
+{
+	void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+	struct cgu_pll_select cgu_mux[] = {
+		{ CPM_MSCCDR,  MPLL, 30 },
+		{ CPM_LPCDR,   VPLL, 30 },
+		{ CPM_LPCDR1,  VPLL, 30 },
+		{ CPM_GPUCDR,  MPLL, 30 },
+		{ CPM_HDMICDR, VPLL, 30 },
+		{ CPM_I2SCDR,  EPLL, 30 },
+		{ CPM_BCHCDR,  MPLL, 30 },
+		{ CPM_VPUCDR,  0x1,  30 },
+		{ CPM_UHCCDR,  0x3,  30 },
+		{ CPM_CIMCDR,  0x1,  31 },
+		{ CPM_PCMCDR,  0x5,  29 },
+		{ CPM_SSICDR,  0x3,  30 },
+	};
+
+	/* PLL stable time set to default -- 1ms */
+	clrsetbits_le32(cpm_regs + CPM_CPPCR, 0xfffff, (16 << 8) | 0x20);
+
+	pll_init_one(APLL, JZ4780_APLL_M, JZ4780_APLL_N, JZ4780_APLL_OD);
+	pll_init_one(MPLL, JZ4780_MPLL_M, JZ4780_MPLL_N, JZ4780_MPLL_OD);
+	pll_init_one(VPLL, JZ4780_VPLL_M, JZ4780_VPLL_N, JZ4780_VPLL_OD);
+	pll_init_one(EPLL, JZ4780_EPLL_M, JZ4780_EPLL_N, JZ4780_EPLL_OD);
+
+	cpu_mux_select(MPLL);
+	ddr_mux_select(MPLL);
+	cgu_mux_init(cgu_mux, ARRAY_SIZE(cgu_mux));
+}
+
+const u32 jz4780_clk_get_efuse_clk(void)
+{
+	void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+	u32 cpccr = readl(cpm_regs + CPM_CPCCR);
+	u32 ahb2_div = ((cpccr & CPM_CPCCR_H2DIV_MASK) >>
+			CPM_CPCCR_H2DIV_BIT) + 1;
+	return JZ4780_SYS_MEM_SPEED / ahb2_div;
+}
+
+void jz4780_clk_ungate_ethernet(void)
+{
+	void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+
+	clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_MAC);
+	clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_NEMC);
+}
+
+void jz4780_clk_ungate_mmc(void)
+{
+	void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+	u32 msc_cdr = JZ4780_SYS_MEM_SPEED / 24000000 / 2 - 1;
+
+	msc_cdr |= CPM_MSCCDR_MPCS_MPLL | CPM_MSCCDR_CE;
+	writel(msc_cdr, cpm_regs + CPM_MSCCDR);
+	writel(msc_cdr, cpm_regs + CPM_MSCCDR1);
+	writel(msc_cdr, cpm_regs + CPM_MSCCDR2);
+
+	/* The wait_for_bit() won't fit, thus unbounded loop here. */
+	while (readl(cpm_regs + CPM_MSCCDR1) & CPM_MSCCDR_MSC_BUSY)
+		;
+}
+
+void jz4780_clk_ungate_uart(const unsigned int uart)
+{
+	void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+
+	if (uart == 0)
+		clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_UART0);
+	else if (uart == 1)
+		clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_UART1);
+	else if (uart == 2)
+		clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_UART2);
+	else if (uart == 3)
+		clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_UART3);
+	else if (uart == 4)
+		clrbits_le32(cpm_regs + CPM_CLKGR1, CPM_CLKGR1_UART4);
+	else
+		printf("%s[%i]: Invalid UART %d\n", __func__, __LINE__, uart);
+}

+ 53 - 0
arch/mips/mach-jz47xx/jz4780/reset.c

@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * JZ4780 common routines
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ */
+
+#include <config.h>
+#include <common.h>
+#include <asm/io.h>
+#include <mach/jz4780.h>
+
+/* WDT */
+#define WDT_TDR		0x00
+#define WDT_TCER	0x04
+#define WDT_TCNT	0x08
+#define WDT_TCSR	0x0C
+
+/* Register definition */
+#define WDT_TCSR_PRESCALE_BIT	3
+#define WDT_TCSR_PRESCALE_MASK	(0x7 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE1	(0x0 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE4	(0x1 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE16	(0x2 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE64	(0x3 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE256	(0x4 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE1024	(0x5 << WDT_TCSR_PRESCALE_BIT)
+#define WDT_TCSR_EXT_EN		BIT(2)
+#define WDT_TCSR_RTC_EN		BIT(1)
+#define WDT_TCSR_PCK_EN		BIT(0)
+
+#define WDT_TCER_TCEN		BIT(0)
+
+void _machine_restart(void)
+{
+	void __iomem *wdt_regs = (void __iomem *)WDT_BASE;
+
+	/* EXTAL as the timer clock input. */
+	writew(WDT_TCSR_PRESCALE1 | WDT_TCSR_EXT_EN, wdt_regs + WDT_TCSR);
+
+	/* Reset the WDT counter and timeout. */
+	writew(0, wdt_regs + WDT_TCNT);
+	writew(0, wdt_regs + WDT_TDR);
+
+	jz4780_tcu_wdt_start();
+
+	/* WDT start */
+	writeb(WDT_TCER_TCEN, wdt_regs + WDT_TCER);
+
+	for (;;)
+		;
+}

+ 270 - 0
arch/mips/mach-jz47xx/jz4780/sdram.c

@@ -0,0 +1,270 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * JZ4780 DDR initialization
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * Based on spl/common/{jz4780_ddr,jz_ddr3_init}.c from X-Boot
+ * Copyright (c) 2006-2013 Ingenic Semiconductor
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <mach/jz4780.h>
+#include <mach/jz4780_dram.h>
+
+static const u32 get_mem_clk(void)
+{
+	const u32 mpll_out = ((u64)JZ4780_SYS_EXTAL * JZ4780_MPLL_M) /
+			     (JZ4780_MPLL_N * JZ4780_MPLL_OD);
+	return mpll_out / JZ4780_SYS_MEM_DIV;
+}
+
+u32 sdram_size(int cs)
+{
+	u32 dw = DDR_DW32 ? 4 : 2;
+	u32 banks = DDR_BANK8 ? 8 : 4;
+	u32 size = 0;
+
+	if ((cs == 0) && DDR_CS0EN) {
+		size = (1 << (DDR_ROW + DDR_COL)) * dw * banks;
+		if (DDR_CS1EN && (size > 0x20000000))
+			size = 0x20000000;
+	} else if ((cs == 1) && DDR_CS1EN) {
+		size = (1 << (DDR_ROW + DDR_COL)) * dw * banks;
+	}
+
+	return size;
+}
+
+static void ddr_cfg_init(void)
+{
+	void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE;
+	u32 ddrc_cfg, tmp;
+
+	tmp = DDR_CL;
+	if (tmp)
+		tmp--;
+	if (tmp > 4)
+		tmp = 4;
+
+	ddrc_cfg = DDRC_CFG_TYPE_DDR3 | DDRC_CFG_IMBA |
+		   DDR_DW32 | DDRC_CFG_MPRT | ((tmp | 0x8) << 2) |
+		   ((DDR_ROW - 12) << 11) | ((DDR_COL - 8) << 8) |
+		   (DDR_CS0EN << 6) | (DDR_BANK8 << 1) |
+		   ((DDR_ROW - 12) << 27) | ((DDR_COL - 8) << 24) |
+		   (DDR_CS1EN << 7) | (DDR_BANK8 << 23);
+
+	if (DDR_BL > 4)
+		ddrc_cfg |= BIT(21);
+
+	writel(ddrc_cfg, ddr_ctl_regs + DDRC_CFG);
+}
+
+static void ddr_phy_init(const struct jz4780_ddr_config *ddr_config)
+{
+	void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE;
+	void __iomem *ddr_phy_regs = ddr_ctl_regs + DDR_PHY_OFFSET;
+	unsigned int count = 0, i;
+	u32 reg, mask;
+
+	writel(DDRP_DCR_TYPE_DDR3 | (DDR_BANK8 << 3), ddr_phy_regs + DDRP_DCR);
+
+	writel(ddr_config->mr0, ddr_phy_regs + DDRP_MR0);
+	writel(ddr_config->mr1, ddr_phy_regs + DDRP_MR1);
+	writel(0, ddr_phy_regs + DDRP_ODTCR);
+	writel(0, ddr_phy_regs + DDRP_MR2);
+
+	writel(ddr_config->ptr0, ddr_phy_regs + DDRP_PTR0);
+	writel(ddr_config->ptr1, ddr_phy_regs + DDRP_PTR1);
+	writel(ddr_config->ptr2, ddr_phy_regs + DDRP_PTR2);
+
+	writel(ddr_config->dtpr0, ddr_phy_regs + DDRP_DTPR0);
+	writel(ddr_config->dtpr1, ddr_phy_regs + DDRP_DTPR1);
+	writel(ddr_config->dtpr2, ddr_phy_regs + DDRP_DTPR2);
+
+	writel(DDRP_PGCR_DQSCFG | (7 << DDRP_PGCR_CKEN_BIT) |
+	       (2 << DDRP_PGCR_CKDV_BIT) |
+	       (DDR_CS0EN | (DDR_CS1EN << 1)) << DDRP_PGCR_RANKEN_BIT |
+	       DDRP_PGCR_ZCKSEL_32 | DDRP_PGCR_PDDISDX,
+	       ddr_phy_regs + DDRP_PGCR);
+
+	for (i = 0; i < 8; i++)
+		clrbits_le32(ddr_phy_regs + DDRP_DXGCR(i), 0x3 << 9);
+
+	count = 0;
+	mask = DDRP_PGSR_IDONE | DDRP_PGSR_DLDONE | DDRP_PGSR_ZCDONE;
+	for (;;) {
+		reg = readl(ddr_phy_regs + DDRP_PGSR);
+		if ((reg == mask) || (reg == 0x1f))
+			break;
+		if (count++ == 10000)
+			hang();
+	}
+
+	/* DQS extension and early set to 1 */
+	clrsetbits_le32(ddr_phy_regs + DDRP_DSGCR, 0x7E << 4, 0x12 << 4);
+
+	/* 500 pull up and 500 pull down */
+	clrsetbits_le32(ddr_phy_regs + DDRP_DXCCR, 0xFF << 4, 0xC4 << 4);
+
+	/* Initialise phy */
+	writel(DDRP_PIR_INIT | DDRP_PIR_DRAMINT | DDRP_PIR_DRAMRST,
+	       ddr_phy_regs + DDRP_PIR);
+
+	count = 0;
+	mask |= DDRP_PGSR_DIDONE;
+	for (;;) {
+		reg = readl(ddr_phy_regs + DDRP_PGSR);
+		if ((reg == mask) || (reg == 0x1f))
+			break;
+		if (count++ == 20000)
+			hang();
+	}
+
+	writel(DDRP_PIR_INIT | DDRP_PIR_QSTRN, ddr_phy_regs + DDRP_PIR);
+
+	count = 0;
+	mask |= DDRP_PGSR_DTDONE;
+	for (;;) {
+		reg = readl(ddr_phy_regs + DDRP_PGSR);
+		if (reg == mask)
+			break;
+		if (count++ != 50000)
+			continue;
+		reg &= DDRP_PGSR_DTDONE | DDRP_PGSR_DTERR | DDRP_PGSR_DTIERR;
+		if (reg)
+			hang();
+		count = 0;
+	}
+
+	/* Override impedance */
+	clrsetbits_le32(ddr_phy_regs + DDRP_ZQXCR0(0), 0x3ff,
+		((ddr_config->pullup & 0x1f) << DDRP_ZQXCR_PULLUP_IMPE_BIT) |
+		((ddr_config->pulldn & 0x1f) << DDRP_ZQXCR_PULLDOWN_IMPE_BIT) |
+		DDRP_ZQXCR_ZDEN);
+}
+
+#define JZBIT(bit) ((bit % 4) * 8)
+#define JZMASK(bit) (0x1f << JZBIT(bit))
+
+static void remap_swap(int a, int b)
+{
+	void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE;
+	u32 remmap[2], tmp[2];
+
+	remmap[0] = readl(ddr_ctl_regs + DDRC_REMMAP(a / 4));
+	remmap[1] = readl(ddr_ctl_regs + DDRC_REMMAP(b / 4));
+
+	tmp[0] = (remmap[0] & JZMASK(a)) >> JZBIT(a);
+	tmp[1] = (remmap[1] & JZMASK(b)) >> JZBIT(b);
+
+	remmap[0] &= ~JZMASK(a);
+	remmap[1] &= ~JZMASK(b);
+
+	writel(remmap[0] | (tmp[1] << JZBIT(a)),
+	       ddr_ctl_regs + DDRC_REMMAP(a / 4));
+	writel(remmap[1] | (tmp[0] << JZBIT(b)),
+	       ddr_ctl_regs + DDRC_REMMAP(b / 4));
+}
+
+static void mem_remap(void)
+{
+	u32 start = (DDR_ROW + DDR_COL + (DDR_DW32 ? 4 : 2) / 2) - 12;
+	u32 num = DDR_BANK8 ? 3 : 2;
+
+	if (DDR_CS0EN && DDR_CS1EN)
+		num++;
+
+	for (; num > 0; num--)
+		remap_swap(0 + num - 1, start + num - 1);
+}
+
+/* Fetch DRAM config from board file */
+__weak const struct jz4780_ddr_config *jz4780_get_ddr_config(void)
+{
+	return NULL;
+}
+
+void sdram_init(void)
+{
+	const struct jz4780_ddr_config *ddr_config = jz4780_get_ddr_config();
+	void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE;
+	void __iomem *ddr_phy_regs = ddr_ctl_regs + DDR_PHY_OFFSET;
+	void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+	u32 mem_clk, tmp, i;
+	u32 mem_base0, mem_base1;
+	u32 mem_mask0, mem_mask1;
+	u32 mem_size0, mem_size1;
+
+	if (!ddr_config)
+		hang();
+
+	/* Reset DLL in DDR PHY */
+	writel(0x3, cpm_regs + 0xd0);
+	mdelay(400);
+	writel(0x1, cpm_regs + 0xd0);
+	mdelay(400);
+
+	/* Enter reset */
+	writel(0xf << 20, ddr_ctl_regs + DDRC_CTRL);
+
+	mem_clk = get_mem_clk();
+
+	tmp = 1000000000 / mem_clk;
+	if (1000000000 % mem_clk)
+		tmp++;
+	tmp = DDR_tREFI / tmp;
+	tmp = tmp / (16 * (1 << DDR_CLK_DIV)) - 1;
+	if (tmp > 0xff)
+		tmp = 0xff;
+	if (tmp < 1)
+		tmp = 1;
+
+	writel(0x0, ddr_ctl_regs + DDRC_CTRL);
+
+	writel(0x150000, ddr_phy_regs + DDRP_DTAR);
+	ddr_phy_init(ddr_config);
+
+	writel(DDRC_CTRL_CKE | DDRC_CTRL_ALH, ddr_ctl_regs + DDRC_CTRL);
+	writel(0x0, ddr_ctl_regs + DDRC_CTRL);
+
+	ddr_cfg_init();
+
+	for (i = 0; i < 6; i++)
+		writel(ddr_config->timing[i], ddr_ctl_regs + DDRC_TIMING(i));
+
+	mem_size0 = sdram_size(0);
+	mem_size1 = sdram_size(1);
+
+	if (!mem_size1 && mem_size0 > 0x20000000) {
+		mem_base0 = 0x0;
+		mem_mask0 = ~(((mem_size0 * 2) >> 24) - 1) & DDRC_MMAP_MASK_MASK;
+	} else {
+		mem_base0 = (DDR_MEM_PHY_BASE >> 24) & 0xff;
+		mem_mask0 = ~((mem_size0 >> 24) - 1) & DDRC_MMAP_MASK_MASK;
+	}
+
+	if (mem_size1) {
+		mem_mask1 = ~((mem_size1 >> 24) - 1) & DDRC_MMAP_MASK_MASK;
+		mem_base1 = ((DDR_MEM_PHY_BASE + mem_size0) >> 24) & 0xff;
+	} else {
+		mem_mask1 = 0;
+		mem_base1 = 0xff;
+	}
+
+	writel(mem_base0 << DDRC_MMAP_BASE_BIT | mem_mask0,
+	       ddr_ctl_regs + DDRC_MMAP0);
+	writel(mem_base1 << DDRC_MMAP_BASE_BIT | mem_mask1,
+	       ddr_ctl_regs + DDRC_MMAP1);
+	writel(DDRC_CTRL_CKE | DDRC_CTRL_ALH, ddr_ctl_regs + DDRC_CTRL);
+	writel((DDR_CLK_DIV << 1) | DDRC_REFCNT_REF_EN |
+	       (tmp << DDRC_REFCNT_CON_BIT),
+	       ddr_ctl_regs + DDRC_REFCNT);
+	writel((1 << 15) | (4 << 12) | (1 << 11) | (1 << 8) | (0 << 6) |
+	       (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1),
+	       ddr_ctl_regs + DDRC_CTRL);
+	mem_remap();
+	clrbits_le32(ddr_ctl_regs + DDRC_ST, 0x40);
+}

+ 239 - 0
arch/mips/mach-jz47xx/jz4780/timer.c

@@ -0,0 +1,239 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * JZ4780 timer
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ */
+
+#include <config.h>
+#include <common.h>
+#include <div64.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <mach/jz4780.h>
+
+#define TCU_TSR		0x1C	/* Timer Stop Register */
+#define TCU_TSSR	0x2C	/* Timer Stop Set Register */
+#define TCU_TSCR	0x3C	/* Timer Stop Clear Register */
+#define TCU_TER		0x10	/* Timer Counter Enable Register */
+#define TCU_TESR	0x14	/* Timer Counter Enable Set Register */
+#define TCU_TECR	0x18	/* Timer Counter Enable Clear Register */
+#define TCU_TFR		0x20	/* Timer Flag Register */
+#define TCU_TFSR	0x24	/* Timer Flag Set Register */
+#define TCU_TFCR	0x28	/* Timer Flag Clear Register */
+#define TCU_TMR		0x30	/* Timer Mask Register */
+#define TCU_TMSR	0x34	/* Timer Mask Set Register */
+#define TCU_TMCR	0x38	/* Timer Mask Clear Register */
+/* n = 0,1,2,3,4,5 */
+#define TCU_TDFR(n)	(0x40 + (n) * 0x10)	/* Timer Data Full Reg */
+#define TCU_TDHR(n)	(0x44 + (n) * 0x10)	/* Timer Data Half Reg */
+#define TCU_TCNT(n)	(0x48 + (n) * 0x10)	/* Timer Counter Reg */
+#define TCU_TCSR(n)	(0x4C + (n) * 0x10)	/* Timer Control Reg */
+
+#define TCU_OSTCNTL	0xe4
+#define TCU_OSTCNTH	0xe8
+#define TCU_OSTCSR	0xec
+#define TCU_OSTCNTHBUF	0xfc
+
+/* Register definitions */
+#define TCU_TCSR_PWM_SD		BIT(9)
+#define TCU_TCSR_PWM_INITL_HIGH	BIT(8)
+#define TCU_TCSR_PWM_EN		BIT(7)
+#define TCU_TCSR_PRESCALE_BIT	3
+#define TCU_TCSR_PRESCALE_MASK	(0x7 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE1	(0x0 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE4	(0x1 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE16	(0x2 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE64	(0x3 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE256	(0x4 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE1024	(0x5 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_EXT_EN		BIT(2)
+#define TCU_TCSR_RTC_EN		BIT(1)
+#define TCU_TCSR_PCK_EN		BIT(0)
+
+#define TCU_TER_TCEN5		BIT(5)
+#define TCU_TER_TCEN4		BIT(4)
+#define TCU_TER_TCEN3		BIT(3)
+#define TCU_TER_TCEN2		BIT(2)
+#define TCU_TER_TCEN1		BIT(1)
+#define TCU_TER_TCEN0		BIT(0)
+
+#define TCU_TESR_TCST5		BIT(5)
+#define TCU_TESR_TCST4		BIT(4)
+#define TCU_TESR_TCST3		BIT(3)
+#define TCU_TESR_TCST2		BIT(2)
+#define TCU_TESR_TCST1		BIT(1)
+#define TCU_TESR_TCST0		BIT(0)
+
+#define TCU_TECR_TCCL5		BIT(5)
+#define TCU_TECR_TCCL4		BIT(4)
+#define TCU_TECR_TCCL3		BIT(3)
+#define TCU_TECR_TCCL2		BIT(2)
+#define TCU_TECR_TCCL1		BIT(1)
+#define TCU_TECR_TCCL0		BIT(0)
+
+#define TCU_TFR_HFLAG5		BIT(21)
+#define TCU_TFR_HFLAG4		BIT(20)
+#define TCU_TFR_HFLAG3		BIT(19)
+#define TCU_TFR_HFLAG2		BIT(18)
+#define TCU_TFR_HFLAG1		BIT(17)
+#define TCU_TFR_HFLAG0		BIT(16)
+#define TCU_TFR_FFLAG5		BIT(5)
+#define TCU_TFR_FFLAG4		BIT(4)
+#define TCU_TFR_FFLAG3		BIT(3)
+#define TCU_TFR_FFLAG2		BIT(2)
+#define TCU_TFR_FFLAG1		BIT(1)
+#define TCU_TFR_FFLAG0		BIT(0)
+
+#define TCU_TFSR_HFLAG5		BIT(21)
+#define TCU_TFSR_HFLAG4		BIT(20)
+#define TCU_TFSR_HFLAG3		BIT(19)
+#define TCU_TFSR_HFLAG2		BIT(18)
+#define TCU_TFSR_HFLAG1		BIT(17)
+#define TCU_TFSR_HFLAG0		BIT(16)
+#define TCU_TFSR_FFLAG5		BIT(5)
+#define TCU_TFSR_FFLAG4		BIT(4)
+#define TCU_TFSR_FFLAG3		BIT(3)
+#define TCU_TFSR_FFLAG2		BIT(2)
+#define TCU_TFSR_FFLAG1		BIT(1)
+#define TCU_TFSR_FFLAG0		BIT(0)
+
+#define TCU_TFCR_HFLAG5		BIT(21)
+#define TCU_TFCR_HFLAG4		BIT(20)
+#define TCU_TFCR_HFLAG3		BIT(19)
+#define TCU_TFCR_HFLAG2		BIT(18)
+#define TCU_TFCR_HFLAG1		BIT(17)
+#define TCU_TFCR_HFLAG0		BIT(16)
+#define TCU_TFCR_FFLAG5		BIT(5)
+#define TCU_TFCR_FFLAG4		BIT(4)
+#define TCU_TFCR_FFLAG3		BIT(3)
+#define TCU_TFCR_FFLAG2		BIT(2)
+#define TCU_TFCR_FFLAG1		BIT(1)
+#define TCU_TFCR_FFLAG0		BIT(0)
+
+#define TCU_TMR_HMASK5		BIT(21)
+#define TCU_TMR_HMASK4		BIT(20)
+#define TCU_TMR_HMASK3		BIT(19)
+#define TCU_TMR_HMASK2		BIT(18)
+#define TCU_TMR_HMASK1		BIT(17)
+#define TCU_TMR_HMASK0		BIT(16)
+#define TCU_TMR_FMASK5		BIT(5)
+#define TCU_TMR_FMASK4		BIT(4)
+#define TCU_TMR_FMASK3		BIT(3)
+#define TCU_TMR_FMASK2		BIT(2)
+#define TCU_TMR_FMASK1		BIT(1)
+#define TCU_TMR_FMASK0		BIT(0)
+
+#define TCU_TMSR_HMST5		BIT(21)
+#define TCU_TMSR_HMST4		BIT(20)
+#define TCU_TMSR_HMST3		BIT(19)
+#define TCU_TMSR_HMST2		BIT(18)
+#define TCU_TMSR_HMST1		BIT(17)
+#define TCU_TMSR_HMST0		BIT(16)
+#define TCU_TMSR_FMST5		BIT(5)
+#define TCU_TMSR_FMST4		BIT(4)
+#define TCU_TMSR_FMST3		BIT(3)
+#define TCU_TMSR_FMST2		BIT(2)
+#define TCU_TMSR_FMST1		BIT(1)
+#define TCU_TMSR_FMST0		BIT(0)
+
+#define TCU_TMCR_HMCL5		BIT(21)
+#define TCU_TMCR_HMCL4		BIT(20)
+#define TCU_TMCR_HMCL3		BIT(19)
+#define TCU_TMCR_HMCL2		BIT(18)
+#define TCU_TMCR_HMCL1		BIT(17)
+#define TCU_TMCR_HMCL0		BIT(16)
+#define TCU_TMCR_FMCL5		BIT(5)
+#define TCU_TMCR_FMCL4		BIT(4)
+#define TCU_TMCR_FMCL3		BIT(3)
+#define TCU_TMCR_FMCL2		BIT(2)
+#define TCU_TMCR_FMCL1		BIT(1)
+#define TCU_TMCR_FMCL0		BIT(0)
+
+#define TCU_TSR_WDTS		BIT(16)
+#define TCU_TSR_STOP5		BIT(5)
+#define TCU_TSR_STOP4		BIT(4)
+#define TCU_TSR_STOP3		BIT(3)
+#define TCU_TSR_STOP2		BIT(2)
+#define TCU_TSR_STOP1		BIT(1)
+#define TCU_TSR_STOP0		BIT(0)
+
+#define TCU_TSSR_WDTSS		BIT(16)
+#define TCU_TSSR_STPS5		BIT(5)
+#define TCU_TSSR_STPS4		BIT(4)
+#define TCU_TSSR_STPS3		BIT(3)
+#define TCU_TSSR_STPS2		BIT(2)
+#define TCU_TSSR_STPS1		BIT(1)
+#define TCU_TSSR_STPS0		BIT(0)
+
+#define TCU_TSSR_WDTSC		BIT(16)
+#define TCU_TSSR_STPC5		BIT(5)
+#define TCU_TSSR_STPC4		BIT(4)
+#define TCU_TSSR_STPC3		BIT(3)
+#define TCU_TSSR_STPC2		BIT(2)
+#define TCU_TSSR_STPC1		BIT(1)
+#define TCU_TSSR_STPC0		BIT(0)
+
+#define TER_OSTEN		BIT(15)
+
+#define OSTCSR_CNT_MD		BIT(15)
+#define OSTCSR_SD		BIT(9)
+#define OSTCSR_PRESCALE_16	(0x2 << 3)
+#define OSTCSR_EXT_EN		BIT(2)
+
+int timer_init(void)
+{
+	void __iomem *regs = (void __iomem *)TCU_BASE;
+
+	writel(OSTCSR_SD, regs + TCU_OSTCSR);
+	reset_timer();
+	writel(OSTCSR_CNT_MD | OSTCSR_EXT_EN | OSTCSR_PRESCALE_16,
+	       regs + TCU_OSTCSR);
+	writew(TER_OSTEN, regs + TCU_TESR);
+	return 0;
+}
+
+void reset_timer(void)
+{
+	void __iomem *regs = (void __iomem *)TCU_BASE;
+
+	writel(0, regs + TCU_OSTCNTH);
+	writel(0, regs + TCU_OSTCNTL);
+}
+
+static u64 get_timer64(void)
+{
+	void __iomem *regs = (void __iomem *)TCU_BASE;
+	u32 low = readl(regs + TCU_OSTCNTL);
+	u32 high = readl(regs + TCU_OSTCNTHBUF);
+
+	return ((u64)high << 32) | low;
+}
+
+ulong get_timer(ulong base)
+{
+	return lldiv(get_timer64(), 3000) - base;
+}
+
+void __udelay(unsigned long usec)
+{
+	/* OST count increments at 3MHz */
+	u64 end = get_timer64() + ((u64)usec * 3);
+
+	while (get_timer64() < end)
+		;
+}
+
+unsigned long long get_ticks(void)
+{
+	return get_timer64();
+}
+
+void jz4780_tcu_wdt_start(void)
+{
+	void __iomem *tcu_regs = (void __iomem *)TCU_BASE;
+
+	/* Enable WDT clock */
+	writel(TCU_TSSR_WDTSC, tcu_regs + TCU_TSCR);
+}

+ 50 - 0
arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds

@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\
+		LENGTH = CONFIG_SPL_MAX_SIZE }
+MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \
+		LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
+
+OUTPUT_ARCH(mips)
+ENTRY(_start)
+SECTIONS
+{
+	.text :
+	{
+		__image_copy_start = .;
+		arch/mips/mach-jz47xx/start.o	(.text*)
+		*(.text*)
+	} >.sram
+
+	. = ALIGN(4);
+	.rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram
+
+	. = ALIGN(4);
+	.data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram
+
+	. = ALIGN(4);
+	__image_copy_end = .;
+
+	.bss : {
+		. = ALIGN(4);
+		__bss_start = .;
+		*(.sbss.*)
+		*(.bss.*)
+		*(COMMON)
+		. = ALIGN(4);
+		__bss_end = .;
+	} >.sdram
+
+	/DISCARD/ : {
+		*(.dynbss)
+		*(.dynstr)
+		*(.dynamic)
+		*(.interp)
+		*(.hash)
+		*(.gnu.*)
+		*(.plt)
+		*(.got.plt)
+		*(.rel.plt)
+		*(.rel.dyn)
+	}
+}

+ 98 - 0
arch/mips/mach-jz47xx/start.S

@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *  Startup Code for MIPS32 XBURST CPU-core
+ *
+ *  Copyright (c) 2010 Xiangfu Liu <xiangfu@sharism.cc>
+ */
+
+#include <config.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/cacheops.h>
+#include <asm/cache.h>
+#include <mach/jz4780.h>
+
+	.set noreorder
+
+	.globl _start
+	.text
+_start:
+#ifdef CONFIG_SPL_BUILD
+
+	/* magic value ("MSPL") */
+	.word 0x4d53504c
+
+	/* Invalidate BTB */
+	mfc0	t0, CP0_CONFIG, 7
+	nop
+	ori	t0, 2
+	mtc0	t0, CP0_CONFIG, 7
+	nop
+
+	/*
+	 * CU0=UM=EXL=IE=0, BEV=ERL=1, IP2~7=1
+	 */
+	li	t0, 0x0040FC04
+	mtc0	t0, CP0_STATUS
+
+	/* CAUSE register */
+	/* IV=1, use the specical interrupt vector (0x200) */
+	li	t1, 0x00800000
+	mtc0	t1, CP0_CAUSE
+
+#ifdef CONFIG_SOC_JZ4780
+	/* enable bridge radical mode */
+	la	t0, CPM_BASE
+	lw	t1, 0x24(t0)
+	ori	t1, t1, 0x22
+	sw	t1, 0x24(t0)
+#endif
+
+	/* Set up stack */
+	li	sp, CONFIG_SPL_STACK
+
+	b		board_init_f
+	 nop
+
+#ifdef CONFIG_SOC_JZ4780
+
+	.globl enable_caches
+	.ent enable_caches
+enable_caches:
+	mtc0	zero, CP0_TAGLO
+	mtc0	zero, CP0_TAGHI
+
+	li	t0, KSEG0
+	addu	t1, t0, CONFIG_SYS_DCACHE_SIZE
+1:
+	cache	INDEX_STORE_TAG_D, 0(t0)
+	bne	t0, t1, 1b
+	addiu	t0, t0, CONFIG_SYS_CACHELINE_SIZE
+
+	li	t0, KSEG0
+	addu	t1, t0, CONFIG_SYS_ICACHE_SIZE
+2:
+	cache	INDEX_STORE_TAG_I, 0(t0)
+	bne	t0, t1, 2b
+	addiu	t0, t0, CONFIG_SYS_CACHELINE_SIZE
+
+	/* Invalidate BTB */
+	mfc0	t0, CP0_CONFIG, 7
+	nop
+	ori	t0, 2
+	mtc0	t0, CP0_CONFIG, 7
+	nop
+
+	/* Enable caches */
+	li	t0, CONF_CM_CACHABLE_NONCOHERENT
+	mtc0	t0, CP0_CONFIG
+	nop
+
+	jr	ra
+	 nop
+
+	.end enable_caches
+
+#endif /* CONFIG_SOC_JZ4780 */
+#endif /* !CONFIG_SPL_BUILD */

+ 86 - 0
arch/mips/mach-mscc/Kconfig

@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+menu "MSCC VCore-III platforms"
+	depends on ARCH_MSCC
+
+config SOC_VCOREIII
+	select MIPS_TUNE_24KC
+	select ROM_EXCEPTION_VECTORS
+	select SUPPORTS_BIG_ENDIAN
+	select SUPPORTS_CPU_MIPS32_R1
+	select SUPPORTS_CPU_MIPS32_R2
+	select SUPPORTS_LITTLE_ENDIAN
+	bool
+
+config SYS_SOC
+	default "mscc"
+
+config SOC_OCELOT
+	bool
+	select SOC_VCOREIII
+	help
+	  This supports MSCC Ocelot family of SOCs.
+
+config SOC_LUTON
+	bool
+	select SOC_VCOREIII
+	help
+	  This supports MSCC Luton family of SOCs.
+
+config SYS_CONFIG_NAME
+	default "vcoreiii"
+
+choice
+	prompt "Board select"
+
+config TARGET_OCELOT_PCB120
+	bool "MSCC PCB120 Reference Board (aka VSC5635EV)"
+	select SOC_OCELOT
+	help
+	  When selected, CONFIG_DEFAULT_DEVICE_TREE should be set to
+	  ocelot_pcb120
+
+config TARGET_OCELOT_PCB123
+	bool "MSCC PCB123 Reference Board (aka VSC7514EV))"
+	select SOC_OCELOT
+	help
+	  When selected, CONFIG_DEFAULT_DEVICE_TREE should be set to
+	  ocelot_pcb123
+
+config TARGET_LUTON_PCB091
+	bool "MSCC PCB091 Reference Board"
+	select SOC_LUTON
+	select MSCC_BITBANG_SPI_GPIO
+	help
+	  When selected, CONFIG_DEFAULT_DEVICE_TREE should be set to
+	  luton_pcb091
+endchoice
+
+choice
+	prompt "DDR type"
+
+config DDRTYPE_H5TQ4G63MFR
+	bool "Hynix H5TQ4G63MFR-PBC (4Gbit, DDR3-800, 256Mbitx16)"
+
+config DDRTYPE_MT41K256M16
+	bool "Micron MT41K256M16 (4Gbit, DDR3L-800, 256Mbitx16)"
+
+config DDRTYPE_H5TQ1G63BFA
+	bool "Hynix H5TQ1G63BFA (1Gbit DDR3, x16)"
+
+config DDRTYPE_MT41J128M16HA
+	bool "Micron MT41J128M16HA-15E:D (2Gbit DDR3, x16)"
+
+config DDRTYPE_MT41K128M16JT
+	bool "Micron MT41K128M16JT-125 (2Gbit DDR3L, 128Mbitx16)"
+
+config DDRTYPE_MT47H128M8HQ
+	bool "Micron MT47H128M8-3 (1Gbit, DDR-533@CL4 @ 4.80ns 16Mbisx8x8)"
+
+endchoice
+
+source "board/mscc/ocelot/Kconfig"
+
+source "board/mscc/luton/Kconfig"
+
+endmenu

+ 6 - 0
arch/mips/mach-mscc/Makefile

@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+CFLAGS_cpu.o += -finline-limit=64000
+
+obj-y += cpu.o dram.o reset.o lowlevel_init.o
+obj-$(CONFIG_SOC_LUTON) += lowlevel_init_luton.o

+ 102 - 0
arch/mips/mach-mscc/cpu.c

@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#include <common.h>
+
+#include <asm/io.h>
+#include <asm/types.h>
+
+#include <mach/tlb.h>
+#include <mach/ddr.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if CONFIG_SYS_SDRAM_SIZE <= SZ_64M
+#define MSCC_RAM_TLB_SIZE   SZ_64M
+#define MSCC_ATTRIB2   MMU_REGIO_INVAL
+#elif CONFIG_SYS_SDRAM_SIZE <= SZ_128M
+#define MSCC_RAM_TLB_SIZE   SZ_64M
+#define MSCC_ATTRIB2   MMU_REGIO_RW
+#elif CONFIG_SYS_SDRAM_SIZE <= SZ_256M
+#define MSCC_RAM_TLB_SIZE   SZ_256M
+#define MSCC_ATTRIB2   MMU_REGIO_INVAL
+#elif CONFIG_SYS_SDRAM_SIZE <= SZ_512M
+#define MSCC_RAM_TLB_SIZE   SZ_256M
+#define MSCC_ATTRIB2   MMU_REGIO_RW
+#else
+#define MSCC_RAM_TLB_SIZE   SZ_512M
+#define MSCC_ATTRIB2   MMU_REGIO_RW
+#endif
+
+/* NOTE: lowlevel_init() function does not have access to the
+ * stack. Thus, all called functions must be inlined, and (any) local
+ * variables must be kept in registers.
+ */
+void vcoreiii_tlb_init(void)
+{
+	register int tlbix = 0;
+
+	/*
+	 * Unlike most of the MIPS based SoCs, the IO register address
+	 * are not in KSEG0. The mainline linux kernel built in legacy
+	 * mode needs to access some of the registers very early in
+	 * the boot and make the assumption that the bootloader has
+	 * already configured them, so we have to match this
+	 * expectation.
+	 */
+	create_tlb(tlbix++, MSCC_IO_ORIGIN1_OFFSET, SZ_16M, MMU_REGIO_RW,
+		   MMU_REGIO_RW);
+#ifdef CONFIG_SOC_LUTON
+	create_tlb(tlbix++, MSCC_IO_ORIGIN2_OFFSET, SZ_16M, MMU_REGIO_RW,
+		   MMU_REGIO_RW);
+#endif
+
+#if  CONFIG_SYS_TEXT_BASE == MSCC_FLASH_TO
+	/*
+	 * If U-Boot is located in NOR then we want to be able to use
+	 * the data cache in order to boot in a decent duration
+	 */
+	create_tlb(tlbix++, MSCC_FLASH_TO, SZ_16M, MMU_REGIO_RO_C,
+		   MMU_REGIO_RO_C);
+	create_tlb(tlbix++, MSCC_FLASH_TO + SZ_32M, SZ_16M, MMU_REGIO_RO_C,
+		   MMU_REGIO_RO_C);
+
+	/*
+	 * Using cache for RAM also helps to improve boot time. Thanks
+	 * to this the time to relocate U-Boot in RAM went from 2.092
+	 * secs to 0.104 secs.
+	 */
+	create_tlb(tlbix++, MSCC_DDR_TO, MSCC_RAM_TLB_SIZE, MMU_REGIO_RW,
+		   MSCC_ATTRIB2);
+
+	/* Enable caches by clearing the bit ERL, which is set on reset */
+	write_c0_status(read_c0_status() & ~BIT(2));
+#endif /* CONFIG_SYS_TEXT_BASE */
+}
+
+int mach_cpu_init(void)
+{
+	/* Speed up NOR flash access */
+#ifdef CONFIG_SOC_LUTON
+	writel(ICPU_PI_MST_CFG_TRISTATE_CTRL +
+	       ICPU_PI_MST_CFG_CLK_DIV(4), BASE_CFG + ICPU_PI_MST_CFG);
+
+	writel(ICPU_SPI_MST_CFG_FAST_READ_ENA +
+	       ICPU_SPI_MST_CFG_CS_DESELECT_TIME(0x19) +
+	       ICPU_SPI_MST_CFG_CLK_DIV(9), BASE_CFG + ICPU_SPI_MST_CFG);
+#else
+	writel(ICPU_SPI_MST_CFG_CS_DESELECT_TIME(0x19) +
+	       ICPU_SPI_MST_CFG_CLK_DIV(9), BASE_CFG + ICPU_SPI_MST_CFG);
+	/*
+	 * Legacy and mainline linux kernel expect that the
+	 * interruption map was set as it was done by redboot.
+	 */
+	writel(~0, BASE_CFG + ICPU_DST_INTR_MAP(0));
+	writel(0, BASE_CFG + ICPU_DST_INTR_MAP(1));
+	writel(0, BASE_CFG + ICPU_DST_INTR_MAP(2));
+	writel(0, BASE_CFG + ICPU_DST_INTR_MAP(3));
+#endif
+	return 0;
+}

+ 73 - 0
arch/mips/mach-mscc/dram.c

@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#include <common.h>
+
+#include <asm/io.h>
+#include <asm/types.h>
+
+#include <mach/tlb.h>
+#include <mach/ddr.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static inline int vcoreiii_train_bytelane(void)
+{
+	int ret;
+
+	ret = hal_vcoreiii_train_bytelane(0);
+
+#ifdef CONFIG_SOC_OCELOT
+	if (ret)
+		return ret;
+	ret = hal_vcoreiii_train_bytelane(1);
+#endif
+
+	return ret;
+}
+
+int vcoreiii_ddr_init(void)
+{
+	int res;
+
+	if (!(readl(BASE_CFG + ICPU_MEMCTRL_STAT)
+	      & ICPU_MEMCTRL_STAT_INIT_DONE)) {
+		hal_vcoreiii_init_memctl();
+		hal_vcoreiii_wait_memctl();
+		if (hal_vcoreiii_init_dqs() || vcoreiii_train_bytelane())
+			hal_vcoreiii_ddr_failed();
+	}
+#if (CONFIG_SYS_TEXT_BASE != 0x20000000)
+	res = dram_check();
+	if (res == 0)
+		hal_vcoreiii_ddr_verified();
+	else
+		hal_vcoreiii_ddr_failed();
+
+	/* Clear boot-mode and read-back to activate/verify */
+	clrbits_le32(BASE_CFG + ICPU_GENERAL_CTRL,
+		     ICPU_GENERAL_CTRL_BOOT_MODE_ENA);
+	readl(BASE_CFG + ICPU_GENERAL_CTRL);
+#else
+	res = 0;
+#endif
+	return res;
+}
+
+int print_cpuinfo(void)
+{
+	printf("MSCC VCore-III MIPS 24Kec\n");
+
+	return 0;
+}
+
+int dram_init(void)
+{
+	while (vcoreiii_ddr_init())
+		;
+
+	gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
+	return 0;
+}

+ 49 - 0
arch/mips/mach-mscc/include/ioremap.h

@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef __ASM_MACH_MSCC_IOREMAP_H
+#define __ASM_MACH_MSCC_IOREMAP_H
+
+#include <linux/types.h>
+#include <mach/common.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_vcoreiii_internal_registers(phys_addr_t offset)
+{
+	if ((offset >= MSCC_IO_ORIGIN1_OFFSET &&
+	     offset < (MSCC_IO_ORIGIN1_OFFSET + MSCC_IO_ORIGIN1_SIZE)) ||
+	    (offset >= MSCC_IO_ORIGIN2_OFFSET &&
+	     offset < (MSCC_IO_ORIGIN2_OFFSET + MSCC_IO_ORIGIN2_SIZE)))
+		return 1;
+
+	return 0;
+}
+
+static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size,
+					 unsigned long flags)
+{
+	if (is_vcoreiii_internal_registers(offset))
+		return (void __iomem *)offset;
+
+	return NULL;
+}
+
+static inline int plat_iounmap(const volatile void __iomem *addr)
+{
+	return is_vcoreiii_internal_registers((unsigned long)addr);
+}
+
+#define _page_cachable_default	_CACHE_CACHABLE_NONCOHERENT
+
+#endif				/* __ASM_MACH_MSCC_IOREMAP_H */

+ 28 - 0
arch/mips/mach-mscc/include/mach/common.h

@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef __ASM_MACH_COMMON_H
+#define __ASM_MACH_COMMON_H
+
+#if defined(CONFIG_SOC_OCELOT)
+#include <mach/ocelot/ocelot.h>
+#include <mach/ocelot/ocelot_devcpu_gcb.h>
+#include <mach/ocelot/ocelot_icpu_cfg.h>
+#elif defined(CONFIG_SOC_LUTON)
+#include <mach/luton/luton.h>
+#include <mach/luton/luton_devcpu_gcb.h>
+#include <mach/luton/luton_icpu_cfg.h>
+#else
+#error Unsupported platform
+#endif
+
+#define MSCC_DDR_TO	0x20000000	/* DDR RAM base offset */
+#define MSCC_MEMCTL1_TO	0x40000000	/* SPI/PI base offset */
+#define MSCC_MEMCTL2_TO	0x50000000	/* SPI/PI base offset */
+#define MSCC_FLASH_TO	MSCC_MEMCTL1_TO	/* Flash base offset */
+
+#define VCOREIII_TIMER_DIVIDER 25	/* Clock tick ~ 0.1 us */
+
+#endif				/* __ASM_MACH_COMMON_H */

+ 814 - 0
arch/mips/mach-mscc/include/mach/ddr.h

@@ -0,0 +1,814 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef __ASM_MACH_DDR_H
+#define __ASM_MACH_DDR_H
+
+#include <asm/cacheops.h>
+#include <asm/io.h>
+#include <asm/reboot.h>
+#include <mach/common.h>
+
+#define MIPS_VCOREIII_MEMORY_DDR3
+#define MIPS_VCOREIII_DDR_SIZE CONFIG_SYS_SDRAM_SIZE
+
+#if defined(CONFIG_DDRTYPE_H5TQ1G63BFA)	/* Serval1 Refboard */
+
+/* Hynix H5TQ1G63BFA (1Gbit DDR3, x16) @ 3.20ns */
+#define VC3_MPAR_bank_addr_cnt    3
+#define VC3_MPAR_row_addr_cnt     13
+#define VC3_MPAR_col_addr_cnt     10
+#define VC3_MPAR_tREFI            2437
+#define VC3_MPAR_tRAS_min         12
+#define VC3_MPAR_CL               6
+#define VC3_MPAR_tWTR             4
+#define VC3_MPAR_tRC              16
+#define VC3_MPR_tFAW             16
+#define VC3_MPAR_tRP              5
+#define VC3_MPAR_tRRD             4
+#define VC3_MPAR_tRCD             5
+#define VC3_MPAR_tMRD             4
+#define VC3_MPAR_tRFC             35
+#define VC3_MPAR_CWL              5
+#define VC3_MPAR_tXPR             38
+#define VC3_MPAR_tMOD             12
+#define VC3_MPAR_tDLLK            512
+#define VC3_MPAR_tWR              5
+
+#elif defined(CONFIG_DDRTYPE_MT41J128M16HA)	/* Validation board */
+
+/* Micron MT41J128M16HA-15E:D (2Gbit DDR3, x16) @ 3.20ns */
+#define VC3_MPAR_bank_addr_cnt    3
+#define VC3_MPAR_row_addr_cnt     14
+#define VC3_MPAR_col_addr_cnt     10
+#define VC3_MPAR_tREFI            2437
+#define VC3_MPAR_tRAS_min         12
+#define VC3_MPAR_CL               5
+#define VC3_MPAR_tWTR             4
+#define VC3_MPAR_tRC              16
+#define VC3_MPAR_tFAW             16
+#define VC3_MPAR_tRP              5
+#define VC3_MPAR_tRRD             4
+#define VC3_MPAR_tRCD             5
+#define VC3_MPAR_tMRD             4
+#define VC3_MPAR_tRFC             50
+#define VC3_MPAR_CWL              5
+#define VC3_MPAR_tXPR             54
+#define VC3_MPAR_tMOD             12
+#define VC3_MPAR_tDLLK            512
+#define VC3_MPAR_tWR              5
+
+#elif defined(CONFIG_DDRTYPE_MT41K256M16)	/* JR2 Validation board */
+
+/* Micron MT41K256M16 (4Gbit, DDR3L-800, 256Mbitx16) @ 3.20ns */
+#define VC3_MPAR_bank_addr_cnt    3
+#define VC3_MPAR_row_addr_cnt     15
+#define VC3_MPAR_col_addr_cnt     10
+#define VC3_MPAR_tREFI            2437
+#define VC3_MPAR_tRAS_min         12
+#define VC3_MPAR_CL               5
+#define VC3_MPAR_tWTR             4
+#define VC3_MPAR_tRC              16
+#define VC3_MPAR_tFAW             16
+#define VC3_MPAR_tRP              5
+#define VC3_MPAR_tRRD             4
+#define VC3_MPAR_tRCD             5
+#define VC3_MPAR_tMRD             4
+#define VC3_MPAR_tRFC             82
+#define VC3_MPAR_CWL              5
+#define VC3_MPAR_tXPR             85
+#define VC3_MPAR_tMOD             12
+#define VC3_MPAR_tDLLK            512
+#define VC3_MPAR_tWR              5
+
+#elif defined(CONFIG_DDRTYPE_H5TQ4G63MFR)	/* JR2 Reference board */
+
+/* Hynix H5TQ4G63MFR-PBC (4Gbit, DDR3-800, 256Mbitx16) - 2kb pages @ 3.20ns */
+#define VC3_MPAR_bank_addr_cnt    3
+#define VC3_MPAR_row_addr_cnt     15
+#define VC3_MPAR_col_addr_cnt     10
+#define VC3_MPAR_tREFI            2437
+#define VC3_MPAR_tRAS_min         12
+#define VC3_MPAR_CL               6
+#define VC3_MPAR_tWTR             4
+#define VC3_MPAR_tRC              17
+#define VC3_MPAR_tFAW             16
+#define VC3_MPAR_tRP              5
+#define VC3_MPAR_tRRD             4
+#define VC3_MPAR_tRCD             5
+#define VC3_MPAR_tMRD             4
+#define VC3_MPAR_tRFC             82
+#define VC3_MPAR_CWL              5
+#define VC3_MPAR_tXPR             85
+#define VC3_MPAR_tMOD             12
+#define VC3_MPAR_tDLLK            512
+#define VC3_MPAR_tWR              5
+
+#elif defined(CONFIG_DDRTYPE_MT41K128M16JT)
+
+/* Micron Micron MT41K128M16JT-125 (2Gbit DDR3L, 128Mbitx16) @ 3.20ns */
+#define VC3_MPAR_bank_addr_cnt    3
+#define VC3_MPAR_row_addr_cnt     14
+#define VC3_MPAR_col_addr_cnt     10
+#define VC3_MPAR_tREFI            2437
+#define VC3_MPAR_tRAS_min         12
+#define VC3_MPAR_CL               6
+#define VC3_MPAR_tWTR             4
+#define VC3_MPAR_tRC              16
+#define VC3_MPAR_tFAW             16
+#define VC3_MPAR_tRP              5
+#define VC3_MPAR_tRRD             4
+#define VC3_MPAR_tRCD             5
+#define VC3_MPAR_tMRD             4
+#define VC3_MPAR_tRFC             82
+#define VC3_MPAR_CWL              5
+#define VC3_MPAR_tXPR             85
+#define VC3_MPAR_tMOD             12
+#define VC3_MPAR_tDLLK            512
+#define VC3_MPAR_tWR              5
+
+#elif defined(CONFIG_DDRTYPE_MT47H128M8HQ)	/* Luton10/26 Refboards */
+
+/* Micron 1Gb MT47H128M8-3 16Meg x 8 x 8 banks, DDR-533@CL4 @ 4.80ns */
+#define VC3_MPAR_bank_addr_cnt    3
+#define VC3_MPAR_row_addr_cnt     14
+#define VC3_MPAR_col_addr_cnt     10
+#define VC3_MPAR_tREFI            1625
+#define VC3_MPAR_tRAS_min         9
+#define VC3_MPAR_CL               4
+#define VC3_MPAR_tWTR             2
+#define VC3_MPAR_tRC              12
+#define VC3_MPAR_tFAW             8
+#define VC3_MPAR_tRP              4
+#define VC3_MPAR_tRRD             2
+#define VC3_MPAR_tRCD             4
+
+#define VC3_MPAR_tRPA             4
+#define VC3_MPAR_tRP              4
+
+#define VC3_MPAR_tMRD             2
+#define VC3_MPAR_tRFC             27
+
+#define VC3_MPAR__400_ns_dly      84
+
+#define VC3_MPAR_tWR              4
+#undef MIPS_VCOREIII_MEMORY_DDR3
+#else
+
+#error Unknown DDR system configuration - please add!
+
+#endif
+
+#ifdef CONFIG_SOC_OCELOT
+#define MIPS_VCOREIII_MEMORY_16BIT 1
+#endif
+
+#define MIPS_VCOREIII_MEMORY_SSTL_ODT 7
+#define MIPS_VCOREIII_MEMORY_SSTL_DRIVE 7
+#define VCOREIII_DDR_DQS_MODE_CALIBRATE
+
+#ifdef MIPS_VCOREIII_MEMORY_16BIT
+#define VC3_MPAR_16BIT       1
+#else
+#define VC3_MPAR_16BIT       0
+#endif
+
+#ifdef MIPS_VCOREIII_MEMORY_DDR3
+#define VC3_MPAR_DDR3_MODE    1	/* DDR3 */
+#define VC3_MPAR_BURST_LENGTH 8	/* Always 8 (1) for DDR3 */
+#ifdef MIPS_VCOREIII_MEMORY_16BIT
+#define VC3_MPAR_BURST_SIZE   1	/* Always 1 for DDR3/16bit */
+#else
+#define VC3_MPAR_BURST_SIZE   0
+#endif
+#else
+#define VC3_MPAR_DDR3_MODE    0	/* DDR2 */
+#ifdef MIPS_VCOREIII_MEMORY_16BIT
+#define VC3_MPAR_BURST_LENGTH 4	/* in DDR2 16-bit mode, use burstlen 4 */
+#else
+#define VC3_MPAR_BURST_LENGTH 8	/* For 8-bit IF we must run burst-8 */
+#endif
+#define VC3_MPAR_BURST_SIZE   0	/* Always 0 for DDR2 */
+#endif
+
+#define VC3_MPAR_RL VC3_MPAR_CL
+#if !defined(MIPS_VCOREIII_MEMORY_DDR3)
+#define VC3_MPAR_WL (VC3_MPAR_RL - 1)
+#define VC3_MPAR_MD VC3_MPAR_tMRD
+#define VC3_MPAR_ID VC3_MPAR__400_ns_dly
+#define VC3_MPAR_SD VC3_MPAR_tXSRD
+#define VC3_MPAR_OW (VC3_MPAR_WL - 2)
+#define VC3_MPAR_OR (VC3_MPAR_WL - 3)
+#define VC3_MPAR_RP (VC3_MPAR_bank_addr_cnt < 3 ? VC3_MPAR_tRP : VC3_MPAR_tRPA)
+#define VC3_MPAR_FAW (VC3_MPAR_bank_addr_cnt < 3 ? 1 : VC3_MPAR_tFAW)
+#define VC3_MPAR_BL (VC3_MPAR_BURST_LENGTH == 4 ? 2 : 4)
+#define MSCC_MEMPARM_MR0 \
+	(VC3_MPAR_BURST_LENGTH == 8 ? 3 : 2) | (VC3_MPAR_CL << 4) | \
+	((VC3_MPAR_tWR - 1) << 9)
+/* DLL-on, Full-OD, AL=0, RTT=off, nDQS-on, RDQS-off, out-en */
+#define MSCC_MEMPARM_MR1 0x382
+#define MSCC_MEMPARM_MR2 0
+#define MSCC_MEMPARM_MR3 0
+#else
+#define VC3_MPAR_WL VC3_MPAR_CWL
+#define VC3_MPAR_MD VC3_MPAR_tMOD
+#define VC3_MPAR_ID VC3_MPAR_tXPR
+#define VC3_MPAR_SD VC3_MPAR_tDLLK
+#define VC3_MPAR_OW 2
+#define VC3_MPAR_OR 2
+#define VC3_MPAR_RP VC3_MPAR_tRP
+#define VC3_MPAR_FAW VC3_MPAR_tFAW
+#define VC3_MPAR_BL 4
+#define MSCC_MEMPARM_MR0 ((VC3_MPAR_RL - 4) << 4) | ((VC3_MPAR_tWR - 4) << 9)
+/* ODT_RTT: “0x0040” for 120ohm, and “0x0004” for 60ohm. */
+#define MSCC_MEMPARM_MR1 0x0040
+#define MSCC_MEMPARM_MR2 ((VC3_MPAR_WL - 5) << 3)
+#define MSCC_MEMPARM_MR3 0
+#endif				/* MIPS_VCOREIII_MEMORY_DDR3 */
+
+#define MSCC_MEMPARM_MEMCFG                                             \
+	((MIPS_VCOREIII_DDR_SIZE > SZ_512M) ?				\
+	 ICPU_MEMCTRL_CFG_DDR_512MBYTE_PLUS : 0) |			\
+	(VC3_MPAR_16BIT ? ICPU_MEMCTRL_CFG_DDR_WIDTH : 0) |		\
+	(VC3_MPAR_DDR3_MODE ? ICPU_MEMCTRL_CFG_DDR_MODE : 0) |		\
+	(VC3_MPAR_BURST_SIZE ? ICPU_MEMCTRL_CFG_BURST_SIZE : 0) |	\
+	(VC3_MPAR_BURST_LENGTH == 8 ? ICPU_MEMCTRL_CFG_BURST_LEN : 0) | \
+	(VC3_MPAR_bank_addr_cnt == 3 ? ICPU_MEMCTRL_CFG_BANK_CNT : 0) | \
+	ICPU_MEMCTRL_CFG_MSB_ROW_ADDR(VC3_MPAR_row_addr_cnt - 1) |	\
+	ICPU_MEMCTRL_CFG_MSB_COL_ADDR(VC3_MPAR_col_addr_cnt - 1)
+
+#ifdef CONFIG_SOC_OCELOT
+#define MSCC_MEMPARM_PERIOD					\
+	ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF(8) |		\
+	ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD(VC3_MPAR_tREFI)
+
+#define MSCC_MEMPARM_TIMING0                                            \
+	ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY(VC3_MPAR_RL + VC3_MPAR_BL + 1 - \
+					  VC3_MPAR_WL) |		\
+	ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY(VC3_MPAR_BL - 1) |	\
+	ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY(VC3_MPAR_BL) |		\
+	ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY(VC3_MPAR_tRAS_min - 1) |	\
+	ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY(VC3_MPAR_WL +		\
+					     VC3_MPAR_BL +		\
+					     VC3_MPAR_tWR - 1) |	\
+	ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY(VC3_MPAR_BL - 1) |		\
+		ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY(VC3_MPAR_WL - 1) |	\
+	ICPU_MEMCTRL_TIMING0_RD_DATA_XFR_DLY(VC3_MPAR_RL - 3)
+
+#define MSCC_MEMPARM_TIMING1                                            \
+	ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY(VC3_MPAR_tRC - 1) | \
+	ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY(VC3_MPAR_FAW - 1) |		\
+	ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY(VC3_MPAR_RP - 1) |	\
+	ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY(VC3_MPAR_tRRD - 1) |	\
+	ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY(VC3_MPAR_tRCD - 1) |	\
+	ICPU_MEMCTRL_TIMING1_WR_TO_RD_DLY(VC3_MPAR_WL +			\
+					  VC3_MPAR_BL +			\
+					  VC3_MPAR_tWTR - 1)
+
+#define MSCC_MEMPARM_TIMING2					\
+	ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY(VC3_MPAR_RP - 1) |	\
+	ICPU_MEMCTRL_TIMING2_MDSET_DLY(VC3_MPAR_MD - 1) |		\
+	ICPU_MEMCTRL_TIMING2_REF_DLY(VC3_MPAR_tRFC - 1) |		\
+	ICPU_MEMCTRL_TIMING2_INIT_DLY(VC3_MPAR_ID - 1)
+
+#define MSCC_MEMPARM_TIMING3						\
+	ICPU_MEMCTRL_TIMING3_WR_TO_RD_CS_CHANGE_DLY(VC3_MPAR_WL +	\
+						    VC3_MPAR_tWTR - 1) |\
+	ICPU_MEMCTRL_TIMING3_ODT_RD_DLY(VC3_MPAR_OR - 1) |		\
+	ICPU_MEMCTRL_TIMING3_ODT_WR_DLY(VC3_MPAR_OW - 1) |		\
+	ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY(VC3_MPAR_RL - 3)
+
+#else
+#define MSCC_MEMPARM_PERIOD					\
+	ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF(1) |		\
+	ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD(VC3_MPAR_tREFI)
+
+#define MSCC_MEMPARM_TIMING0                                            \
+	ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY(VC3_MPAR_tRAS_min - 1) |	\
+	ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY(VC3_MPAR_CL +		\
+					     (VC3_MPAR_BURST_LENGTH == 8 ? 2 : 0) + \
+					     VC3_MPAR_tWR) |		\
+	ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY(VC3_MPAR_BURST_LENGTH == 8 ? 3 : 1) | \
+	ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY(VC3_MPAR_CL - 3) |		\
+	ICPU_MEMCTRL_TIMING0_RD_DATA_XFR_DLY(VC3_MPAR_CL - 3)
+
+#define MSCC_MEMPARM_TIMING1                                            \
+	ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY(VC3_MPAR_tRC - 1) | \
+	ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY(VC3_MPAR_tFAW - 1) |		\
+	ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY(VC3_MPAR_tRP - 1) |	\
+	ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY(VC3_MPAR_tRRD - 1) |	\
+	ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY(VC3_MPAR_tRCD - 1) |	\
+	ICPU_MEMCTRL_TIMING1_WR_TO_RD_DLY(VC3_MPAR_CL +			\
+					  (VC3_MPAR_BURST_LENGTH == 8 ? 2 : 0) + \
+					  VC3_MPAR_tWTR)
+#define MSCC_MEMPARM_TIMING2                                            \
+	ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY(VC3_MPAR_tRPA - 1) |		\
+	ICPU_MEMCTRL_TIMING2_MDSET_DLY(VC3_MPAR_tMRD - 1) |		\
+	ICPU_MEMCTRL_TIMING2_REF_DLY(VC3_MPAR_tRFC - 1) |		\
+	ICPU_MEMCTRL_TIMING2_FOUR_HUNDRED_NS_DLY(VC3_MPAR__400_ns_dly)
+
+#define MSCC_MEMPARM_TIMING3						\
+	ICPU_MEMCTRL_TIMING3_WR_TO_RD_CS_CHANGE_DLY(VC3_MPAR_CL - 1) |	\
+	ICPU_MEMCTRL_TIMING3_ODT_WR_DLY(VC3_MPAR_CL - 1) |		\
+	ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY(VC3_MPAR_CL - 1)
+
+#endif
+
+enum {
+	DDR_TRAIN_OK,
+	DDR_TRAIN_CONTINUE,
+	DDR_TRAIN_ERROR,
+};
+
+/*
+ * We actually have very few 'pause' possibilities apart from
+ * these assembly nops (at this very early stage).
+ */
+#define PAUSE() asm volatile("nop; nop; nop; nop; nop; nop; nop; nop")
+
+/* NB: Assumes inlining as no stack is available! */
+static inline void set_dly(u32 bytelane, u32 dly)
+{
+	register u32 r = readl(BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane));
+
+	r &= ~ICPU_MEMCTRL_DQS_DLY_DQS_DLY_M;
+	r |= ICPU_MEMCTRL_DQS_DLY_DQS_DLY(dly);
+	writel(r, BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane));
+}
+
+static inline bool incr_dly(u32 bytelane)
+{
+	register u32 r = readl(BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane));
+
+	if (ICPU_MEMCTRL_DQS_DLY_DQS_DLY(r) < 31) {
+		writel(r + 1, BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane));
+		return true;
+	}
+
+	return false;
+}
+
+static inline bool adjust_dly(int adjust)
+{
+	register u32 r = readl(BASE_CFG + ICPU_MEMCTRL_DQS_DLY(0));
+
+	if (ICPU_MEMCTRL_DQS_DLY_DQS_DLY(r) < 31) {
+		writel(r + adjust, BASE_CFG + ICPU_MEMCTRL_DQS_DLY(0));
+		return true;
+	}
+
+	return false;
+}
+
+/* NB: Assumes inlining as no stack is available! */
+static inline void center_dly(u32 bytelane, u32 start)
+{
+	register u32 r = readl(BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane)) - start;
+
+	writel(start + (r >> 1), BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane));
+}
+
+static inline void memphy_soft_reset(void)
+{
+	setbits_le32(BASE_CFG + ICPU_MEMPHY_CFG, ICPU_MEMPHY_CFG_PHY_FIFO_RST);
+	PAUSE();
+	clrbits_le32(BASE_CFG + ICPU_MEMPHY_CFG, ICPU_MEMPHY_CFG_PHY_FIFO_RST);
+	PAUSE();
+}
+
+#ifdef CONFIG_SOC_OCELOT
+static u8 training_data[] = { 0xfe, 0x11, 0x33, 0x55, 0x77, 0x99, 0xbb, 0xdd };
+
+static inline void sleep_100ns(u32 val)
+{
+	/* Set the timer tick generator to 100 ns */
+	writel(VCOREIII_TIMER_DIVIDER - 1, BASE_CFG + ICPU_TIMER_TICK_DIV);
+
+	/* Set the timer value */
+	writel(val, BASE_CFG + ICPU_TIMER_VALUE(0));
+
+	/* Enable timer 0 for one-shot */
+	writel(ICPU_TIMER_CTRL_ONE_SHOT_ENA | ICPU_TIMER_CTRL_TIMER_ENA,
+	       BASE_CFG + ICPU_TIMER_CTRL(0));
+
+	/* Wait for timer 0 to reach 0 */
+	while (readl(BASE_CFG + ICPU_TIMER_VALUE(0)) != 0)
+		;
+}
+
+static inline void hal_vcoreiii_ddr_reset_assert(void)
+{
+	/* DDR has reset pin on GPIO 19 toggle Low-High to release */
+	setbits_le32(BASE_DEVCPU_GCB + PERF_GPIO_OE, BIT(19));
+	writel(BIT(19), BASE_DEVCPU_GCB + PERF_GPIO_OUT_CLR);
+	sleep_100ns(10000);
+}
+
+static inline void hal_vcoreiii_ddr_reset_release(void)
+{
+	/* DDR has reset pin on GPIO 19 toggle Low-High to release */
+	setbits_le32(BASE_DEVCPU_GCB + PERF_GPIO_OE, BIT(19));
+	writel(BIT(19), BASE_DEVCPU_GCB + PERF_GPIO_OUT_SET);
+	sleep_100ns(10000);
+}
+
+/*
+ * DDR memory sanity checking failed, tally and do hard reset
+ *
+ * NB: Assumes inlining as no stack is available!
+ */
+static inline void hal_vcoreiii_ddr_failed(void)
+{
+	register u32 reset;
+
+	writel(readl(BASE_CFG + ICPU_GPR(6)) + 1, BASE_CFG + ICPU_GPR(6));
+
+	clrbits_le32(BASE_DEVCPU_GCB + PERF_GPIO_OE, BIT(19));
+
+	/* We have to execute the reset function from cache. Indeed,
+	 * the reboot workaround in _machine_restart() will change the
+	 * SPI NOR into SW bitbang.
+	 *
+	 * This will render the CPU unable to execute directly from
+	 * the NOR, which is why the reset instructions are prefetched
+	 * into the I-cache.
+	 *
+	 * When failing the DDR initialization we are executing from
+	 * NOR.
+	 *
+	 * The last instruction in _machine_restart() will reset the
+	 * MIPS CPU (and the cache), and the CPU will start executing
+	 * from the reset vector.
+	 */
+	reset = KSEG0ADDR(_machine_restart);
+	icache_lock((void *)reset, 128);
+	asm volatile ("jr %0"::"r" (reset));
+
+	panic("DDR init failed\n");
+}
+
+/*
+ * DDR memory sanity checking done, possibly enable ECC.
+ *
+ * NB: Assumes inlining as no stack is available!
+ */
+static inline void hal_vcoreiii_ddr_verified(void)
+{
+#ifdef MIPS_VCOREIII_MEMORY_ECC
+	/* Finally, enable ECC */
+	register u32 val = readl(BASE_CFG + ICPU_MEMCTRL_CFG);
+
+	val |= ICPU_MEMCTRL_CFG_DDR_ECC_ERR_ENA;
+	val &= ~ICPU_MEMCTRL_CFG_BURST_SIZE;
+
+	writel(val, BASE_CFG + ICPU_MEMCTRL_CFG);
+#endif
+
+	/* Reset Status register - sticky bits */
+	writel(readl(BASE_CFG + ICPU_MEMCTRL_STAT), BASE_CFG + ICPU_MEMCTRL_STAT);
+}
+
+/* NB: Assumes inlining as no stack is available! */
+static inline int look_for(u32 bytelane)
+{
+	register u32 i;
+
+	/* Reset FIFO in case any previous access failed */
+	for (i = 0; i < sizeof(training_data); i++) {
+		register u32 byte;
+
+		memphy_soft_reset();
+		/* Reset sticky bits */
+		writel(readl(BASE_CFG + ICPU_MEMCTRL_STAT),
+		       BASE_CFG + ICPU_MEMCTRL_STAT);
+		/* Read data */
+		byte = __raw_readb((void __iomem *)MSCC_DDR_TO + bytelane +
+				   (i * 4));
+
+		/*
+		 * Prevent the compiler reordering the instruction so
+		 * the read of RAM happens after the check of the
+		 * errors.
+		 */
+		rmb();
+		if (readl(BASE_CFG + ICPU_MEMCTRL_STAT) &
+		    (ICPU_MEMCTRL_STAT_RDATA_MASKED |
+		     ICPU_MEMCTRL_STAT_RDATA_DUMMY)) {
+			/* Noise on the line */
+			goto read_error;
+		}
+		/* If mismatch, increment DQS - if possible */
+		if (byte != training_data[i]) {
+ read_error:
+			if (!incr_dly(bytelane))
+				return DDR_TRAIN_ERROR;
+			return DDR_TRAIN_CONTINUE;
+		}
+	}
+	return DDR_TRAIN_OK;
+}
+
+/* NB: Assumes inlining as no stack is available! */
+static inline int look_past(u32 bytelane)
+{
+	register u32 i;
+
+	/* Reset FIFO in case any previous access failed */
+	for (i = 0; i < sizeof(training_data); i++) {
+		register u32 byte;
+
+		memphy_soft_reset();
+		/* Ack sticky bits */
+		writel(readl(BASE_CFG + ICPU_MEMCTRL_STAT),
+		       BASE_CFG + ICPU_MEMCTRL_STAT);
+		byte = __raw_readb((void __iomem *)MSCC_DDR_TO + bytelane +
+				   (i * 4));
+		/*
+		 * Prevent the compiler reordering the instruction so
+		 * the read of RAM happens after the check of the
+		 * errors.
+		 */
+		rmb();
+		if (readl(BASE_CFG + ICPU_MEMCTRL_STAT) &
+		    (ICPU_MEMCTRL_STAT_RDATA_MASKED |
+		     ICPU_MEMCTRL_STAT_RDATA_DUMMY)) {
+			/* Noise on the line */
+			goto read_error;
+		}
+		/* Bail out when we see first mismatch */
+		if (byte != training_data[i]) {
+ read_error:
+			return DDR_TRAIN_OK;
+		}
+	}
+	/* All data compares OK, increase DQS and retry */
+	if (!incr_dly(bytelane))
+		return DDR_TRAIN_ERROR;
+
+	return DDR_TRAIN_CONTINUE;
+}
+
+static inline int hal_vcoreiii_train_bytelane(u32 bytelane)
+{
+	register int res;
+	register u32 dqs_s;
+
+	set_dly(bytelane, 0);	/* Start training at DQS=0 */
+	while ((res = look_for(bytelane)) == DDR_TRAIN_CONTINUE)
+		;
+	if (res != DDR_TRAIN_OK)
+		return res;
+
+	dqs_s = readl(BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane));
+	while ((res = look_past(bytelane)) == DDR_TRAIN_CONTINUE)
+		;
+	if (res != DDR_TRAIN_OK)
+		return res;
+	/* Reset FIFO - for good measure */
+	memphy_soft_reset();
+	/* Adjust to center [dqs_s;cur] */
+	center_dly(bytelane, dqs_s);
+	return DDR_TRAIN_OK;
+}
+
+/* This algorithm is converted from the TCL training algorithm used
+ * during silicon simulation.
+ * NB: Assumes inlining as no stack is available!
+ */
+static inline int hal_vcoreiii_init_dqs(void)
+{
+#define MAX_DQS 32
+	register u32 i, j;
+
+	for (i = 0; i < MAX_DQS; i++) {
+		set_dly(0, i);	/* Byte-lane 0 */
+		for (j = 0; j < MAX_DQS; j++) {
+			__maybe_unused register u32  byte;
+
+			set_dly(1, j);	/* Byte-lane 1 */
+			/* Reset FIFO in case any previous access failed */
+			memphy_soft_reset();
+			writel(readl(BASE_CFG + ICPU_MEMCTRL_STAT),
+			       BASE_CFG + ICPU_MEMCTRL_STAT);
+			byte = __raw_readb((void __iomem *)MSCC_DDR_TO);
+			byte = __raw_readb((void __iomem *)(MSCC_DDR_TO + 1));
+			if (!(readl(BASE_CFG + ICPU_MEMCTRL_STAT) &
+			    (ICPU_MEMCTRL_STAT_RDATA_MASKED |
+			     ICPU_MEMCTRL_STAT_RDATA_DUMMY)))
+				return 0;
+		}
+	}
+	return -1;
+}
+
+static inline int dram_check(void)
+{
+	register u32 i;
+
+	for (i = 0; i < 8; i++) {
+		__raw_writel(~i, (void __iomem *)(MSCC_DDR_TO + (i * 4)));
+		if (__raw_readl((void __iomem *)(MSCC_DDR_TO + (i * 4))) != ~i)
+			return 1;
+	}
+	return 0;
+}
+#else				/* Luton */
+
+static inline void sleep_100ns(u32 val)
+{
+}
+
+static inline void hal_vcoreiii_ddr_reset_assert(void)
+{
+	setbits_le32(BASE_CFG + ICPU_MEMPHY_CFG, ICPU_MEMPHY_CFG_PHY_RST);
+	setbits_le32(BASE_CFG + ICPU_RESET, ICPU_RESET_MEM_RST_FORCE);
+}
+
+static inline void hal_vcoreiii_ddr_reset_release(void)
+{
+}
+
+static inline void hal_vcoreiii_ddr_failed(void)
+{
+	register u32 memphy_cfg = readl(BASE_CFG + ICPU_MEMPHY_CFG);
+
+	/* Do a fifo reset and start over */
+	writel(memphy_cfg | ICPU_MEMPHY_CFG_PHY_FIFO_RST,
+	       BASE_CFG + ICPU_MEMPHY_CFG);
+	writel(memphy_cfg & ~ICPU_MEMPHY_CFG_PHY_FIFO_RST,
+	       BASE_CFG + ICPU_MEMPHY_CFG);
+	writel(memphy_cfg | ICPU_MEMPHY_CFG_PHY_FIFO_RST,
+	       BASE_CFG + ICPU_MEMPHY_CFG);
+}
+
+static inline void hal_vcoreiii_ddr_verified(void)
+{
+}
+
+static inline int look_for(u32 data)
+{
+	register u32 byte = __raw_readb((void __iomem *)MSCC_DDR_TO);
+
+	if (data != byte) {
+		if (!incr_dly(0))
+			return DDR_TRAIN_ERROR;
+		return DDR_TRAIN_CONTINUE;
+	}
+
+	return DDR_TRAIN_OK;
+}
+
+/* This algorithm is converted from the TCL training algorithm used
+ * during silicon simulation.
+ * NB: Assumes inlining as no stack is available!
+ */
+static inline int hal_vcoreiii_train_bytelane(u32 bytelane)
+{
+	register int res;
+
+	set_dly(bytelane, 0);	/* Start training at DQS=0 */
+	while ((res = look_for(0xff)) == DDR_TRAIN_CONTINUE)
+		;
+	if (res != DDR_TRAIN_OK)
+		return res;
+
+	set_dly(bytelane, 0);	/* Start training at DQS=0 */
+	while ((res = look_for(0x00)) == DDR_TRAIN_CONTINUE)
+
+		;
+
+	if (res != DDR_TRAIN_OK)
+		return res;
+
+	adjust_dly(-3);
+
+	return DDR_TRAIN_OK;
+}
+
+static inline int hal_vcoreiii_init_dqs(void)
+{
+	return 0;
+}
+
+static inline int dram_check(void)
+{
+	register u32 i;
+
+	for (i = 0; i < 8; i++) {
+		__raw_writel(~i, (void __iomem *)(MSCC_DDR_TO + (i * 4)));
+
+		if (__raw_readl((void __iomem *)(MSCC_DDR_TO + (i * 4))) != ~i)
+			return 1;
+	}
+
+	return 0;
+}
+#endif
+
+/*
+ * NB: Called *early* to init memory controller - assumes inlining as
+ * no stack is available!
+ */
+static inline void hal_vcoreiii_init_memctl(void)
+{
+	/* Ensure DDR is in reset */
+	hal_vcoreiii_ddr_reset_assert();
+
+	/* Wait maybe not needed, but ... */
+	PAUSE();
+
+	/* Drop sys ctl memory controller forced reset */
+	clrbits_le32(BASE_CFG + ICPU_RESET, ICPU_RESET_MEM_RST_FORCE);
+
+	PAUSE();
+
+	/* Drop Reset, enable SSTL */
+	writel(ICPU_MEMPHY_CFG_PHY_SSTL_ENA, BASE_CFG + ICPU_MEMPHY_CFG);
+	PAUSE();
+
+	/* Start the automatic SSTL output and ODT drive-strength calibration */
+	writel(ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT(MIPS_VCOREIII_MEMORY_SSTL_ODT) |
+	       /* drive strength */
+	       ICPU_MEMPHY_ZCAL_ZCAL_PROG(MIPS_VCOREIII_MEMORY_SSTL_DRIVE) |
+	       /* Start calibration process */
+	       ICPU_MEMPHY_ZCAL_ZCAL_ENA, BASE_CFG + ICPU_MEMPHY_ZCAL);
+
+	/* Wait for ZCAL to clear */
+	while (readl(BASE_CFG + ICPU_MEMPHY_ZCAL) & ICPU_MEMPHY_ZCAL_ZCAL_ENA)
+		;
+#ifdef CONFIG_SOC_OCELOT
+	/* Check no ZCAL_ERR */
+	if (readl(BASE_CFG + ICPU_MEMPHY_ZCAL_STAT)
+	    & ICPU_MEMPHY_ZCAL_STAT_ZCAL_ERR)
+		hal_vcoreiii_ddr_failed();
+#endif
+	/* Drive CL, CK, ODT */
+	setbits_le32(BASE_CFG + ICPU_MEMPHY_CFG, ICPU_MEMPHY_CFG_PHY_ODT_OE |
+		     ICPU_MEMPHY_CFG_PHY_CK_OE | ICPU_MEMPHY_CFG_PHY_CL_OE);
+
+	/* Initialize memory controller */
+	writel(MSCC_MEMPARM_MEMCFG, BASE_CFG + ICPU_MEMCTRL_CFG);
+	writel(MSCC_MEMPARM_PERIOD, BASE_CFG + ICPU_MEMCTRL_REF_PERIOD);
+
+#ifdef CONFIG_SOC_OCELOT
+	writel(MSCC_MEMPARM_TIMING0, BASE_CFG + ICPU_MEMCTRL_TIMING0);
+#else /* Luton */
+	clrbits_le32(BASE_CFG + ICPU_MEMCTRL_TIMING0, ((1 << 20) - 1));
+	setbits_le32(BASE_CFG + ICPU_MEMCTRL_TIMING0, MSCC_MEMPARM_TIMING0);
+#endif
+
+	writel(MSCC_MEMPARM_TIMING1, BASE_CFG + ICPU_MEMCTRL_TIMING1);
+	writel(MSCC_MEMPARM_TIMING2, BASE_CFG + ICPU_MEMCTRL_TIMING2);
+	writel(MSCC_MEMPARM_TIMING3, BASE_CFG + ICPU_MEMCTRL_TIMING3);
+	writel(MSCC_MEMPARM_MR0, BASE_CFG + ICPU_MEMCTRL_MR0_VAL);
+	writel(MSCC_MEMPARM_MR1, BASE_CFG + ICPU_MEMCTRL_MR1_VAL);
+	writel(MSCC_MEMPARM_MR2, BASE_CFG + ICPU_MEMCTRL_MR2_VAL);
+	writel(MSCC_MEMPARM_MR3, BASE_CFG + ICPU_MEMCTRL_MR3_VAL);
+
+#ifdef CONFIG_SOC_OCELOT
+	/* Termination setup - enable ODT */
+	writel(ICPU_MEMCTRL_TERMRES_CTRL_LOCAL_ODT_RD_ENA |
+	       /* Assert ODT0 for any write */
+	       ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA(3),
+	       BASE_CFG + ICPU_MEMCTRL_TERMRES_CTRL);
+
+	/* Release Reset from DDR */
+	hal_vcoreiii_ddr_reset_release();
+
+	writel(readl(BASE_CFG + ICPU_GPR(7)) + 1, BASE_CFG + ICPU_GPR(7));
+#else				/* Luton */
+	/* Termination setup - disable ODT */
+	writel(0, BASE_CFG + ICPU_MEMCTRL_TERMRES_CTRL);
+
+#endif
+}
+
+static inline void hal_vcoreiii_wait_memctl(void)
+{
+	/* Now, rip it! */
+	writel(ICPU_MEMCTRL_CTRL_INITIALIZE, BASE_CFG + ICPU_MEMCTRL_CTRL);
+
+	while (!(readl(BASE_CFG + ICPU_MEMCTRL_STAT)
+		 & ICPU_MEMCTRL_STAT_INIT_DONE))
+		;
+
+	/* Settle...? */
+	sleep_100ns(10000);
+#ifdef CONFIG_SOC_OCELOT
+	/* Establish data contents in DDR RAM for training */
+
+	__raw_writel(0xcacafefe, ((void __iomem *)MSCC_DDR_TO));
+	__raw_writel(0x22221111, ((void __iomem *)MSCC_DDR_TO + 0x4));
+	__raw_writel(0x44443333, ((void __iomem *)MSCC_DDR_TO + 0x8));
+	__raw_writel(0x66665555, ((void __iomem *)MSCC_DDR_TO + 0xC));
+	__raw_writel(0x88887777, ((void __iomem *)MSCC_DDR_TO + 0x10));
+	__raw_writel(0xaaaa9999, ((void __iomem *)MSCC_DDR_TO + 0x14));
+	__raw_writel(0xccccbbbb, ((void __iomem *)MSCC_DDR_TO + 0x18));
+	__raw_writel(0xeeeedddd, ((void __iomem *)MSCC_DDR_TO + 0x1C));
+#else
+	__raw_writel(0xff, ((void __iomem *)MSCC_DDR_TO));
+#endif
+}
+#endif				/* __ASM_MACH_DDR_H */

+ 24 - 0
arch/mips/mach-mscc/include/mach/luton/luton.h

@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Microsemi Ocelot Switch driver
+ *
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef _MSCC_OCELOT_H_
+#define _MSCC_OCELOT_H_
+
+#include <linux/bitops.h>
+#include <dm.h>
+
+/*
+ * Target offset base(s)
+ */
+#define MSCC_IO_ORIGIN1_OFFSET 0x60000000
+#define MSCC_IO_ORIGIN1_SIZE   0x01000000
+#define MSCC_IO_ORIGIN2_OFFSET 0x70000000
+#define MSCC_IO_ORIGIN2_SIZE   0x00200000
+#define BASE_CFG        ((void __iomem *)0x70000000)
+#define BASE_DEVCPU_GCB ((void __iomem *)0x60070000)
+
+#endif

+ 14 - 0
arch/mips/mach-mscc/include/mach/luton/luton_devcpu_gcb.h

@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef _MSCC_OCELOT_DEVCPU_GCB_H_
+#define _MSCC_OCELOT_DEVCPU_GCB_H_
+
+#define PERF_SOFT_RST                                     0x90
+
+#define PERF_SOFT_RST_SOFT_SWC_RST                        BIT(1)
+#define PERF_SOFT_RST_SOFT_CHIP_RST                       BIT(0)
+
+#endif

+ 245 - 0
arch/mips/mach-mscc/include/mach/luton/luton_icpu_cfg.h

@@ -0,0 +1,245 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef _MSCC_OCELOT_ICPU_CFG_H_
+#define _MSCC_OCELOT_ICPU_CFG_H_
+
+#define ICPU_GPR(x) (0x4 * (x))
+#define ICPU_GPR_RSZ                                      0x4
+
+#define ICPU_RESET                                        0x20
+
+#define ICPU_RESET_CORE_RST_CPU_ONLY                      BIT(3)
+#define ICPU_RESET_CORE_RST_PROTECT                       BIT(2)
+#define ICPU_RESET_CORE_RST_FORCE                         BIT(1)
+#define ICPU_RESET_MEM_RST_FORCE                          BIT(0)
+
+#define ICPU_GENERAL_CTRL                                 0x24
+
+#define ICPU_GENERAL_CTRL_SWC_CLEAR_IF                    BIT(6)
+#define ICPU_GENERAL_CTRL_CPU_BUSIF_SLEEP_DIS             BIT(5)
+#define ICPU_GENERAL_CTRL_CPU_BUSIF_WERR_ENA              BIT(4)
+#define ICPU_GENERAL_CTRL_IF_MASTER_DIS                   BIT(3)
+#define ICPU_GENERAL_CTRL_IF_MASTER_SPI_ENA               BIT(2)
+#define ICPU_GENERAL_CTRL_IF_MASTER_PI_ENA                BIT(1)
+
+#define ICPU_GENERAL_CTRL_BOOT_MODE_ENA                   BIT(0)
+
+#define ICPU_PI_MST_CFG                                   0x2c
+
+#define ICPU_PI_MST_CFG_ATE_MODE_DIS                      BIT(7)
+#define ICPU_PI_MST_CFG_CLK_POL                           BIT(6)
+#define ICPU_PI_MST_CFG_TRISTATE_CTRL                     BIT(5)
+#define ICPU_PI_MST_CFG_CLK_DIV(x)                        ((x) & GENMASK(4, 0))
+#define ICPU_PI_MST_CFG_CLK_DIV_M                         GENMASK(4, 0)
+
+#define ICPU_SPI_MST_CFG                                  0x50
+
+#define ICPU_SPI_MST_CFG_FAST_READ_ENA                    BIT(10)
+#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME(x)              (((x) << 5) & GENMASK(9, 5))
+#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME_M               GENMASK(9, 5)
+#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME_X(x)            (((x) & GENMASK(9, 5)) >> 5)
+#define ICPU_SPI_MST_CFG_CLK_DIV(x)                       ((x) & GENMASK(4, 0))
+#define ICPU_SPI_MST_CFG_CLK_DIV_M                        GENMASK(4, 0)
+
+#define ICPU_SW_MODE                                      0x64
+
+#define ICPU_SW_MODE_SW_PIN_CTRL_MODE                     BIT(13)
+#define ICPU_SW_MODE_SW_SPI_SCK                           BIT(12)
+#define ICPU_SW_MODE_SW_SPI_SCK_OE                        BIT(11)
+#define ICPU_SW_MODE_SW_SPI_SDO                           BIT(10)
+#define ICPU_SW_MODE_SW_SPI_SDO_OE                        BIT(9)
+#define ICPU_SW_MODE_SW_SPI_CS(x)                         (((x) << 5) & GENMASK(8, 5))
+#define ICPU_SW_MODE_SW_SPI_CS_M                          GENMASK(8, 5)
+#define ICPU_SW_MODE_SW_SPI_CS_X(x)                       (((x) & GENMASK(8, 5)) >> 5)
+#define ICPU_SW_MODE_SW_SPI_CS_OE(x)                      (((x) << 1) & GENMASK(4, 1))
+#define ICPU_SW_MODE_SW_SPI_CS_OE_M                       GENMASK(4, 1)
+#define ICPU_SW_MODE_SW_SPI_CS_OE_X(x)                    (((x) & GENMASK(4, 1)) >> 1)
+#define ICPU_SW_MODE_SW_SPI_SDI                           BIT(0)
+
+#define ICPU_INTR_ENA                                     0x88
+
+#define ICPU_INTR_IRQ0_ENA                                0x98
+#define ICPU_INTR_IRQ0_ENA_IRQ0_ENA                       BIT(0)
+
+#define ICPU_MEMCTRL_CTRL                                 0x234
+
+#define ICPU_MEMCTRL_CTRL_PWR_DOWN                        BIT(3)
+#define ICPU_MEMCTRL_CTRL_MDSET                           BIT(2)
+#define ICPU_MEMCTRL_CTRL_STALL_REF_ENA                   BIT(1)
+#define ICPU_MEMCTRL_CTRL_INITIALIZE                      BIT(0)
+
+#define ICPU_MEMCTRL_CFG                                  0x238
+
+#define ICPU_MEMCTRL_CFG_DDR_512MBYTE_PLUS                BIT(16)
+#define ICPU_MEMCTRL_CFG_DDR_ECC_ERR_ENA                  BIT(15)
+#define ICPU_MEMCTRL_CFG_DDR_ECC_COR_ENA                  BIT(14)
+#define ICPU_MEMCTRL_CFG_DDR_ECC_ENA                      BIT(13)
+#define ICPU_MEMCTRL_CFG_DDR_WIDTH                        BIT(12)
+#define ICPU_MEMCTRL_CFG_DDR_MODE                         BIT(11)
+#define ICPU_MEMCTRL_CFG_BURST_SIZE                       BIT(10)
+#define ICPU_MEMCTRL_CFG_BURST_LEN                        BIT(9)
+#define ICPU_MEMCTRL_CFG_BANK_CNT                         BIT(8)
+#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR(x)                  (((x) << 4) & GENMASK(7, 4))
+#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR_M                   GENMASK(7, 4)
+#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR_X(x)                (((x) & GENMASK(7, 4)) >> 4)
+#define ICPU_MEMCTRL_CFG_MSB_COL_ADDR(x)                  ((x) & GENMASK(3, 0))
+#define ICPU_MEMCTRL_CFG_MSB_COL_ADDR_M                   GENMASK(3, 0)
+
+#define ICPU_MEMCTRL_STAT                                 0x23C
+
+#define ICPU_MEMCTRL_STAT_RDATA_MASKED                    BIT(5)
+#define ICPU_MEMCTRL_STAT_RDATA_DUMMY                     BIT(4)
+#define ICPU_MEMCTRL_STAT_RDATA_ECC_ERR                   BIT(3)
+#define ICPU_MEMCTRL_STAT_RDATA_ECC_COR                   BIT(2)
+#define ICPU_MEMCTRL_STAT_PWR_DOWN_ACK                    BIT(1)
+#define ICPU_MEMCTRL_STAT_INIT_DONE                       BIT(0)
+
+#define ICPU_MEMCTRL_REF_PERIOD                           0x240
+
+#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF(x)           (((x) << 16) & GENMASK(19, 16))
+#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF_M            GENMASK(19, 16)
+#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF_X(x)         (((x) & GENMASK(19, 16)) >> 16)
+#define ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD(x)             ((x) & GENMASK(15, 0))
+#define ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD_M              GENMASK(15, 0)
+
+#define ICPU_MEMCTRL_TIMING0                              0x248
+
+#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY(x)              (((x) << 28) & GENMASK(31, 28))
+#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY_M               GENMASK(31, 28)
+#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY_X(x)            (((x) & GENMASK(31, 28)) >> 28)
+#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY(x)          (((x) << 24) & GENMASK(27, 24))
+#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY_M           GENMASK(27, 24)
+#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY_X(x)        (((x) & GENMASK(27, 24)) >> 24)
+#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY(x)          (((x) << 20) & GENMASK(23, 20))
+#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY_M           GENMASK(23, 20)
+#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY_X(x)        (((x) & GENMASK(23, 20)) >> 20)
+#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY(x)          (((x) << 16) & GENMASK(19, 16))
+#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY_M           GENMASK(19, 16)
+#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY_X(x)        (((x) & GENMASK(19, 16)) >> 16)
+#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY(x)           (((x) << 12) & GENMASK(15, 12))
+#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY_M            GENMASK(15, 12)
+#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY_X(x)         (((x) & GENMASK(15, 12)) >> 12)
+#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY(x)           (((x) << 8) & GENMASK(11, 8))
+#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY_M            GENMASK(11, 8)
+#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY_X(x)         (((x) & GENMASK(11, 8)) >> 8)
+#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY(x)           (((x) << 4) & GENMASK(7, 4))
+#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY_M            GENMASK(7, 4)
+#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY_X(x)         (((x) & GENMASK(7, 4)) >> 4)
+#define ICPU_MEMCTRL_TIMING0_RD_DATA_XFR_DLY(x)           ((x) & GENMASK(3, 0))
+#define ICPU_MEMCTRL_TIMING0_RD_DATA_XFR_DLY_M            GENMASK(3, 0)
+
+#define ICPU_MEMCTRL_TIMING1                              0x24c
+
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY(x)  (((x) << 24) & GENMASK(31, 24))
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY_M   GENMASK(31, 24)
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY_X(x) (((x) & GENMASK(31, 24)) >> 24)
+#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY(x)             (((x) << 16) & GENMASK(23, 16))
+#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY_M              GENMASK(23, 16)
+#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY_X(x)           (((x) & GENMASK(23, 16)) >> 16)
+#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY(x)          (((x) << 12) & GENMASK(15, 12))
+#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY_M           GENMASK(15, 12)
+#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY_X(x)        (((x) & GENMASK(15, 12)) >> 12)
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY(x)            (((x) << 8) & GENMASK(11, 8))
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY_M             GENMASK(11, 8)
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY_X(x)          (((x) & GENMASK(11, 8)) >> 8)
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY(x)            (((x) << 4) & GENMASK(7, 4))
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY_M             GENMASK(7, 4)
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY_X(x)          (((x) & GENMASK(7, 4)) >> 4)
+#define ICPU_MEMCTRL_TIMING1_WR_TO_RD_DLY(x)              ((x) & GENMASK(3, 0))
+#define ICPU_MEMCTRL_TIMING1_WR_TO_RD_DLY_M               GENMASK(3, 0)
+
+#define ICPU_MEMCTRL_TIMING2                              0x250
+
+#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY(x)             (((x) << 28) & GENMASK(31, 28))
+#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY_M              GENMASK(31, 28)
+#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY_X(x)           (((x) & GENMASK(31, 28)) >> 28)
+#define ICPU_MEMCTRL_TIMING2_MDSET_DLY(x)                 (((x) << 24) & GENMASK(27, 24))
+#define ICPU_MEMCTRL_TIMING2_MDSET_DLY_M                  GENMASK(27, 24)
+#define ICPU_MEMCTRL_TIMING2_MDSET_DLY_X(x)               (((x) & GENMASK(27, 24)) >> 24)
+#define ICPU_MEMCTRL_TIMING2_REF_DLY(x)                   (((x) << 16) & GENMASK(23, 16))
+#define ICPU_MEMCTRL_TIMING2_REF_DLY_M                    GENMASK(23, 16)
+#define ICPU_MEMCTRL_TIMING2_REF_DLY_X(x)                 (((x) & GENMASK(23, 16)) >> 16)
+#define ICPU_MEMCTRL_TIMING2_FOUR_HUNDRED_NS_DLY(x)       ((x) & GENMASK(15, 0))
+#define ICPU_MEMCTRL_TIMING2_FOUR_HUNDRED_NS_DLY_M        GENMASK(15, 0)
+
+#define ICPU_MEMCTRL_TIMING3                              0x254
+
+#define ICPU_MEMCTRL_TIMING3_RMW_DLY(x)                   (((x) << 16) & GENMASK(19, 16))
+#define ICPU_MEMCTRL_TIMING3_RMW_DLY_M                    GENMASK(19, 16)
+#define ICPU_MEMCTRL_TIMING3_RMW_DLY_X(x)                 (((x) & GENMASK(19, 16)) >> 16)
+#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY(x)                (((x) << 12) & GENMASK(15, 12))
+#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY_M                 GENMASK(15, 12)
+#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY_X(x)              (((x) & GENMASK(15, 12)) >> 12)
+#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY(x)                (((x) << 8) & GENMASK(11, 8))
+#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY_M                 GENMASK(11, 8)
+#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY_X(x)              (((x) & GENMASK(11, 8)) >> 8)
+#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY(x)          (((x) << 4) & GENMASK(7, 4))
+#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY_M           GENMASK(7, 4)
+#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY_X(x)        (((x) & GENMASK(7, 4)) >> 4)
+#define ICPU_MEMCTRL_TIMING3_WR_TO_RD_CS_CHANGE_DLY(x)    ((x) & GENMASK(3, 0))
+#define ICPU_MEMCTRL_TIMING3_WR_TO_RD_CS_CHANGE_DLY_M     GENMASK(3, 0)
+
+#define ICPU_MEMCTRL_MR0_VAL                              0x258
+
+#define ICPU_MEMCTRL_MR1_VAL                              0x25c
+
+#define ICPU_MEMCTRL_MR2_VAL                              0x260
+
+#define ICPU_MEMCTRL_MR3_VAL                              0x264
+
+#define ICPU_MEMCTRL_TERMRES_CTRL                         0x268
+
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_EXT              BIT(11)
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA(x)           (((x) << 7) & GENMASK(10, 7))
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA_M            GENMASK(10, 7)
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA_X(x)         (((x) & GENMASK(10, 7)) >> 7)
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_EXT              BIT(6)
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA(x)           (((x) << 2) & GENMASK(5, 2))
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA_M            GENMASK(5, 2)
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA_X(x)         (((x) & GENMASK(5, 2)) >> 2)
+#define ICPU_MEMCTRL_TERMRES_CTRL_LOCAL_ODT_RD_EXT        BIT(1)
+#define ICPU_MEMCTRL_TERMRES_CTRL_LOCAL_ODT_RD_ENA        BIT(0)
+
+#define ICPU_MEMCTRL_DQS_DLY(x) (0x270)
+
+#define ICPU_MEMCTRL_DQS_DLY_TRAIN_DQ_ENA                 BIT(11)
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1(x)              (((x) << 8) & GENMASK(10, 8))
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1_M               GENMASK(10, 8)
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1_X(x)            (((x) & GENMASK(10, 8)) >> 8)
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0(x)              (((x) << 5) & GENMASK(7, 5))
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0_M               GENMASK(7, 5)
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0_X(x)            (((x) & GENMASK(7, 5)) >> 5)
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY(x)                   ((x) & GENMASK(4, 0))
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_M                    GENMASK(4, 0)
+
+#define ICPU_MEMPHY_CFG                                   0x278
+
+#define ICPU_MEMPHY_CFG_PHY_FLUSH_DIS                     BIT(10)
+#define ICPU_MEMPHY_CFG_PHY_RD_ADJ_DIS                    BIT(9)
+#define ICPU_MEMPHY_CFG_PHY_DQS_EXT                       BIT(8)
+#define ICPU_MEMPHY_CFG_PHY_FIFO_RST                      BIT(7)
+#define ICPU_MEMPHY_CFG_PHY_DLL_BL_RST                    BIT(6)
+#define ICPU_MEMPHY_CFG_PHY_DLL_CL_RST                    BIT(5)
+#define ICPU_MEMPHY_CFG_PHY_ODT_OE                        BIT(4)
+#define ICPU_MEMPHY_CFG_PHY_CK_OE                         BIT(3)
+#define ICPU_MEMPHY_CFG_PHY_CL_OE                         BIT(2)
+#define ICPU_MEMPHY_CFG_PHY_SSTL_ENA                      BIT(1)
+#define ICPU_MEMPHY_CFG_PHY_RST                           BIT(0)
+#define ICPU_MEMPHY_DQ_DLY_TRM                            0x180
+#define ICPU_MEMPHY_DQ_DLY_TRM_RSZ                        0x4
+
+#define ICPU_MEMPHY_ZCAL                                  0x294
+
+#define ICPU_MEMPHY_ZCAL_ZCAL_CLK_SEL                     BIT(9)
+#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT(x)                 (((x) << 5) & GENMASK(8, 5))
+#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT_M                  GENMASK(8, 5)
+#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT_X(x)               (((x) & GENMASK(8, 5)) >> 5)
+#define ICPU_MEMPHY_ZCAL_ZCAL_PROG(x)                     (((x) << 1) & GENMASK(4, 1))
+#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_M                      GENMASK(4, 1)
+#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_X(x)                   (((x) & GENMASK(4, 1)) >> 1)
+#define ICPU_MEMPHY_ZCAL_ZCAL_ENA                         BIT(0)
+
+#endif

+ 24 - 0
arch/mips/mach-mscc/include/mach/ocelot/ocelot.h

@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Microsemi Ocelot Switch driver
+ *
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef _MSCC_OCELOT_H_
+#define _MSCC_OCELOT_H_
+
+#include <linux/bitops.h>
+#include <dm.h>
+
+/*
+ * Target offset base(s)
+ */
+#define MSCC_IO_ORIGIN1_OFFSET 0x70000000
+#define MSCC_IO_ORIGIN1_SIZE   0x00200000
+#define MSCC_IO_ORIGIN2_OFFSET 0x71000000
+#define MSCC_IO_ORIGIN2_SIZE   0x01000000
+#define BASE_CFG        ((void __iomem *)0x70000000)
+#define BASE_DEVCPU_GCB ((void __iomem *)0x71070000)
+
+#endif

+ 21 - 0
arch/mips/mach-mscc/include/mach/ocelot/ocelot_devcpu_gcb.h

@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef _MSCC_OCELOT_DEVCPU_GCB_H_
+#define _MSCC_OCELOT_DEVCPU_GCB_H_
+
+#define PERF_SOFT_RST                                     0x8
+
+#define PERF_SOFT_RST_SOFT_NON_CFG_RST                    BIT(2)
+#define PERF_SOFT_RST_SOFT_SWC_RST                        BIT(1)
+#define PERF_SOFT_RST_SOFT_CHIP_RST                       BIT(0)
+
+#define PERF_GPIO_OUT_SET                                 0x34
+
+#define PERF_GPIO_OUT_CLR                                 0x38
+
+#define PERF_GPIO_OE                                      0x44
+
+#endif

+ 274 - 0
arch/mips/mach-mscc/include/mach/ocelot/ocelot_icpu_cfg.h

@@ -0,0 +1,274 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef _MSCC_OCELOT_ICPU_CFG_H_
+#define _MSCC_OCELOT_ICPU_CFG_H_
+
+#define ICPU_GPR(x) (0x4 * (x))
+#define ICPU_GPR_RSZ                                      0x4
+
+#define ICPU_RESET                                        0x20
+
+#define ICPU_RESET_CORE_RST_CPU_ONLY                      BIT(3)
+#define ICPU_RESET_CORE_RST_PROTECT                       BIT(2)
+#define ICPU_RESET_CORE_RST_FORCE                         BIT(1)
+#define ICPU_RESET_MEM_RST_FORCE                          BIT(0)
+
+#define ICPU_GENERAL_CTRL                                 0x24
+
+#define ICPU_GENERAL_CTRL_CPU_BUSIF_SLEEP_DIS             BIT(14)
+#define ICPU_GENERAL_CTRL_CPU_BUSIF_WERR_ENA              BIT(13)
+#define ICPU_GENERAL_CTRL_CPU_8051_IROM_ENA               BIT(12)
+#define ICPU_GENERAL_CTRL_CPU_MIPS_DIS                    BIT(11)
+#define ICPU_GENERAL_CTRL_IF_MIIM_SLV_ADDR_SEL            BIT(10)
+#define ICPU_GENERAL_CTRL_IF_MIIM_SLV_ENA                 BIT(9)
+#define ICPU_GENERAL_CTRL_IF_PI_SLV_DONEPOL               BIT(8)
+#define ICPU_GENERAL_CTRL_IF_PI_MST_ENA                   BIT(7)
+#define ICPU_GENERAL_CTRL_IF_PI_SLV_ENA                   BIT(6)
+#define ICPU_GENERAL_CTRL_IF_SI_OWNER(x)                  (((x) << 4) & GENMASK(5, 4))
+#define ICPU_GENERAL_CTRL_IF_SI_OWNER_M                   GENMASK(5, 4)
+#define ICPU_GENERAL_CTRL_IF_SI_OWNER_X(x)                (((x) & GENMASK(5, 4)) >> 4)
+#define ICPU_GENERAL_CTRL_SSI_MST_CONTENTION              BIT(3)
+#define ICPU_GENERAL_CTRL_CPU_BE_ENA                      BIT(2)
+#define ICPU_GENERAL_CTRL_CPU_DIS                         BIT(1)
+#define ICPU_GENERAL_CTRL_BOOT_MODE_ENA                   BIT(0)
+#define ICPU_SPI_MST_CFG                                  0x3c
+
+#define ICPU_SPI_MST_CFG_A32B_ENA                         BIT(11)
+#define ICPU_SPI_MST_CFG_FAST_READ_ENA                    BIT(10)
+#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME(x)              (((x) << 5) & GENMASK(9, 5))
+#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME_M               GENMASK(9, 5)
+#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME_X(x)            (((x) & GENMASK(9, 5)) >> 5)
+#define ICPU_SPI_MST_CFG_CLK_DIV(x)                       ((x) & GENMASK(4, 0))
+#define ICPU_SPI_MST_CFG_CLK_DIV_M                        GENMASK(4, 0)
+
+#define ICPU_SW_MODE                                      0x50
+
+#define ICPU_SW_MODE_SW_PIN_CTRL_MODE                     BIT(13)
+#define ICPU_SW_MODE_SW_SPI_SCK                           BIT(12)
+#define ICPU_SW_MODE_SW_SPI_SCK_OE                        BIT(11)
+#define ICPU_SW_MODE_SW_SPI_SDO                           BIT(10)
+#define ICPU_SW_MODE_SW_SPI_SDO_OE                        BIT(9)
+#define ICPU_SW_MODE_SW_SPI_CS(x)                         (((x) << 5) & GENMASK(8, 5))
+#define ICPU_SW_MODE_SW_SPI_CS_M                          GENMASK(8, 5)
+#define ICPU_SW_MODE_SW_SPI_CS_X(x)                       (((x) & GENMASK(8, 5)) >> 5)
+#define ICPU_SW_MODE_SW_SPI_CS_OE(x)                      (((x) << 1) & GENMASK(4, 1))
+#define ICPU_SW_MODE_SW_SPI_CS_OE_M                       GENMASK(4, 1)
+#define ICPU_SW_MODE_SW_SPI_CS_OE_X(x)                    (((x) & GENMASK(4, 1)) >> 1)
+#define ICPU_SW_MODE_SW_SPI_SDI                           BIT(0)
+
+#define ICPU_INTR_ENA					  0x88
+
+#define ICPU_DST_INTR_MAP(x)  (0x98 + 0x4 * (x))
+#define ICPU_DST_INTR_MAP_RSZ                             0x4
+
+#define ICPU_DST_INTR_IDENT                               0xa8
+#define ICPU_DST_INTR_IDENT_RSZ                           0x4
+
+#define ICPU_TIMER_TICK_DIV                               0xe8
+#define ICPU_TIMER_VALUE(x) (0xec + 0x4 * (x))
+
+#define ICPU_TIMER_CTRL(x) (0x104 + 0x4 * (x))
+#define ICPU_TIMER_CTRL_MAX_FREQ_ENA			  BIT(3)
+#define ICPU_TIMER_CTRL_ONE_SHOT_ENA			  BIT(2)
+#define ICPU_TIMER_CTRL_TIMER_ENA			  BIT(1)
+#define ICPU_TIMER_CTRL_FORCE_RELOAD			  BIT(0)
+
+#define ICPU_MEMCTRL_CTRL                                 0x110
+#define ICPU_MEMCTRL_CTRL_PWR_DOWN                        BIT(3)
+#define ICPU_MEMCTRL_CTRL_MDSET                           BIT(2)
+#define ICPU_MEMCTRL_CTRL_STALL_REF_ENA                   BIT(1)
+#define ICPU_MEMCTRL_CTRL_INITIALIZE                      BIT(0)
+
+#define ICPU_MEMCTRL_CFG                                  0x114
+
+#define ICPU_MEMCTRL_CFG_DDR_512MBYTE_PLUS                BIT(16)
+#define ICPU_MEMCTRL_CFG_DDR_ECC_ERR_ENA                  BIT(15)
+#define ICPU_MEMCTRL_CFG_DDR_ECC_COR_ENA                  BIT(14)
+#define ICPU_MEMCTRL_CFG_DDR_ECC_ENA                      BIT(13)
+#define ICPU_MEMCTRL_CFG_DDR_WIDTH                        BIT(12)
+#define ICPU_MEMCTRL_CFG_DDR_MODE                         BIT(11)
+#define ICPU_MEMCTRL_CFG_BURST_SIZE                       BIT(10)
+#define ICPU_MEMCTRL_CFG_BURST_LEN                        BIT(9)
+#define ICPU_MEMCTRL_CFG_BANK_CNT                         BIT(8)
+#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR(x)                  (((x) << 4) & GENMASK(7, 4))
+#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR_M                   GENMASK(7, 4)
+#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR_X(x)                (((x) & GENMASK(7, 4)) >> 4)
+#define ICPU_MEMCTRL_CFG_MSB_COL_ADDR(x)                  ((x) & GENMASK(3, 0))
+#define ICPU_MEMCTRL_CFG_MSB_COL_ADDR_M                   GENMASK(3, 0)
+
+#define ICPU_MEMCTRL_STAT                                 0x118
+
+#define ICPU_MEMCTRL_STAT_RDATA_MASKED                    BIT(5)
+#define ICPU_MEMCTRL_STAT_RDATA_DUMMY                     BIT(4)
+#define ICPU_MEMCTRL_STAT_RDATA_ECC_ERR                   BIT(3)
+#define ICPU_MEMCTRL_STAT_RDATA_ECC_COR                   BIT(2)
+#define ICPU_MEMCTRL_STAT_PWR_DOWN_ACK                    BIT(1)
+#define ICPU_MEMCTRL_STAT_INIT_DONE                       BIT(0)
+
+#define ICPU_MEMCTRL_REF_PERIOD                           0x11c
+
+#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF(x)           (((x) << 16) & GENMASK(19, 16))
+#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF_M            GENMASK(19, 16)
+#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF_X(x)         (((x) & GENMASK(19, 16)) >> 16)
+#define ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD(x)             ((x) & GENMASK(15, 0))
+#define ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD_M              GENMASK(15, 0)
+
+#define ICPU_MEMCTRL_TIMING0                              0x124
+
+#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY(x)              (((x) << 28) & GENMASK(31, 28))
+#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY_M               GENMASK(31, 28)
+#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY_X(x)            (((x) & GENMASK(31, 28)) >> 28)
+#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY(x)          (((x) << 24) & GENMASK(27, 24))
+#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY_M           GENMASK(27, 24)
+#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY_X(x)        (((x) & GENMASK(27, 24)) >> 24)
+#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY(x)          (((x) << 20) & GENMASK(23, 20))
+#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY_M           GENMASK(23, 20)
+#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY_X(x)        (((x) & GENMASK(23, 20)) >> 20)
+#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY(x)          (((x) << 16) & GENMASK(19, 16))
+#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY_M           GENMASK(19, 16)
+#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY_X(x)        (((x) & GENMASK(19, 16)) >> 16)
+#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY(x)           (((x) << 12) & GENMASK(15, 12))
+#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY_M            GENMASK(15, 12)
+#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY_X(x)         (((x) & GENMASK(15, 12)) >> 12)
+#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY(x)           (((x) << 8) & GENMASK(11, 8))
+#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY_M            GENMASK(11, 8)
+#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY_X(x)         (((x) & GENMASK(11, 8)) >> 8)
+#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY(x)           (((x) << 4) & GENMASK(7, 4))
+#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY_M            GENMASK(7, 4)
+#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY_X(x)         (((x) & GENMASK(7, 4)) >> 4)
+#define ICPU_MEMCTRL_TIMING0_RD_DATA_XFR_DLY(x)           ((x) & GENMASK(3, 0))
+#define ICPU_MEMCTRL_TIMING0_RD_DATA_XFR_DLY_M            GENMASK(3, 0)
+
+#define ICPU_MEMCTRL_TIMING1                              0x128
+
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY(x)  (((x) << 24) & GENMASK(31, 24))
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY_M   GENMASK(31, 24)
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY_X(x) (((x) & GENMASK(31, 24)) >> 24)
+#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY(x)             (((x) << 16) & GENMASK(23, 16))
+#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY_M              GENMASK(23, 16)
+#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY_X(x)           (((x) & GENMASK(23, 16)) >> 16)
+#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY(x)          (((x) << 12) & GENMASK(15, 12))
+#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY_M           GENMASK(15, 12)
+#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY_X(x)        (((x) & GENMASK(15, 12)) >> 12)
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY(x)            (((x) << 8) & GENMASK(11, 8))
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY_M             GENMASK(11, 8)
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY_X(x)          (((x) & GENMASK(11, 8)) >> 8)
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY(x)            (((x) << 4) & GENMASK(7, 4))
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY_M             GENMASK(7, 4)
+#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY_X(x)          (((x) & GENMASK(7, 4)) >> 4)
+#define ICPU_MEMCTRL_TIMING1_WR_TO_RD_DLY(x)              ((x) & GENMASK(3, 0))
+#define ICPU_MEMCTRL_TIMING1_WR_TO_RD_DLY_M               GENMASK(3, 0)
+
+#define ICPU_MEMCTRL_TIMING2                              0x12c
+
+#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY(x)             (((x) << 28) & GENMASK(31, 28))
+#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY_M              GENMASK(31, 28)
+#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY_X(x)           (((x) & GENMASK(31, 28)) >> 28)
+#define ICPU_MEMCTRL_TIMING2_MDSET_DLY(x)                 (((x) << 24) & GENMASK(27, 24))
+#define ICPU_MEMCTRL_TIMING2_MDSET_DLY_M                  GENMASK(27, 24)
+#define ICPU_MEMCTRL_TIMING2_MDSET_DLY_X(x)               (((x) & GENMASK(27, 24)) >> 24)
+#define ICPU_MEMCTRL_TIMING2_REF_DLY(x)                   (((x) << 16) & GENMASK(23, 16))
+#define ICPU_MEMCTRL_TIMING2_REF_DLY_M                    GENMASK(23, 16)
+#define ICPU_MEMCTRL_TIMING2_REF_DLY_X(x)                 (((x) & GENMASK(23, 16)) >> 16)
+#define ICPU_MEMCTRL_TIMING2_INIT_DLY(x)                  ((x) & GENMASK(15, 0))
+#define ICPU_MEMCTRL_TIMING2_INIT_DLY_M                   GENMASK(15, 0)
+
+#define ICPU_MEMCTRL_TIMING3                              0x130
+
+#define ICPU_MEMCTRL_TIMING3_RMW_DLY(x)                   (((x) << 16) & GENMASK(19, 16))
+#define ICPU_MEMCTRL_TIMING3_RMW_DLY_M                    GENMASK(19, 16)
+#define ICPU_MEMCTRL_TIMING3_RMW_DLY_X(x)                 (((x) & GENMASK(19, 16)) >> 16)
+#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY(x)                (((x) << 12) & GENMASK(15, 12))
+#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY_M                 GENMASK(15, 12)
+#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY_X(x)              (((x) & GENMASK(15, 12)) >> 12)
+#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY(x)                (((x) << 8) & GENMASK(11, 8))
+#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY_M                 GENMASK(11, 8)
+#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY_X(x)              (((x) & GENMASK(11, 8)) >> 8)
+#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY(x)          (((x) << 4) & GENMASK(7, 4))
+#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY_M           GENMASK(7, 4)
+#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY_X(x)        (((x) & GENMASK(7, 4)) >> 4)
+#define ICPU_MEMCTRL_TIMING3_WR_TO_RD_CS_CHANGE_DLY(x)    ((x) & GENMASK(3, 0))
+#define ICPU_MEMCTRL_TIMING3_WR_TO_RD_CS_CHANGE_DLY_M     GENMASK(3, 0)
+
+#define ICPU_MEMCTRL_MR0_VAL                              0x138
+
+#define ICPU_MEMCTRL_MR1_VAL                              0x13c
+
+#define ICPU_MEMCTRL_MR2_VAL                              0x140
+
+#define ICPU_MEMCTRL_MR3_VAL                              0x144
+
+#define ICPU_MEMCTRL_TERMRES_CTRL                         0x148
+
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_EXT              BIT(11)
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA(x)           (((x) << 7) & GENMASK(10, 7))
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA_M            GENMASK(10, 7)
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA_X(x)         (((x) & GENMASK(10, 7)) >> 7)
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_EXT              BIT(6)
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA(x)           (((x) << 2) & GENMASK(5, 2))
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA_M            GENMASK(5, 2)
+#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA_X(x)         (((x) & GENMASK(5, 2)) >> 2)
+#define ICPU_MEMCTRL_TERMRES_CTRL_LOCAL_ODT_RD_EXT        BIT(1)
+#define ICPU_MEMCTRL_TERMRES_CTRL_LOCAL_ODT_RD_ENA        BIT(0)
+
+#define ICPU_MEMCTRL_DQS_DLY(x) (0x150 + 0x4 * (x))
+#define ICPU_MEMCTRL_DQS_DLY_RSZ                          0x4
+
+#define ICPU_MEMCTRL_DQS_DLY_TRAIN_DQ_ENA                 BIT(11)
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1(x)              (((x) << 8) & GENMASK(10, 8))
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1_M               GENMASK(10, 8)
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1_X(x)            (((x) & GENMASK(10, 8)) >> 8)
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0(x)              (((x) << 5) & GENMASK(7, 5))
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0_M               GENMASK(7, 5)
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0_X(x)            (((x) & GENMASK(7, 5)) >> 5)
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY(x)                   ((x) & GENMASK(4, 0))
+#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_M                    GENMASK(4, 0)
+
+#define ICPU_MEMPHY_CFG                                   0x160
+
+#define ICPU_MEMPHY_CFG_PHY_FLUSH_DIS                     BIT(10)
+#define ICPU_MEMPHY_CFG_PHY_RD_ADJ_DIS                    BIT(9)
+#define ICPU_MEMPHY_CFG_PHY_DQS_EXT                       BIT(8)
+#define ICPU_MEMPHY_CFG_PHY_FIFO_RST                      BIT(7)
+#define ICPU_MEMPHY_CFG_PHY_DLL_BL_RST                    BIT(6)
+#define ICPU_MEMPHY_CFG_PHY_DLL_CL_RST                    BIT(5)
+#define ICPU_MEMPHY_CFG_PHY_ODT_OE                        BIT(4)
+#define ICPU_MEMPHY_CFG_PHY_CK_OE                         BIT(3)
+#define ICPU_MEMPHY_CFG_PHY_CL_OE                         BIT(2)
+#define ICPU_MEMPHY_CFG_PHY_SSTL_ENA                      BIT(1)
+#define ICPU_MEMPHY_CFG_PHY_RST                           BIT(0)
+
+#define ICPU_MEMPHY_ZCAL                                  0x188
+
+#define ICPU_MEMPHY_ZCAL_ZCAL_CLK_SEL                     BIT(9)
+#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT(x)                 (((x) << 5) & GENMASK(8, 5))
+#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT_M                  GENMASK(8, 5)
+#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT_X(x)               (((x) & GENMASK(8, 5)) >> 5)
+#define ICPU_MEMPHY_ZCAL_ZCAL_PROG(x)                     (((x) << 1) & GENMASK(4, 1))
+#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_M                      GENMASK(4, 1)
+#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_X(x)                   (((x) & GENMASK(4, 1)) >> 1)
+#define ICPU_MEMPHY_ZCAL_ZCAL_ENA                         BIT(0)
+
+#define ICPU_MEMPHY_ZCAL_STAT                             0x18c
+
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_ZCTRL(x)               (((x) << 12) & GENMASK(31, 12))
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_ZCTRL_M                GENMASK(31, 12)
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_ZCTRL_X(x)             (((x) & GENMASK(31, 12)) >> 12)
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPU(x)          (((x) << 8) & GENMASK(9, 8))
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPU_M           GENMASK(9, 8)
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPU_X(x)        (((x) & GENMASK(9, 8)) >> 8)
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPD(x)          (((x) << 6) & GENMASK(7, 6))
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPD_M           GENMASK(7, 6)
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPD_X(x)        (((x) & GENMASK(7, 6)) >> 6)
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PU(x)             (((x) << 4) & GENMASK(5, 4))
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PU_M              GENMASK(5, 4)
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PU_X(x)           (((x) & GENMASK(5, 4)) >> 4)
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PD(x)             (((x) << 2) & GENMASK(3, 2))
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PD_M              GENMASK(3, 2)
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PD_X(x)           (((x) & GENMASK(3, 2)) >> 2)
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_ERR                    BIT(1)
+#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_DONE                   BIT(0)
+#endif

+ 55 - 0
arch/mips/mach-mscc/include/mach/tlb.h

@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef __ASM_MACH_TLB_H
+#define __ASM_MACH_TLB_H
+
+#include <asm/mipsregs.h>
+#include <mach/common.h>
+#include <linux/sizes.h>
+
+#define TLB_HI_MASK      0xffffe000
+#define TLB_LO_MASK      0x3fffffff	/* Masks off Fill bits */
+#define TLB_LO_SHIFT     6	/* PFN Start bit */
+
+#define PAGEMASK_SHIFT   13
+
+#define MMU_PAGE_CACHED   (3 << 3)	/* C(5:3) Cache Coherency Attributes */
+#define MMU_PAGE_UNCACHED (2 << 3)	/* C(5:3) Cache Coherency Attributes */
+#define MMU_PAGE_DIRTY    BIT(2)	/* = Writeable */
+#define MMU_PAGE_VALID    BIT(1)
+#define MMU_PAGE_GLOBAL   BIT(0)
+#define MMU_REGIO_RO_C    (MMU_PAGE_CACHED | MMU_PAGE_VALID | MMU_PAGE_GLOBAL)
+#define MMU_REGIO_RO      (MMU_PAGE_UNCACHED | MMU_PAGE_VALID | MMU_PAGE_GLOBAL)
+#define MMU_REGIO_RW      (MMU_PAGE_DIRTY | MMU_REGIO_RO)
+#define MMU_REGIO_INVAL   (MMU_PAGE_GLOBAL)
+
+#define TLB_COUNT_MASK	  GENMASK(5, 0)
+#define TLB_COUNT_OFF	  25
+
+static inline u32 get_tlb_count(void)
+{
+	register u32 config1;
+
+	config1 = read_c0_config1();
+	config1 >>= TLB_COUNT_OFF;
+	config1 &= TLB_COUNT_MASK;
+
+	return 1 + config1;
+}
+
+static inline void create_tlb(int index, u32 offset, u32 size, u32 tlb_attrib1,
+			      u32 tlb_attrib2)
+{
+	register u32 tlb_mask, tlb_lo0, tlb_lo1;
+
+	tlb_mask = ((size >> 12) - 1) << PAGEMASK_SHIFT;
+	tlb_lo0 = tlb_attrib1 | (offset >> TLB_LO_SHIFT);
+	tlb_lo1 = tlb_attrib2 | ((offset + size) >> TLB_LO_SHIFT);
+
+	write_one_tlb(index, tlb_mask, offset & TLB_HI_MASK,
+		      tlb_lo0 & TLB_LO_MASK, tlb_lo1 & TLB_LO_MASK);
+}
+#endif				/* __ASM_MACH_TLB_H */

+ 30 - 0
arch/mips/mach-mscc/lowlevel_init.S

@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+
+    .set noreorder
+    .extern     vcoreiii_tlb_init
+#ifdef CONFIG_SOC_LUTON
+    .extern     pll_init
+#endif
+
+LEAF(lowlevel_init)
+	/*
+	 * As we have no stack yet, we can assume the restricted
+	 * luxury of the sX-registers without saving them
+	 */
+	move	s0,ra
+
+	jal	vcoreiii_tlb_init
+	 nop
+#ifdef CONFIG_SOC_LUTON
+	jal	pll_init
+	 nop
+#endif
+	jr	s0
+	 nop
+	END(lowlevel_init)

+ 62 - 0
arch/mips/mach-mscc/lowlevel_init_luton.S

@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+
+#define BASE_MACRO      0x600a0000
+#define REG_OFFSET(t, o) (t + (o*4))
+#define REG_MACRO(x) REG_OFFSET(BASE_MACRO, x)
+#define BIT(nr)			(1 << (nr))
+
+#define MACRO_CTRL_PLL5G_STATUS_PLL5G_STATUS0 REG_MACRO(6)
+#define MACRO_CTRL_PLL5G_STATUS_PLL5G_STATUS0_LOCK_STATUS BIT(0)
+#define MACRO_CTRL_PLL5G_CFG_PLL5G_CFG2 REG_MACRO(2)
+#define MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0 REG_MACRO(0)
+#define MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0_CPU_CLK_DIV (0x3F << 6)
+#define MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0_CPU_CLK_DIV_ENC(x) (x << 6)
+
+    .set noreorder
+LEAF(pll_init)
+	/* Make sure PLL is locked */
+	lw	v0, MACRO_CTRL_PLL5G_STATUS_PLL5G_STATUS0
+	andi	v1, v0, MACRO_CTRL_PLL5G_STATUS_PLL5G_STATUS0_LOCK_STATUS
+	bne	v1, zero, 1f
+	 nop
+
+	/* Black magic from frontend */
+	li	v1, 0x00610400
+	sw	v1, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG2
+
+	li	v1, 0x00610c00
+	sw	v1, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG2
+
+	li	v1, 0x00610800
+	sw	v1, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG2
+
+	li	v1, 0x00610000
+	sw	v1, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG2
+
+	/* Wait for lock */
+2:	lw	v0, MACRO_CTRL_PLL5G_STATUS_PLL5G_STATUS0
+	andi	v1, v0, MACRO_CTRL_PLL5G_STATUS_PLL5G_STATUS0_LOCK_STATUS
+	/* Keep looping if zero (no lock bit yet) */
+	beq	v1, zero, 2b
+	 nop
+
+	/* Setup PLL CPU clock divider for 416MHz */
+1:	lw	v0, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0
+
+	/* Keep reserved bits */
+	li	v1, ~MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0_CPU_CLK_DIV
+	and	v0, v0, v1
+
+	/* Set code 6 ~ 416.66 MHz */
+	ori	v0, v0, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0_CPU_CLK_DIV_ENC(6)
+
+	sw	v0, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0
+	jr      ra
+	 nop
+	END(pll_init)

+ 30 - 0
arch/mips/mach-mscc/reset.c

@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#include <common.h>
+
+#include <asm/sections.h>
+#include <asm/io.h>
+
+#include <asm/reboot.h>
+
+void _machine_restart(void)
+{
+	register u32 resetbits = PERF_SOFT_RST_SOFT_CHIP_RST;
+	(void)readl(BASE_DEVCPU_GCB + PERF_SOFT_RST);
+
+	/* Make sure VCore is NOT protected from reset */
+	clrbits_le32(BASE_CFG + ICPU_RESET, ICPU_RESET_CORE_RST_PROTECT);
+
+	/* Change to SPI bitbang for SPI reset workaround... */
+	writel(ICPU_SW_MODE_SW_SPI_CS_OE(1) | ICPU_SW_MODE_SW_SPI_CS(1) |
+	       ICPU_SW_MODE_SW_PIN_CTRL_MODE, BASE_CFG + ICPU_SW_MODE);
+
+	/* Do the global reset */
+	writel(resetbits, BASE_DEVCPU_GCB + PERF_SOFT_RST);
+
+	while (1)
+		; /* NOP */
+}

+ 13 - 1
arch/mips/mach-mt7620/cpu.c

@@ -89,9 +89,21 @@ void watchdog_reset(void)
 		wdt_reset(watchdog_dev);
 	}
 }
+#endif
 
 int arch_misc_init(void)
 {
+	/*
+	 * It has been noticed, that sometimes the d-cache is not in a
+	 * "clean-state" when U-Boot is running on MT7688. This was
+	 * detected when using the ethernet driver (which uses d-cache)
+	 * and a TFTP command does not complete. Flushing the complete
+	 * d-cache (again?) here seems to fix this issue.
+	 */
+	flush_dcache_range(gd->bd->bi_memstart,
+			   gd->bd->bi_memstart + gd->ram_size - 1);
+
+#ifdef CONFIG_WATCHDOG
 	/* Init watchdog */
 	if (uclass_get_device_by_seq(UCLASS_WDT, 0, &watchdog_dev)) {
 		debug("Watchdog: Not found by seq!\n");
@@ -103,7 +115,7 @@ int arch_misc_init(void)
 
 	wdt_start(watchdog_dev, 60000, 0);	/* 60 seconds */
 	printf("Watchdog: Started\n");
+#endif
 
 	return 0;
 }
-#endif

+ 15 - 0
board/imgtec/ci20/Kconfig

@@ -0,0 +1,15 @@
+if TARGET_JZ4780_CI20
+
+config SYS_BOARD
+	default "ci20"
+
+config SYS_VENDOR
+	default "imgtec"
+
+config SYS_CONFIG_NAME
+	default "ci20"
+
+config SYS_TEXT_BASE
+	default 0x80000000
+
+endif

+ 6 - 0
board/imgtec/ci20/MAINTAINERS

@@ -0,0 +1,6 @@
+Creator CI20 BOARD
+M:      Ezequiel Garcia <ezequiel@collabora.com>
+S:      Maintained
+F:      board/imgtec/ci20/
+F:      include/configs/ci20.h
+F:      configs/ci20_mmc_defconfig

+ 3 - 0
board/imgtec/ci20/Makefile

@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y := ci20.o

+ 10 - 0
board/imgtec/ci20/README

@@ -0,0 +1,10 @@
+CI20 U-Boot
+
+Installation to an SD card:
+  Repartition your card with an MBR such that the first partition starts at an
+  offset of no less than 270KB. Then install U-Boot SPL & the full U-Boot image
+  to the card like so:
+
+    dd if=spl/u-boot-spl.bin of=/dev/sdX obs=512 seek=1
+    dd if=u-boot-dtb.img of=/dev/sdX obs=1K seek=14
+    sync

+ 362 - 0
board/imgtec/ci20/ci20.c

@@ -0,0 +1,362 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * CI20 setup code
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ */
+
+#include <common.h>
+#include <environment.h>
+#include <net.h>
+#include <netdev.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <mach/jz4780.h>
+#include <mach/jz4780_dram.h>
+#include <mach/jz4780_gpio.h>
+
+struct ci20_otp {
+	u32	serial_number;
+	u32	date;
+	u8	manufacturer[2];
+	u8	mac[6];
+} __packed;
+
+static void ci20_mux_mmc(void)
+{
+	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+
+	/* setup MSC1 pins */
+	writel(0x30f00000, gpio_regs + GPIO_PXINTC(4));
+	writel(0x30f00000, gpio_regs + GPIO_PXMASKC(4));
+	writel(0x30f00000, gpio_regs + GPIO_PXPAT1C(4));
+	writel(0x30f00000, gpio_regs + GPIO_PXPAT0C(4));
+	writel(0x30f00000, gpio_regs + GPIO_PXPENC(4));
+	jz4780_clk_ungate_mmc();
+}
+
+#ifndef CONFIG_SPL_BUILD
+
+static void ci20_mux_eth(void)
+{
+	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+
+#ifdef CONFIG_NAND
+	/* setup pins (some already setup for NAND) */
+	writel(0x04030000, gpio_regs + GPIO_PXINTC(0));
+	writel(0x04030000, gpio_regs + GPIO_PXMASKC(0));
+	writel(0x04030000, gpio_regs + GPIO_PXPAT1C(0));
+	writel(0x04030000, gpio_regs + GPIO_PXPAT0C(0));
+	writel(0x04030000, gpio_regs + GPIO_PXPENS(0));
+#else
+	/* setup pins (as above +NAND CS +RD/WE +SDx +SAx) */
+	writel(0x0dff00ff, gpio_regs + GPIO_PXINTC(0));
+	writel(0x0dff00ff, gpio_regs + GPIO_PXMASKC(0));
+	writel(0x0dff00ff, gpio_regs + GPIO_PXPAT1C(0));
+	writel(0x0dff00ff, gpio_regs + GPIO_PXPAT0C(0));
+	writel(0x0dff00ff, gpio_regs + GPIO_PXPENS(0));
+	writel(0x00000003, gpio_regs + GPIO_PXINTC(1));
+	writel(0x00000003, gpio_regs + GPIO_PXMASKC(1));
+	writel(0x00000003, gpio_regs + GPIO_PXPAT1C(1));
+	writel(0x00000003, gpio_regs + GPIO_PXPAT0C(1));
+	writel(0x00000003, gpio_regs + GPIO_PXPENS(1));
+#endif
+}
+
+static void ci20_mux_jtag(void)
+{
+#ifdef CONFIG_JTAG
+	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+
+	/* enable JTAG */
+	writel(3 << 30, gpio_regs + GPIO_PXINTC(0));
+	writel(3 << 30, gpio_regs + GPIO_PXMASKC(0));
+	writel(3 << 30, gpio_regs + GPIO_PXPAT1C(0));
+	writel(3 << 30, gpio_regs + GPIO_PXPAT0C(0));
+#endif
+}
+
+static void ci20_mux_nand(void)
+{
+	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+
+	/* setup pins */
+	writel(0x002c00ff, gpio_regs + GPIO_PXINTC(0));
+	writel(0x002c00ff, gpio_regs + GPIO_PXMASKC(0));
+	writel(0x002c00ff, gpio_regs + GPIO_PXPAT1C(0));
+	writel(0x002c00ff, gpio_regs + GPIO_PXPAT0C(0));
+	writel(0x002c00ff, gpio_regs + GPIO_PXPENS(0));
+	writel(0x00000003, gpio_regs + GPIO_PXINTC(1));
+	writel(0x00000003, gpio_regs + GPIO_PXMASKC(1));
+	writel(0x00000003, gpio_regs + GPIO_PXPAT1C(1));
+	writel(0x00000003, gpio_regs + GPIO_PXPAT0C(1));
+	writel(0x00000003, gpio_regs + GPIO_PXPENS(1));
+
+	/* FRB0_N */
+	jz47xx_gpio_direction_input(JZ_GPIO(0, 20));
+	writel(20, gpio_regs + GPIO_PXPENS(0));
+
+	/* disable write protect */
+	jz47xx_gpio_direction_output(JZ_GPIO(5, 22), 1);
+}
+
+static void ci20_mux_uart(void)
+{
+	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+
+	/* UART0 */
+	writel(0x9, gpio_regs + GPIO_PXINTC(5));
+	writel(0x9, gpio_regs + GPIO_PXMASKC(5));
+	writel(0x9, gpio_regs + GPIO_PXPAT1C(5));
+	writel(0x9, gpio_regs + GPIO_PXPAT0C(5));
+	writel(0x9, gpio_regs + GPIO_PXPENC(5));
+	jz4780_clk_ungate_uart(0);
+
+	/* UART 1 and 2 */
+	jz4780_clk_ungate_uart(1);
+	jz4780_clk_ungate_uart(2);
+
+#ifndef CONFIG_JTAG
+	/* UART3 */
+	writel(1 << 12, gpio_regs + GPIO_PXINTC(3));
+	writel(1 << 12, gpio_regs + GPIO_PXMASKS(3));
+	writel(1 << 12, gpio_regs + GPIO_PXPAT1S(3));
+	writel(1 << 12, gpio_regs + GPIO_PXPAT0C(3));
+	writel(3 << 30, gpio_regs + GPIO_PXINTC(0));
+	writel(3 << 30, gpio_regs + GPIO_PXMASKC(0));
+	writel(3 << 30, gpio_regs + GPIO_PXPAT1C(0));
+	writel(1 << 30, gpio_regs + GPIO_PXPAT0C(0));
+	writel(1 << 31, gpio_regs + GPIO_PXPAT0S(0));
+	jz4780_clk_ungate_uart(3);
+#endif
+
+	/* UART4 */
+	writel(0x100400, gpio_regs + GPIO_PXINTC(2));
+	writel(0x100400, gpio_regs + GPIO_PXMASKC(2));
+	writel(0x100400, gpio_regs + GPIO_PXPAT1S(2));
+	writel(0x100400, gpio_regs + GPIO_PXPAT0C(2));
+	writel(0x100400, gpio_regs + GPIO_PXPENC(2));
+	jz4780_clk_ungate_uart(4);
+}
+
+int board_early_init_f(void)
+{
+	ci20_mux_jtag();
+	ci20_mux_uart();
+
+	ci20_mux_eth();
+	ci20_mux_mmc();
+	ci20_mux_nand();
+
+	/* SYS_POWER_IND high (LED blue, VBUS off) */
+	jz47xx_gpio_direction_output(JZ_GPIO(5, 15), 0);
+
+	/* LEDs off */
+	jz47xx_gpio_direction_output(JZ_GPIO(2, 0), 0);
+	jz47xx_gpio_direction_output(JZ_GPIO(2, 1), 0);
+	jz47xx_gpio_direction_output(JZ_GPIO(2, 2), 0);
+	jz47xx_gpio_direction_output(JZ_GPIO(2, 3), 0);
+
+	return 0;
+}
+
+int misc_init_r(void)
+{
+	const u32 efuse_clk = jz4780_clk_get_efuse_clk();
+	struct ci20_otp otp;
+	char manufacturer[3];
+
+	/* Read the board OTP data */
+	jz4780_efuse_init(efuse_clk);
+	jz4780_efuse_read(0x18, 16, (u8 *)&otp);
+
+	/* Set MAC address */
+	if (!is_valid_ethaddr(otp.mac)) {
+		/* no MAC assigned, generate one from the unique chip ID */
+		jz4780_efuse_read(0x8, 4, &otp.mac[0]);
+		jz4780_efuse_read(0x12, 2, &otp.mac[4]);
+		otp.mac[0] = (otp.mac[0] | 0x02) & ~0x01;
+	}
+	eth_env_set_enetaddr("ethaddr", otp.mac);
+
+	/* Put other board information into the environment */
+	env_set_ulong("serial#", otp.serial_number);
+	env_set_ulong("board_date", otp.date);
+	manufacturer[0] = otp.manufacturer[0];
+	manufacturer[1] = otp.manufacturer[1];
+	manufacturer[2] = 0;
+	env_set("board_mfr", manufacturer);
+
+	return 0;
+}
+
+#ifdef CONFIG_DRIVER_DM9000
+int board_eth_init(bd_t *bis)
+{
+	/* Enable clock */
+	jz4780_clk_ungate_ethernet();
+
+	/* Enable power (PB25) */
+	jz47xx_gpio_direction_output(JZ_GPIO(1, 25), 1);
+
+	/* Reset (PF12) */
+	mdelay(10);
+	jz47xx_gpio_direction_output(JZ_GPIO(5, 12), 0);
+	mdelay(10);
+	jz47xx_gpio_direction_output(JZ_GPIO(5, 12), 1);
+	mdelay(10);
+
+	return dm9000_initialize(bis);
+}
+#endif /* CONFIG_DRIVER_DM9000 */
+#endif
+
+static u8 ci20_revision(void)
+{
+	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+	int val;
+
+	jz47xx_gpio_direction_input(JZ_GPIO(2, 18));
+	jz47xx_gpio_direction_input(JZ_GPIO(2, 19));
+
+	/* Enable pullups */
+	writel(BIT(18) | BIT(19), gpio_regs + GPIO_PXPENC(2));
+
+	/* Read PC18/19 for version */
+	val = (!!jz47xx_gpio_get_value(JZ_GPIO(2, 18))) |
+	     ((!!jz47xx_gpio_get_value(JZ_GPIO(2, 19))) << 1);
+
+	if (val == 3)	/* Rev 1 boards had no pulldowns - giving 3 */
+		return 1;
+	if (val == 1)	/* Rev 2 boards pulldown port C bit 18 giving 1 */
+		return 2;
+
+	return 0;
+}
+
+int dram_init(void)
+{
+	gd->ram_size = sdram_size(0) + sdram_size(1);
+	return 0;
+}
+
+/* U-Boot common routines */
+int checkboard(void)
+{
+	printf("Board: Creator CI20 (rev.%d)\n", ci20_revision());
+	return 0;
+}
+
+#ifdef CONFIG_SPL_BUILD
+
+#if defined(CONFIG_SPL_MMC_SUPPORT)
+int board_mmc_init(bd_t *bd)
+{
+	ci20_mux_mmc();
+	return jz_mmc_init((void __iomem *)MSC0_BASE);
+}
+#endif
+
+static const struct jz4780_ddr_config K4B2G0846Q_48_config = {
+	.timing = {
+		(4 << DDRC_TIMING1_TRTP_BIT) | (13 << DDRC_TIMING1_TWTR_BIT) |
+		(6 << DDRC_TIMING1_TWR_BIT) | (5 << DDRC_TIMING1_TWL_BIT),
+
+		(4 << DDRC_TIMING2_TCCD_BIT) | (15 << DDRC_TIMING2_TRAS_BIT) |
+		(6 << DDRC_TIMING2_TRCD_BIT) | (6 << DDRC_TIMING2_TRL_BIT),
+
+		(4 << DDRC_TIMING3_ONUM) | (7 << DDRC_TIMING3_TCKSRE_BIT) |
+		(6 << DDRC_TIMING3_TRP_BIT) | (4 << DDRC_TIMING3_TRRD_BIT) |
+		(21 << DDRC_TIMING3_TRC_BIT),
+
+		(31 << DDRC_TIMING4_TRFC_BIT) | (1 << DDRC_TIMING4_TRWCOV_BIT) |
+		(4 << DDRC_TIMING4_TCKE_BIT) | (9 << DDRC_TIMING4_TMINSR_BIT) |
+		(8 << DDRC_TIMING4_TXP_BIT) | (3 << DDRC_TIMING4_TMRD_BIT),
+
+		(8 << DDRC_TIMING5_TRTW_BIT) | (4 << DDRC_TIMING5_TRDLAT_BIT) |
+		(4 << DDRC_TIMING5_TWDLAT_BIT),
+
+		(25 << DDRC_TIMING6_TXSRD_BIT) | (12 << DDRC_TIMING6_TFAW_BIT) |
+		(2 << DDRC_TIMING6_TCFGW_BIT) | (2 << DDRC_TIMING6_TCFGR_BIT),
+	},
+
+	/* PHY */
+	/* Mode Register 0 */
+	.mr0 = 0x420,
+#ifdef SDRAM_DISABLE_DLL
+	.mr1 = (DDR3_MR1_DIC_7 | DDR3_MR1_RTT_DIS | DDR3_MR1_DLL_DISABLE),
+#else
+	.mr1 = (DDR3_MR1_DIC_7 | DDR3_MR1_RTT_DIS),
+#endif
+
+	.ptr0 = 0x002000d4,
+	.ptr1 = 0x02230d40,
+	.ptr2 = 0x04013880,
+
+	.dtpr0 = 0x2a8f6690,
+	.dtpr1 = 0x00400860,
+	.dtpr2 = 0x10042a00,
+
+	.pullup = 0x0b,
+	.pulldn = 0x0b,
+};
+
+static const struct jz4780_ddr_config H5TQ2G83CFR_48_config = {
+	.timing = {
+		(4 << DDRC_TIMING1_TRTP_BIT) | (13 << DDRC_TIMING1_TWTR_BIT) |
+		(6 << DDRC_TIMING1_TWR_BIT) | (5 << DDRC_TIMING1_TWL_BIT),
+
+		(4 << DDRC_TIMING2_TCCD_BIT) | (16 << DDRC_TIMING2_TRAS_BIT) |
+		(6 << DDRC_TIMING2_TRCD_BIT) | (6 << DDRC_TIMING2_TRL_BIT),
+
+		(4 << DDRC_TIMING3_ONUM) | (7 << DDRC_TIMING3_TCKSRE_BIT) |
+		(6 << DDRC_TIMING3_TRP_BIT) | (4 << DDRC_TIMING3_TRRD_BIT) |
+		(22 << DDRC_TIMING3_TRC_BIT),
+
+		(42 << DDRC_TIMING4_TRFC_BIT) | (1 << DDRC_TIMING4_TRWCOV_BIT) |
+		(4 << DDRC_TIMING4_TCKE_BIT) | (7 << DDRC_TIMING4_TMINSR_BIT) |
+		(3 << DDRC_TIMING4_TXP_BIT) | (3 << DDRC_TIMING4_TMRD_BIT),
+
+		(8 << DDRC_TIMING5_TRTW_BIT) | (4 << DDRC_TIMING5_TRDLAT_BIT) |
+		(4 << DDRC_TIMING5_TWDLAT_BIT),
+
+		(25 << DDRC_TIMING6_TXSRD_BIT) | (20 << DDRC_TIMING6_TFAW_BIT) |
+		(2 << DDRC_TIMING6_TCFGW_BIT) | (2 << DDRC_TIMING6_TCFGR_BIT),
+	},
+
+	/* PHY */
+	/* Mode Register 0 */
+	.mr0 = 0x420,
+#ifdef SDRAM_DISABLE_DLL
+	.mr1 = (DDR3_MR1_DIC_7 | DDR3_MR1_RTT_DIS | DDR3_MR1_DLL_DISABLE),
+#else
+	.mr1 = (DDR3_MR1_DIC_7 | DDR3_MR1_RTT_DIS),
+#endif
+
+	.ptr0 = 0x002000d4,
+	.ptr1 = 0x02d30d40,
+	.ptr2 = 0x04013880,
+
+	.dtpr0 = 0x2c906690,
+	.dtpr1 = 0x005608a0,
+	.dtpr2 = 0x10042a00,
+
+	.pullup = 0x0e,
+	.pulldn = 0x0e,
+};
+
+#if (CONFIG_SYS_MHZ != 1200)
+#error No DDR configuration for CPU speed
+#endif
+
+const struct jz4780_ddr_config *jz4780_get_ddr_config(void)
+{
+	const int board_revision = ci20_revision();
+
+	if (board_revision == 2)
+		return &K4B2G0846Q_48_config;
+	else /* Fall back to H5TQ2G83CFR RAM */
+		return &H5TQ2G83CFR_48_config;
+}
+#endif

+ 14 - 0
board/mscc/luton/Kconfig

@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+if SOC_LUTON
+
+config SYS_VENDOR
+	default "mscc"
+
+config SYS_BOARD
+	default "luton"
+
+config SYS_CONFIG_NAME
+	default "luton"
+
+endif

+ 3 - 0
board/mscc/luton/Makefile

@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+obj-$(CONFIG_SOC_LUTON)	:= luton.o

+ 28 - 0
board/mscc/luton/luton.c

@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+#define MSCC_GPIO_ALT0		0x88
+#define MSCC_GPIO_ALT1		0x8C
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void board_debug_uart_init(void)
+{
+	/* too early for the pinctrl driver, so configure the UART pins here */
+	setbits_le32(BASE_DEVCPU_GCB + MSCC_GPIO_ALT0, BIT(30) | BIT(31));
+}
+
+int board_early_init_r(void)
+{
+	/* Prepare SPI controller to be used in master mode */
+	writel(0, BASE_CFG + ICPU_SW_MODE);
+
+	/* Address of boot parameters */
+	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE;
+	return 0;
+}

+ 14 - 0
board/mscc/ocelot/Kconfig

@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+config SYS_VENDOR
+	default "mscc"
+
+if SOC_OCELOT
+
+config SYS_BOARD
+	default "ocelot"
+
+config SYS_CONFIG_NAME
+	default "ocelot"
+
+endif

+ 4 - 0
board/mscc/ocelot/Makefile

@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+obj-$(CONFIG_SOC_OCELOT)	:= ocelot.o
+

+ 58 - 0
board/mscc/ocelot/ocelot.c

@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/types.h>
+#include <environment.h>
+#include <spi.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define MSCC_GPIO_ALT0		0x54
+#define MSCC_GPIO_ALT1		0x58
+
+void external_cs_manage(struct udevice *dev, bool enable)
+{
+	u32 cs = spi_chip_select(dev);
+	/* IF_SI0_OWNER, select the owner of the SI interface
+	 * Encoding: 0: SI Slave
+	 *           1: SI Boot Master
+	 *           2: SI Master Controller
+	 */
+	if (!enable) {
+		writel(ICPU_SW_MODE_SW_PIN_CTRL_MODE |
+		       ICPU_SW_MODE_SW_SPI_CS(BIT(cs)), BASE_CFG + ICPU_SW_MODE);
+		clrsetbits_le32(BASE_CFG + ICPU_GENERAL_CTRL,
+				ICPU_GENERAL_CTRL_IF_SI_OWNER_M,
+				ICPU_GENERAL_CTRL_IF_SI_OWNER(2));
+	} else {
+		writel(0, BASE_CFG + ICPU_SW_MODE);
+		clrsetbits_le32(BASE_CFG + ICPU_GENERAL_CTRL,
+				ICPU_GENERAL_CTRL_IF_SI_OWNER_M,
+				ICPU_GENERAL_CTRL_IF_SI_OWNER(1));
+	}
+}
+
+void board_debug_uart_init(void)
+{
+	/* too early for the pinctrl driver, so configure the UART pins here */
+	setbits_le32(BASE_DEVCPU_GCB + MSCC_GPIO_ALT0, BIT(6) | BIT(7));
+	clrbits_le32(BASE_DEVCPU_GCB + MSCC_GPIO_ALT1, BIT(6) | BIT(7));
+}
+
+int board_early_init_r(void)
+{
+	/* Prepare SPI controller to be used in master mode */
+	writel(0, BASE_CFG + ICPU_SW_MODE);
+	clrsetbits_le32(BASE_CFG + ICPU_GENERAL_CTRL,
+			ICPU_GENERAL_CTRL_IF_SI_OWNER_M,
+			ICPU_GENERAL_CTRL_IF_SI_OWNER(2));
+
+	/* Address of boot parameters */
+	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE;
+	return 0;
+}

+ 48 - 0
configs/ci20_mmc_defconfig

@@ -0,0 +1,48 @@
+CONFIG_MIPS=y
+CONFIG_SPL_LDSCRIPT="arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds"
+CONFIG_SYS_TEXT_BASE=0x80010000
+CONFIG_SPL_GPIO_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_SPL_MMC_SUPPORT=y
+CONFIG_SPL=y
+CONFIG_ARCH_JZ47XX=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_FIT=y
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttyS4,115200 rw rootwait root=/dev/mmcblk0p1"
+CONFIG_USE_BOOTCOMMAND=y
+CONFIG_BOOTCOMMAND="ext4load mmc 0:1 0x88000000 /boot/uImage; bootm 0x88000000"
+CONFIG_MISC_INIT_R=y
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_BOARD_EARLY_INIT_F=y
+# CONFIG_SPL_BANNER_PRINT is not set
+# CONFIG_TPL_BANNER_PRINT is not set
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_DM=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_MMC=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_FAT=y
+# CONFIG_SPL_DOS_PARTITION is not set
+CONFIG_DEFAULT_DEVICE_TREE="ci20"
+CONFIG_ENV_IS_IN_MMC=y
+# CONFIG_DM_WARN is not set
+# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_JZ4780_EFUSE=y
+CONFIG_MMC=y
+CONFIG_MMC_BROKEN_CD=y
+CONFIG_DM_MMC=y
+# CONFIG_MMC_HW_PARTITIONING is not set
+CONFIG_MMC_IO_VOLTAGE=y
+CONFIG_MMC_UHS_SUPPORT=y
+CONFIG_MMC_HS400_SUPPORT=y
+# CONFIG_MMC_VERBOSE is not set
+CONFIG_SPL_MMC_TINY=y
+CONFIG_JZ47XX_MMC=y
+CONFIG_DM_SERIAL=y
+CONFIG_SYS_NS16550=y
+CONFIG_USE_TINY_PRINTF=y
+CONFIG_SPL_TINY_MEMSET=y
+CONFIG_LZO=y

+ 6 - 1
configs/comtrend_ar5315u_ram_defconfig

@@ -28,11 +28,14 @@ CONFIG_CMD_MEMINFO=y
 CONFIG_CMD_SF=y
 CONFIG_CMD_SPI=y
 CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
 # CONFIG_CMD_MISC is not set
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="comtrend,ar-5315u"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
 CONFIG_DM_GPIO=y
 CONFIG_LED=y
 CONFIG_LED_BCM6328=y
@@ -41,6 +44,8 @@ CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SPI_FLASH_MTD=y
+CONFIG_DM_ETH=y
+CONFIG_BCM6368_ETH=y
 CONFIG_PHY=y
 CONFIG_BCM6318_USBH_PHY=y
 CONFIG_BCM6328_POWER_DOMAIN=y

+ 6 - 1
configs/comtrend_ar5387un_ram_defconfig

@@ -28,11 +28,14 @@ CONFIG_CMD_MEMINFO=y
 CONFIG_CMD_SF=y
 CONFIG_CMD_SPI=y
 CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
 # CONFIG_CMD_MISC is not set
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="comtrend,ar-5387un"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
 CONFIG_DM_GPIO=y
 CONFIG_LED=y
 CONFIG_LED_BCM6328=y
@@ -41,6 +44,8 @@ CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_MTD=y
+CONFIG_DM_ETH=y
+CONFIG_BCM6368_ETH=y
 CONFIG_PHY=y
 CONFIG_BCM6368_USBH_PHY=y
 CONFIG_POWER_DOMAIN=y

+ 7 - 1
configs/comtrend_ct5361_ram_defconfig

@@ -25,11 +25,14 @@ CONFIG_CMD_LICENSE=y
 CONFIG_CMD_MEMINFO=y
 # CONFIG_CMD_LOADS is not set
 CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
 # CONFIG_CMD_MISC is not set
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="comtrend,ct-5361"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
 CONFIG_DM_GPIO=y
 CONFIG_BCM6345_GPIO=y
 CONFIG_LED=y
@@ -40,6 +43,9 @@ CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_CFI_FLASH=y
 CONFIG_SYS_FLASH_PROTECTION=y
 CONFIG_SYS_FLASH_CFI=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_BCM6348_ETH=y
 CONFIG_PHY=y
 CONFIG_BCM6348_USBH_PHY=y
 CONFIG_DM_RESET=y

+ 6 - 1
configs/comtrend_vr3032u_ram_defconfig

@@ -26,15 +26,20 @@ CONFIG_CMD_MEMINFO=y
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_LOADS is not set
 CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
 # CONFIG_CMD_MISC is not set
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="comtrend,vr-3032u"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
 CONFIG_DM_GPIO=y
 CONFIG_LED=y
 CONFIG_LED_BCM6328=y
 CONFIG_LED_BLINK=y
+CONFIG_DM_ETH=y
+CONFIG_BCM6368_ETH=y
 CONFIG_PHY=y
 CONFIG_BCM6368_USBH_PHY=y
 CONFIG_POWER_DOMAIN=y

+ 7 - 1
configs/comtrend_wap5813n_ram_defconfig

@@ -25,11 +25,14 @@ CONFIG_CMD_LICENSE=y
 CONFIG_CMD_MEMINFO=y
 # CONFIG_CMD_LOADS is not set
 CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
 # CONFIG_CMD_MISC is not set
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="comtrend,wap-5813n"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
 CONFIG_DM_GPIO=y
 CONFIG_BCM6345_GPIO=y
 CONFIG_LED=y
@@ -40,6 +43,9 @@ CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_CFI_FLASH=y
 CONFIG_SYS_FLASH_PROTECTION=y
 CONFIG_SYS_FLASH_CFI=y
+CONFIG_DM_ETH=y
+CONFIG_PHY_GIGE=y
+CONFIG_BCM6368_ETH=y
 CONFIG_PHY=y
 CONFIG_BCM6368_USBH_PHY=y
 CONFIG_DM_RESET=y

+ 0 - 1
configs/gardena-smart-gateway-mt7688-ram_defconfig

@@ -36,7 +36,6 @@ CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="spi-nand0=gd5f,nor0=spi0.0"
 CONFIG_MTDPARTS_DEFAULT="spi0.0:640k(uboot),64k(uboot_env0),64k(uboot_env1),64k(factory),-(unused);gd5f:-(nand)"
 CONFIG_CMD_UBI=y
-CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="gardena-smart-gateway-mt7688"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_NET_RANDOM_ETHADDR=y

+ 0 - 1
configs/gardena-smart-gateway-mt7688_defconfig

@@ -39,7 +39,6 @@ CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="spi-nand0=gd5f,nor0=spi0.0"
 CONFIG_MTDPARTS_DEFAULT="spi0.0:640k(uboot),64k(uboot_env0),64k(uboot_env1),64k(factory),-(unused);gd5f:-(nand)"
 CONFIG_CMD_UBI=y
-CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="gardena-smart-gateway-mt7688"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_NET_RANDOM_ETHADDR=y

+ 7 - 1
configs/huawei_hg556a_ram_defconfig

@@ -25,11 +25,14 @@ CONFIG_CMD_LICENSE=y
 CONFIG_CMD_MEMINFO=y
 # CONFIG_CMD_LOADS is not set
 CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
 # CONFIG_CMD_MISC is not set
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="huawei,hg556a"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
 CONFIG_DM_GPIO=y
 CONFIG_BCM6345_GPIO=y
 CONFIG_LED=y
@@ -40,6 +43,9 @@ CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_CFI_FLASH=y
 CONFIG_SYS_FLASH_PROTECTION=y
 CONFIG_SYS_FLASH_CFI=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_BCM6348_ETH=y
 CONFIG_PHY=y
 CONFIG_BCM6358_USBH_PHY=y
 CONFIG_DM_RESET=y

+ 0 - 1
configs/linkit-smart-7688-ram_defconfig

@@ -26,7 +26,6 @@ CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
 CONFIG_CMD_TIME=y
-CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="linkit-smart-7688"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_NET_RANDOM_ETHADDR=y

+ 0 - 1
configs/linkit-smart-7688_defconfig

@@ -30,7 +30,6 @@ CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
 CONFIG_CMD_TIME=y
-CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="linkit-smart-7688"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_NET_RANDOM_ETHADDR=y

+ 64 - 0
configs/mscc_luton_defconfig

@@ -0,0 +1,64 @@
+CONFIG_MIPS=y
+CONFIG_SYS_TEXT_BASE=0x40000000
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_DEBUG_UART_BOARD_INIT=y
+CONFIG_DEBUG_UART_BASE=0x70100000
+CONFIG_DEBUG_UART_CLOCK=208333333
+CONFIG_ARCH_MSCC=y
+CONFIG_TARGET_LUTON_PCB091=y
+CONFIG_DDRTYPE_MT47H128M8HQ=y
+CONFIG_SYS_LITTLE_ENDIAN=y
+CONFIG_MIPS_BOOT_FDT=y
+CONFIG_DEBUG_UART=y
+CONFIG_FIT=y
+CONFIG_BOOTDELAY=3
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttyS0,115200"
+CONFIG_LOGLEVEL=7
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_SYS_PROMPT="pcb091 # "
+# CONFIG_CMD_BDI is not set
+# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_CRC32 is not set
+CONFIG_CMD_MD5SUM=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_MEMTEST=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_DHCP=y
+# CONFIG_NET_TFTP_VARS is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_PING=y
+CONFIG_CMD_MTDPARTS=y
+CONFIG_MTDIDS_DEFAULT="nor0=spi_flash"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=spi_flash:512k(UBoot),256k(Env),256k(conf),6m@1m(linux)"
+# CONFIG_ISO_PARTITION is not set
+CONFIG_DEFAULT_DEVICE_TREE="luton_pcb091"
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_CLK=y
+CONFIG_DM_GPIO=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_DM_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_DM_SERIAL=y
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_SOFT_SPI=y
+CONFIG_LZMA=y

+ 67 - 0
configs/mscc_ocelot_defconfig

@@ -0,0 +1,67 @@
+CONFIG_MIPS=y
+CONFIG_SYS_TEXT_BASE=0x40000000
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_DEBUG_UART_BOARD_INIT=y
+CONFIG_DEBUG_UART_BASE=0x70100000
+CONFIG_DEBUG_UART_CLOCK=250000000
+CONFIG_ARCH_MSCC=y
+CONFIG_TARGET_OCELOT_PCB123=y
+CONFIG_SYS_LITTLE_ENDIAN=y
+CONFIG_DEBUG_UART=y
+CONFIG_FIT=y
+CONFIG_BOOTDELAY=3
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttyS0,115200"
+CONFIG_LOGLEVEL=7
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_SYS_PROMPT="pcb123 # "
+# CONFIG_CMD_BDI is not set
+# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_CRC32 is not set
+CONFIG_CMD_MD5SUM=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_MEMTEST=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_DHCP=y
+# CONFIG_NET_TFTP_VARS is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_PING=y
+CONFIG_CMD_MTDPARTS=y
+CONFIG_MTDIDS_DEFAULT="nor0=spi_flash"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=spi_flash:512k(UBoot),256k(Env),256k(conf),15m(linux),15m(linux.bk)"
+CONFIG_CMD_UBI=y
+# CONFIG_CMD_UBIFS is not set
+# CONFIG_ISO_PARTITION is not set
+CONFIG_DEFAULT_DEVICE_TREE="ocelot_pcb123"
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_CLK=y
+CONFIG_DM_GPIO=y
+CONFIG_MTD=y
+CONFIG_MTD_SPI_NAND=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_DM_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_DM_SERIAL=y
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_DESIGNWARE_SPI=y
+CONFIG_LZMA=y

+ 60 - 0
configs/mscc_ocelot_pcb120_defconfig

@@ -0,0 +1,60 @@
+CONFIG_MIPS=y
+CONFIG_SYS_TEXT_BASE=0x40000000
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_ARCH_MSCC=y
+CONFIG_SYS_LITTLE_ENDIAN=y
+CONFIG_FIT=y
+CONFIG_BOOTDELAY=3
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttyS0,115200"
+CONFIG_LOGLEVEL=7
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_SYS_PROMPT="pcb120 # "
+# CONFIG_CMD_BDI is not set
+# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_CRC32 is not set
+CONFIG_CMD_MD5SUM=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_MEMTEST=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_DHCP=y
+# CONFIG_NET_TFTP_VARS is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_PING=y
+CONFIG_CMD_MTDPARTS=y
+CONFIG_MTDIDS_DEFAULT="nor0=spi_flash"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=spi_flash:512k(UBoot),256k(Env),256k(conf),15m(linux),15m(linux.bk)"
+CONFIG_CMD_UBI=y
+# CONFIG_CMD_UBIFS is not set
+# CONFIG_ISO_PARTITION is not set
+CONFIG_DEFAULT_DEVICE_TREE="ocelot_pcb120"
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_CLK=y
+CONFIG_DM_GPIO=y
+CONFIG_MTD=y
+CONFIG_MTD_SPI_NAND=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_DM_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_DM_SERIAL=y
+CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_DESIGNWARE_SPI=y
+CONFIG_LZMA=y

+ 7 - 1
configs/netgear_dgnd3700v2_ram_defconfig

@@ -27,17 +27,23 @@ CONFIG_CMD_MEMINFO=y
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_LOADS is not set
 CONFIG_CMD_USB=y
-# CONFIG_CMD_NET is not set
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
 # CONFIG_CMD_MISC is not set
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="netgear,dgnd3700v2"
+CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
 CONFIG_DM_GPIO=y
 CONFIG_BCM6345_GPIO=y
 CONFIG_LED=y
 CONFIG_LED_BCM6328=y
 CONFIG_LED_BLINK=y
 CONFIG_LED_GPIO=y
+CONFIG_DM_ETH=y
+CONFIG_PHY_GIGE=y
+CONFIG_BCM6368_ETH=y
 CONFIG_PHY=y
 CONFIG_BCM6368_USBH_PHY=y
 CONFIG_POWER_DOMAIN=y

+ 7 - 1
configs/sagem_f@st1704_ram_defconfig

@@ -27,11 +27,14 @@ CONFIG_CMD_MEMINFO=y
 # CONFIG_CMD_LOADS is not set
 CONFIG_CMD_SF=y
 CONFIG_CMD_SPI=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
 # CONFIG_CMD_MISC is not set
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="sagem,f@st1704"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
 CONFIG_DM_GPIO=y
 CONFIG_BCM6345_GPIO=y
 CONFIG_LED=y
@@ -40,6 +43,9 @@ CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SPI_FLASH_MTD=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_BCM6348_ETH=y
 CONFIG_DM_RESET=y
 CONFIG_RESET_BCM6345=y
 # CONFIG_SPL_SERIAL_PRESENT is not set

+ 7 - 1
configs/sfr_nb4-ser_ram_defconfig

@@ -26,11 +26,14 @@ CONFIG_CMD_LICENSE=y
 CONFIG_CMD_MEMINFO=y
 # CONFIG_CMD_LOADS is not set
 CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
 # CONFIG_CMD_MISC is not set
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="sfr,nb4-ser"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
 CONFIG_DM_GPIO=y
 CONFIG_BCM6345_GPIO=y
 CONFIG_LED=y
@@ -42,6 +45,9 @@ CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_CFI_FLASH=y
 CONFIG_SYS_FLASH_PROTECTION=y
 CONFIG_SYS_FLASH_CFI=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_BCM6348_ETH=y
 CONFIG_PHY=y
 CONFIG_BCM6358_USBH_PHY=y
 CONFIG_DM_RESET=y

+ 9 - 0
drivers/dma/Kconfig

@@ -26,6 +26,15 @@ config SANDBOX_DMA
 	  Enable support for a test DMA uclass implementation. It stimulates
 	  DMA transfer by simple copying data between channels.
 
+config BCM6348_IUDMA
+	bool "BCM6348 IUDMA driver"
+	depends on ARCH_BMIPS
+	select DMA_CHANNELS
+	help
+	  Enable the BCM6348 IUDMA driver.
+	  This driver support data transfer from devices to
+	  memory and from memory to devices.
+
 config TI_EDMA3
 	bool "TI EDMA3 driver"
 	help

+ 1 - 0
drivers/dma/Makefile

@@ -7,6 +7,7 @@ obj-$(CONFIG_DMA) += dma-uclass.o
 
 obj-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o
 obj-$(CONFIG_APBH_DMA) += apbh_dma.o
+obj-$(CONFIG_BCM6348_IUDMA) += bcm6348-iudma.o
 obj-$(CONFIG_FSL_DMA) += fsl_dma.o
 obj-$(CONFIG_SANDBOX_DMA) += sandbox-dma-test.o
 obj-$(CONFIG_TI_KSNAV) += keystone_nav.o keystone_nav_cfg.o

+ 642 - 0
drivers/dma/bcm6348-iudma.c

@@ -0,0 +1,642 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/dma/bcm63xx-iudma.c:
+ *	Copyright (C) 2015 Simon Arlott <simon@fire.lp0.eu>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c:
+ *	Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ *
+ * Derived from bcm963xx_4.12L.06B_consumer/shared/opensource/include/bcm963xx/63268_map_part.h:
+ *	Copyright (C) 2000-2010 Broadcom Corporation
+ *
+ * Derived from bcm963xx_4.12L.06B_consumer/bcmdrivers/opensource/net/enet/impl4/bcmenet.c:
+ *	Copyright (C) 2010 Broadcom Corporation
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dma-uclass.h>
+#include <memalign.h>
+#include <reset.h>
+#include <asm/io.h>
+
+#define DMA_RX_DESC	6
+#define DMA_TX_DESC	1
+
+/* DMA Channels */
+#define DMA_CHAN_FLOWC(x)		((x) >> 1)
+#define DMA_CHAN_MAX			16
+#define DMA_CHAN_SIZE			0x10
+#define DMA_CHAN_TOUT			500
+
+/* DMA Global Configuration register */
+#define DMA_CFG_REG			0x00
+#define  DMA_CFG_ENABLE_SHIFT		0
+#define  DMA_CFG_ENABLE_MASK		(1 << DMA_CFG_ENABLE_SHIFT)
+#define  DMA_CFG_FLOWC_ENABLE(x)	BIT(DMA_CHAN_FLOWC(x) + 1)
+#define  DMA_CFG_NCHANS_SHIFT		24
+#define  DMA_CFG_NCHANS_MASK		(0xf << DMA_CFG_NCHANS_SHIFT)
+
+/* DMA Global Flow Control registers */
+#define DMA_FLOWC_THR_LO_REG(x)		(0x04 + DMA_CHAN_FLOWC(x) * 0x0c)
+#define DMA_FLOWC_THR_HI_REG(x)		(0x08 + DMA_CHAN_FLOWC(x) * 0x0c)
+#define DMA_FLOWC_ALLOC_REG(x)		(0x0c + DMA_CHAN_FLOWC(x) * 0x0c)
+#define  DMA_FLOWC_ALLOC_FORCE_SHIFT	31
+#define  DMA_FLOWC_ALLOC_FORCE_MASK	(1 << DMA_FLOWC_ALLOC_FORCE_SHIFT)
+
+/* DMA Global Reset register */
+#define DMA_RST_REG			0x34
+#define  DMA_RST_CHAN_SHIFT		0
+#define  DMA_RST_CHAN_MASK(x)		(1 << x)
+
+/* DMA Channel Configuration register */
+#define DMAC_CFG_REG(x)			(DMA_CHAN_SIZE * (x) + 0x00)
+#define  DMAC_CFG_ENABLE_SHIFT		0
+#define  DMAC_CFG_ENABLE_MASK		(1 << DMAC_CFG_ENABLE_SHIFT)
+#define  DMAC_CFG_PKT_HALT_SHIFT	1
+#define  DMAC_CFG_PKT_HALT_MASK		(1 << DMAC_CFG_PKT_HALT_SHIFT)
+#define  DMAC_CFG_BRST_HALT_SHIFT	2
+#define  DMAC_CFG_BRST_HALT_MASK	(1 << DMAC_CFG_BRST_HALT_SHIFT)
+
+/* DMA Channel Max Burst Length register */
+#define DMAC_BURST_REG(x)		(DMA_CHAN_SIZE * (x) + 0x0c)
+
+/* DMA SRAM Descriptor Ring Start register */
+#define DMAS_RSTART_REG(x)		(DMA_CHAN_SIZE * (x) + 0x00)
+
+/* DMA SRAM State/Bytes done/ring offset register */
+#define DMAS_STATE_DATA_REG(x)		(DMA_CHAN_SIZE * (x) + 0x04)
+
+/* DMA SRAM Buffer Descriptor status and length register */
+#define DMAS_DESC_LEN_STATUS_REG(x)	(DMA_CHAN_SIZE * (x) + 0x08)
+
+/* DMA SRAM Buffer Descriptor status and length register */
+#define DMAS_DESC_BASE_BUFPTR_REG(x)	(DMA_CHAN_SIZE * (x) + 0x0c)
+
+/* DMA Descriptor Status */
+#define DMAD_ST_CRC_SHIFT		8
+#define DMAD_ST_CRC_MASK		(1 << DMAD_ST_CRC_SHIFT)
+#define DMAD_ST_WRAP_SHIFT		12
+#define DMAD_ST_WRAP_MASK		(1 << DMAD_ST_WRAP_SHIFT)
+#define DMAD_ST_SOP_SHIFT		13
+#define DMAD_ST_SOP_MASK		(1 << DMAD_ST_SOP_SHIFT)
+#define DMAD_ST_EOP_SHIFT		14
+#define DMAD_ST_EOP_MASK		(1 << DMAD_ST_EOP_SHIFT)
+#define DMAD_ST_OWN_SHIFT		15
+#define DMAD_ST_OWN_MASK		(1 << DMAD_ST_OWN_SHIFT)
+
+#define DMAD6348_ST_OV_ERR_SHIFT	0
+#define DMAD6348_ST_OV_ERR_MASK		(1 << DMAD6348_ST_OV_ERR_SHIFT)
+#define DMAD6348_ST_CRC_ERR_SHIFT	1
+#define DMAD6348_ST_CRC_ERR_MASK	(1 << DMAD6348_ST_CRC_ERR_SHIFT)
+#define DMAD6348_ST_RX_ERR_SHIFT	2
+#define DMAD6348_ST_RX_ERR_MASK		(1 << DMAD6348_ST_RX_ERR_SHIFT)
+#define DMAD6348_ST_OS_ERR_SHIFT	4
+#define DMAD6348_ST_OS_ERR_MASK		(1 << DMAD6348_ST_OS_ERR_SHIFT)
+#define DMAD6348_ST_UN_ERR_SHIFT	9
+#define DMAD6348_ST_UN_ERR_MASK		(1 << DMAD6348_ST_UN_ERR_SHIFT)
+
+struct bcm6348_dma_desc {
+	uint16_t length;
+	uint16_t status;
+	uint32_t address;
+};
+
+struct bcm6348_chan_priv {
+	void __iomem *dma_ring;
+	uint8_t dma_ring_size;
+	uint8_t desc_id;
+	uint8_t desc_cnt;
+	bool *busy_desc;
+	bool running;
+};
+
+struct bcm6348_iudma_hw {
+	uint16_t err_mask;
+};
+
+struct bcm6348_iudma_priv {
+	const struct bcm6348_iudma_hw *hw;
+	void __iomem *base;
+	void __iomem *chan;
+	void __iomem *sram;
+	struct bcm6348_chan_priv **ch_priv;
+	uint8_t n_channels;
+};
+
+static inline bool bcm6348_iudma_chan_is_rx(uint8_t ch)
+{
+	return !(ch & 1);
+}
+
+static inline void bcm6348_iudma_fdc(void *ptr, ulong size)
+{
+	ulong start = (ulong) ptr;
+
+	flush_dcache_range(start, start + size);
+}
+
+static inline void bcm6348_iudma_idc(void *ptr, ulong size)
+{
+	ulong start = (ulong) ptr;
+
+	invalidate_dcache_range(start, start + size);
+}
+
+static void bcm6348_iudma_chan_stop(struct bcm6348_iudma_priv *priv,
+				    uint8_t ch)
+{
+	unsigned int timeout = DMA_CHAN_TOUT;
+
+	do {
+		uint32_t cfg, halt;
+
+		if (timeout > DMA_CHAN_TOUT / 2)
+			halt = DMAC_CFG_PKT_HALT_MASK;
+		else
+			halt = DMAC_CFG_BRST_HALT_MASK;
+
+		/* try to stop dma channel */
+		writel_be(halt, priv->chan + DMAC_CFG_REG(ch));
+		mb();
+
+		/* check if channel was stopped */
+		cfg = readl_be(priv->chan + DMAC_CFG_REG(ch));
+		if (!(cfg & DMAC_CFG_ENABLE_MASK))
+			break;
+
+		udelay(1);
+	} while (--timeout);
+
+	if (!timeout)
+		pr_err("unable to stop channel %u\n", ch);
+
+	/* reset dma channel */
+	setbits_be32(priv->base + DMA_RST_REG, DMA_RST_CHAN_MASK(ch));
+	mb();
+	clrbits_be32(priv->base + DMA_RST_REG, DMA_RST_CHAN_MASK(ch));
+}
+
+static int bcm6348_iudma_disable(struct dma *dma)
+{
+	struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+	struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
+
+	/* stop dma channel */
+	bcm6348_iudma_chan_stop(priv, dma->id);
+
+	/* dma flow control */
+	if (bcm6348_iudma_chan_is_rx(dma->id))
+		writel_be(DMA_FLOWC_ALLOC_FORCE_MASK,
+			  DMA_FLOWC_ALLOC_REG(dma->id));
+
+	/* init channel config */
+	ch_priv->running = false;
+	ch_priv->desc_id = 0;
+	if (bcm6348_iudma_chan_is_rx(dma->id))
+		ch_priv->desc_cnt = 0;
+	else
+		ch_priv->desc_cnt = ch_priv->dma_ring_size;
+
+	return 0;
+}
+
+static int bcm6348_iudma_enable(struct dma *dma)
+{
+	const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+	struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
+	struct bcm6348_dma_desc *dma_desc = ch_priv->dma_ring;
+	uint8_t i;
+
+	/* dma ring init */
+	for (i = 0; i < ch_priv->desc_cnt; i++) {
+		if (bcm6348_iudma_chan_is_rx(dma->id)) {
+			ch_priv->busy_desc[i] = false;
+			dma_desc->status |= DMAD_ST_OWN_MASK;
+		} else {
+			dma_desc->status = 0;
+			dma_desc->length = 0;
+			dma_desc->address = 0;
+		}
+
+		if (i == ch_priv->desc_cnt - 1)
+			dma_desc->status |= DMAD_ST_WRAP_MASK;
+
+		dma_desc++;
+	}
+
+	/* init to first descriptor */
+	ch_priv->desc_id = 0;
+
+	/* force cache writeback */
+	bcm6348_iudma_fdc(ch_priv->dma_ring,
+			  sizeof(*dma_desc) * ch_priv->desc_cnt);
+
+	/* clear sram */
+	writel_be(0, priv->sram + DMAS_STATE_DATA_REG(dma->id));
+	writel_be(0, priv->sram + DMAS_DESC_LEN_STATUS_REG(dma->id));
+	writel_be(0, priv->sram + DMAS_DESC_BASE_BUFPTR_REG(dma->id));
+
+	/* set dma ring start */
+	writel_be(virt_to_phys(ch_priv->dma_ring),
+		  priv->sram + DMAS_RSTART_REG(dma->id));
+
+	/* set flow control */
+	if (bcm6348_iudma_chan_is_rx(dma->id)) {
+		u32 val;
+
+		setbits_be32(priv->base + DMA_CFG_REG,
+			     DMA_CFG_FLOWC_ENABLE(dma->id));
+
+		val = ch_priv->desc_cnt / 3;
+		writel_be(val, priv->base + DMA_FLOWC_THR_LO_REG(dma->id));
+
+		val = (ch_priv->desc_cnt * 2) / 3;
+		writel_be(val, priv->base + DMA_FLOWC_THR_HI_REG(dma->id));
+
+		writel_be(0, priv->base + DMA_FLOWC_ALLOC_REG(dma->id));
+	}
+
+	/* set dma max burst */
+	writel_be(ch_priv->desc_cnt,
+		  priv->chan + DMAC_BURST_REG(dma->id));
+
+	/* kick rx dma channel */
+	if (bcm6348_iudma_chan_is_rx(dma->id))
+		setbits_be32(priv->chan + DMAC_CFG_REG(dma->id),
+			     DMAC_CFG_ENABLE_MASK);
+
+	/* channel is now enabled */
+	ch_priv->running = true;
+
+	return 0;
+}
+
+static int bcm6348_iudma_request(struct dma *dma)
+{
+	const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+	struct bcm6348_chan_priv *ch_priv;
+
+	/* check if channel is valid */
+	if (dma->id >= priv->n_channels)
+		return -ENODEV;
+
+	/* alloc channel private data */
+	priv->ch_priv[dma->id] = calloc(1, sizeof(struct bcm6348_chan_priv));
+	if (!priv->ch_priv[dma->id])
+		return -ENOMEM;
+	ch_priv = priv->ch_priv[dma->id];
+
+	/* alloc dma ring */
+	if (bcm6348_iudma_chan_is_rx(dma->id))
+		ch_priv->dma_ring_size = DMA_RX_DESC;
+	else
+		ch_priv->dma_ring_size = DMA_TX_DESC;
+
+	ch_priv->dma_ring =
+		malloc_cache_aligned(sizeof(struct bcm6348_dma_desc) *
+				     ch_priv->dma_ring_size);
+	if (!ch_priv->dma_ring)
+		return -ENOMEM;
+
+	/* init channel config */
+	ch_priv->running = false;
+	ch_priv->desc_id = 0;
+	if (bcm6348_iudma_chan_is_rx(dma->id)) {
+		ch_priv->desc_cnt = 0;
+		ch_priv->busy_desc = calloc(ch_priv->desc_cnt, sizeof(bool));
+	} else {
+		ch_priv->desc_cnt = ch_priv->dma_ring_size;
+		ch_priv->busy_desc = NULL;
+	}
+
+	return 0;
+}
+
+static int bcm6348_iudma_receive(struct dma *dma, void **dst, void *metadata)
+{
+	const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+	const struct bcm6348_iudma_hw *hw = priv->hw;
+	struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
+	struct bcm6348_dma_desc *dma_desc = dma_desc = ch_priv->dma_ring;
+	int ret;
+
+	/* get dma ring descriptor address */
+	dma_desc += ch_priv->desc_id;
+
+	/* invalidate cache data */
+	bcm6348_iudma_idc(dma_desc, sizeof(*dma_desc));
+
+	/* check dma own */
+	if (dma_desc->status & DMAD_ST_OWN_MASK)
+		return -EAGAIN;
+
+	/* check pkt */
+	if (!(dma_desc->status & DMAD_ST_EOP_MASK) ||
+	    !(dma_desc->status & DMAD_ST_SOP_MASK) ||
+	    (dma_desc->status & hw->err_mask)) {
+		pr_err("invalid pkt received (ch=%ld desc=%u) (st=%04x)\n",
+		       dma->id, ch_priv->desc_id, dma_desc->status);
+		ret = -EAGAIN;
+	} else {
+		/* set dma buffer address */
+		*dst = phys_to_virt(dma_desc->address);
+
+		/* invalidate cache data */
+		bcm6348_iudma_idc(*dst, dma_desc->length);
+
+		/* return packet length */
+		ret = dma_desc->length;
+	}
+
+	/* busy dma descriptor */
+	ch_priv->busy_desc[ch_priv->desc_id] = true;
+
+	/* increment dma descriptor */
+	ch_priv->desc_id = (ch_priv->desc_id + 1) % ch_priv->desc_cnt;
+
+	return ret;
+}
+
+static int bcm6348_iudma_send(struct dma *dma, void *src, size_t len,
+			      void *metadata)
+{
+	const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+	struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
+	struct bcm6348_dma_desc *dma_desc;
+	uint16_t status;
+
+	/* flush cache */
+	bcm6348_iudma_fdc(src, len);
+
+	/* get dma ring descriptor address */
+	dma_desc = ch_priv->dma_ring;
+	dma_desc += ch_priv->desc_id;
+
+	/* config dma descriptor */
+	status = (DMAD_ST_OWN_MASK |
+		  DMAD_ST_EOP_MASK |
+		  DMAD_ST_CRC_MASK |
+		  DMAD_ST_SOP_MASK);
+	if (ch_priv->desc_id == ch_priv->desc_cnt - 1)
+		status |= DMAD_ST_WRAP_MASK;
+
+	/* set dma descriptor */
+	dma_desc->address = virt_to_phys(src);
+	dma_desc->length = len;
+	dma_desc->status = status;
+
+	/* flush cache */
+	bcm6348_iudma_fdc(dma_desc, sizeof(*dma_desc));
+
+	/* kick tx dma channel */
+	setbits_be32(priv->chan + DMAC_CFG_REG(dma->id), DMAC_CFG_ENABLE_MASK);
+
+	/* poll dma status */
+	do {
+		/* invalidate cache */
+		bcm6348_iudma_idc(dma_desc, sizeof(*dma_desc));
+
+		if (!(dma_desc->status & DMAD_ST_OWN_MASK))
+			break;
+	} while(1);
+
+	/* increment dma descriptor */
+	ch_priv->desc_id = (ch_priv->desc_id + 1) % ch_priv->desc_cnt;
+
+	return 0;
+}
+
+static int bcm6348_iudma_free_rcv_buf(struct dma *dma, void *dst, size_t size)
+{
+	const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+	struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
+	struct bcm6348_dma_desc *dma_desc = ch_priv->dma_ring;
+	uint16_t status;
+	uint8_t i;
+	u32 cfg;
+
+	/* get dirty dma descriptor */
+	for (i = 0; i < ch_priv->desc_cnt; i++) {
+		if (phys_to_virt(dma_desc->address) == dst)
+			break;
+
+		dma_desc++;
+	}
+
+	/* dma descriptor not found */
+	if (i == ch_priv->desc_cnt) {
+		pr_err("dirty dma descriptor not found\n");
+		return -ENOENT;
+	}
+
+	/* invalidate cache */
+	bcm6348_iudma_idc(ch_priv->dma_ring,
+			  sizeof(*dma_desc) * ch_priv->desc_cnt);
+
+	/* free dma descriptor */
+	ch_priv->busy_desc[i] = false;
+
+	status = DMAD_ST_OWN_MASK;
+	if (i == ch_priv->desc_cnt - 1)
+		status |= DMAD_ST_WRAP_MASK;
+
+	dma_desc->status |= status;
+	dma_desc->length = PKTSIZE_ALIGN;
+
+	/* tell dma we allocated one buffer */
+	writel_be(1, DMA_FLOWC_ALLOC_REG(dma->id));
+
+	/* flush cache */
+	bcm6348_iudma_fdc(ch_priv->dma_ring,
+			  sizeof(*dma_desc) * ch_priv->desc_cnt);
+
+	/* kick rx dma channel if disabled */
+	cfg = readl_be(priv->chan + DMAC_CFG_REG(dma->id));
+	if (!(cfg & DMAC_CFG_ENABLE_MASK))
+		setbits_be32(priv->chan + DMAC_CFG_REG(dma->id),
+			     DMAC_CFG_ENABLE_MASK);
+
+	return 0;
+}
+
+static int bcm6348_iudma_add_rcv_buf(struct dma *dma, void *dst, size_t size)
+{
+	const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+	struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
+	struct bcm6348_dma_desc *dma_desc = ch_priv->dma_ring;
+
+	/* no more dma descriptors available */
+	if (ch_priv->desc_cnt == ch_priv->dma_ring_size) {
+		pr_err("max number of buffers reached\n");
+		return -EINVAL;
+	}
+
+	/* get next dma descriptor */
+	dma_desc += ch_priv->desc_cnt;
+
+	/* init dma descriptor */
+	dma_desc->address = virt_to_phys(dst);
+	dma_desc->length = size;
+	dma_desc->status = 0;
+
+	/* flush cache */
+	bcm6348_iudma_fdc(dma_desc, sizeof(*dma_desc));
+
+	/* increment dma descriptors */
+	ch_priv->desc_cnt++;
+
+	return 0;
+}
+
+static int bcm6348_iudma_prepare_rcv_buf(struct dma *dma, void *dst,
+					 size_t size)
+{
+	const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+	struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
+
+	/* only add new rx buffers if channel isn't running */
+	if (ch_priv->running)
+		return bcm6348_iudma_free_rcv_buf(dma, dst, size);
+	else
+		return bcm6348_iudma_add_rcv_buf(dma, dst, size);
+}
+
+static const struct dma_ops bcm6348_iudma_ops = {
+	.disable = bcm6348_iudma_disable,
+	.enable = bcm6348_iudma_enable,
+	.prepare_rcv_buf = bcm6348_iudma_prepare_rcv_buf,
+	.request = bcm6348_iudma_request,
+	.receive = bcm6348_iudma_receive,
+	.send = bcm6348_iudma_send,
+};
+
+static const struct bcm6348_iudma_hw bcm6348_hw = {
+	.err_mask = (DMAD6348_ST_OV_ERR_MASK |
+		     DMAD6348_ST_CRC_ERR_MASK |
+		     DMAD6348_ST_RX_ERR_MASK |
+		     DMAD6348_ST_OS_ERR_MASK |
+		     DMAD6348_ST_UN_ERR_MASK),
+};
+
+static const struct bcm6348_iudma_hw bcm6368_hw = {
+	.err_mask = 0,
+};
+
+static const struct udevice_id bcm6348_iudma_ids[] = {
+	{
+		.compatible = "brcm,bcm6348-iudma",
+		.data = (ulong)&bcm6348_hw,
+	}, {
+		.compatible = "brcm,bcm6368-iudma",
+		.data = (ulong)&bcm6368_hw,
+	}, { /* sentinel */ }
+};
+
+static int bcm6348_iudma_probe(struct udevice *dev)
+{
+	struct dma_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+	struct bcm6348_iudma_priv *priv = dev_get_priv(dev);
+	const struct bcm6348_iudma_hw *hw =
+		(const struct bcm6348_iudma_hw *)dev_get_driver_data(dev);
+	uint8_t ch;
+	int i;
+
+	uc_priv->supported = (DMA_SUPPORTS_DEV_TO_MEM |
+			      DMA_SUPPORTS_MEM_TO_DEV);
+	priv->hw = hw;
+
+	/* dma global base address */
+	priv->base = dev_remap_addr_name(dev, "dma");
+	if (!priv->base)
+		return -EINVAL;
+
+	/* dma channels base address */
+	priv->chan = dev_remap_addr_name(dev, "dma-channels");
+	if (!priv->chan)
+		return -EINVAL;
+
+	/* dma sram base address */
+	priv->sram = dev_remap_addr_name(dev, "dma-sram");
+	if (!priv->sram)
+		return -EINVAL;
+
+	/* get number of channels */
+	priv->n_channels = dev_read_u32_default(dev, "dma-channels", 8);
+	if (priv->n_channels > DMA_CHAN_MAX)
+		return -EINVAL;
+
+	/* try to enable clocks */
+	for (i = 0; ; i++) {
+		struct clk clk;
+		int ret;
+
+		ret = clk_get_by_index(dev, i, &clk);
+		if (ret < 0)
+			break;
+
+		ret = clk_enable(&clk);
+		if (ret < 0) {
+			pr_err("error enabling clock %d\n", i);
+			return ret;
+		}
+
+		ret = clk_free(&clk);
+		if (ret < 0) {
+			pr_err("error freeing clock %d\n", i);
+			return ret;
+		}
+	}
+
+	/* try to perform resets */
+	for (i = 0; ; i++) {
+		struct reset_ctl reset;
+		int ret;
+
+		ret = reset_get_by_index(dev, i, &reset);
+		if (ret < 0)
+			break;
+
+		ret = reset_deassert(&reset);
+		if (ret < 0) {
+			pr_err("error deasserting reset %d\n", i);
+			return ret;
+		}
+
+		ret = reset_free(&reset);
+		if (ret < 0) {
+			pr_err("error freeing reset %d\n", i);
+			return ret;
+		}
+	}
+
+	/* disable dma controller */
+	clrbits_be32(priv->base + DMA_CFG_REG, DMA_CFG_ENABLE_MASK);
+
+	/* alloc channel private data pointers */
+	priv->ch_priv = calloc(priv->n_channels,
+			       sizeof(struct bcm6348_chan_priv*));
+	if (!priv->ch_priv)
+		return -ENOMEM;
+
+	/* stop dma channels */
+	for (ch = 0; ch < priv->n_channels; ch++)
+		bcm6348_iudma_chan_stop(priv, ch);
+
+	/* enable dma controller */
+	setbits_be32(priv->base + DMA_CFG_REG, DMA_CFG_ENABLE_MASK);
+
+	return 0;
+}
+
+U_BOOT_DRIVER(bcm6348_iudma) = {
+	.name = "bcm6348_iudma",
+	.id = UCLASS_DMA,
+	.of_match = bcm6348_iudma_ids,
+	.ops = &bcm6348_iudma_ops,
+	.priv_auto_alloc_size = sizeof(struct bcm6348_iudma_priv),
+	.probe = bcm6348_iudma_probe,
+};

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels