Merge git://git.denx.de/u-boot-arc
diff --git a/arch/Kconfig b/arch/Kconfig
index ca617e7..2ca5305 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -14,6 +14,7 @@
 	select HAVE_PRIVATE_LIBGCC
 	select HAVE_GENERIC_BOARD
 	select SYS_GENERIC_BOARD
+	select SUPPORT_OF_CONTROL
 
 config ARM
 	bool "ARM architecture"
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 24f5c02..c044ad4 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -123,7 +123,7 @@
 	int "Cache Line Length (as power of 2)"
 	range 5 7
 	default "6"
-	depends on !SYS_DCACHE_OFF || !SYS_DCACHE_OFF
+	depends on !SYS_DCACHE_OFF || !SYS_ICACHE_OFF
 	help
 	  Starting with ARC700 4.9, Cache line length is configurable,
 	  This option specifies "N", with Line-len = 2 power N
@@ -133,6 +133,14 @@
 choice
 	prompt "Target select"
 
+config TARGET_DUMMY
+	bool "Dummy target"
+	help
+	  Please select one of real target boards below!
+	  This target is only meant to force "makedefconfig" to put
+	  TARGET_xxx in defconfig even this is the first target from the list
+	  below.
+
 config TARGET_TB100
 	bool "Support tb100"
 
