aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2014-03-15 14:55:53 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2014-05-29 19:48:15 -0400
commit6a28cf59ff1144398d9d32d409ed8cbf1215922d (patch)
treee7f8469ba2efaac1b6d6e2ad45f164eef8b96c77 /arch/arm/mm
parentbda0b74e6a5a4ce25198f55889bb321532c63d92 (diff)
ARM: l2c: add L2C-210 specific handlers
Add L2C-210 specific cache operation handlers. These are tailored to the requirements of the L2C-210 cache controller, which doesn't require any workarounds. We avoid using the way operations during normal operation, which means we can avoid locking: the only time we use the way operations are during initialisation, and when disabling the cache. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mm')
-rw-r--r--arch/arm/mm/cache-l2x0.c123
1 files changed, 122 insertions, 1 deletions
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 9586be73ca4f..d07fa4fc95a3 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -389,6 +389,108 @@ static const struct l2c_init_data l2x0_init_fns __initconst = {
389}; 389};
390 390
391/* 391/*
392 * L2C-210 specific code.
393 *
394 * The L2C-2x0 PA, set/way and sync operations are atomic, but we must
395 * ensure that no background operation is running. The way operations
396 * are all background tasks.
397 *
398 * While a background operation is in progress, any new operation is
399 * ignored (unspecified whether this causes an error.) Thankfully, not
400 * used on SMP.
401 *
402 * Never has a different sync register other than L2X0_CACHE_SYNC, but
403 * we use sync_reg_offset here so we can share some of this with L2C-310.
404 */
405static void __l2c210_cache_sync(void __iomem *base)
406{
407 writel_relaxed(0, base + sync_reg_offset);
408}
409
410static void __l2c210_op_pa_range(void __iomem *reg, unsigned long start,
411 unsigned long end)
412{
413 while (start < end) {
414 writel_relaxed(start, reg);
415 start += CACHE_LINE_SIZE;
416 }
417}
418
419static void l2c210_inv_range(unsigned long start, unsigned long end)
420{
421 void __iomem *base = l2x0_base;
422
423 if (start & (CACHE_LINE_SIZE - 1)) {
424 start &= ~(CACHE_LINE_SIZE - 1);
425 writel_relaxed(start, base + L2X0_CLEAN_INV_LINE_PA);
426 start += CACHE_LINE_SIZE;
427 }
428
429 if (end & (CACHE_LINE_SIZE - 1)) {
430 end &= ~(CACHE_LINE_SIZE - 1);
431 writel_relaxed(end, base + L2X0_CLEAN_INV_LINE_PA);
432 }
433
434 __l2c210_op_pa_range(base + L2X0_INV_LINE_PA, start, end);
435 __l2c210_cache_sync(base);
436}
437
438static void l2c210_clean_range(unsigned long start, unsigned long end)
439{
440 void __iomem *base = l2x0_base;
441
442 start &= ~(CACHE_LINE_SIZE - 1);
443 __l2c210_op_pa_range(base + L2X0_CLEAN_LINE_PA, start, end);
444 __l2c210_cache_sync(base);
445}
446
447static void l2c210_flush_range(unsigned long start, unsigned long end)
448{
449 void __iomem *base = l2x0_base;
450
451 start &= ~(CACHE_LINE_SIZE - 1);
452 __l2c210_op_pa_range(base + L2X0_CLEAN_INV_LINE_PA, start, end);
453 __l2c210_cache_sync(base);
454}
455
456static void l2c210_flush_all(void)
457{
458 void __iomem *base = l2x0_base;
459
460 BUG_ON(!irqs_disabled());
461
462 __l2c_op_way(base + L2X0_CLEAN_INV_WAY);
463 __l2c210_cache_sync(base);
464}
465
466static void l2c210_sync(void)
467{
468 __l2c210_cache_sync(l2x0_base);
469}
470
471static void l2c210_resume(void)
472{
473 void __iomem *base = l2x0_base;
474
475 if (!(readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN))
476 l2c_enable(base, l2x0_saved_regs.aux_ctrl, 1);
477}
478
479static const struct l2c_init_data l2c210_data __initconst = {
480 .num_lock = 1,
481 .enable = l2c_enable,
482 .outer_cache = {
483 .inv_range = l2c210_inv_range,
484 .clean_range = l2c210_clean_range,
485 .flush_range = l2c210_flush_range,
486 .flush_all = l2c210_flush_all,
487 .disable = l2c_disable,
488 .sync = l2c210_sync,
489 .resume = l2c210_resume,
490 },
491};
492
493/*
392 * L2C-310 specific code. 494 * L2C-310 specific code.
393 * 495 *
394 * Errata: 496 * Errata:
@@ -623,6 +725,10 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
623 data = &l2x0_init_fns; 725 data = &l2x0_init_fns;
624 break; 726 break;
625 727
728 case L2X0_CACHE_ID_PART_L210:
729 data = &l2c210_data;
730 break;
731
626 case L2X0_CACHE_ID_PART_L310: 732 case L2X0_CACHE_ID_PART_L310:
627 data = &l2c310_init_fns; 733 data = &l2c310_init_fns;
628 break; 734 break;
@@ -672,6 +778,21 @@ static void __init l2x0_of_parse(const struct device_node *np,
672 *aux_mask &= ~mask; 778 *aux_mask &= ~mask;
673} 779}
674 780
781static const struct l2c_init_data of_l2c210_data __initconst = {
782 .num_lock = 1,
783 .of_parse = l2x0_of_parse,
784 .enable = l2c_enable,
785 .outer_cache = {
786 .inv_range = l2c210_inv_range,
787 .clean_range = l2c210_clean_range,
788 .flush_range = l2c210_flush_range,
789 .flush_all = l2c210_flush_all,
790 .disable = l2c_disable,
791 .sync = l2c210_sync,
792 .resume = l2c210_resume,
793 },
794};
795
675static const struct l2c_init_data of_l2x0_data __initconst = { 796static const struct l2c_init_data of_l2x0_data __initconst = {
676 .of_parse = l2x0_of_parse, 797 .of_parse = l2x0_of_parse,
677 .enable = l2x0_enable, 798 .enable = l2x0_enable,
@@ -1117,7 +1238,7 @@ static const struct l2c_init_data of_tauros3_data __initconst = {
1117 1238
1118#define L2C_ID(name, fns) { .compatible = name, .data = (void *)&fns } 1239#define L2C_ID(name, fns) { .compatible = name, .data = (void *)&fns }
1119static const struct of_device_id l2x0_ids[] __initconst = { 1240static const struct of_device_id l2x0_ids[] __initconst = {
1120 L2C_ID("arm,l210-cache", of_l2x0_data), 1241 L2C_ID("arm,l210-cache", of_l2c210_data),
1121 L2C_ID("arm,l220-cache", of_l2x0_data), 1242 L2C_ID("arm,l220-cache", of_l2x0_data),
1122 L2C_ID("arm,pl310-cache", of_pl310_data), 1243 L2C_ID("arm,pl310-cache", of_pl310_data),
1123 L2C_ID("brcm,bcm11351-a2-pl310-cache", of_bcm_l2x0_data), 1244 L2C_ID("brcm,bcm11351-a2-pl310-cache", of_bcm_l2x0_data),