aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2014-06-29 09:33:58 -0400
committerVineet Gupta <vgupta@synopsys.com>2014-07-23 02:00:20 -0400
commit1b1a22b13352f6798935e01a32c18aaad4090e0a (patch)
tree5d265c568739d0fb27cd6c14a919238346f7d06f /arch
parentda40ff48bda631b2530e561d5cc0663baae8d7de (diff)
ARC: move common ops for line/full cache into helpers
INV cmd for dcache provides 2 modes discard or wback-before-discard. One is default and other needs to be set, if so desired. This is common for line-op/entire-cache-op. So refactor them out into a helper Doesn't affect generated code but paves way for any common micro-optimization. Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arc/mm/cache_arc700.c68
1 files changed, 32 insertions, 36 deletions
diff --git a/arch/arc/mm/cache_arc700.c b/arch/arc/mm/cache_arc700.c
index 8070928e89de..1e6766cf9650 100644
--- a/arch/arc/mm/cache_arc700.c
+++ b/arch/arc/mm/cache_arc700.c
@@ -266,10 +266,32 @@ static inline void __cache_line_loop(unsigned long paddr, unsigned long vaddr,
266 * Machine specific helpers for Entire D-Cache or Per Line ops 266 * Machine specific helpers for Entire D-Cache or Per Line ops
267 */ 267 */
268 268
269static inline void wait_for_flush(void) 269static unsigned int __before_dc_op(const int op)
270{ 270{
271 while (read_aux_reg(ARC_REG_DC_CTRL) & DC_CTRL_FLUSH_STATUS) 271 unsigned int reg = reg;
272 ; 272
273 if (op == OP_FLUSH_N_INV) {
274 /* Dcache provides 2 cmd: FLUSH or INV
275 * INV inturn has sub-modes: DISCARD or FLUSH-BEFORE
276 * flush-n-inv is achieved by INV cmd but with IM=1
277 * So toggle INV sub-mode depending on op request and default
278 */
279 reg = read_aux_reg(ARC_REG_DC_CTRL);
280 write_aux_reg(ARC_REG_DC_CTRL, reg | DC_CTRL_INV_MODE_FLUSH)
281 ;
282 }
283
284 return reg;
285}
286
287static void __after_dc_op(const int op, unsigned int reg)
288{
289 if (op & OP_FLUSH) /* flush / flush-n-inv both wait */
290 while (read_aux_reg(ARC_REG_DC_CTRL) & DC_CTRL_FLUSH_STATUS);
291
292 /* Switch back to default Invalidate mode */
293 if (op == OP_FLUSH_N_INV)
294 write_aux_reg(ARC_REG_DC_CTRL, reg & ~DC_CTRL_INV_MODE_FLUSH);
273} 295}
274 296
275/* 297/*
@@ -280,18 +302,10 @@ static inline void wait_for_flush(void)
280 */ 302 */
281static inline void __dc_entire_op(const int cacheop) 303static inline void __dc_entire_op(const int cacheop)
282{ 304{
283 unsigned int tmp = tmp; 305 unsigned int ctrl_reg;
284 int aux; 306 int aux;
285 307
286 if (cacheop == OP_FLUSH_N_INV) { 308 ctrl_reg = __before_dc_op(cacheop);
287 /* Dcache provides 2 cmd: FLUSH or INV
288 * INV inturn has sub-modes: DISCARD or FLUSH-BEFORE
289 * flush-n-inv is achieved by INV cmd but with IM=1
290 * Default INV sub-mode is DISCARD, which needs to be toggled
291 */
292 tmp = read_aux_reg(ARC_REG_DC_CTRL);
293 write_aux_reg(ARC_REG_DC_CTRL, tmp | DC_CTRL_INV_MODE_FLUSH);
294 }
295 309
296 if (cacheop & OP_INV) /* Inv or flush-n-inv use same cmd reg */ 310 if (cacheop & OP_INV) /* Inv or flush-n-inv use same cmd reg */
297 aux = ARC_REG_DC_IVDC; 311 aux = ARC_REG_DC_IVDC;
@@ -300,12 +314,7 @@ static inline void __dc_entire_op(const int cacheop)
300 314
301 write_aux_reg(aux, 0x1); 315 write_aux_reg(aux, 0x1);
302 316
303 if (cacheop & OP_FLUSH) /* flush / flush-n-inv both wait */ 317 __after_dc_op(cacheop, ctrl_reg);
304 wait_for_flush();
305
306 /* Switch back the DISCARD ONLY Invalidate mode */
307 if (cacheop == OP_FLUSH_N_INV)
308 write_aux_reg(ARC_REG_DC_CTRL, tmp & ~DC_CTRL_INV_MODE_FLUSH);
309} 318}
310 319
311/* For kernel mappings cache operation: index is same as paddr */ 320/* For kernel mappings cache operation: index is same as paddr */
@@ -317,29 +326,16 @@ static inline void __dc_entire_op(const int cacheop)
317static inline void __dc_line_op(unsigned long paddr, unsigned long vaddr, 326static inline void __dc_line_op(unsigned long paddr, unsigned long vaddr,
318 unsigned long sz, const int cacheop) 327 unsigned long sz, const int cacheop)
319{ 328{
320 unsigned long flags, tmp = tmp; 329 unsigned long flags;
330 unsigned int ctrl_reg;
321 331
322 local_irq_save(flags); 332 local_irq_save(flags);
323 333
324 if (cacheop == OP_FLUSH_N_INV) { 334 ctrl_reg = __before_dc_op(cacheop);
325 /*
326 * Dcache provides 2 cmd: FLUSH or INV
327 * INV inturn has sub-modes: DISCARD or FLUSH-BEFORE
328 * flush-n-inv is achieved by INV cmd but with IM=1
329 * Default INV sub-mode is DISCARD, which needs to be toggled
330 */
331 tmp = read_aux_reg(ARC_REG_DC_CTRL);
332 write_aux_reg(ARC_REG_DC_CTRL, tmp | DC_CTRL_INV_MODE_FLUSH);
333 }
334 335
335 __cache_line_loop(paddr, vaddr, sz, cacheop); 336 __cache_line_loop(paddr, vaddr, sz, cacheop);
336 337
337 if (cacheop & OP_FLUSH) /* flush / flush-n-inv both wait */ 338 __after_dc_op(cacheop, ctrl_reg);
338 wait_for_flush();
339
340 /* Switch back the DISCARD ONLY Invalidate mode */
341 if (cacheop == OP_FLUSH_N_INV)
342 write_aux_reg(ARC_REG_DC_CTRL, tmp & ~DC_CTRL_INV_MODE_FLUSH);
343 339
344 local_irq_restore(flags); 340 local_irq_restore(flags);
345} 341}