diff --git a/arch/arc/cpu/arcv1/Makefile b/arch/arc/cpu/arcv1/Makefile
index 3704ebe..6d17ab2 100644
--- a/arch/arc/cpu/arcv1/Makefile
+++ b/arch/arc/cpu/arcv1/Makefile
@@ -4,4 +4,4 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
-obj-y += start.o
+obj-y += ivt.o
diff --git a/arch/arc/cpu/arcv1/ivt.S b/arch/arc/cpu/arcv1/ivt.S
new file mode 100644
index 0000000..7df47a2
--- /dev/null
+++ b/arch/arc/cpu/arcv1/ivt.S
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+.section .ivt, "ax",@progbits
+.align 4
+_ivt:
+	/* Critical system events */
+	j	_start			/* 0 - 0x000 */
+	j	memory_error		/* 1 - 0x008 */
+	j	instruction_error	/* 2 - 0x010 */
+
+	/* Device interrupts */
+.rept	29
+	j	interrupt_handler	/* 3:31 - 0x018:0xF8 */
+.endr
+	/* Exceptions */
+	j	EV_MachineCheck		/* 0x100, Fatal Machine check  (0x20) */
+	j	EV_TLBMissI		/* 0x108, Intruction TLB miss  (0x21) */
+	j	EV_TLBMissD		/* 0x110, Data TLB miss        (0x22) */
+	j	EV_TLBProtV		/* 0x118, Protection Violation (0x23)
+							or Misaligned Access  */
+	j	EV_PrivilegeV		/* 0x120, Privilege Violation  (0x24) */
+	j	EV_Trap			/* 0x128, Trap exception       (0x25) */
+	j	EV_Extension		/* 0x130, Extn Intruction Excp (0x26) */
diff --git a/arch/arc/cpu/arcv1/start.S b/arch/arc/cpu/arcv1/start.S
deleted file mode 100644
index 01cfba4..0000000
--- a/arch/arc/cpu/arcv1/start.S
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved.
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#include <asm-offsets.h>
-#include <config.h>
-#include <asm/arcregs.h>
-
-/*
- * Note on the LD/ST addressing modes with address register write-back
- *
- * LD.a same as LD.aw
- *
- * LD.a    reg1, [reg2, x]  => Pre Incr
- *      Eff Addr for load = [reg2 + x]
- *
- * LD.ab   reg1, [reg2, x]  => Post Incr
- *      Eff Addr for load = [reg2]
- */
-
-.macro PUSH reg
-	st.a	\reg, [%sp, -4]
-.endm
-
-.macro PUSHAX aux
-	lr	%r9, [\aux]
-	PUSH	%r9
-.endm
-
-.macro  SAVE_R1_TO_R24
-	PUSH	%r1
-	PUSH	%r2
-	PUSH	%r3
-	PUSH	%r4
-	PUSH	%r5
-	PUSH	%r6
-	PUSH	%r7
-	PUSH	%r8
-	PUSH	%r9
-	PUSH	%r10
-	PUSH	%r11
-	PUSH	%r12
-	PUSH	%r13
-	PUSH	%r14
-	PUSH	%r15
-	PUSH	%r16
-	PUSH	%r17
-	PUSH	%r18
-	PUSH	%r19
-	PUSH	%r20
-	PUSH	%r21
-	PUSH	%r22
-	PUSH	%r23
-	PUSH	%r24
-.endm
-
-.macro SAVE_ALL_SYS
-	/* saving %r0 to reg->r0 in advance since we read %ecr into it */
-	st	%r0, [%sp, -8]
-	lr	%r0, [%ecr]	/* all stack addressing is manual so far */
-	st	%r0, [%sp]
-	st	%sp, [%sp, -4]
-	/* now move %sp to reg->r0 position so we can do "push" automatically */
-	sub	%sp, %sp, 8
-
-	SAVE_R1_TO_R24
-	PUSH	%r25
-	PUSH	%gp
-	PUSH	%fp
-	PUSH	%blink
-	PUSHAX	%eret
-	PUSHAX	%erstatus
-	PUSH	%lp_count
-	PUSHAX	%lp_end
-	PUSHAX	%lp_start
-	PUSHAX	%erbta
-.endm
-
-.macro SAVE_EXCEPTION_SOURCE
-#ifdef CONFIG_MMU
-	/* If MMU exists exception faulting address is loaded in EFA reg */
-	lr	%r0, [%efa]
-#else
-	/* Otherwise in ERET (exception return) reg */
-	lr	%r0, [%eret]
-#endif
-.endm
-
-.section .ivt, "ax",@progbits
-.align 4
-_ivt:
-	/* Critical system events */
-	j	_start			/* 0 - 0x000 */
-	j	memory_error		/* 1 - 0x008 */
-	j	instruction_error	/* 2 - 0x010 */
-
-	/* Device interrupts */
-.rept	29
-	j	interrupt_handler	/* 3:31 - 0x018:0xF8 */
-.endr
-	/* Exceptions */
-	j	EV_MachineCheck		/* 0x100, Fatal Machine check  (0x20) */
-	j	EV_TLBMissI		/* 0x108, Intruction TLB miss  (0x21) */
-	j	EV_TLBMissD		/* 0x110, Data TLB miss        (0x22) */
-	j	EV_TLBProtV		/* 0x118, Protection Violation (0x23)
-							or Misaligned Access  */
-	j	EV_PrivilegeV		/* 0x120, Privilege Violation  (0x24) */
-	j	EV_Trap			/* 0x128, Trap exception       (0x25) */
-	j	EV_Extension		/* 0x130, Extn Intruction Excp (0x26) */
-
-.text
-.globl _start
-_start:
-	/* Setup interrupt vector base that matches "__text_start" */
-	sr	__ivt_start, [ARC_AUX_INTR_VEC_BASE]
-
-	/* Setup stack pointer */
-	mov	%sp, CONFIG_SYS_INIT_SP_ADDR
-	mov	%fp, %sp
-
-	/* Clear bss */
-	mov	%r0, __bss_start
-	mov	%r1, __bss_end
-
-clear_bss:
-	st.ab	0, [%r0, 4]
-	brlt	%r0, %r1, clear_bss
-
-	/* Zero the one and only argument of "board_init_f" */
-	mov_s	%r0, 0
-	j	board_init_f
-
-memory_error:
-	SAVE_ALL_SYS
-	SAVE_EXCEPTION_SOURCE
-	mov	%r1, %sp
-	j	do_memory_error
-
-instruction_error:
-	SAVE_ALL_SYS
-	SAVE_EXCEPTION_SOURCE
-	mov	%r1, %sp
-	j	do_instruction_error
-
-interrupt_handler:
-	/* Todo - save and restore CPU context when interrupts will be in use */
-	bl	do_interrupt_handler
-	rtie
-
-EV_MachineCheck:
-	SAVE_ALL_SYS
-	SAVE_EXCEPTION_SOURCE
-	mov	%r1, %sp
-	j	do_machine_check_fault
-
-EV_TLBMissI:
-	SAVE_ALL_SYS
-	mov	%r0, %sp
-	j	do_itlb_miss
-
-EV_TLBMissD:
-	SAVE_ALL_SYS
-	mov	%r0, %sp
-	j	do_dtlb_miss
-
-EV_TLBProtV:
-	SAVE_ALL_SYS
-	SAVE_EXCEPTION_SOURCE
-	mov	%r1, %sp
-	j	do_tlb_prot_violation
-
-EV_PrivilegeV:
-	SAVE_ALL_SYS
-	mov	%r0, %sp
-	j	do_privilege_violation
-
-EV_Trap:
-	SAVE_ALL_SYS
-	mov	%r0, %sp
-	j	do_trap
-
-EV_Extension:
-	SAVE_ALL_SYS
-	mov	%r0, %sp
-	j	do_extension
-
-/*
- * void relocate_code (addr_sp, gd, addr_moni)
- *
- * This "function" does not return, instead it continues in RAM
- * after relocating the monitor code.
- *
- * r0 = start_addr_sp
- * r1 = new__gd
- * r2 = relocaddr
- */
-.align 4
-.globl	relocate_code
-relocate_code:
-	/*
-	 * r0-r12 might be clobbered by C functions
-	 * so we use r13-r16 for storage here
-	 */
-	mov	%r13, %r0		/* save addr_sp */
-	mov	%r14, %r1		/* save addr of gd */
-	mov	%r15, %r2		/* save addr of destination */
-
-	mov	%r16, %r2		/* %r9 - relocation offset */
-	sub	%r16, %r16, __image_copy_start
-
-/* Set up the stack */
-stack_setup:
-	mov	%sp, %r13
-	mov	%fp, %sp
-
-/* Check if monitor is loaded right in place for relocation */
-	mov	%r0, __image_copy_start
-	cmp	%r0, %r15		/* skip relocation if code loaded */
-	bz	do_board_init_r		/* in target location already */
-
-/* Copy data (__image_copy_start - __image_copy_end) to new location */
-	mov	%r1, %r15
-	mov	%r2, __image_copy_end
-	sub	%r2, %r2, %r0		/* r3 <- amount of bytes to copy */
-	asr	%r2, %r2, 2		/* r3 <- amount of words to copy */
-	mov	%lp_count, %r2
-	lp	copy_end
-	ld.ab	%r2,[%r0,4]
-	st.ab	%r2,[%r1,4]
-copy_end:
-
-/* Fix relocations related issues */
-	bl	do_elf_reloc_fixups
-#ifndef CONFIG_SYS_ICACHE_OFF
-	bl	invalidate_icache_all
-#endif
-#ifndef CONFIG_SYS_DCACHE_OFF
-	bl	flush_dcache_all
-#endif
-
-/* Update position of intterupt vector table */
-	lr	%r0, [ARC_AUX_INTR_VEC_BASE]	/* Read current position */
-	add	%r0, %r0, %r16			/* Update address */
-	sr	%r0, [ARC_AUX_INTR_VEC_BASE]	/* Write new position */
-
-do_board_init_r:
-/* Prepare for exection of "board_init_r" in relocated monitor */
-	mov	%r2, board_init_r	/* old address of "board_init_r()" */
-	add	%r2, %r2, %r16		/* new address of "board_init_r()" */
-	mov	%r0, %r14		/* 1-st parameter: gd_t */
-	mov	%r1, %r15		/* 2-nd parameter: dest_addr */
-	j	[%r2]
diff --git a/arch/arc/cpu/arcv2/Makefile b/arch/arc/cpu/arcv2/Makefile
index cc69e5a..e338a0a 100644
--- a/arch/arc/cpu/arcv2/Makefile
+++ b/arch/arc/cpu/arcv2/Makefile
@@ -4,4 +4,4 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
-obj-y += start.o
+obj-y += ivt.o
diff --git a/arch/arc/cpu/arcv2/ivt.S b/arch/arc/cpu/arcv2/ivt.S
new file mode 100644
index 0000000..d110b5b
--- /dev/null
+++ b/arch/arc/cpu/arcv2/ivt.S
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2013-2015 Synopsys, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+.section .ivt, "a",@progbits
+.align 4
+	/* Critical system events */
+.word	_start			/* 0 - 0x000 */
+.word	memory_error		/* 1 - 0x008 */
+.word	instruction_error	/* 2 - 0x010 */
+
+	/* Exceptions */
+.word	EV_MachineCheck		/* 0x100, Fatal Machine check  (0x20) */
+.word	EV_TLBMissI		/* 0x108, Intruction TLB miss  (0x21) */
+.word	EV_TLBMissD		/* 0x110, Data TLB miss        (0x22) */
+.word	EV_TLBProtV		/* 0x118, Protection Violation (0x23)
+							or Misaligned Access  */
+.word	EV_PrivilegeV		/* 0x120, Privilege Violation  (0x24) */
+.word	EV_Trap			/* 0x128, Trap exception       (0x25) */
+.word	EV_Extension		/* 0x130, Extn Intruction Excp (0x26) */
+
+	/* Device interrupts */
+.rept	29
+	j	interrupt_handler	/* 3:31 - 0x018:0xF8 */
+.endr
diff --git a/arch/arc/cpu/arcv2/start.S b/arch/arc/cpu/arcv2/start.S
deleted file mode 100644
index 3ce6896..0000000
--- a/arch/arc/cpu/arcv2/start.S
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (C) 2013-2015 Synopsys, Inc. All rights reserved.
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#include <asm-offsets.h>
-#include <config.h>
-#include <asm/arcregs.h>
-
-/*
- * Note on the LD/ST addressing modes with address register write-back
- *
- * LD.a same as LD.aw
- *
- * LD.a    reg1, [reg2, x]  => Pre Incr
- *      Eff Addr for load = [reg2 + x]
- *
- * LD.ab   reg1, [reg2, x]  => Post Incr
- *      Eff Addr for load = [reg2]
- */
-
-.macro PUSH reg
-	st.a	\reg, [%sp, -4]
-.endm
-
-.macro PUSHAX aux
-	lr	%r9, [\aux]
-	PUSH	%r9
-.endm
-
-.macro  SAVE_R1_TO_R24
-	PUSH	%r1
-	PUSH	%r2
-	PUSH	%r3
-	PUSH	%r4
-	PUSH	%r5
-	PUSH	%r6
-	PUSH	%r7
-	PUSH	%r8
-	PUSH	%r9
-	PUSH	%r10
-	PUSH	%r11
-	PUSH	%r12
-	PUSH	%r13
-	PUSH	%r14
-	PUSH	%r15
-	PUSH	%r16
-	PUSH	%r17
-	PUSH	%r18
-	PUSH	%r19
-	PUSH	%r20
-	PUSH	%r21
-	PUSH	%r22
-	PUSH	%r23
-	PUSH	%r24
-.endm
-
-.macro SAVE_ALL_SYS
-	/* saving %r0 to reg->r0 in advance since weread %ecr into it */
-	st	%r0, [%sp, -8]
-	lr	%r0, [%ecr]	/* all stack addressing is manual so far */
-	st	%r0, [%sp]
-	st	%sp, [%sp, -4]
-	/* now move %sp to reg->r0 position so we can do "push" automatically */
-	sub	%sp, %sp, 8
-
-	SAVE_R1_TO_R24
-	PUSH	%r25
-	PUSH	%gp
-	PUSH	%fp
-	PUSH	%blink
-	PUSHAX	%eret
-	PUSHAX	%erstatus
-	PUSH	%lp_count
-	PUSHAX	%lp_end
-	PUSHAX	%lp_start
-	PUSHAX	%erbta
-.endm
-
-.macro SAVE_EXCEPTION_SOURCE
-#ifdef CONFIG_MMU
-	/* If MMU exists exception faulting address is loaded in EFA reg */
-	lr	%r0, [%efa]
-#else
-	/* Otherwise in ERET (exception return) reg */
-	lr	%r0, [%eret]
-#endif
-.endm
-
-.section .ivt, "a",@progbits
-.align 4
-	/* Critical system events */
-.word	_start			/* 0 - 0x000 */
-.word	memory_error		/* 1 - 0x008 */
-.word	instruction_error	/* 2 - 0x010 */
-
-	/* Exceptions */
-.word	EV_MachineCheck		/* 0x100, Fatal Machine check  (0x20) */
-.word	EV_TLBMissI		/* 0x108, Intruction TLB miss  (0x21) */
-.word	EV_TLBMissD		/* 0x110, Data TLB miss        (0x22) */
-.word	EV_TLBProtV		/* 0x118, Protection Violation (0x23)
-							or Misaligned Access  */
-.word	EV_PrivilegeV		/* 0x120, Privilege Violation  (0x24) */
-.word	EV_Trap			/* 0x128, Trap exception       (0x25) */
-.word	EV_Extension		/* 0x130, Extn Intruction Excp (0x26) */
-
-	/* Device interrupts */
-.rept	29
-	j	interrupt_handler	/* 3:31 - 0x018:0xF8 */
-.endr
-
-.text
-.globl _start
-_start:
-	/* Setup interrupt vector base that matches "__text_start" */
-	sr	__ivt_start, [ARC_AUX_INTR_VEC_BASE]
-
-	/* Setup stack pointer */
-	mov	%sp, CONFIG_SYS_INIT_SP_ADDR
-	mov	%fp, %sp
-
-	/* Clear bss */
-	mov	%r0, __bss_start
-	mov	%r1, __bss_end
-
-clear_bss:
-	st.ab	0, [%r0, 4]
-	brlt	%r0, %r1, clear_bss
-
-	/* Zero the one and only argument of "board_init_f" */
-	mov_s	%r0, 0
-	j	board_init_f
-
-memory_error:
-	SAVE_ALL_SYS
-	SAVE_EXCEPTION_SOURCE
-	mov	%r1, %sp
-	j	do_memory_error
-
-instruction_error:
-	SAVE_ALL_SYS
-	SAVE_EXCEPTION_SOURCE
-	mov	%r1, %sp
-	j	do_instruction_error
-
-interrupt_handler:
-	/* Todo - save and restore CPU context when interrupts will be in use */
-	bl	do_interrupt_handler
-	rtie
-
-EV_MachineCheck:
-	SAVE_ALL_SYS
-	SAVE_EXCEPTION_SOURCE
-	mov	%r1, %sp
-	j	do_machine_check_fault
-
-EV_TLBMissI:
-	SAVE_ALL_SYS
-	mov	%r0, %sp
-	j	do_itlb_miss
-
-EV_TLBMissD:
-	SAVE_ALL_SYS
-	mov	%r0, %sp
-	j	do_dtlb_miss
-
-EV_TLBProtV:
-	SAVE_ALL_SYS
-	SAVE_EXCEPTION_SOURCE
-	mov	%r1, %sp
-	j	do_tlb_prot_violation
-
-EV_PrivilegeV:
-	SAVE_ALL_SYS
-	mov	%r0, %sp
-	j	do_privilege_violation
-
-EV_Trap:
-	SAVE_ALL_SYS
-	mov	%r0, %sp
-	j	do_trap
-
-EV_Extension:
-	SAVE_ALL_SYS
-	mov	%r0, %sp
-	j	do_extension
-
-/*
- * void relocate_code (addr_sp, gd, addr_moni)
- *
- * This "function" does not return, instead it continues in RAM
- * after relocating the monitor code.
- *
- * r0 = start_addr_sp
- * r1 = new__gd
- * r2 = relocaddr
- */
-.align 4
-.globl	relocate_code
-relocate_code:
-	/*
-	 * r0-r12 might be clobbered by C functions
-	 * so we use r13-r16 for storage here
-	 */
-	mov	%r13, %r0		/* save addr_sp */
-	mov	%r14, %r1		/* save addr of gd */
-	mov	%r15, %r2		/* save addr of destination */
-
-	mov	%r16, %r2		/* %r9 - relocation offset */
-	sub	%r16, %r16, __image_copy_start
-
-/* Set up the stack */
-stack_setup:
-	mov	%sp, %r13
-	mov	%fp, %sp
-
-/* Check if monitor is loaded right in place for relocation */
-	mov	%r0, __image_copy_start
-	cmp	%r0, %r15		/* skip relocation if code loaded */
-	bz	do_board_init_r		/* in target location already */
-
-/* Copy data (__image_copy_start - __image_copy_end) to new location */
-	mov	%r1, %r15
-	mov	%r2, __image_copy_end
-	sub	%r2, %r2, %r0		/* r3 <- amount of bytes to copy */
-	asr	%r2, %r2, 2		/* r3 <- amount of words to copy */
-	mov	%lp_count, %r2
-	lp	copy_end
-	ld.ab	%r2,[%r0,4]
-	st.ab	%r2,[%r1,4]
-copy_end:
-
-/* Fix relocations related issues */
-	bl	do_elf_reloc_fixups
-#ifndef CONFIG_SYS_ICACHE_OFF
-	bl	invalidate_icache_all
-#endif
-#ifndef CONFIG_SYS_DCACHE_OFF
-	bl	flush_dcache_all
-#endif
-
-/* Update position of intterupt vector table */
-	lr	%r0, [ARC_AUX_INTR_VEC_BASE]	/* Read current position */
-	add	%r0, %r0, %r16			/* Update address */
-	sr	%r0, [ARC_AUX_INTR_VEC_BASE]	/* Write new position */
-
-do_board_init_r:
-/* Prepare for exection of "board_init_r" in relocated monitor */
-	mov	%r2, board_init_r	/* old address of "board_init_r()" */
-	add	%r2, %r2, %r16		/* new address of "board_init_r()" */
-	mov	%r0, %r14		/* 1-st parameter: gd_t */
-	mov	%r1, %r15		/* 2-nd parameter: dest_addr */
-	j	[%r2]
diff --git a/arch/arc/dts/Makefile b/arch/arc/dts/Makefile
new file mode 100644
index 0000000..5bc6f44
--- /dev/null
+++ b/arch/arc/dts/Makefile
@@ -0,0 +1,12 @@
+dtb-$(CONFIG_TARGET_ARCANGEL4) +=  arcangel4.dtb
+dtb-$(CONFIG_TARGET_TB100) +=  abilis_tb100.dtb
+
+targets += $(dtb-y)
+
+DTC_FLAGS += -R 4 -p 0x1000
+
+PHONY += dtbs
+dtbs: $(addprefix $(obj)/, $(dtb-y))
+	@:
+
+clean-files := *.dtb
diff --git a/arch/arc/dts/abilis_tb100.dts b/arch/arc/dts/abilis_tb100.dts
new file mode 100644
index 0000000..cf395c4
--- /dev/null
+++ b/arch/arc/dts/abilis_tb100.dts
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2015 Synopsys, Inc. (www.synopsys.com)
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+/dts-v1/;
+
+#include "skeleton.dtsi"
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	aliases {
+		console = &uart0;
+	};
+
+	uart0: serial@ff100000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0xff100000 0x1000>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+	};
+};
diff --git a/arch/arc/dts/arcangel4.dts b/arch/arc/dts/arcangel4.dts
new file mode 100644
index 0000000..bfcb9d8
--- /dev/null
+++ b/arch/arc/dts/arcangel4.dts
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2015 Synopsys, Inc. (www.synopsys.com)
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+/dts-v1/;
+
+#include "skeleton.dtsi"
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	aliases {
+		console = &arcuart0;
+	};
+
+	arcuart0: serial@0xc0fc1000 {
+		compatible = "snps,arc-uart";
+		reg = <0xc0fc1000 0x100>;
+		clock-frequency = <80000000>;
+	};
+
+};
diff --git a/arch/arc/dts/skeleton.dtsi b/arch/arc/dts/skeleton.dtsi
new file mode 100644
index 0000000..b41d241
--- /dev/null
+++ b/arch/arc/dts/skeleton.dtsi
@@ -0,0 +1,13 @@
+/*
+ * Skeleton device tree; the bare minimum needed to boot; just include and
+ * add a compatible value.  The bootloader will typically populate the memory
+ * node.
+ */
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	chosen { };
+	aliases { };
+	memory { device_type = "memory"; reg = <0 0>; };
+};
diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h
index 6a36a81..0e11dcc 100644
--- a/arch/arc/include/asm/arcregs.h
+++ b/arch/arc/include/asm/arcregs.h
@@ -46,6 +46,10 @@
 #define ARC_AUX_DC_PTAG		0x5C
 #endif
 #define ARC_BCR_DC_BUILD	0x72
