Hi Vikas, On 14 March 2017 at 11:27, Vikas Manocha <vikas.mano...@st.com> wrote: > This patch adds armv7m instruction & data cache support. > > Signed-off-by: Vikas Manocha <vikas.mano...@st.com> > cc: Christophe KERELLO <christophe.kere...@st.com> > --- > > Changed in v3: > - uint32 replcaed with u32. > - multiple read of hardware register replaced with single. > - pointers replaced with macros for base address. > - register names added as comment for system control block registers. > > Changed in v2: > - changed strucures for memory mapped cache registers to macros > - added lines better readability. > - replaced magic numbers with macros. > > arch/arm/cpu/armv7m/Makefile | 2 +- > arch/arm/cpu/armv7m/cache.c | 291 > ++++++++++++++++++++++++++++++++++++++++++ > arch/arm/include/asm/armv7m.h | 26 +++- > arch/arm/lib/Makefile | 2 + > 4 files changed, 318 insertions(+), 3 deletions(-) > create mode 100644 arch/arm/cpu/armv7m/cache.c > > diff --git a/arch/arm/cpu/armv7m/Makefile b/arch/arm/cpu/armv7m/Makefile > index aff60e8..41efe11 100644 > --- a/arch/arm/cpu/armv7m/Makefile > +++ b/arch/arm/cpu/armv7m/Makefile > @@ -6,4 +6,4 @@ > # > > extra-y := start.o > -obj-y += cpu.o > +obj-y += cpu.o cache.o > diff --git a/arch/arm/cpu/armv7m/cache.c b/arch/arm/cpu/armv7m/cache.c > new file mode 100644 > index 0000000..9021525 > --- /dev/null > +++ b/arch/arm/cpu/armv7m/cache.c > @@ -0,0 +1,291 @@ > +/* > + * (C) Copyright 2017 > + * Vikas Manocha, ST Micoelectronics, vikas.mano...@st.com. > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#include <common.h> > +#include <asm/armv7m.h> > +#include <asm/io.h> > +#include <errno.h>
put this one below common.h > + > +/* Cache maintenance operation registers */ > + > +#define IC_IALLU (V7M_CACHE_MAINT_BASE + 0x00) > +#define INVAL_ICACHE_POU 0 > +#define IC_IMVALU (V7M_CACHE_MAINT_BASE + 0x08) > +#define DC_IMVAC (V7M_CACHE_MAINT_BASE + 0x0C) > +#define DC_ISW (V7M_CACHE_MAINT_BASE + 0x10) > +#define DC_CMVAU (V7M_CACHE_MAINT_BASE + 0x14) > +#define DC_CMVAC (V7M_CACHE_MAINT_BASE + 0x18) > +#define DC_CSW (V7M_CACHE_MAINT_BASE + 0x1C) > +#define DC_CIMVAC (V7M_CACHE_MAINT_BASE + 0x20) > +#define DC_CISW (V7M_CACHE_MAINT_BASE + 0x24) > +#define WAYS_SHIFT 30 > +#define SETS_SHIFT 5 > + > +/* armv7m processor feature registers */ > + > +#define CLIDR (V7M_PROC_FTR_BASE + 0x00) > +#define CTR (V7M_PROC_FTR_BASE + 0x04) > +#define CCSIDR (V7M_PROC_FTR_BASE + 0x08) > +#define MASK_NUM_WAYS GENMASK(12, 3) > +#define MASK_NUM_SETS GENMASK(27, 13) > +#define CLINE_SIZE_MASK GENMASK(2, 0) > +#define NUM_WAYS_SHIFT 3 > +#define NUM_SETS_SHIFT 13 > +#define CSSELR (V7M_PROC_FTR_BASE + 0x0C) > +#define SEL_I_OR_D BIT(0) > + > +enum cache_type { > + DCACHE = 0, Do you need the =0 ? > + ICACHE, > +}; > + > +/* PoU : Point of Unification, Poc: Point of Coherency */ > +enum cache_action { > + INVALIDATE_POU, /* for i-cache invalidate by address */ > + INVALIDATE_POC, /* for d-cache invalidate by address */ > + INVALIDATE_SET_WAY, /* for d-cache invalidate by sets/ways */ > + FLUSH_POU, > + FLUSH_POC, > + FLUSH_SET_WAY, > + FLUSH_INVAL_POC, > + FLUSH_INVAL_SET_WAY, Can you add comments for the rest? > +}; > + > +#ifndef CONFIG_SYS_DCACHE_OFF > +struct dcache_config { > + u32 ways; > + u32 sets; > +}; > + > +static void get_cache_ways_sets(struct dcache_config *cache) > +{ > + u32 cache_size_id = readl(CCSIDR); blank line here > + cache->ways = (cache_size_id & MASK_NUM_WAYS) >> NUM_WAYS_SHIFT; > + cache->sets = (cache_size_id & MASK_NUM_SETS) >> NUM_SETS_SHIFT; > +} > + > +static u32 *get_action_reg_set_ways(enum cache_action action) Can you please add a function comment? What does this return? > +{ > + switch (action) { > + case INVALIDATE_SET_WAY: > + return (u32 *)DC_ISW; Can you drop these casts by using a C structure or by putting thecast in the #define? > + case FLUSH_SET_WAY: > + return (u32 *)DC_CSW; > + case FLUSH_INVAL_SET_WAY: > + return (u32 *)DC_CISW; > + default: > + break; > + }; > + > + return NULL; > +} > + > +static u32 *get_action_reg_range(enum cache_action action) > +{ > + switch (action) { > + case INVALIDATE_POU: > + return (u32 *)IC_IMVALU; > + case INVALIDATE_POC: > + return (u32 *)DC_IMVAC; > + case FLUSH_POU: > + return (u32 *)DC_CMVAU; > + case FLUSH_POC: > + return (u32 *)DC_CMVAC; > + case FLUSH_INVAL_POC: > + return (u32 *)DC_CIMVAC; > + default: > + break; > + } > + > + return NULL; > +} > + > +static u32 get_cline_size(enum cache_type type) Why u32? Should it be uint or ulong? > +{ > + u32 size; > + > + if (type == DCACHE) > + clrbits_le32(CSSELR, BIT(SEL_I_OR_D)); > + else if (type == ICACHE) > + setbits_le32(CSSELR, BIT(SEL_I_OR_D)); > + dsb(); > + > + size = readl(CCSIDR) & CLINE_SIZE_MASK; > + /* Size enocoded as 2 less than log(no_of_words_in_cache_line) base 2 > */ > + size = 1 << (size + 2); > + debug("cache line size is %d\n", size); > + > + return size; > +} > + > +static __attribute__((unused)) int action_cache_range(enum cache_action > action, > + u32 start_addr, int64_t size) Function comment. Can you use __used ? > +{ > + u32 cline_size; > + u32 *action_reg; > + enum cache_type type; > + > + action_reg = get_action_reg_range(action); > + if (!action_reg) > + return -EINVAL; > + if (action == INVALIDATE_POU) > + type = ICACHE; > + else > + type = DCACHE; > + > + /* Cache line size is minium size for the cache action */ > + cline_size = get_cline_size(type); > + /* Align start address to cache line boundary */ > + start_addr &= ~(cline_size - 1); > + do { > + writel(start_addr, action_reg); > + size -= cline_size; > + start_addr += cline_size; > + } while (size > cline_size); > + dsb(); > + isb(); > + debug("cache action on range done\n"); > + > + return 0; > +} > + > +static int action_dcache_all(enum cache_action action) Function comment. Regards, Simon _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot