Merge branch 'master' of git://git.denx.de/u-boot-spi
diff --git a/Makefile b/Makefile
index 0a674bf..37cc4c3 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2015
 PATCHLEVEL = 07
 SUBLEVEL =
-EXTRAVERSION = -rc2
+EXTRAVERSION = -rc3
 NAME =
 
 # *DOCUMENTATION*
diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h
index 0e11dcc..667f218 100644
--- a/arch/arc/include/asm/arcregs.h
+++ b/arch/arc/include/asm/arcregs.h
@@ -47,9 +47,12 @@
 #endif
 #define ARC_BCR_DC_BUILD	0x72
 #define ARC_BCR_SLC		0xce
-#define ARC_AUX_SLC_CONTROL	0x903
+#define ARC_AUX_SLC_CONFIG	0x901
+#define ARC_AUX_SLC_CTRL	0x903
 #define ARC_AUX_SLC_FLUSH	0x904
 #define ARC_AUX_SLC_INVALIDATE	0x905
+#define ARC_AUX_SLC_IVDL	0x910
+#define ARC_AUX_SLC_FLDL	0x912
 
 #ifndef __ASSEMBLY__
 /* Accessors for auxiliary registers */
diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h
index 0b3ebd9..432606a 100644
--- a/arch/arc/include/asm/cache.h
+++ b/arch/arc/include/asm/cache.h
@@ -29,12 +29,7 @@
 
 #ifndef __ASSEMBLY__
 
-#ifdef CONFIG_ISA_ARCV2
-void slc_enable(void);
-void slc_disable(void);
-void slc_flush(void);
-void slc_invalidate(void);
-#endif
+void cache_init(void);
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/arc/lib/bootm.c b/arch/arc/lib/bootm.c
index d185a50..04d9d9c 100644
--- a/arch/arc/lib/bootm.c
+++ b/arch/arc/lib/bootm.c
@@ -53,6 +53,9 @@
 		hang();
 }
 
+__weak void smp_set_core_boot_addr(unsigned long addr, int corenr) {}
+__weak void smp_kick_all_cpus(void) {}
+
 /* Subcommand: GO */
 static void boot_jump_linux(bootm_headers_t *images, int flag)
 {
@@ -80,6 +83,9 @@
 		r2 = (unsigned int)getenv("bootargs");
 	}
 
+	smp_set_core_boot_addr((unsigned long)kernel_entry, -1);
+	smp_kick_all_cpus();
+
 	if (!fake)
 		kernel_entry(r0, 0, r2);
 }
diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c
index e369e5a..ed8e8e7 100644
--- a/arch/arc/lib/cache.c
+++ b/arch/arc/lib/cache.c
@@ -5,9 +5,13 @@
  */
 
 #include <config.h>
+#include <linux/compiler.h>
+#include <linux/kernel.h>
 #include <asm/arcregs.h>
 #include <asm/cache.h>
 
+#define CACHE_LINE_MASK		(~(CONFIG_SYS_CACHELINE_SIZE - 1))
+
 /* Bit values in IC_CTRL */
 #define IC_CTRL_CACHE_DISABLE	(1 << 0)
 
@@ -18,60 +22,186 @@
 #define CACHE_VER_NUM_MASK	0xF
 #define SLC_CTRL_SB		(1 << 2)
 