+#define ARC_BCR_SLC		0xce
+#define ARC_AUX_SLC_CONTROL	0x903
+#define ARC_AUX_SLC_FLUSH	0x904
+#define ARC_AUX_SLC_INVALIDATE	0x905
 
 #ifndef __ASSEMBLY__
 /* Accessors for auxiliary registers */
diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h
index 8a77cd9..0b3ebd9 100644
--- a/arch/arc/include/asm/cache.h
+++ b/arch/arc/include/asm/cache.h
@@ -27,4 +27,15 @@
 #define CONFIG_ARC_MMU_VER 4
 #endif
 
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_ISA_ARCV2
+void slc_enable(void);
+void slc_disable(void);
+void slc_flush(void);
+void slc_invalidate(void);
+#endif
+
+#endif /* __ASSEMBLY__ */
+
 #endif /* __ASM_ARC_CACHE_H */
diff --git a/arch/arc/include/asm/config.h b/arch/arc/include/asm/config.h
index 8936f5c..d2d7919 100644
--- a/arch/arc/include/asm/config.h
+++ b/arch/arc/include/asm/config.h
@@ -7,7 +7,6 @@
 #ifndef __ASM_ARC_CONFIG_H_
 #define __ASM_ARC_CONFIG_H_
 
-#define CONFIG_SYS_GENERIC_GLOBAL_DATA
 #define CONFIG_SYS_BOOT_RAMDISK_HIGH
 #define CONFIG_ARCH_EARLY_INIT_R
 
