diff options
author | Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> | 2018-03-21 15:58:48 +0300 |
---|---|---|
committer | Alexey Brodkin <abrodkin@synopsys.com> | 2018-03-21 17:06:44 +0300 |
commit | 5d7a24d6462389ab5a1ac3baa800659155e81329 (patch) | |
tree | 033b54d0ed41533840c1d1da7fbb9032e34c3df9 /arch/arc | |
parent | c4ef14d2cc06ca7cca7e1484b5d9a8b1decb02ac (diff) |
ARC: Cache: Add support for FLUSH_N_INV D$ operations
As of today __dc_line_op() and __dc_entire_op() support
only separate flush (OP_FLUSH) and invalidate (OP_INV) operations.
Add support of combined flush and invalidate (OP_FLUSH_N_INV)
operation which we planing to use in subsequent patches.
Signed-off-by: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
Diffstat (limited to 'arch/arc')
-rw-r--r-- | arch/arc/lib/cache.c | 42 |
1 files changed, 19 insertions, 23 deletions
diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c index 2252542f16c..83b77b97160 100644 --- a/arch/arc/lib/cache.c +++ b/arch/arc/lib/cache.c @@ -21,8 +21,9 @@ #define DC_CTRL_FLUSH_STATUS BIT(8) #define CACHE_VER_NUM_MASK 0xF -#define OP_INV 0x1 -#define OP_FLUSH 0x2 +#define OP_INV BIT(0) +#define OP_FLUSH BIT(1) +#define OP_FLUSH_N_INV (OP_FLUSH | OP_INV) /* Bit val in SLC_CONTROL */ #define SLC_CTRL_DIS 0x001 @@ -396,36 +397,32 @@ static inline void __dcache_line_loop(unsigned long paddr, unsigned long sz, } } -static unsigned int __before_dc_op(const int op) +static void __before_dc_op(const int op) { - unsigned int reg; + unsigned int ctrl; - 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); - } + ctrl = read_aux_reg(ARC_AUX_DC_CTRL); - return reg; + /* IM bit implies flush-n-inv, instead of vanilla inv */ + if (op == OP_INV) + ctrl &= ~DC_CTRL_INV_MODE_FLUSH; + else + ctrl |= DC_CTRL_INV_MODE_FLUSH; + + write_aux_reg(ARC_AUX_DC_CTRL, ctrl); } -static void __after_dc_op(const int op, unsigned int reg) +static void __after_dc_op(const int op) { 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); + + __before_dc_op(cacheop); if (cacheop & OP_INV) /* Inv or flush-n-inv use same cmd reg */ aux = ARC_AUX_DC_IVDC; @@ -434,16 +431,15 @@ static inline void __dc_entire_op(const int cacheop) write_aux_reg(aux, 0x1); - __after_dc_op(cacheop, ctrl_reg); + __after_dc_op(cacheop); } static inline void __dc_line_op(unsigned long paddr, unsigned long sz, const int cacheop) { - unsigned int ctrl_reg = __before_dc_op(cacheop); - + __before_dc_op(cacheop); __dcache_line_loop(paddr, sz, cacheop); - __after_dc_op(cacheop, ctrl_reg); + __after_dc_op(cacheop); } #else #define __dc_entire_op(cacheop) |