+#define OP_INV		0x1
+#define OP_FLUSH	0x2
+#define OP_INV_IC	0x3
+
+#ifdef CONFIG_ISA_ARCV2
+/*
+ * By default that variable will fall into .bss section.
+ * But .bss section is not relocated and so it will be initilized before
+ * relocation but will be used after being zeroed.
+ */
+int slc_line_sz __section(".data");
+int slc_exists __section(".data");
+
+static unsigned int __before_slc_op(const int op)
+{
+	unsigned int reg = reg;
+
+	if (op == OP_INV) {
+		/*
+		 * IM is set by default and implies Flush-n-inv
+		 * Clear it here for vanilla inv
+		 */
+		reg = read_aux_reg(ARC_AUX_SLC_CTRL);
+		write_aux_reg(ARC_AUX_SLC_CTRL, reg & ~DC_CTRL_INV_MODE_FLUSH);
+	}
+
+	return reg;
+}
+
+static void __after_slc_op(const int op, unsigned int reg)
+{
+	if (op & OP_FLUSH)	/* flush / flush-n-inv both wait */
+		while (read_aux_reg(ARC_AUX_SLC_CTRL) &
+		       DC_CTRL_FLUSH_STATUS)
+			;
+
+	/* Switch back to default Invalidate mode */
+	if (op == OP_INV)
+		write_aux_reg(ARC_AUX_SLC_CTRL, reg | DC_CTRL_INV_MODE_FLUSH);
+}
+
+static inline void __slc_line_loop(unsigned long paddr, unsigned long sz,
+				   const int op)
+{
+	unsigned int aux_cmd;
+	int num_lines;
+
+#define SLC_LINE_MASK	(~(slc_line_sz - 1))
+
+	aux_cmd = op & OP_INV ? ARC_AUX_SLC_IVDL : ARC_AUX_SLC_FLDL;
+
+	sz += paddr & ~SLC_LINE_MASK;
+	paddr &= SLC_LINE_MASK;
+
+	num_lines = DIV_ROUND_UP(sz, slc_line_sz);
+
+	while (num_lines-- > 0) {
+		write_aux_reg(aux_cmd, paddr);
+		paddr += slc_line_sz;
+	}
+}
+
+static inline void __slc_entire_op(const int cacheop)
+{
+	int aux;
+	unsigned int ctrl_reg = __before_slc_op(cacheop);
+
+	if (cacheop & OP_INV)	/* Inv or flush-n-inv use same cmd reg */
+		aux = ARC_AUX_SLC_INVALIDATE;
+	else
+		aux = ARC_AUX_SLC_FLUSH;
+
+	write_aux_reg(aux, 0x1);
+
+	__after_slc_op(cacheop, ctrl_reg);
+}
+
+static inline void __slc_line_op(unsigned long paddr, unsigned long sz,
+				 const int cacheop)
+{
+	unsigned int ctrl_reg = __before_slc_op(cacheop);
+	__slc_line_loop(paddr, sz, cacheop);
+	__after_slc_op(cacheop, ctrl_reg);
+}
+#else
+#define __slc_entire_op(cacheop)
+#define __slc_line_op(paddr, sz, cacheop)
+#endif
+
+static inline int icache_exists(void)
+{
+	/* Check if Instruction Cache is available */
+	if (read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK)
+		return 1;
+	else
+		return 0;
+}
+
+static inline int dcache_exists(void)
+{
+	/* Check if Data Cache is available */
+	if (read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK)
+		return 1;
+	else
+		return 0;
+}
+
+void cache_init(void)
+{
+#ifdef CONFIG_ISA_ARCV2
+	/* Check if System-Level Cache (SLC) is available */
+	if (read_aux_reg(ARC_BCR_SLC) & CACHE_VER_NUM_MASK) {
+#define LSIZE_OFFSET	4
+#define LSIZE_MASK	3
+		if (read_aux_reg(ARC_AUX_SLC_CONFIG) &
+		    (LSIZE_MASK << LSIZE_OFFSET))
+			slc_line_sz = 64;
+		else
+			slc_line_sz = 128;
+		slc_exists = 1;
+	} else {
+		slc_exists = 0;
+	}
+#endif
+}
+
 int icache_status(void)
 {
-	/* If no cache in CPU exit immediately */
-	if (!(read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK))
+	if (!icache_exists())
 		return 0;
 
-	return (read_aux_reg(ARC_AUX_IC_CTRL) & IC_CTRL_CACHE_DISABLE) !=
-	       IC_CTRL_CACHE_DISABLE;
+	if (read_aux_reg(ARC_AUX_IC_CTRL) & IC_CTRL_CACHE_DISABLE)
+		return 0;
+	else
+		return 1;
 }
 
 void icache_enable(void)
 {
-	/* If no cache in CPU exit immediately */
-	if (!(read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK))
-		return;
-
-	write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) &
-		      ~IC_CTRL_CACHE_DISABLE);
+	if (icache_exists())
+		write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) &
+			      ~IC_CTRL_CACHE_DISABLE);
 }
 
 void icache_disable(void)
 {
-	/* If no cache in CPU exit immediately */
-	if (!(read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK))
-		return;
-
-	write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) |
-		      IC_CTRL_CACHE_DISABLE);
+	if (icache_exists())
+		write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) |
+			      IC_CTRL_CACHE_DISABLE);
 }
 
+#ifndef CONFIG_SYS_DCACHE_OFF
 void invalidate_icache_all(void)
 {
-	/* 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);
+	if (icache_status()) {
+		write_aux_reg(ARC_AUX_IC_IVIC, 1);
+		read_aux_reg(ARC_AUX_IC_CTRL);	/* blocks */
+	}
 }
+#else
+void invalidate_icache_all(void)
+{
+}
+#endif
 
 int dcache_status(void)
 {
-	/* If no cache in CPU exit immediately */
-	if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK))
+	if (!dcache_exists())
 		return 0;
 