diff --git a/arch/arc/include/asm/init_helpers.h b/arch/arc/include/asm/init_helpers.h
new file mode 100644
index 0000000..7607e19
--- /dev/null
+++ b/arch/arc/include/asm/init_helpers.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (C) 2013-2015 Synopsys, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _ASM_ARC_INIT_HELPERS_H
+#define _ASM_ARC_INIT_HELPERS_H
+
+int init_cache_f_r(void);
+
+#endif	/* _ASM_ARC_INIT_HELPERS_H */
diff --git a/arch/arc/include/asm/relocate.h b/arch/arc/include/asm/relocate.h
new file mode 100644
index 0000000..4c5f923
--- /dev/null
+++ b/arch/arc/include/asm/relocate.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2013-2015 Synopsys, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _ASM_ARC_RELOCATE_H
+#define _ASM_ARC_RELOCATE_H
+
+#include <common.h>
+
+int copy_uboot_to_ram(void);
+int clear_bss(void);
+int do_elf_reloc_fixups(void);
+
+#endif	/* _ASM_ARC_RELOCATE_H */
diff --git a/arch/arc/include/asm/u-boot-arc.h b/arch/arc/include/asm/u-boot-arc.h
index 0c0e8e6..a56ccf1 100644
--- a/arch/arc/include/asm/u-boot-arc.h
+++ b/arch/arc/include/asm/u-boot-arc.h
@@ -9,4 +9,7 @@
 
 int arch_early_init_r(void);
 
