Merge branch 'master' of git://git.denx.de/u-boot-arc
diff --git a/arch/arc/include/asm/io.h b/arch/arc/include/asm/io.h
index b6f7724..42e7f22 100644
--- a/arch/arc/include/asm/io.h
+++ b/arch/arc/include/asm/io.h
@@ -10,6 +10,46 @@
 #include <linux/types.h>
 #include <asm/byteorder.h>
 
+#ifdef CONFIG_ISA_ARCV2
+
+/*
+ * ARCv2 based HS38 cores are in-order issue, but still weakly ordered
+ * due to micro-arch buffering/queuing of load/store, cache hit vs. miss ...
+ *
+ * Explicit barrier provided by DMB instruction
+ *  - Operand supports fine grained load/store/load+store semantics
+ *  - Ensures that selected memory operation issued before it will complete
+ *    before any subsequent memory operation of same type
+ *  - DMB guarantees SMP as well as local barrier semantics
+ *    (asm-generic/barrier.h ensures sane smp_*mb if not defined here, i.e.
+ *    UP: barrier(), SMP: smp_*mb == *mb)
+ *  - DSYNC provides DMB+completion_of_cache_bpu_maintenance_ops hence not needed
+ *    in the general case. Plus it only provides full barrier.
+ */
+
+#define mb()	asm volatile("dmb 3\n" : : : "memory")
+#define rmb()	asm volatile("dmb 1\n" : : : "memory")
+#define wmb()	asm volatile("dmb 2\n" : : : "memory")
+
+#else
+
+/*
+ * ARCompact based cores (ARC700) only have SYNC instruction which is super
+ * heavy weight as it flushes the pipeline as well.
+ * There are no real SMP implementations of such cores.
+ */
+
+#define mb()	asm volatile("sync\n" : : : "memory")
+#endif
+
+#ifdef CONFIG_ISA_ARCV2
+#define __iormb()		rmb()
+#define __iowmb()		wmb()
+#else
+#define __iormb()		do { } while (0)
+#define __iowmb()		do { } while (0)
+#endif
+
 /*
  * Given a physical address and a length, return a virtual address
  * that can be used to access the memory range with the caching
@@ -72,18 +112,6 @@
 	return w;
 }
 
-#define readb __raw_readb
-
-static inline u16 readw(const volatile void __iomem *addr)
-{
-	return __le16_to_cpu(__raw_readw(addr));
-}
-
-static inline u32 readl(const volatile void __iomem *addr)
-{
-	return __le32_to_cpu(__raw_readl(addr));
-}
-
 static inline void __raw_writeb(u8 b, volatile void __iomem *addr)
 {
 	__asm__ __volatile__("stb%U1	%0, %1\n"
@@ -108,10 +136,6 @@
 			     : "memory");
 }
 
-#define writeb __raw_writeb
-#define writew(b, addr) __raw_writew(__cpu_to_le16(b), addr)
-#define writel(b, addr) __raw_writel(__cpu_to_le32(b), addr)
-
 static inline int __raw_readsb(unsigned int addr, void *data, int bytelen)
 {
 	__asm__ __volatile__ ("1:ld.di	r8, [r0]\n"
@@ -184,6 +208,45 @@
 	return longlen;
 }
 
+/*
+ * MMIO can also get buffered/optimized in micro-arch, so barriers needed
+ * Based on ARM model for the typical use case
+ *
+ *	<ST [DMA buffer]>
+ *	<writel MMIO "go" reg>
+ *  or:
+ *	<readl MMIO "status" reg>
+ *	<LD [DMA buffer]>
+ *
+ * http://lkml.kernel.org/r/20150622133656.GG1583@arm.com
+ */
+#define readb(c)		({ u8  __v = readb_relaxed(c); __iormb(); __v; })
+#define readw(c)		({ u16 __v = readw_relaxed(c); __iormb(); __v; })
+#define readl(c)		({ u32 __v = readl_relaxed(c); __iormb(); __v; })
+
+#define writeb(v,c)		({ __iowmb(); writeb_relaxed(v,c); })
+#define writew(v,c)		({ __iowmb(); writew_relaxed(v,c); })
+#define writel(v,c)		({ __iowmb(); writel_relaxed(v,c); })
+
+/*
+ * Relaxed API for drivers which can handle barrier ordering themselves
+ *
+ * Also these are defined to perform little endian accesses.
+ * To provide the typical device register semantics of fixed endian,
+ * swap the byte order for Big Endian
+ *
+ * http://lkml.kernel.org/r/201603100845.30602.arnd@arndb.de
+ */
+#define readb_relaxed(c)	__raw_readb(c)
+#define readw_relaxed(c) ({ u16 __r = le16_to_cpu((__force __le16) \
+					__raw_readw(c)); __r; })
+#define readl_relaxed(c) ({ u32 __r = le32_to_cpu((__force __le32) \
+					__raw_readl(c)); __r; })
+
+#define writeb_relaxed(v,c)	__raw_writeb(v,c)
+#define writew_relaxed(v,c)	__raw_writew((__force u16) cpu_to_le16(v),c)
+#define writel_relaxed(v,c)	__raw_writel((__force u32) cpu_to_le32(v),c)
+
 #define out_arch(type, endian, a, v)	__raw_write##type(cpu_to_##endian(v), a)
 #define in_arch(type, endian, a)	endian##_to_cpu(__raw_read##type(a))
 
diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c
index d1fb661..b6ec8311 100644
--- a/arch/arc/lib/cache.c
+++ b/arch/arc/lib/cache.c
@@ -209,6 +209,9 @@
 	read_decode_cache_bcr_arcv2();
 
 	if (ioc_exists) {
+		flush_dcache_all();
+		invalidate_dcache_all();
+
 		/* IO coherency base - 0x8z */
 		write_aux_reg(ARC_AUX_IO_COH_AP0_BASE, 0x80000);
 		/* IO coherency aperture size - 512Mb: 0x8z-0xAz */
@@ -417,13 +420,10 @@
 
 void invalidate_dcache_all(void)
 {
-#ifdef CONFIG_ISA_ARCV2
-	if (!ioc_exists)
-#endif
-		__dc_entire_op(OP_INV);
+	__dc_entire_op(OP_INV);
 
 #ifdef CONFIG_ISA_ARCV2
-	if (slc_exists && !ioc_exists)
+	if (slc_exists)
 		__slc_entire_op(OP_INV);
 #endif
 }
diff --git a/board/synopsys/axs101/axs101.c b/board/synopsys/axs101/axs101.c
index 84ee2bf..a5e774b 100644
--- a/board/synopsys/axs101/axs101.c
+++ b/board/synopsys/axs101/axs101.c
@@ -54,7 +54,7 @@
 	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));
+	flush_dcache_all();
 }
 
 void smp_kick_all_cpus(void)
diff --git a/configs/axs103_defconfig b/configs/axs103_defconfig
index 96a3de6..c8474de 100644
--- a/configs/axs103_defconfig
+++ b/configs/axs103_defconfig
@@ -1,7 +1,7 @@
 CONFIG_ARC=y
 CONFIG_ISA_ARCV2=y
 CONFIG_DM_SERIAL=y
-CONFIG_SYS_CLK_FREQ=50000000
+CONFIG_SYS_CLK_FREQ=100000000
 CONFIG_SYS_TEXT_BASE=0x81000000
 CONFIG_DEFAULT_DEVICE_TREE="axs10x"
 CONFIG_BOOTDELAY=3