-	return (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_CACHE_DISABLE) !=
-		DC_CTRL_CACHE_DISABLE;
+	if (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_CACHE_DISABLE)
+		return 0;
+	else
+		return 1;
 }
 
 void dcache_enable(void)
 {
-	/* If no cache in CPU exit immediately */
-	if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK))
+	if (!dcache_exists())
 		return;
 
 	write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) &
@@ -80,91 +210,123 @@
 
 void dcache_disable(void)
 {
-	/* If no cache in CPU exit immediately */
-	if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK))
+	if (!dcache_exists())
 		return;
 
 	write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) |
 		      DC_CTRL_CACHE_DISABLE);
 }
 
-void flush_dcache_all(void)
-{
-	/* If no cache in CPU exit immediately */
-	if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK))
-		return;
-
-	/* Do flush of entire cache */
-	write_aux_reg(ARC_AUX_DC_FLSH, 1);
-
-	/* Wait flush end */
-	while (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS)
-		;
-}
-
 #ifndef CONFIG_SYS_DCACHE_OFF
-static void dcache_flush_line(unsigned addr)
+/*
+ * Common Helper for Line Operations on {I,D}-Cache
+ */
+static inline void __cache_line_loop(unsigned long paddr, unsigned long sz,
+				     const int cacheop)
 {
+	unsigned int aux_cmd;
 #if (CONFIG_ARC_MMU_VER == 3)
-	write_aux_reg(ARC_AUX_DC_PTAG, addr);
+	unsigned int aux_tag;
 #endif
-	write_aux_reg(ARC_AUX_DC_FLDL, addr);
+	int num_lines;
 
-	/* Wait flush end */
-	while (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS)
-		;
-
-#ifndef CONFIG_SYS_ICACHE_OFF
-	/*
-	 * Invalidate I$ for addresses range just flushed from D$.
-	 * If we try to execute data flushed above it will be valid/correct
-	 */
+	if (cacheop == OP_INV_IC) {
+		aux_cmd = ARC_AUX_IC_IVIL;
 #if (CONFIG_ARC_MMU_VER == 3)
-	write_aux_reg(ARC_AUX_IC_PTAG, addr);
+		aux_tag = ARC_AUX_IC_PTAG;
 #endif
-	write_aux_reg(ARC_AUX_IC_IVIL, addr);
-#endif /* CONFIG_SYS_ICACHE_OFF */
+	} else {
+		/* d$ cmd: INV (discard or wback-n-discard) OR FLUSH (wback) */
+		aux_cmd = cacheop & OP_INV ? ARC_AUX_DC_IVDL : ARC_AUX_DC_FLDL;
+#if (CONFIG_ARC_MMU_VER == 3)
+		aux_tag = ARC_AUX_DC_PTAG;
+#endif
+	}
+
+	sz += paddr & ~CACHE_LINE_MASK;
+	paddr &= CACHE_LINE_MASK;
+
+	num_lines = DIV_ROUND_UP(sz, CONFIG_SYS_CACHELINE_SIZE);
+
+	while (num_lines-- > 0) {
+#if (CONFIG_ARC_MMU_VER == 3)
+		write_aux_reg(aux_tag, paddr);
+#endif
+		write_aux_reg(aux_cmd, paddr);
+		paddr += CONFIG_SYS_CACHELINE_SIZE;
+	}
 }
-#endif /* CONFIG_SYS_DCACHE_OFF */
 
-void flush_dcache_range(unsigned long start, unsigned long end)
+static unsigned int __before_dc_op(const int op)
 {
-#ifndef CONFIG_SYS_DCACHE_OFF
-	unsigned int addr;
+	unsigned int reg;
 
-	start = start & (~(CONFIG_SYS_CACHELINE_SIZE - 1));
-	end = end & (~(CONFIG_SYS_CACHELINE_SIZE - 1));
+	if (op == OP_INV) {
+		/*
+		 * IM is set by default and implies Flush-n-inv
+		 * Clear it here for vanilla inv
+		 */
+		reg = read_aux_reg(ARC_AUX_DC_CTRL);
+		write_aux_reg(ARC_AUX_DC_CTRL, reg & ~DC_CTRL_INV_MODE_FLUSH);
+	}
 
-	for (addr = start; addr <= end; addr += CONFIG_SYS_CACHELINE_SIZE)
-		dcache_flush_line(addr);
-#endif /* CONFIG_SYS_DCACHE_OFF */
+	return reg;
 }
 