+void	board_init_f_r_trampoline(ulong) __attribute__ ((noreturn));
+void	board_init_f_r(void) __attribute__ ((noreturn));
+
 #endif	/* __ASM_ARC_U_BOOT_ARC_H__ */
diff --git a/arch/arc/lib/Makefile b/arch/arc/lib/Makefile
index b8028c9..b887904 100644
--- a/arch/arc/lib/Makefile
+++ b/arch/arc/lib/Makefile
@@ -18,6 +18,9 @@
 obj-y += memset.o
 obj-y += reset.o
 obj-y += timer.o
+obj-y += start.o
+obj-y += ints_low.o
+obj-y += init_helpers.o
 
 obj-$(CONFIG_CMD_BOOTM) += bootm.o
 
diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c
index a227723..e369e5a 100644
--- a/arch/arc/lib/cache.c
+++ b/arch/arc/lib/cache.c
@@ -16,6 +16,7 @@
 #define DC_CTRL_INV_MODE_FLUSH	(1 << 6)
 #define DC_CTRL_FLUSH_STATUS	(1 << 8)
 #define CACHE_VER_NUM_MASK	0xF
+#define SLC_CTRL_SB		(1 << 2)
 
 int icache_status(void)
 {
@@ -49,10 +50,12 @@
 
 void invalidate_icache_all(void)
 {
-#ifndef CONFIG_SYS_ICACHE_OFF
+	/* If no cache in CPU exit immediately */
+	if (!(read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK))
+		return;
+
 	/* Any write to IC_IVIC register triggers invalidation of entire I$ */
 	write_aux_reg(ARC_AUX_IC_IVIC, 1);
-#endif /* CONFIG_SYS_ICACHE_OFF */
 }
 
 int dcache_status(void)
@@ -156,13 +159,60 @@
 
 void invalidate_dcache_all(void)
 {
-#ifndef CONFIG_SYS_DCACHE_OFF
+	/* If no cache in CPU exit immediately */
+	if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK))
+		return;
+
 	/* Write 1 to DC_IVDC register triggers invalidation of entire D$ */
 	write_aux_reg(ARC_AUX_DC_IVDC, 1);
-#endif /* CONFIG_SYS_DCACHE_OFF */
 }
 
 void flush_cache(unsigned long start, unsigned long size)
 {
 	flush_dcache_range(start, start + size);
 }
