diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2014-03-15 12:48:11 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2014-05-29 19:48:05 -0400 |
commit | b98556f26dca7f7a7401cdb67b77848f1176a379 (patch) | |
tree | 88638eb18842e8f34898923fa79db78fbeb045f2 /arch/arm/mm | |
parent | cdef8689ef640d5f83e1ac95c6a190f4859c9bf3 (diff) |
ARM: l2c: move and add ARM L2C-2x0/L2C-310 save/resume code to non-OF
Add the save/resume code hooks to the non-OF implementations as well.
There's no reason for the non-OF implementations to be any different
from the OF implementations.
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.c | 151 |
1 files changed, 77 insertions, 74 deletions
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index 713cdcef25d1..4d985c17291c 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c | |||
@@ -383,6 +383,21 @@ static void l2x0_enable(void __iomem *base, u32 aux, unsigned num_lock) | |||
383 | writel_relaxed(L2X0_CTRL_EN, base + L2X0_CTRL); | 383 | writel_relaxed(L2X0_CTRL_EN, base + L2X0_CTRL); |
384 | } | 384 | } |
385 | 385 | ||
386 | static void l2x0_resume(void) | ||
387 | { | ||
388 | if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) { | ||
389 | /* restore aux ctrl and enable l2 */ | ||
390 | l2x0_unlock(readl_relaxed(l2x0_base + L2X0_CACHE_ID)); | ||
391 | |||
392 | writel_relaxed(l2x0_saved_regs.aux_ctrl, l2x0_base + | ||
393 | L2X0_AUX_CTRL); | ||
394 | |||
395 | l2x0_inv_all(); | ||
396 | |||
397 | writel_relaxed(L2X0_CTRL_EN, l2x0_base + L2X0_CTRL); | ||
398 | } | ||
399 | } | ||
400 | |||
386 | static const struct l2c_init_data l2x0_init_fns __initconst = { | 401 | static const struct l2c_init_data l2x0_init_fns __initconst = { |
387 | .enable = l2x0_enable, | 402 | .enable = l2x0_enable, |
388 | .outer_cache = { | 403 | .outer_cache = { |
@@ -392,6 +407,7 @@ static const struct l2c_init_data l2x0_init_fns __initconst = { | |||
392 | .flush_all = l2x0_flush_all, | 407 | .flush_all = l2x0_flush_all, |
393 | .disable = l2x0_disable, | 408 | .disable = l2x0_disable, |
394 | .sync = l2x0_cache_sync, | 409 | .sync = l2x0_cache_sync, |
410 | .resume = l2x0_resume, | ||
395 | }, | 411 | }, |
396 | }; | 412 | }; |
397 | 413 | ||
@@ -422,6 +438,65 @@ static const struct l2c_init_data l2x0_init_fns __initconst = { | |||
422 | * Affects: store buffer | 438 | * Affects: store buffer |
423 | * store buffer is not automatically drained. | 439 | * store buffer is not automatically drained. |
424 | */ | 440 | */ |
441 | static void __init pl310_save(void __iomem *base) | ||
442 | { | ||
443 | u32 l2x0_revision = readl_relaxed(base + L2X0_CACHE_ID) & | ||
444 | L2X0_CACHE_ID_RTL_MASK; | ||
445 | |||
446 | l2x0_saved_regs.tag_latency = readl_relaxed(base + | ||
447 | L2X0_TAG_LATENCY_CTRL); | ||
448 | l2x0_saved_regs.data_latency = readl_relaxed(base + | ||
449 | L2X0_DATA_LATENCY_CTRL); | ||
450 | l2x0_saved_regs.filter_end = readl_relaxed(base + | ||
451 | L2X0_ADDR_FILTER_END); | ||
452 | l2x0_saved_regs.filter_start = readl_relaxed(base + | ||
453 | L2X0_ADDR_FILTER_START); | ||
454 | |||
455 | if (l2x0_revision >= L310_CACHE_ID_RTL_R2P0) { | ||
456 | /* | ||
457 | * From r2p0, there is Prefetch offset/control register | ||
458 | */ | ||
459 | l2x0_saved_regs.prefetch_ctrl = readl_relaxed(base + | ||
460 | L2X0_PREFETCH_CTRL); | ||
461 | /* | ||
462 | * From r3p0, there is Power control register | ||
463 | */ | ||
464 | if (l2x0_revision >= L310_CACHE_ID_RTL_R3P0) | ||
465 | l2x0_saved_regs.pwr_ctrl = readl_relaxed(base + | ||
466 | L2X0_POWER_CTRL); | ||
467 | } | ||
468 | } | ||
469 | |||
470 | static void pl310_resume(void) | ||
471 | { | ||
472 | u32 l2x0_revision; | ||
473 | |||
474 | if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) { | ||
475 | /* restore pl310 setup */ | ||
476 | writel_relaxed(l2x0_saved_regs.tag_latency, | ||
477 | l2x0_base + L2X0_TAG_LATENCY_CTRL); | ||
478 | writel_relaxed(l2x0_saved_regs.data_latency, | ||
479 | l2x0_base + L2X0_DATA_LATENCY_CTRL); | ||
480 | writel_relaxed(l2x0_saved_regs.filter_end, | ||
481 | l2x0_base + L2X0_ADDR_FILTER_END); | ||
482 | writel_relaxed(l2x0_saved_regs.filter_start, | ||
483 | l2x0_base + L2X0_ADDR_FILTER_START); | ||
484 | |||
485 | l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) & | ||
486 | L2X0_CACHE_ID_RTL_MASK; | ||
487 | |||
488 | if (l2x0_revision >= L310_CACHE_ID_RTL_R2P0) { | ||
489 | writel_relaxed(l2x0_saved_regs.prefetch_ctrl, | ||
490 | l2x0_base + L2X0_PREFETCH_CTRL); | ||
491 | if (l2x0_revision >= L310_CACHE_ID_RTL_R3P0) | ||
492 | writel_relaxed(l2x0_saved_regs.pwr_ctrl, | ||
493 | l2x0_base + L2X0_POWER_CTRL); | ||
494 | } | ||
495 | } | ||
496 | |||
497 | l2x0_resume(); | ||
498 | } | ||
499 | |||
425 | static void __init l2c310_fixup(void __iomem *base, u32 cache_id, | 500 | static void __init l2c310_fixup(void __iomem *base, u32 cache_id, |
426 | struct outer_cache_fns *fns) | 501 | struct outer_cache_fns *fns) |
427 | { | 502 | { |
@@ -455,6 +530,7 @@ static const struct l2c_init_data l2c310_init_fns __initconst = { | |||
455 | .num_lock = 8, | 530 | .num_lock = 8, |
456 | .enable = l2c_enable, | 531 | .enable = l2c_enable, |
457 | .fixup = l2c310_fixup, | 532 | .fixup = l2c310_fixup, |
533 | .save = pl310_save, | ||
458 | .outer_cache = { | 534 | .outer_cache = { |
459 | .inv_range = l2x0_inv_range, | 535 | .inv_range = l2x0_inv_range, |
460 | .clean_range = l2x0_clean_range, | 536 | .clean_range = l2x0_clean_range, |
@@ -462,6 +538,7 @@ static const struct l2c_init_data l2c310_init_fns __initconst = { | |||
462 | .flush_all = l2x0_flush_all, | 538 | .flush_all = l2x0_flush_all, |
463 | .disable = l2x0_disable, | 539 | .disable = l2x0_disable, |
464 | .sync = l2x0_cache_sync, | 540 | .sync = l2x0_cache_sync, |
541 | .resume = pl310_resume, | ||
465 | }, | 542 | }, |
466 | }; | 543 | }; |
467 | 544 | ||
@@ -614,21 +691,6 @@ static void __init l2x0_of_parse(const struct device_node *np, | |||
614 | *aux_mask &= ~mask; | 691 | *aux_mask &= ~mask; |
615 | } | 692 | } |
616 | 693 | ||
617 | static void l2x0_resume(void) | ||
618 | { | ||
619 | if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) { | ||
620 | /* restore aux ctrl and enable l2 */ | ||
621 | l2x0_unlock(readl_relaxed(l2x0_base + L2X0_CACHE_ID)); | ||
622 | |||
623 | writel_relaxed(l2x0_saved_regs.aux_ctrl, l2x0_base + | ||
624 | L2X0_AUX_CTRL); | ||
625 | |||
626 | l2x0_inv_all(); | ||
627 | |||
628 | writel_relaxed(L2X0_CTRL_EN, l2x0_base + L2X0_CTRL); | ||
629 | } | ||
630 | } | ||
631 | |||
632 | static const struct l2c_init_data of_l2x0_data __initconst = { | 694 | static const struct l2c_init_data of_l2x0_data __initconst = { |
633 | .of_parse = l2x0_of_parse, | 695 | .of_parse = l2x0_of_parse, |
634 | .enable = l2x0_enable, | 696 | .enable = l2x0_enable, |
@@ -677,65 +739,6 @@ static void __init pl310_of_parse(const struct device_node *np, | |||
677 | } | 739 | } |
678 | } | 740 | } |
679 | 741 | ||
680 | static void __init pl310_save(void __iomem *base) | ||
681 | { | ||
682 | u32 l2x0_revision = readl_relaxed(base + L2X0_CACHE_ID) & | ||
683 | L2X0_CACHE_ID_RTL_MASK; | ||
684 | |||
685 | l2x0_saved_regs.tag_latency = readl_relaxed(base + | ||
686 | L2X0_TAG_LATENCY_CTRL); | ||
687 | l2x0_saved_regs.data_latency = readl_relaxed(base + | ||
688 | L2X0_DATA_LATENCY_CTRL); | ||
689 | l2x0_saved_regs.filter_end = readl_relaxed(base + | ||
690 | L2X0_ADDR_FILTER_END); | ||
691 | l2x0_saved_regs.filter_start = readl_relaxed(base + | ||
692 | L2X0_ADDR_FILTER_START); | ||
693 | |||
694 | if (l2x0_revision >= L310_CACHE_ID_RTL_R2P0) { | ||
695 | /* | ||
696 | * From r2p0, there is Prefetch offset/control register | ||
697 | */ | ||
698 | l2x0_saved_regs.prefetch_ctrl = readl_relaxed(base + | ||
699 | L2X0_PREFETCH_CTRL); | ||
700 | /* | ||
701 | * From r3p0, there is Power control register | ||
702 | */ | ||
703 | if (l2x0_revision >= L310_CACHE_ID_RTL_R3P0) | ||
704 | l2x0_saved_regs.pwr_ctrl = readl_relaxed(base + | ||
705 | L2X0_POWER_CTRL); | ||
706 | } | ||
707 | } | ||
708 | |||
709 | static void pl310_resume(void) | ||
710 | { | ||
711 | u32 l2x0_revision; | ||
712 | |||
713 | if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) { | ||
714 | /* restore pl310 setup */ | ||
715 | writel_relaxed(l2x0_saved_regs.tag_latency, | ||
716 | l2x0_base + L2X0_TAG_LATENCY_CTRL); | ||
717 | writel_relaxed(l2x0_saved_regs.data_latency, | ||
718 | l2x0_base + L2X0_DATA_LATENCY_CTRL); | ||
719 | writel_relaxed(l2x0_saved_regs.filter_end, | ||
720 | l2x0_base + L2X0_ADDR_FILTER_END); | ||
721 | writel_relaxed(l2x0_saved_regs.filter_start, | ||
722 | l2x0_base + L2X0_ADDR_FILTER_START); | ||
723 | |||
724 | l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) & | ||
725 | L2X0_CACHE_ID_RTL_MASK; | ||
726 | |||
727 | if (l2x0_revision >= L310_CACHE_ID_RTL_R2P0) { | ||
728 | writel_relaxed(l2x0_saved_regs.prefetch_ctrl, | ||
729 | l2x0_base + L2X0_PREFETCH_CTRL); | ||
730 | if (l2x0_revision >= L310_CACHE_ID_RTL_R3P0) | ||
731 | writel_relaxed(l2x0_saved_regs.pwr_ctrl, | ||
732 | l2x0_base + L2X0_POWER_CTRL); | ||
733 | } | ||
734 | } | ||
735 | |||
736 | l2x0_resume(); | ||
737 | } | ||
738 | |||
739 | static const struct l2c_init_data of_pl310_data __initconst = { | 742 | static const struct l2c_init_data of_pl310_data __initconst = { |
740 | .num_lock = 8, | 743 | .num_lock = 8, |
741 | .of_parse = pl310_of_parse, | 744 | .of_parse = pl310_of_parse, |