aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVineet Gupta2014-08-29 00:25:15 -0500
committerVineet Gupta2017-05-02 17:57:22 -0500
commit0d77117fc5c0333d024a183d6790167bb90c3b62 (patch)
treeb4ce890e687f3a3de92c13cba45dc7b416695bc7
parent7d3d162bbd515070dfa4f422778276aa28f114d4 (diff)
downloadkernel-0d77117fc5c0333d024a183d6790167bb90c3b62.tar.gz
kernel-0d77117fc5c0333d024a183d6790167bb90c3b62.tar.xz
kernel-0d77117fc5c0333d024a183d6790167bb90c3b62.zip
ARCv2: mm: Implement cache region flush operations
These are more efficient than the per-line ops Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
-rw-r--r--arch/arc/include/asm/cache.h6
-rw-r--r--arch/arc/mm/cache.c68
2 files changed, 74 insertions, 0 deletions
diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h
index 5008021fba98..16e457706129 100644
--- a/arch/arc/include/asm/cache.h
+++ b/arch/arc/include/asm/cache.h
@@ -62,6 +62,8 @@ extern unsigned long perip_base, perip_end;
62#define ARC_REG_IC_BCR 0x77 /* Build Config reg */ 62#define ARC_REG_IC_BCR 0x77 /* Build Config reg */
63#define ARC_REG_IC_IVIC 0x10 63#define ARC_REG_IC_IVIC 0x10
64#define ARC_REG_IC_CTRL 0x11 64#define ARC_REG_IC_CTRL 0x11
65#define ARC_REG_IC_IVIR 0x16
66#define ARC_REG_IC_ENDR 0x17
65#define ARC_REG_IC_IVIL 0x19 67#define ARC_REG_IC_IVIL 0x19
66#define ARC_REG_IC_PTAG 0x1E 68#define ARC_REG_IC_PTAG 0x1E
67#define ARC_REG_IC_PTAG_HI 0x1F 69#define ARC_REG_IC_PTAG_HI 0x1F
@@ -76,6 +78,8 @@ extern unsigned long perip_base, perip_end;
76#define ARC_REG_DC_IVDL 0x4A 78#define ARC_REG_DC_IVDL 0x4A
77#define ARC_REG_DC_FLSH 0x4B 79#define ARC_REG_DC_FLSH 0x4B
78#define ARC_REG_DC_FLDL 0x4C 80#define ARC_REG_DC_FLDL 0x4C
81#define ARC_REG_DC_STARTR 0x4D
82#define ARC_REG_DC_ENDR 0x4E
79#define ARC_REG_DC_PTAG 0x5C 83#define ARC_REG_DC_PTAG 0x5C
80#define ARC_REG_DC_PTAG_HI 0x5F 84#define ARC_REG_DC_PTAG_HI 0x5F
81 85
@@ -83,6 +87,8 @@ extern unsigned long perip_base, perip_end;
83#define DC_CTRL_DIS 0x001 87#define DC_CTRL_DIS 0x001
84#define DC_CTRL_INV_MODE_FLUSH 0x040 88#define DC_CTRL_INV_MODE_FLUSH 0x040
85#define DC_CTRL_FLUSH_STATUS 0x100 89#define DC_CTRL_FLUSH_STATUS 0x100
90#define DC_CTRL_RGN_OP_INV 0x200
91#define DC_CTRL_RGN_OP_MSK 0xE00
86 92
87/*System-level cache (L2 cache) related Auxiliary registers */ 93/*System-level cache (L2 cache) related Auxiliary registers */
88#define ARC_REG_SLC_CFG 0x901 94#define ARC_REG_SLC_CFG 0x901
diff --git a/arch/arc/mm/cache.c b/arch/arc/mm/cache.c
index 18132eb56150..8401fcb75d19 100644
--- a/arch/arc/mm/cache.c
+++ b/arch/arc/mm/cache.c
@@ -21,6 +21,10 @@
21#include <asm/cachectl.h> 21#include <asm/cachectl.h>
22#include <asm/setup.h> 22#include <asm/setup.h>
23 23
24#ifdef CONFIG_ISA_ARCV2
25#define USE_RGN_FLSH 1
26#endif
27
24static int l2_line_sz; 28static int l2_line_sz;
25static int ioc_exists; 29static int ioc_exists;
26int slc_enable = 1, ioc_enable = 1; 30int slc_enable = 1, ioc_enable = 1;
@@ -332,6 +336,8 @@ void __cache_line_loop_v3(phys_addr_t paddr, unsigned long vaddr,
332 } 336 }
333} 337}
334 338
339#ifndef USE_RGN_FLSH
340
335/* 341/*
336 * In HS38x (MMU v4), I-cache is VIPT (can alias), D-cache is PIPT 342 * In HS38x (MMU v4), I-cache is VIPT (can alias), D-cache is PIPT
337 * Here's how cache ops are implemented 343 * Here's how cache ops are implemented
@@ -394,6 +400,68 @@ void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr,
394 } 400 }
395} 401}
396 402
403#else
404
405/*
406 * optimized flush operation which takes a region as opposed to iterating per line
407 */
408static inline
409void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr,
410 unsigned long sz, const int op, const int full_page)
411{
412 const unsigned int ctl = ARC_REG_DC_CTRL;
413 unsigned int s, e, val;
414
415 /* Only for Non aliasing I-cache in HS38 */
416 if (op == OP_INV_IC) {
417 s = ARC_REG_IC_IVIR;
418 e = ARC_REG_IC_ENDR;
419 } else {
420 s = ARC_REG_DC_STARTR;
421 e = ARC_REG_DC_ENDR;
422 }
423
424 if (!full_page) {
425 /* for any leading gap between @paddr and start of cache line */
426 sz += paddr & ~CACHE_LINE_MASK;
427 paddr &= CACHE_LINE_MASK;
428
429 /*
430 * account for any trailing gap to end of cache line
431 * this is equivalent to DIV_ROUND_UP() in line ops above
432 */
433 sz += L1_CACHE_BYTES - 1;
434 }
435
436 if (is_pae40_enabled()) {
437 /* TBD: check if crossing 4TB boundary */
438 if (op == OP_INV_IC)
439 write_aux_reg(ARC_REG_IC_PTAG_HI, (u64)paddr >> 32);
440 else
441 write_aux_reg(ARC_REG_DC_PTAG_HI, (u64)paddr >> 32);
442 }
443
444 /*
445 * Flush / Invalidate is provided by DC_CTRL.RNG_OP 0 or 1
446 * Flush-n-invalidate additionally uses setting DC_CTRL.IM = 1
447 * just as for line ops which is handled in __before_dc_op()
448 */
449 val = read_aux_reg(ctl) & ~DC_CTRL_RGN_OP_MSK;
450
451 if (op & OP_INV)
452 val |= DC_CTRL_RGN_OP_INV;
453
454 write_aux_reg(ctl, val);
455
456 /* ENDR needs to be set ahead of START */
457 write_aux_reg(e, paddr + sz); /* ENDR is exclusive */
458 write_aux_reg(s, paddr);
459
460 /* caller waits on DC_CTRL.FS */
461}
462
463#endif
464
397#if (CONFIG_ARC_MMU_VER < 3) 465#if (CONFIG_ARC_MMU_VER < 3)
398#define __cache_line_loop __cache_line_loop_v2 466#define __cache_line_loop __cache_line_loop_v2
399#elif (CONFIG_ARC_MMU_VER == 3) 467#elif (CONFIG_ARC_MMU_VER == 3)