+
+#ifdef CONFIG_ISA_ARCV2
+void slc_enable(void)
+{
+	/* If SLC ver = 0, no SLC present in CPU */
+	if (!(read_aux_reg(ARC_BCR_SLC) & 0xff))
+		return;
+
+	write_aux_reg(ARC_AUX_SLC_CONTROL,
+		      read_aux_reg(ARC_AUX_SLC_CONTROL) & ~1);
+}
+
+void slc_disable(void)
+{
+	/* If SLC ver = 0, no SLC present in CPU */
+	if (!(read_aux_reg(ARC_BCR_SLC) & 0xff))
+		return;
+
+	write_aux_reg(ARC_AUX_SLC_CONTROL,
+		      read_aux_reg(ARC_AUX_SLC_CONTROL) | 1);
+}
+
+void slc_flush(void)
+{
+	/* If SLC ver = 0, no SLC present in CPU */
+	if (!(read_aux_reg(ARC_BCR_SLC) & 0xff))
+		return;
+
+	write_aux_reg(ARC_AUX_SLC_FLUSH, 1);
+
+	/* Wait flush end */
+	while (read_aux_reg(ARC_AUX_SLC_CONTROL) & SLC_CTRL_SB)
+		;
+}
+
+void slc_invalidate(void)
+{
+	/* If SLC ver = 0, no SLC present in CPU */
+	if (!(read_aux_reg(ARC_BCR_SLC) & 0xff))
+		return;
+
+	write_aux_reg(ARC_AUX_SLC_INVALIDATE, 1);
+}
+
+#endif /* CONFIG_ISA_ARCV2 */
diff --git a/arch/arc/lib/cpu.c b/arch/arc/lib/cpu.c
index 50634b8..3c930bc 100644
--- a/arch/arc/lib/cpu.c
+++ b/arch/arc/lib/cpu.c
@@ -12,19 +12,6 @@
 
 int arch_cpu_init(void)
 {
-#ifdef CONFIG_SYS_ICACHE_OFF
-	icache_disable();
-#else
-	icache_enable();
-	invalidate_icache_all();
-#endif
-
-	flush_dcache_all();
-#ifdef CONFIG_SYS_DCACHE_OFF
-	dcache_disable();
-#else
-	dcache_enable();
-#endif
 	timer_init();
 
 /* In simulation (ISS) "CHIPID" and "ARCNUM" are all "ff" */
diff --git a/arch/arc/lib/init_helpers.c b/arch/arc/lib/init_helpers.c
new file mode 100644
index 0000000..25690ee
--- /dev/null
+++ b/arch/arc/lib/init_helpers.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2013-2015 Synopsys, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int init_cache_f_r(void)
+{
+#ifndef CONFIG_SYS_ICACHE_OFF
+	icache_enable();
+	/* Make sure no stale entries persist from before we disabled cache */
+	invalidate_icache_all();
+#endif
+
+#ifndef CONFIG_SYS_DCACHE_OFF
+	dcache_enable();
+	/* Make sure no stale entries persist from before we disabled cache */
+	invalidate_dcache_all();
+#endif
+	return 0;
+}
diff --git a/arch/arc/lib/ints_low.S b/arch/arc/lib/ints_low.S
new file mode 100644
index 0000000..161cf37
--- /dev/null
+++ b/arch/arc/lib/ints_low.S
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2013-2015 Synopsys, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <linux/linkage.h>
+
+/*
+ * Note on the LD/ST addressing modes with address register write-back
+ *
+ * LD.a same as LD.aw
+ *
+ * LD.a    reg1, [reg2, x]  => Pre Incr
+ *      Eff Addr for load = [reg2 + x]
+ *
+ * LD.ab   reg1, [reg2, x]  => Post Incr
+ *      Eff Addr for load = [reg2]
+ */
+
+.macro PUSH reg
+	st.a	\reg, [%sp, -4]
+.endm
+
+.macro PUSHAX aux
+	lr	%r9, [\aux]
+	PUSH	%r9
+.endm
+
+.macro  SAVE_R1_TO_R24
+	PUSH	%r1
+	PUSH	%r2
+	PUSH	%r3
+	PUSH	%r4
+	PUSH	%r5
+	PUSH	%r6
+	PUSH	%r7
+	PUSH	%r8
+	PUSH	%r9
+	PUSH	%r10
+	PUSH	%r11
+	PUSH	%r12
+	PUSH	%r13
+	PUSH	%r14
+	PUSH	%r15
+	PUSH	%r16
+	PUSH	%r17
+	PUSH	%r18
+	PUSH	%r19
+	PUSH	%r20
+	PUSH	%r21
+	PUSH	%r22
+	PUSH	%r23
+	PUSH	%r24
+.endm
+
+.macro SAVE_ALL_SYS
+	/* saving %r0 to reg->r0 in advance since we read %ecr into it */
+	st	%r0, [%sp, -8]
+	lr	%r0, [%ecr]	/* all stack addressing is manual so far */
+	st	%r0, [%sp]
+	st	%sp, [%sp, -4]
+	/* now move %sp to reg->r0 position so we can do "push" automatically */
+	sub	%sp, %sp, 8
+
+	SAVE_R1_TO_R24
+	PUSH	%r25
+	PUSH	%gp
+	PUSH	%fp
+	PUSH	%blink
+	PUSHAX	%eret
+	PUSHAX	%erstatus
+	PUSH	%lp_count
+	PUSHAX	%lp_end
+	PUSHAX	%lp_start
+	PUSHAX	%erbta
+.endm
+
+.macro SAVE_EXCEPTION_SOURCE
+#ifdef CONFIG_MMU
+	/* If MMU exists exception faulting address is loaded in EFA reg */
+	lr	%r0, [%efa]
+#else
+	/* Otherwise in ERET (exception return) reg */
+	lr	%r0, [%eret]
+#endif
+.endm
+
+ENTRY(memory_error)
+	SAVE_ALL_SYS
+	SAVE_EXCEPTION_SOURCE
+	mov	%r1, %sp
+	j	do_memory_error
+ENDPROC(memory_error)
+
+ENTRY(instruction_error)
+	SAVE_ALL_SYS
+	SAVE_EXCEPTION_SOURCE
+	mov	%r1, %sp
+	j	do_instruction_error
+ENDPROC(instruction_error)
+
+ENTRY(interrupt_handler)
+	/* Todo - save and restore CPU context when interrupts will be in use */
+	bl	do_interrupt_handler
+	rtie
+ENDPROC(interrupt_handler)
+
+ENTRY(EV_MachineCheck)
+	SAVE_ALL_SYS
+	SAVE_EXCEPTION_SOURCE
+	mov	%r1, %sp
+	j	do_machine_check_fault
+ENDPROC(EV_MachineCheck)
+
+ENTRY(EV_TLBMissI)
+	SAVE_ALL_SYS
+	mov	%r0, %sp
+	j	do_itlb_miss
+ENDPROC(EV_TLBMissI)
+
+ENTRY(EV_TLBMissD)
+	SAVE_ALL_SYS
+	mov	%r0, %sp
+	j	do_dtlb_miss
+ENDPROC(EV_TLBMissD)
+
+ENTRY(EV_TLBProtV)
+	SAVE_ALL_SYS
+	SAVE_EXCEPTION_SOURCE
+	mov	%r1, %sp
+	j	do_tlb_prot_violation
+ENDPROC(EV_TLBProtV)
+
+ENTRY(EV_PrivilegeV)
+	SAVE_ALL_SYS
+	mov	%r0, %sp
+	j	do_privilege_violation
+ENDPROC(EV_PrivilegeV)
+
+ENTRY(EV_Trap)
+	SAVE_ALL_SYS
+	mov	%r0, %sp
+	j	do_trap
+ENDPROC(EV_Trap)
+
+ENTRY(EV_Extension)
+	SAVE_ALL_SYS
+	mov	%r0, %sp
+	j	do_extension
+ENDPROC(EV_Extension)
diff --git a/arch/arc/lib/relocate.c b/arch/arc/lib/relocate.c
index 7797782..5c2c2d1 100644
--- a/arch/arc/lib/relocate.c
+++ b/arch/arc/lib/relocate.c
@@ -10,6 +10,25 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+int copy_uboot_to_ram(void)
+{
+	size_t len = (size_t)&__image_copy_end - (size_t)&__image_copy_start;
+
+	memcpy((void *)gd->relocaddr, (void *)&__image_copy_start, len);
+
+	return 0;
+}
+
+int clear_bss(void)
+{
+	ulong dst_addr = (ulong)&__bss_start + gd->reloc_off;
+	size_t len = (size_t)&__bss_end - (size_t)&__bss_start;
+
+	memset((void *)dst_addr, 0x00, len);
+
+	return 0;
+}
+
 /*
  * Base functionality is taken from x86 version with added ARC-specifics
  */
diff --git a/arch/arc/lib/start.S b/arch/arc/lib/start.S
new file mode 100644
index 0000000..e1ef19c
--- /dev/null
+++ b/arch/arc/lib/start.S
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <linux/linkage.h>
+#include <asm/arcregs.h>
+
+ENTRY(_start)
+	/* Setup interrupt vector base that matches "__text_start" */
+	sr	__ivt_start, [ARC_AUX_INTR_VEC_BASE]
+
+	/* Setup stack- and frame-pointers */
+	mov	%sp, CONFIG_SYS_INIT_SP_ADDR
+	mov	%fp, %sp
+
+	/* Unconditionally disable caches */
+#ifdef CONFIG_ISA_ARCV2
+	bl	slc_flush
+	bl	slc_disable
+#endif
+	bl	flush_dcache_all
+	bl	dcache_disable
+	bl	icache_disable
+
+	/* Allocate and zero GD, update SP */
+	mov	%r0, %sp
+	bl	board_init_f_mem
+
+	/* Update stack- and frame-pointers */
+	mov	%sp, %r0
+	mov	%fp, %sp
+
+	/* Zero the one and only argument of "board_init_f" */
+	mov_s	%r0, 0
+	j	board_init_f
+ENDPROC(_start)
+
+/*
+ * void board_init_f_r_trampoline(stack-pointer address)
+ *
+ * This "function" does not return, instead it continues in RAM
+ * after relocating the monitor code.
+ *
+ * r0 = new stack-pointer
+ */
+ENTRY(board_init_f_r_trampoline)
+	/* Set up the stack- and frame-pointers */
+	mov	%sp, %r0
+	mov	%fp, %sp
+
+	/* Update position of intterupt vector table */
+	lr	%r0, [ARC_AUX_INTR_VEC_BASE]
+	ld	%r1, [%r25, GD_RELOC_OFF]
+	add	%r0, %r0, %r1
+	sr	%r0, [ARC_AUX_INTR_VEC_BASE]
+
+	/* Re-enter U-Boot by calling board_init_f_r */
+	j	board_init_f_r
+ENDPROC(board_init_f_r_trampoline)
diff --git a/board/synopsys/axs101/axs101.c b/board/synopsys/axs101/axs101.c
index d1271ff..7742049 100644
--- a/board/synopsys/axs101/axs101.c
+++ b/board/synopsys/axs101/axs101.c
@@ -27,9 +27,9 @@
 	host->ioaddr = (void *)ARC_DWMMC_BASE;
 	host->buswidth = 4;
 	host->dev_index = 0;
-	host->bus_hz = 25000000;
+	host->bus_hz = 50000000;
 
-	add_dwmci(host, 52000000, 400000);
+	add_dwmci(host, host->bus_hz, 400000);
 
 	return 0;
 }
