aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVineet Gupta2017-05-02 17:28:12 -0500
committerVineet Gupta2017-05-02 18:16:07 -0500
commitee40bd1e0c3fb83d810f258952692ffdebc14726 (patch)
tree1aabc93d6ac3559e9940125e21cdcc445dbf180b
parent0d77117fc5c0333d024a183d6790167bb90c3b62 (diff)
downloadkernel-ee40bd1e0c3fb83d810f258952692ffdebc14726.tar.gz
kernel-ee40bd1e0c3fb83d810f258952692ffdebc14726.tar.xz
kernel-ee40bd1e0c3fb83d810f258952692ffdebc14726.zip
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.c46
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
409void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr, 409void __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 */
479static inline void __before_dc_op(const int op) 471static 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
486static 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
492static inline void __after_dc_op(const int op) 510static inline void __after_dc_op(const int op)
493{ 511{
494 if (op & OP_FLUSH) { 512 if (op & OP_FLUSH) {