ARCv2: mm: Merge 2 updates to DC_CTRL for region flush
authorVineet Gupta <vgupta@synopsys.com>
Tue, 2 May 2017 22:28:12 +0000 (15:28 -0700)
committerVineet Gupta <vgupta@synopsys.com>
Tue, 2 May 2017 23:16:07 +0000 (16:16 -0700)
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>
arch/arc/mm/cache.c

index 8401fcb75d19947c285f50d54e59fd5fe993bd1f..a867575a758b9845c09a84fb4515f17f08f1272b 100644 (file)
@@ -409,8 +409,7 @@ static inline
 void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr,
                          unsigned long sz, const int op, const int full_page)
 {
-       const unsigned int ctl = ARC_REG_DC_CTRL;
-       unsigned int s, e, val;
+       unsigned int s, e;
 
        /* Only for Non aliasing I-cache in HS38 */
        if (op == OP_INV_IC) {
@@ -441,18 +440,6 @@ void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr,
                        write_aux_reg(ARC_REG_DC_PTAG_HI, (u64)paddr >> 32);
        }
 
-       /*
-        * Flush / Invalidate is provided by DC_CTRL.RNG_OP 0 or 1
-        * Flush-n-invalidate additionally uses setting DC_CTRL.IM = 1
-        * just as for line ops which is handled in __before_dc_op()
-        */
-       val = read_aux_reg(ctl) & ~DC_CTRL_RGN_OP_MSK;
-
-       if (op & OP_INV)
-               val |= DC_CTRL_RGN_OP_INV;
-
-       write_aux_reg(ctl, val);
-
        /* ENDR needs to be set ahead of START */
        write_aux_reg(e, paddr + sz);   /* ENDR is exclusive */
        write_aux_reg(s, paddr);
@@ -476,6 +463,11 @@ void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr,
  * Machine specific helpers for Entire D-Cache or Per Line ops
  */
 
+#ifndef USE_RGN_FLSH
+/*
+ * this version avoids extra read/write of DC_CTRL for flush or invalid ops
+ * in the non region flush regime (such as for ARCompact)
+ */
 static inline void __before_dc_op(const int op)
 {
        if (op == OP_FLUSH_N_INV) {
@@ -489,6 +481,32 @@ static inline void __before_dc_op(const int op)
        }
 }
 
+#else
+
+static inline void __before_dc_op(const int op)
+{
+       const unsigned int ctl = ARC_REG_DC_CTRL;
+       unsigned int val = read_aux_reg(ctl);
+
+       if (op == OP_FLUSH_N_INV) {
+               val |= DC_CTRL_INV_MODE_FLUSH;
+       }
+
+       if (op != OP_INV_IC) {
+               /*
+                * Flush / Invalidate is provided by DC_CTRL.RNG_OP 0 or 1
+                * combined Flush-n-invalidate uses DC_CTRL.IM = 1 set above
+                */
+               val &= ~DC_CTRL_RGN_OP_MSK;
+               if (op & OP_INV)
+                       val |= DC_CTRL_RGN_OP_INV;
+       }
+       write_aux_reg(ctl, val);
+}
+
+#endif
+
+
 static inline void __after_dc_op(const int op)
 {
        if (op & OP_FLUSH) {