diff --git a/common/board_f.c b/common/board_f.c
index f7ffa54..cb956b8 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -47,7 +47,7 @@
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <asm/sections.h>
-#ifdef CONFIG_X86
+#if defined(CONFIG_X86) || defined(CONFIG_ARC)
 #include <asm/init_helpers.h>
 #include <asm/relocate.h>
 #endif
@@ -761,7 +761,7 @@
 	 * similarly for all archs. When we do generic relocation, hopefully
 	 * we can make all archs enable the dcache prior to relocation.
 	 */
-#ifdef CONFIG_X86
+#if defined(CONFIG_X86) || defined(CONFIG_ARC)
 	/*
 	 * SDRAM and console are now initialised. The final stack can now
 	 * be setup in SDRAM. Code execution will continue in Flash, but
@@ -997,7 +997,7 @@
 	INIT_FUNC_WATCHDOG_RESET
 	reloc_fdt,
 	setup_reloc,
-#ifdef CONFIG_X86
+#if defined(CONFIG_X86) || defined(CONFIG_ARC)
 	copy_uboot_to_ram,
 	clear_bss,
 	do_elf_reloc_fixups,
@@ -1041,7 +1041,7 @@
 #endif
 }
 
-#ifdef CONFIG_X86
+#if defined(CONFIG_X86) || defined(CONFIG_ARC)
 /*
  * For now this code is only used on x86.
  *
diff --git a/configs/arcangel4-be_defconfig b/configs/arcangel4-be_defconfig
index 979f26e..36ea6be 100644
--- a/configs/arcangel4-be_defconfig
+++ b/configs/arcangel4-be_defconfig
@@ -1,5 +1,10 @@
 CONFIG_ARC=y
-CONFIG_TARGET_ARCANGEL4=y
-CONFIG_SYS_CLK_FREQ=70000000
 CONFIG_CPU_BIG_ENDIAN=y
+CONFIG_TARGET_ARCANGEL4=y
+CONFIG_DM=y
+CONFIG_DM_SERIAL=y
+CONFIG_DEFAULT_DEVICE_TREE="arcangel4"
 CONFIG_SYS_TEXT_BASE=0x81000000
+CONFIG_SYS_CLK_FREQ=70000000
+CONFIG_OF_CONTROL=y
+CONFIG_OF_EMBED=y
diff --git a/configs/arcangel4_defconfig b/configs/arcangel4_defconfig
index 797595f..75a91c8 100644
--- a/configs/arcangel4_defconfig
+++ b/configs/arcangel4_defconfig
@@ -1,4 +1,9 @@
 CONFIG_ARC=y
 CONFIG_TARGET_ARCANGEL4=y
-CONFIG_SYS_CLK_FREQ=70000000
+CONFIG_DM=y
+CONFIG_DM_SERIAL=y
+CONFIG_DEFAULT_DEVICE_TREE="arcangel4"
 CONFIG_SYS_TEXT_BASE=0x81000000
+CONFIG_SYS_CLK_FREQ=70000000
+CONFIG_OF_CONTROL=y
+CONFIG_OF_EMBED=y
diff --git a/configs/axs101_defconfig b/configs/axs101_defconfig
index 34ed963..e5e1d87 100644
--- a/configs/axs101_defconfig
+++ b/configs/axs101_defconfig
@@ -1,6 +1,6 @@
 CONFIG_ARC=y
-CONFIG_TARGET_AXS101=y
-CONFIG_SYS_CLK_FREQ=750000000
-CONFIG_ARC_CACHE_LINE_SHIFT=5
 CONFIG_SYS_DCACHE_OFF=y
-CONFIG_SYS_TEXT_BASE=0x81000000
\ No newline at end of file
+CONFIG_ARC_CACHE_LINE_SHIFT=5
+CONFIG_TARGET_AXS101=y
+CONFIG_SYS_TEXT_BASE=0x81000000
+CONFIG_SYS_CLK_FREQ=750000000
diff --git a/configs/axs103_defconfig b/configs/axs103_defconfig
index c63dd4a..7d662ad 100644
--- a/configs/axs103_defconfig
+++ b/configs/axs103_defconfig
@@ -1,5 +1,5 @@
-CONFIG_SYS_TEXT_BASE=0x81000000
-CONFIG_SYS_CLK_FREQ=50000000
 CONFIG_ARC=y
 CONFIG_ISA_ARCV2=y
 CONFIG_TARGET_AXS101=y
+CONFIG_SYS_TEXT_BASE=0x81000000
+CONFIG_SYS_CLK_FREQ=50000000
diff --git a/configs/tb100_defconfig b/configs/tb100_defconfig
index b0e8c9f..59f09d9 100644
--- a/configs/tb100_defconfig
+++ b/configs/tb100_defconfig
@@ -1,5 +1,10 @@
 CONFIG_ARC=y
-CONFIG_TARGET_TB100=y
-CONFIG_SYS_CLK_FREQ=500000000
 CONFIG_ARC_CACHE_LINE_SHIFT=5
+CONFIG_TARGET_TB100=y
+CONFIG_DM=y
+CONFIG_DM_SERIAL=y
+CONFIG_DEFAULT_DEVICE_TREE="abilis_tb100"
 CONFIG_SYS_TEXT_BASE=0x84000000
+CONFIG_SYS_CLK_FREQ=500000000
+CONFIG_OF_CONTROL=y
+CONFIG_OF_EMBED=y
diff --git a/drivers/serial/serial_arc.c b/drivers/serial/serial_arc.c
index 2ddbf32..54e596c 100644
--- a/drivers/serial/serial_arc.c
+++ b/drivers/serial/serial_arc.c
@@ -8,6 +8,7 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <serial.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -23,21 +24,23 @@
 	unsigned int baudh;
 };
 
+
+struct arc_serial_platdata {
+	struct arc_serial_regs *reg;
+	unsigned int uartclk;
+};
+
 /* Bit definitions of STATUS register */
 #define UART_RXEMPTY		(1 << 5)
 #define UART_OVERFLOW_ERR	(1 << 1)
 #define UART_TXEMPTY		(1 << 7)
 
