diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2014-06-29 09:33:58 -0400 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2014-07-23 02:00:20 -0400 |
commit | 1b1a22b13352f6798935e01a32c18aaad4090e0a (patch) | |
tree | 5d265c568739d0fb27cd6c14a919238346f7d06f /arch/arc | |
parent | da40ff48bda631b2530e561d5cc0663baae8d7de (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/arc')
-rw-r--r-- | arch/arc/mm/cache_arc700.c | 68 |
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 | ||
269 | static inline void wait_for_flush(void) | 269 | static 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 | |||
287 | static 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 | */ |
281 | static inline void __dc_entire_op(const int cacheop) | 303 | static 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) | |||
317 | static inline void __dc_line_op(unsigned long paddr, unsigned long vaddr, | 326 | static 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 | } |