+static void __after_dc_op(const int op, unsigned int reg)
+{
+	if (op & OP_FLUSH)	/* flush / flush-n-inv both wait */
+		while (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS)
+			;
+
+	/* Switch back to default Invalidate mode */
+	if (op == OP_INV)
+		write_aux_reg(ARC_AUX_DC_CTRL, reg | DC_CTRL_INV_MODE_FLUSH);
+}
+
+static inline void __dc_entire_op(const int cacheop)
+{
+	int aux;
+	unsigned int ctrl_reg = __before_dc_op(cacheop);
+
+	if (cacheop & OP_INV)	/* Inv or flush-n-inv use same cmd reg */
+		aux = ARC_AUX_DC_IVDC;
+	else
+		aux = ARC_AUX_DC_FLSH;
+
+	write_aux_reg(aux, 0x1);
+
+	__after_dc_op(cacheop, ctrl_reg);
+}
+
+static inline void __dc_line_op(unsigned long paddr, unsigned long sz,
+				const int cacheop)
+{
+	unsigned int ctrl_reg = __before_dc_op(cacheop);
+	__cache_line_loop(paddr, sz, cacheop);
+	__after_dc_op(cacheop, ctrl_reg);
+}
+#else
+#define __dc_entire_op(cacheop)
+#define __dc_line_op(paddr, sz, cacheop)
+#endif /* !CONFIG_SYS_DCACHE_OFF */
+
 void invalidate_dcache_range(unsigned long start, unsigned long end)
 {
-#ifndef CONFIG_SYS_DCACHE_OFF
-	unsigned int addr;
-
-	start = start & (~(CONFIG_SYS_CACHELINE_SIZE - 1));
-	end = end & (~(CONFIG_SYS_CACHELINE_SIZE - 1));
-
-	for (addr = start; addr <= end; addr += CONFIG_SYS_CACHELINE_SIZE) {
-#if (CONFIG_ARC_MMU_VER == 3)
-		write_aux_reg(ARC_AUX_DC_PTAG, addr);
+	__dc_line_op(start, end - start, OP_INV);
+#ifdef CONFIG_ISA_ARCV2
+	if (slc_exists)
+		__slc_line_op(start, end - start, OP_INV);
 #endif
-		write_aux_reg(ARC_AUX_DC_IVDL, addr);
-	}
-#endif /* CONFIG_SYS_DCACHE_OFF */
 }
 