-struct arc_serial_regs *regs;
-
-static void arc_serial_setbrg(void)
+static int arc_serial_setbrg(struct udevice *dev, int baudrate)
 {
-	int arc_console_baud;
+	struct arc_serial_platdata *plat = dev->platdata;
+	struct arc_serial_regs *const regs = plat->reg;
+	int arc_console_baud = gd->cpu_clk / (baudrate * 4) - 1;
 
-	if (!gd->baudrate)
-		gd->baudrate = CONFIG_BAUDRATE;
-
-	arc_console_baud = gd->cpu_clk / (gd->baudrate * 4) - 1;
 	writeb(arc_console_baud & 0xff, &regs->baudl);
 
 #ifdef CONFIG_ARC
@@ -56,34 +59,49 @@
 #else
 	writeb((arc_console_baud & 0xff00) >> 8, &regs->baudh);
 #endif
-}
 
-static int arc_serial_init(void)
-{
-	regs = (struct arc_serial_regs *)CONFIG_ARC_UART_BASE;
-	serial_setbrg();
 	return 0;
 }
 
-static void arc_serial_putc(const char c)
+static int arc_serial_putc(struct udevice *dev, const char c)
 {
+	struct arc_serial_platdata *plat = dev->platdata;
+	struct arc_serial_regs *const regs = plat->reg;
+
 	if (c == '\n')
-		arc_serial_putc('\r');
+		arc_serial_putc(dev, '\r');
 
 	while (!(readb(&regs->status) & UART_TXEMPTY))
 		;
 
 	writeb(c, &regs->data);
+
+	return 0;
 }
 
-static int arc_serial_tstc(void)
+static int arc_serial_tstc(struct arc_serial_regs *const regs)
 {
 	return !(readb(&regs->status) & UART_RXEMPTY);
 }
 
-static int arc_serial_getc(void)
+static int arc_serial_pending(struct udevice *dev, bool input)
 {
-	while (!arc_serial_tstc())
+	struct arc_serial_platdata *plat = dev->platdata;
+	struct arc_serial_regs *const regs = plat->reg;
+	uint32_t status = readb(&regs->status);
+
+	if (input)
+		return status & UART_RXEMPTY ? 0 : 1;
+	else
+		return status & UART_TXEMPTY ? 0 : 1;
+}
+
+static int arc_serial_getc(struct udevice *dev)
+{
+	struct arc_serial_platdata *plat = dev->platdata;
+	struct arc_serial_regs *const regs = plat->reg;
+
+	while (!arc_serial_tstc(regs))
 		;
 
 	/* Check for overflow errors */
@@ -93,23 +111,42 @@
 	return readb(&regs->data) & 0xFF;
 }
 
-static struct serial_device arc_serial_drv = {
-	.name	= "arc_serial",
-	.start	= arc_serial_init,
-	.stop	= NULL,
-	.setbrg	= arc_serial_setbrg,
-	.putc	= arc_serial_putc,
-	.puts	= default_serial_puts,
-	.getc	= arc_serial_getc,
-	.tstc	= arc_serial_tstc,
+static int arc_serial_probe(struct udevice *dev)
+{
+	return 0;
+}
+
+static const struct dm_serial_ops arc_serial_ops = {
+	.putc = arc_serial_putc,
+	.pending = arc_serial_pending,
+	.getc = arc_serial_getc,
+	.setbrg = arc_serial_setbrg,
 };
 
-void arc_serial_initialize(void)
+static const struct udevice_id arc_serial_ids[] = {
+	{ .compatible = "snps,arc-uart" },
+	{ }
+};
+
+static int arc_serial_ofdata_to_platdata(struct udevice *dev)
 {
-	serial_register(&arc_serial_drv);
+	struct arc_serial_platdata *plat = dev_get_platdata(dev);
+	DECLARE_GLOBAL_DATA_PTR;
+
+	plat->reg = (struct arc_serial_regs *)fdtdec_get_addr(gd->fdt_blob,
+							dev->of_offset, "reg");
+	plat->uartclk = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+				       "clock-frequency", 0);
+
+	return 0;
 }
 
-__weak struct serial_device *default_serial_console(void)
-{
-	return &arc_serial_drv;
-}
+U_BOOT_DRIVER(serial_arc) = {
+	.name	= "serial_arc",
+	.id	= UCLASS_SERIAL,
+	.of_match = arc_serial_ids,
+	.ofdata_to_platdata = arc_serial_ofdata_to_platdata,
+	.probe = arc_serial_probe,
+	.ops	= &arc_serial_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/include/configs/tb100.h b/include/configs/tb100.h
index 46df406..501449a 100644
--- a/include/configs/tb100.h
+++ b/include/configs/tb100.h
@@ -35,14 +35,10 @@
 /*
  * UART configuration
  */
-#define CONFIG_CONS_INDEX		1
+#define CONFIG_DW_SERIAL
 #define CONFIG_SYS_NS16550
 #define CONFIG_SYS_NS16550_SERIAL
-#define CONFIG_SYS_NS16550_REG_SIZE	-4
 #define CONFIG_SYS_NS16550_CLK		166666666
-#define CONFIG_SYS_NS16550_COM1		0xFF100000
-#define CONFIG_SYS_NS16550_MEM32
-
 #define CONFIG_BAUDRATE			115200
 
 /*