diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2017-05-02 18:28:12 -0400 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2017-05-02 19:16:07 -0400 |
commit | ee40bd1e0c3fb83d810f258952692ffdebc14726 (patch) | |
tree | 1aabc93d6ac3559e9940125e21cdcc445dbf180b | |
parent | 0d77117fc5c0333d024a183d6790167bb90c3b62 (diff) |
ARCv2: mm: Merge 2 updates to DC_CTRL for region flush
Region Flush has a weird programming model.
1. Flush or Invalidate is selected by DC_CTRL.RGN_OP
2 Flush-n-Invalidate is done by DC_CTRL.IM
Given the code structuring before, case #2 above was generating two
seperate updates to DC_CTRL which was pointless.
| 80a342b0 <__dma_cache_wback_inv_l1>:
| 80a342b0: clri r4
| 80a342b4: lr r2,[dc_ctrl]
| 80a342b8: bset_s r2,r2,0x6
| 80a342ba: sr r2,[dc_ctrl] <-- FIRST
|
| 80a342be: bmskn r3,r0,0x5
|
| 80a342c2: lr r2,[dc_ctrl]
| 80a342c6: and r2,r2,0xfffff1ff
| 80a342ce: bset_s r2,r2,0x9
| 80a342d0: sr r2,[dc_ctrl] <-- SECOND
|
| 80a342d4: add_s r1,r1,0x3f
| 80a342d6: bmsk_s r0,r0,0x5
| 80a342d8: add_s r0,r0,r1
| 80a342da: add_s r0,r0,r3
| 80a342dc: sr r0,[78]
| 80a342e0: sr r3,[77]
|...
|...
So move setting of DC_CTRL.RGN_OP into __before_dc_op() and combine with
any other update.
| 80b63324 <__dma_cache_wback_inv_l1>:
| 80b63324: clri r3
| 80b63328: lr r2,[dc_ctrl]
| 80b6332c: and r2,r2,0xfffff1ff
| 80b63334: or r2,r2,576
| 80b63338: sr r2,[dc_ctrl]
|
| 80b6333c: add_s r1,r1,0x3f
| 80b6333e: bmskn r2,r0,0x5
| 80b63342: add_s r0,r0,r1
| 80b63344: sr r0,[78]
| 80b63348: sr r2,[77]
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
-rw-r--r-- | arch/arc/mm/cache.c | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/arch/arc/mm/cache.c b/arch/arc/mm/cache.c index 8401fcb75d19..a867575a758b 100644 --- a/arch/arc/mm/cache.c +++ b/arch/arc/mm/cache.c | |||
@@ -409,8 +409,7 @@ static inline | |||
409 | void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr, | 409 | void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr, |
410 | unsigned long sz, const int op, const int full_page) | 410 | unsigned long sz, const int op, const int full_page) |
411 | { | 411 | { |
412 | const unsigned int ctl = ARC_REG_DC_CTRL; | 412 | unsigned int s, e; |
413 | unsigned int s, e, val; | ||
414 | 413 | ||
415 | /* Only for Non aliasing I-cache in HS38 */ | 414 | /* Only for Non aliasing I-cache in HS38 */ |
416 | if (op == OP_INV_IC) { | 415 | if (op == OP_INV_IC) { |
@@ -441,18 +440,6 @@ void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr, | |||
441 | write_aux_reg(ARC_REG_DC_PTAG_HI, (u64)paddr >> 32); | 440 | write_aux_reg(ARC_REG_DC_PTAG_HI, (u64)paddr >> 32); |
442 | } | 441 | } |
443 | 442 | ||
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 */ | 443 | /* ENDR needs to be set ahead of START */ |
457 | write_aux_reg(e, paddr + sz); /* ENDR is exclusive */ | 444 | write_aux_reg(e, paddr + sz); /* ENDR is exclusive */ |
458 | write_aux_reg(s, paddr); | 445 | write_aux_reg(s, paddr); |
@@ -476,6 +463,11 @@ void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr, | |||
476 | * Machine specific helpers for Entire D-Cache or Per Line ops | 463 | * Machine specific helpers for Entire D-Cache or Per Line ops |
477 | */ | 464 | */ |
478 | 465 | ||
466 | #ifndef USE_RGN_FLSH | ||
467 | /* | ||
468 | * this version avoids extra read/write of DC_CTRL for flush or invalid ops | ||
469 | * in the non region flush regime (such as for ARCompact) | ||
470 | */ | ||
479 | static inline void __before_dc_op(const int op) | 471 | static inline void __before_dc_op(const int op) |
480 | { | 472 | { |
481 | if (op == OP_FLUSH_N_INV) { | 473 | if (op == OP_FLUSH_N_INV) { |
@@ -489,6 +481,32 @@ static inline void __before_dc_op(const int op) | |||
489 | } | 481 | } |
490 | } | 482 | } |
491 | 483 | ||
484 | #else | ||
485 | |||
486 | static inline void __before_dc_op(const int op) | ||
487 | { | ||
488 | const unsigned int ctl = ARC_REG_DC_CTRL; | ||
489 | unsigned int val = read_aux_reg(ctl); | ||
490 | |||
491 | if (op == OP_FLUSH_N_INV) { | ||
492 | val |= DC_CTRL_INV_MODE_FLUSH; | ||
493 | } | ||
494 | |||
495 | if (op != OP_INV_IC) { | ||
496 | /* | ||
497 | * Flush / Invalidate is provided by DC_CTRL.RNG_OP 0 or 1 | ||
498 | * combined Flush-n-invalidate uses DC_CTRL.IM = 1 set above | ||
499 | */ | ||
500 | val &= ~DC_CTRL_RGN_OP_MSK; | ||
501 | if (op & OP_INV) | ||
502 | val |= DC_CTRL_RGN_OP_INV; | ||
503 | } | ||
504 | write_aux_reg(ctl, val); | ||
505 | } | ||
506 | |||
507 | #endif | ||
508 | |||
509 | |||
492 | static inline void __after_dc_op(const int op) | 510 | static inline void __after_dc_op(const int op) |
493 | { | 511 | { |
494 | if (op & OP_FLUSH) { | 512 | if (op & OP_FLUSH) { |