Merge branch 'master' of git://git.denx.de/u-boot-arc

master
Tom Rini 8 years ago
commit 1e031249a5
  1. 95
      arch/arc/include/asm/io.h
  2. 10
      arch/arc/lib/cache.c
  3. 2
      board/synopsys/axs101/axs101.c
  4. 2
      configs/axs103_defconfig

@ -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 @@ static inline u32 __raw_readl(const volatile void __iomem *addr)
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 @@ static inline void __raw_writel(u32 w, volatile void __iomem *addr)
: "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 @@ static inline int __raw_writesl(unsigned int addr, void *data, int longlen)
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))

@ -209,6 +209,9 @@ void cache_init(void)
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 flush_cache(unsigned long start, unsigned long size)
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
}

@ -54,7 +54,7 @@ void smp_set_core_boot_addr(unsigned long addr, int corenr)
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)

@ -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

Loading…
Cancel
Save