diff options
author | Vineet Gupta | 2014-08-29 00:25:15 -0500 |
---|---|---|
committer | Vineet Gupta | 2017-05-02 17:57:22 -0500 |
commit | 0d77117fc5c0333d024a183d6790167bb90c3b62 (patch) | |
tree | b4ce890e687f3a3de92c13cba45dc7b416695bc7 | |
parent | 7d3d162bbd515070dfa4f422778276aa28f114d4 (diff) | |
download | kernel-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.h | 6 | ||||
-rw-r--r-- | arch/arc/mm/cache.c | 68 |
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 | |||
24 | static int l2_line_sz; | 28 | static int l2_line_sz; |
25 | static int ioc_exists; | 29 | static int ioc_exists; |
26 | int slc_enable = 1, ioc_enable = 1; | 30 | int 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 | */ | ||
408 | static inline | ||
409 | void __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) |