-void invalidate_dcache_all(void)
+void flush_dcache_range(unsigned long start, unsigned long end)
 {
-	/* 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);
+	__dc_line_op(start, end - start, OP_FLUSH);
+#ifdef CONFIG_ISA_ARCV2
+	if (slc_exists)
+		__slc_line_op(start, end - start, OP_FLUSH);
+#endif
 }
 
 void flush_cache(unsigned long start, unsigned long size)
@@ -172,47 +334,20 @@
 	flush_dcache_range(start, start + size);
 }
 
+void invalidate_dcache_all(void)
+{
+	__dc_entire_op(OP_INV);
 #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);
+	if (slc_exists)
+		__slc_entire_op(OP_INV);
+#endif
 }
 
-void slc_disable(void)
+void flush_dcache_all(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);
+	__dc_entire_op(OP_FLUSH);
+#ifdef CONFIG_ISA_ARCV2
+	if (slc_exists)
+		__slc_entire_op(OP_FLUSH);
+#endif
 }
-
-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 3c930bc..4e4dd74 100644
--- a/arch/arc/lib/cpu.c
+++ b/arch/arc/lib/cpu.c
@@ -23,6 +23,8 @@
 	gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
 	gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
 
+	cache_init();
+
 	return 0;
 }
 
diff --git a/arch/arc/lib/init_helpers.c b/arch/arc/lib/init_helpers.c
index 25690ee..dbc8d68 100644
--- a/arch/arc/lib/init_helpers.c
+++ b/arch/arc/lib/init_helpers.c
@@ -10,16 +10,8 @@
 
 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();
+	flush_dcache_all();
 #endif
 	return 0;
 }
diff --git a/arch/arc/lib/start.S b/arch/arc/lib/start.S
index e1ef19c..26a5934 100644
--- a/arch/arc/lib/start.S
+++ b/arch/arc/lib/start.S
@@ -13,19 +13,47 @@
 	/* Setup interrupt vector base that matches "__text_start" */
 	sr	__ivt_start, [ARC_AUX_INTR_VEC_BASE]
 
+	; Disable/enable I-cache according to configuration
+	lr	r5, [ARC_BCR_IC_BUILD]
+	breq	r5, 0, 1f		; I$ doesn't exist
+	lr	r5, [ARC_AUX_IC_CTRL]
+#ifndef CONFIG_SYS_ICACHE_OFF
+	bclr	r5, r5, 0		; 0 - Enable, 1 is Disable
+#else
+	bset	r5, r5, 0		; I$ exists, but is not used
+#endif
+	sr	r5, [ARC_AUX_IC_CTRL]
+
+1:
+	; Disable/enable D-cache according to configuration
+	lr	r5, [ARC_BCR_DC_BUILD]
+	breq	r5, 0, 1f		; D$ doesn't exist
+	lr	r5, [ARC_AUX_DC_CTRL]
+	bclr	r5, r5, 6		; Invalidate (discard w/o wback)
+#ifndef CONFIG_SYS_DCACHE_OFF
+	bclr	r5, r5, 0		; Enable (+Inv)
+#else
+	bset	r5, r5, 0		; Disable (+Inv)
+#endif
+	sr	r5, [ARC_AUX_DC_CTRL]
+
+1:
+#ifdef CONFIG_ISA_ARCV2
+	; Disable System-Level Cache (SLC)
+	lr	r5, [ARC_BCR_SLC]
+	breq	r5, 0, 1f		; SLC doesn't exist
+	lr	r5, [ARC_AUX_SLC_CTRL]
+	bclr	r5, r5, 6		; Invalidate (discard w/o wback)
+	bclr	r5, r5, 0		; Enable (+Inv)
+	sr	r5, [ARC_AUX_SLC_CTRL]
+
+1:
+#endif
+
 	/* 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
diff --git a/arch/arm/dts/uniphier-ph1-ld4-ref.dts b/arch/arm/dts/uniphier-ph1-ld4-ref.dts
index d972c02..25e487a 100644
--- a/arch/arm/dts/uniphier-ph1-ld4-ref.dts
+++ b/arch/arm/dts/uniphier-ph1-ld4-ref.dts
@@ -5,7 +5,7 @@
  * Copyright (C) 2015      Socionext Inc.
  *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 /dts-v1/;
diff --git a/arch/arm/dts/uniphier-ph1-ld4.dtsi b/arch/arm/dts/uniphier-ph1-ld4.dtsi
index c200838..39d7b24 100644
--- a/arch/arm/dts/uniphier-ph1-ld4.dtsi
+++ b/arch/arm/dts/uniphier-ph1-ld4.dtsi
@@ -1,11 +1,9 @@
 /*
  * Device Tree Source for UniPhier PH1-LD4 SoC
  *
- * Copyright (C) 2014-2015 Panasonic Corporation
- * Copyright (C) 2015      Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 /include/ "skeleton.dtsi"
@@ -24,11 +22,26 @@
 		};
 	};
 
+	clocks {
+		arm_timer_clk: arm_timer_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <50000000>;
+		};
+	};
+
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges;
+		interrupt-parent = <&intc>;
+
+		extbus: extbus {
+			compatible = "simple-bus";
+			#address-cells = <2>;
+			#size-cells = <1>;
+		};
 
 		uart0: serial@54006800 {
 			compatible = "socionext,uniphier-uart";
@@ -94,6 +107,12 @@
 			status = "disabled";
 		};
 
+		system-bus-controller-misc@59800000 {
+			compatible = "socionext,uniphier-system-bus-controller-misc",
+				     "syscon";
+			reg = <0x59800000 0x2000>;
+		};
+
 		usb0: usb@5a800100 {
 			compatible = "socionext,uniphier-ehci", "generic-ehci";
 			status = "disabled";
@@ -112,6 +131,28 @@
 			reg = <0x5a820100 0x100>;
 		};
 
+		timer@60000200 {
+			compatible = "arm,cortex-a9-global-timer";
+			reg = <0x60000200 0x20>;
+			interrupts = <1 11 0x104>;
+			clocks = <&arm_timer_clk>;
+		};
+
+		timer@60000600 {
+			compatible = "arm,cortex-a9-twd-timer";
+			reg = <0x60000600 0x20>;
+			interrupts = <1 13 0x104>;
+			clocks = <&arm_timer_clk>;
+		};
+
+		intc: interrupt-controller@60001000 {
+			compatible = "arm,cortex-a9-gic";
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			reg = <0x60001000 0x1000>,
+			      <0x60000100 0x100>;
+		};
+
 		nand: nand@68000000 {
 			compatible = "denali,denali-nand-dt";
 			reg = <0x68000000 0x20>, <0x68100000 0x1000>;
diff --git a/arch/arm/dts/uniphier-ph1-pro4-ref.dts b/arch/arm/dts/uniphier-ph1-pro4-ref.dts
index f6d03e3..b4b7f61 100644
--- a/arch/arm/dts/uniphier-ph1-pro4-ref.dts
+++ b/arch/arm/dts/uniphier-ph1-pro4-ref.dts
@@ -5,7 +5,7 @@
  * Copyright (C) 2015      Socionext Inc.
  *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 /dts-v1/;
diff --git a/arch/arm/dts/uniphier-ph1-pro4.dtsi b/arch/arm/dts/uniphier-ph1-pro4.dtsi
index 8195266..f06906c 100644
--- a/arch/arm/dts/uniphier-ph1-pro4.dtsi
+++ b/arch/arm/dts/uniphier-ph1-pro4.dtsi
@@ -1,11 +1,9 @@
 /*
  * Device Tree Source for UniPhier PH1-Pro4 SoC
  *
- * Copyright (C) 2014-2015 Panasonic Corporation
- * Copyright (C) 2015      Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 /include/ "skeleton.dtsi"
@@ -16,6 +14,7 @@
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
+		enable-method = "socionext,uniphier-smp";
 
 		cpu@0 {
 			device_type = "cpu";
@@ -30,11 +29,26 @@
 		};
 	};
 
+	clocks {
+		arm_timer_clk: arm_timer_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <50000000>;
+		};
+	};
+
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges;
+		interrupt-parent = <&intc>;
+
+		extbus: extbus {
+			compatible = "simple-bus";
+			#address-cells = <2>;
+			#size-cells = <1>;
+		};
 
 		uart0: serial@54006800 {
 			compatible = "socionext,uniphier-uart";
@@ -120,6 +134,12 @@
 			status = "ok";
 		};
 
+		system-bus-controller-misc@59800000 {
+			compatible = "socionext,uniphier-system-bus-controller-misc",
+				     "syscon";
+			reg = <0x59800000 0x2000>;
+		};
+
 		usb2: usb@5a800100 {
 			compatible = "socionext,uniphier-ehci", "generic-ehci";
 			status = "disabled";
@@ -144,6 +164,28 @@
 			reg = <0x65c00000 0x100>;
 		};
 
+		timer@60000200 {
+			compatible = "arm,cortex-a9-global-timer";
+			reg = <0x60000200 0x20>;
+			interrupts = <1 11 0x304>;
+			clocks = <&arm_timer_clk>;
+		};
+
+		timer@60000600 {
+			compatible = "arm,cortex-a9-twd-timer";
+			reg = <0x60000600 0x20>;
+			interrupts = <1 13 0x304>;
+			clocks = <&arm_timer_clk>;
+		};
+
+		intc: interrupt-controller@60001000 {
+			compatible = "arm,cortex-a9-gic";
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			reg = <0x60001000 0x1000>,
+			      <0x60000100 0x100>;
+		};
+
 		nand: nand@68000000 {
 			compatible = "denali,denali-nand-dt";
 			reg = <0x68000000 0x20>, <0x68100000 0x1000>;
diff --git a/arch/arm/dts/uniphier-ph1-sld3-ref.dts b/arch/arm/dts/uniphier-ph1-sld3-ref.dts
index d9616f6..9dc9296 100644
--- a/arch/arm/dts/uniphier-ph1-sld3-ref.dts
+++ b/arch/arm/dts/uniphier-ph1-sld3-ref.dts
@@ -5,7 +5,7 @@
  * Copyright (C) 2015      Socionext Inc.
  *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 /dts-v1/;
diff --git a/arch/arm/dts/uniphier-ph1-sld3.dtsi b/arch/arm/dts/uniphier-ph1-sld3.dtsi
index 44b1989..2fa42a6 100644
--- a/arch/arm/dts/uniphier-ph1-sld3.dtsi
+++ b/arch/arm/dts/uniphier-ph1-sld3.dtsi
@@ -1,11 +1,9 @@
 /*
  * Device Tree Source for UniPhier PH1-sLD3 SoC
  *
- * Copyright (C) 2014-2015 Panasonic Corporation
- * Copyright (C) 2015      Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 /include/ "skeleton.dtsi"
@@ -16,6 +14,7 @@
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
+		enable-method = "socionext,uniphier-smp";
 
 		cpu@0 {
 			device_type = "cpu";
@@ -30,11 +29,48 @@
 		};
 	};
 
+	clocks {
+		arm_timer_clk: arm_timer_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <50000000>;
+		};
+	};
+
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges;
+		interrupt-parent = <&intc>;
+
+		extbus: extbus {
+			compatible = "simple-bus";
+			#address-cells = <2>;
+			#size-cells = <1>;
+		};
+
+		timer@20000200 {
+			compatible = "arm,cortex-a9-global-timer";
+			reg = <0x20000200 0x20>;
+			interrupts = <1 11 0x304>;
+			clocks = <&arm_timer_clk>;
+		};
+
+		timer@20000600 {
+			compatible = "arm,cortex-a9-twd-timer";
+			reg = <0x20000600 0x20>;
+			interrupts = <1 13 0x304>;
+			clocks = <&arm_timer_clk>;
+		};
+
+		intc: interrupt-controller@20001000 {
+			compatible = "arm,cortex-a9-gic";
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			reg = <0x20001000 0x1000>,
+			      <0x20000100 0x100>;
+		};
 
 		uart0: serial@54006800 {
 			compatible = "socionext,uniphier-uart";
@@ -93,6 +129,12 @@
 			status = "disabled";
 		};
 
+		system-bus-controller-misc@59800000 {
+			compatible = "socionext,uniphier-system-bus-controller-misc",
+				     "syscon";
+			reg = <0x59800000 0x2000>;
+		};
+
 		usb0: usb@5a800100 {
 			compatible = "socionext,uniphier-ehci", "generic-ehci";
 			status = "disabled";
diff --git a/arch/arm/dts/uniphier-ph1-sld8-ref.dts b/arch/arm/dts/uniphier-ph1-sld8-ref.dts
index 69e9bfa..2d1359c 100644
--- a/arch/arm/dts/uniphier-ph1-sld8-ref.dts
+++ b/arch/arm/dts/uniphier-ph1-sld8-ref.dts
@@ -5,7 +5,7 @@
  * Copyright (C) 2015      Socionext Inc.
  *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 /dts-v1/;
diff --git a/arch/arm/dts/uniphier-ph1-sld8.dtsi b/arch/arm/dts/uniphier-ph1-sld8.dtsi
index d9f61c2..15df50f 100644
--- a/arch/arm/dts/uniphier-ph1-sld8.dtsi
+++ b/arch/arm/dts/uniphier-ph1-sld8.dtsi
@@ -1,11 +1,9 @@
 /*
  * Device Tree Source for UniPhier PH1-sLD8 SoC
  *
- * Copyright (C) 2014-2015 Panasonic Corporation
- * Copyright (C) 2015      Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 /include/ "skeleton.dtsi"
@@ -24,11 +22,26 @@
 		};
 	};
 
+	clocks {
+		arm_timer_clk: arm_timer_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <50000000>;
+		};
+	};
+
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges;
+		interrupt-parent = <&intc>;
+
+		extbus: extbus {
+			compatible = "simple-bus";
+			#address-cells = <2>;
+			#size-cells = <1>;
+		};
 
 		uart0: serial@54006800 {
 			compatible = "socionext,uniphier-uart";
@@ -94,6 +107,12 @@
 			status = "disabled";
 		};
 
+		system-bus-controller-misc@59800000 {
+			compatible = "socionext,uniphier-system-bus-controller-misc",
+				     "syscon";
+			reg = <0x59800000 0x2000>;
+		};
+
 		usb0: usb@5a800100 {
 			compatible = "socionext,uniphier-ehci", "generic-ehci";
 			status = "disabled";
@@ -112,6 +131,28 @@
 			reg = <0x5a820100 0x100>;
 		};
 
+		timer@60000200 {
+			compatible = "arm,cortex-a9-global-timer";
+			reg = <0x60000200 0x20>;
+			interrupts = <1 11 0x104>;
+			clocks = <&arm_timer_clk>;
+		};
+
+		timer@60000600 {
+			compatible = "arm,cortex-a9-twd-timer";
+			reg = <0x60000600 0x20>;
+			interrupts = <1 13 0x104>;
+			clocks = <&arm_timer_clk>;
+		};
+
+		intc: interrupt-controller@60001000 {
+			compatible = "arm,cortex-a9-gic";
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			reg = <0x60001000 0x1000>,
+			      <0x60000100 0x100>;
+		};
+
 		nand: nand@68000000 {
 			compatible = "denali,denali-nand-dt";
 			reg = <0x68000000 0x20>, <0x68100000 0x1000>;
diff --git a/arch/arm/dts/uniphier-ref-daughter.dtsi b/arch/arm/dts/uniphier-ref-daughter.dtsi
index aca9f58..84b2206 100644
--- a/arch/arm/dts/uniphier-ref-daughter.dtsi
+++ b/arch/arm/dts/uniphier-ref-daughter.dtsi
@@ -1,11 +1,9 @@
 /*
  * Device Tree Source for UniPhier Reference Daughter Board
  *
- * Copyright (C) 2014-2015 Panasonic Corporation
- * Copyright (C) 2015      Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:	GPL-2.0+	X11
  */
 
 &i2c0 {
diff --git a/arch/arm/mach-uniphier/cpu_info.c b/arch/arm/mach-uniphier/cpu_info.c
index c4ba6d2..5d9ed84 100644
--- a/arch/arm/mach-uniphier/cpu_info.c
+++ b/arch/arm/mach-uniphier/cpu_info.c
@@ -34,6 +34,15 @@
 	case 0x29:
 		puts("PH1-sLD8 (MN2WS0270)");
 		break;
+	case 0x2A:
+		puts("PH1-Pro5 (MN2WS0300)");
+		break;
+	case 0x2E:
+		puts("ProXstream2 (MN2WS0310)");
+		break;
+	case 0x2F:
+		puts("PH1-LD6b (MN2WS0320)");
+		break;
 	default:
 		printf("Unknown Processor ID (0x%x)\n", revision);
 		return -1;
diff --git a/board/synopsys/axs101/MAINTAINERS b/board/synopsys/axs101/MAINTAINERS
index 481bbcc..79fff8e 100644
--- a/board/synopsys/axs101/MAINTAINERS
+++ b/board/synopsys/axs101/MAINTAINERS
@@ -4,3 +4,4 @@
 F:	board/synopsys/axs101/
 F:	include/configs/axs101.h
 F:	configs/axs101_defconfig
+F:	configs/axs103_defconfig
diff --git a/board/synopsys/axs101/axs101.c b/board/synopsys/axs101/axs101.c
index 8c16410..d4280f7 100644
--- a/board/synopsys/axs101/axs101.c
+++ b/board/synopsys/axs101/axs101.c
@@ -56,3 +56,33 @@
 
 	return 0;
 }
+
+#ifdef CONFIG_ISA_ARCV2
+#define RESET_VECTOR_ADDR	0x0
+
+void smp_set_core_boot_addr(unsigned long addr, int corenr)
+{
+	/* All cores have reset vector pointing to 0 */
+	writel(addr, (void __iomem *)RESET_VECTOR_ADDR);
+
+	/* Make sure other cores see written value in memory */
+	flush_dcache_range(RESET_VECTOR_ADDR, RESET_VECTOR_ADDR + sizeof(int));
+}
+
+void smp_kick_all_cpus(void)
+{
+/* CPU start CREG */
+#define AXC003_CREG_CPU_START	0xF0001400
+
+/* Bits positions in CPU start CREG */
+#define BITS_START	0
+#define BITS_POLARITY	8
+#define BITS_CORE_SEL	9
+#define BITS_MULTICORE	12
+
+#define CMD	(1 << BITS_MULTICORE) | (1 << BITS_CORE_SEL) | \
+		(1 << BITS_POLARITY) | (1 << BITS_START)
+
+	writel(CMD, (void __iomem *)AXC003_CREG_CPU_START);
+}
+#endif
diff --git a/configs/ph1_ld4_defconfig b/configs/ph1_ld4_defconfig
index 650201a..a71511c 100644
--- a/configs/ph1_ld4_defconfig
+++ b/configs/ph1_ld4_defconfig
@@ -7,10 +7,6 @@
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_HUSH_PARSER=y
-CONFIG_AUTOBOOT_KEYED=y
-CONFIG_AUTOBOOT_PROMPT="Press SPACE to abort autoboot in %d seconds\n"
-CONFIG_AUTOBOOT_DELAY_STR="d"
-CONFIG_AUTOBOOT_STOP_STR=" "
 # CONFIG_CMD_XIMG is not set
 # CONFIG_CMD_ENV_EXISTS is not set
 CONFIG_CMD_NAND=y
diff --git a/configs/ph1_pro4_defconfig b/configs/ph1_pro4_defconfig
index 7d8d9cc..d02712e 100644
--- a/configs/ph1_pro4_defconfig
+++ b/configs/ph1_pro4_defconfig
@@ -6,10 +6,6 @@
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_HUSH_PARSER=y
-CONFIG_AUTOBOOT_KEYED=y
-CONFIG_AUTOBOOT_PROMPT="Press SPACE to abort autoboot in %d seconds\n"
-CONFIG_AUTOBOOT_DELAY_STR="d"
-CONFIG_AUTOBOOT_STOP_STR=" "
 # CONFIG_CMD_XIMG is not set
 # CONFIG_CMD_ENV_EXISTS is not set
 CONFIG_CMD_NAND=y
diff --git a/configs/ph1_sld8_defconfig b/configs/ph1_sld8_defconfig
index 90c44ac..ee4cebc 100644
--- a/configs/ph1_sld8_defconfig
+++ b/configs/ph1_sld8_defconfig
@@ -7,10 +7,6 @@
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_HUSH_PARSER=y
-CONFIG_AUTOBOOT_KEYED=y
-CONFIG_AUTOBOOT_PROMPT="Press SPACE to abort autoboot in %d seconds\n"
-CONFIG_AUTOBOOT_DELAY_STR="d"
-CONFIG_AUTOBOOT_STOP_STR=" "
 # CONFIG_CMD_XIMG is not set
 # CONFIG_CMD_ENV_EXISTS is not set
 CONFIG_CMD_NAND=y