ARCv2: IOC: refactor the IOC and SLC operations into own functions
authorVineet Gupta <vgupta@synopsys.com>
Wed, 22 Jun 2016 10:13:22 +0000 (15:43 +0530)
committerVineet Gupta <vgupta@synopsys.com>
Wed, 18 Jan 2017 22:35:10 +0000 (14:35 -0800)
 - Move IOC setup into arc_ioc_setup()
 - Move SLC disabling into arc_slc_disable()

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
arch/arc/include/asm/cache.h
arch/arc/mm/cache.c

index b3410ff6a62dbcc589ffa411f326d6954c8ba80c..5f924a1024fa5d83b251013385dd938da63f98ed 100644 (file)
@@ -92,8 +92,8 @@ extern unsigned long perip_base, perip_end;
 #define ARC_REG_SLC_RGN_END    0x916
 
 /* Bit val in SLC_CONTROL */
+#define SLC_CTRL_DIS           0x001
 #define SLC_CTRL_IM            0x040
-#define SLC_CTRL_DISABLE       0x001
 #define SLC_CTRL_BUSY          0x100
 #define SLC_CTRL_RGN_OP_INV    0x200
 
index 6d98e1d57a18444a0aaacda7b3b8b10e471cdb87..2c36370a168984a6d3a8bc96638916333c3168e6 100644 (file)
@@ -601,6 +601,40 @@ noinline void slc_op(phys_addr_t paddr, unsigned long sz, const int op)
 #endif
 }
 
+noinline static void slc_entire_op(const int op)
+{
+       unsigned int ctrl, r = ARC_REG_SLC_CTRL;
+
+       ctrl = read_aux_reg(r);
+
+       if (!(op & OP_FLUSH))           /* i.e. OP_INV */
+               ctrl &= ~SLC_CTRL_IM;   /* clear IM: Disable flush before Inv */
+       else
+               ctrl |= SLC_CTRL_IM;
+
+       write_aux_reg(r, ctrl);
+
+       write_aux_reg(ARC_REG_SLC_INVALIDATE, 1);
+
+       /* Important to wait for flush to complete */
+       while (read_aux_reg(r) & SLC_CTRL_BUSY);
+}
+
+static inline void arc_slc_disable(void)
+{
+       const int r = ARC_REG_SLC_CTRL;
+
+       slc_entire_op(OP_FLUSH_N_INV);
+       write_aux_reg(r, read_aux_reg(r) | SLC_CTRL_DIS);
+}
+
+static inline void arc_slc_enable(void)
+{
+       const int r = ARC_REG_SLC_CTRL;
+
+       write_aux_reg(r, read_aux_reg(r) & ~SLC_CTRL_DIS);
+}
+
 /***********************************************************
  * Exported APIs
  */
@@ -927,6 +961,14 @@ SYSCALL_DEFINE3(cacheflush, uint32_t, start, uint32_t, sz, uint32_t, flags)
        return 0;
 }
 
+noinline void arc_ioc_setup(void)
+{
+       write_aux_reg(ARC_REG_IO_COH_AP0_BASE, 0x80000);
+       write_aux_reg(ARC_REG_IO_COH_AP0_SIZE, 0x11);
+       write_aux_reg(ARC_REG_IO_COH_PARTIAL, 1);
+       write_aux_reg(ARC_REG_IO_COH_ENABLE, 1);
+}
+
 void arc_cache_init(void)
 {
        unsigned int __maybe_unused cpu = smp_processor_id();
@@ -989,30 +1031,14 @@ void arc_cache_init(void)
                }
        }
 
-       if (is_isa_arcv2() && l2_line_sz && !slc_enable) {
-
-               /* IM set : flush before invalidate */
-               write_aux_reg(ARC_REG_SLC_CTRL,
-                       read_aux_reg(ARC_REG_SLC_CTRL) | SLC_CTRL_IM);
+       /* Note that SLC disable not formally supported till HS 3.0 */
+       if (is_isa_arcv2() && l2_line_sz && !slc_enable)
+               arc_slc_disable();
 
-               write_aux_reg(ARC_REG_SLC_INVALIDATE, 1);
-
-               /* Important to wait for flush to complete */
-               while (read_aux_reg(ARC_REG_SLC_CTRL) & SLC_CTRL_BUSY);
-               write_aux_reg(ARC_REG_SLC_CTRL,
-                       read_aux_reg(ARC_REG_SLC_CTRL) | SLC_CTRL_DISABLE);
-       }
+       if (is_isa_arcv2() && ioc_enable)
+               arc_ioc_setup();
 
        if (is_isa_arcv2() && ioc_enable) {
-               /* IO coherency base - 0x8z */
-               write_aux_reg(ARC_REG_IO_COH_AP0_BASE, 0x80000);
-               /* IO coherency aperture size - 512Mb: 0x8z-0xAz */
-               write_aux_reg(ARC_REG_IO_COH_AP0_SIZE, 0x11);
-               /* Enable partial writes */
-               write_aux_reg(ARC_REG_IO_COH_PARTIAL, 1);
-               /* Enable IO coherency */
-               write_aux_reg(ARC_REG_IO_COH_ENABLE, 1);
-
                __dma_cache_wback_inv = __dma_cache_wback_inv_ioc;
                __dma_cache_inv = __dma_cache_inv_ioc;
                __dma_cache_wback = __dma_cache_wback_ioc;