aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bus/mvebu-mbus.c
diff options
context:
space:
mode:
authorThomas Petazzoni <thomas.petazzoni@free-electrons.com>2014-11-21 11:00:04 -0500
committerJason Cooper <jason@lakedaemon.net>2014-11-30 11:40:11 -0500
commit4749c02b8da6d8dbc29218652985bda844017e95 (patch)
tree992fd5ce8e264a02637ec8be69a828b16807c75f /drivers/bus/mvebu-mbus.c
parenta0e89c02da974838053a3604025e43600dc6ac45 (diff)
bus: mvebu-mbus: provide a mechanism to save SDRAM window configuration
On Marvell EBU platforms, when doing suspend/resume, the SDRAM window configuration must be saved on suspend, and restored on resume. However, it needs to be restored on resume *before* re-entering the kernel, because the SDRAM window configuration defines the layout of the memory. For this reason, it cannot simply be done in the ->suspend() and ->resume() hooks of the mvebu-mbus driver. Instead, it needs to be restored by the bootloader "boot info" mechanism used when resuming. This mechanism allows the kernel to define a list of (address, value) pairs when suspending, that the bootloader will restore on resume before jumping back into the kernel. This commit therefore adds a new function to the mvebu-mbus driver, called mvebu_mbus_save_cpu_target(), which will be called by the platform code to make the mvebu-mbus driver save the SDRAM window configuration in a way that can be understood by the bootloader "boot info" mechanism. Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Reviewed-by: Gregory CLEMENT <gregory.clement@free-electrons.com> Link: https://lkml.kernel.org/r/1416585613-2113-8-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Jason Cooper <jason@lakedaemon.net>
Diffstat (limited to 'drivers/bus/mvebu-mbus.c')
-rw-r--r--drivers/bus/mvebu-mbus.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c
index e8c159399c82..eb7682dc123b 100644
--- a/drivers/bus/mvebu-mbus.c
+++ b/drivers/bus/mvebu-mbus.c
@@ -110,6 +110,8 @@ struct mvebu_mbus_soc_data {
110 bool has_mbus_bridge; 110 bool has_mbus_bridge;
111 unsigned int (*win_cfg_offset)(const int win); 111 unsigned int (*win_cfg_offset)(const int win);
112 void (*setup_cpu_target)(struct mvebu_mbus_state *s); 112 void (*setup_cpu_target)(struct mvebu_mbus_state *s);
113 int (*save_cpu_target)(struct mvebu_mbus_state *s,
114 u32 *store_addr);
113 int (*show_cpu_target)(struct mvebu_mbus_state *s, 115 int (*show_cpu_target)(struct mvebu_mbus_state *s,
114 struct seq_file *seq, void *v); 116 struct seq_file *seq, void *v);
115}; 117};
@@ -128,6 +130,7 @@ struct mvebu_mbus_state {
128 void __iomem *mbuswins_base; 130 void __iomem *mbuswins_base;
129 void __iomem *sdramwins_base; 131 void __iomem *sdramwins_base;
130 void __iomem *mbusbridge_base; 132 void __iomem *mbusbridge_base;
133 phys_addr_t sdramwins_phys_base;
131 struct dentry *debugfs_root; 134 struct dentry *debugfs_root;
132 struct dentry *debugfs_sdram; 135 struct dentry *debugfs_sdram;
133 struct dentry *debugfs_devs; 136 struct dentry *debugfs_devs;
@@ -541,6 +544,28 @@ mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus)
541 mvebu_mbus_dram_info.num_cs = cs; 544 mvebu_mbus_dram_info.num_cs = cs;
542} 545}
543 546
547static int
548mvebu_mbus_default_save_cpu_target(struct mvebu_mbus_state *mbus,
549 u32 *store_addr)
550{
551 int i;
552
553 for (i = 0; i < 4; i++) {
554 u32 base = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i));
555 u32 size = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i));
556
557 writel(mbus->sdramwins_phys_base + DDR_BASE_CS_OFF(i),
558 store_addr++);
559 writel(base, store_addr++);
560 writel(mbus->sdramwins_phys_base + DDR_SIZE_CS_OFF(i),
561 store_addr++);
562 writel(size, store_addr++);
563 }
564
565 /* We've written 16 words to the store address */
566 return 16;
567}
568
544static void __init 569static void __init
545mvebu_mbus_dove_setup_cpu_target(struct mvebu_mbus_state *mbus) 570mvebu_mbus_dove_setup_cpu_target(struct mvebu_mbus_state *mbus)
546{ 571{
@@ -571,11 +596,35 @@ mvebu_mbus_dove_setup_cpu_target(struct mvebu_mbus_state *mbus)
571 mvebu_mbus_dram_info.num_cs = cs; 596 mvebu_mbus_dram_info.num_cs = cs;
572} 597}
573 598
599static int
600mvebu_mbus_dove_save_cpu_target(struct mvebu_mbus_state *mbus,
601 u32 *store_addr)
602{
603 int i;
604
605 for (i = 0; i < 2; i++) {
606 u32 map = readl(mbus->sdramwins_base + DOVE_DDR_BASE_CS_OFF(i));
607
608 writel(mbus->sdramwins_phys_base + DOVE_DDR_BASE_CS_OFF(i),
609 store_addr++);
610 writel(map, store_addr++);
611 }
612
613 /* We've written 4 words to the store address */
614 return 4;
615}
616
617int mvebu_mbus_save_cpu_target(u32 *store_addr)
618{
619 return mbus_state.soc->save_cpu_target(&mbus_state, store_addr);
620}
621
574static const struct mvebu_mbus_soc_data armada_370_xp_mbus_data = { 622static const struct mvebu_mbus_soc_data armada_370_xp_mbus_data = {
575 .num_wins = 20, 623 .num_wins = 20,
576 .num_remappable_wins = 8, 624 .num_remappable_wins = 8,
577 .has_mbus_bridge = true, 625 .has_mbus_bridge = true,
578 .win_cfg_offset = armada_370_xp_mbus_win_offset, 626 .win_cfg_offset = armada_370_xp_mbus_win_offset,
627 .save_cpu_target = mvebu_mbus_default_save_cpu_target,
579 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, 628 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
580 .show_cpu_target = mvebu_sdram_debug_show_orion, 629 .show_cpu_target = mvebu_sdram_debug_show_orion,
581}; 630};
@@ -584,6 +633,7 @@ static const struct mvebu_mbus_soc_data kirkwood_mbus_data = {
584 .num_wins = 8, 633 .num_wins = 8,
585 .num_remappable_wins = 4, 634 .num_remappable_wins = 4,
586 .win_cfg_offset = orion_mbus_win_offset, 635 .win_cfg_offset = orion_mbus_win_offset,
636 .save_cpu_target = mvebu_mbus_default_save_cpu_target,
587 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, 637 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
588 .show_cpu_target = mvebu_sdram_debug_show_orion, 638 .show_cpu_target = mvebu_sdram_debug_show_orion,
589}; 639};
@@ -592,6 +642,7 @@ static const struct mvebu_mbus_soc_data dove_mbus_data = {
592 .num_wins = 8, 642 .num_wins = 8,
593 .num_remappable_wins = 4, 643 .num_remappable_wins = 4,
594 .win_cfg_offset = orion_mbus_win_offset, 644 .win_cfg_offset = orion_mbus_win_offset,
645 .save_cpu_target = mvebu_mbus_dove_save_cpu_target,
595 .setup_cpu_target = mvebu_mbus_dove_setup_cpu_target, 646 .setup_cpu_target = mvebu_mbus_dove_setup_cpu_target,
596 .show_cpu_target = mvebu_sdram_debug_show_dove, 647 .show_cpu_target = mvebu_sdram_debug_show_dove,
597}; 648};
@@ -604,6 +655,7 @@ static const struct mvebu_mbus_soc_data orion5x_4win_mbus_data = {
604 .num_wins = 8, 655 .num_wins = 8,
605 .num_remappable_wins = 4, 656 .num_remappable_wins = 4,
606 .win_cfg_offset = orion_mbus_win_offset, 657 .win_cfg_offset = orion_mbus_win_offset,
658 .save_cpu_target = mvebu_mbus_default_save_cpu_target,
607 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, 659 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
608 .show_cpu_target = mvebu_sdram_debug_show_orion, 660 .show_cpu_target = mvebu_sdram_debug_show_orion,
609}; 661};
@@ -612,6 +664,7 @@ static const struct mvebu_mbus_soc_data orion5x_2win_mbus_data = {
612 .num_wins = 8, 664 .num_wins = 8,
613 .num_remappable_wins = 2, 665 .num_remappable_wins = 2,
614 .win_cfg_offset = orion_mbus_win_offset, 666 .win_cfg_offset = orion_mbus_win_offset,
667 .save_cpu_target = mvebu_mbus_default_save_cpu_target,
615 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, 668 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
616 .show_cpu_target = mvebu_sdram_debug_show_orion, 669 .show_cpu_target = mvebu_sdram_debug_show_orion,
617}; 670};
@@ -620,6 +673,7 @@ static const struct mvebu_mbus_soc_data mv78xx0_mbus_data = {
620 .num_wins = 14, 673 .num_wins = 14,
621 .num_remappable_wins = 8, 674 .num_remappable_wins = 8,
622 .win_cfg_offset = mv78xx0_mbus_win_offset, 675 .win_cfg_offset = mv78xx0_mbus_win_offset,
676 .save_cpu_target = mvebu_mbus_default_save_cpu_target,
623 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, 677 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
624 .show_cpu_target = mvebu_sdram_debug_show_orion, 678 .show_cpu_target = mvebu_sdram_debug_show_orion,
625}; 679};
@@ -804,6 +858,8 @@ static int __init mvebu_mbus_common_init(struct mvebu_mbus_state *mbus,
804 return -ENOMEM; 858 return -ENOMEM;
805 } 859 }
806 860
861 mbus->sdramwins_phys_base = sdramwins_phys_base;
862
807 if (mbusbridge_phys_base) { 863 if (mbusbridge_phys_base) {
808 mbus->mbusbridge_base = ioremap(mbusbridge_phys_base, 864 mbus->mbusbridge_base = ioremap(mbusbridge_phys_base,
809 mbusbridge_size); 865 mbusbridge_size);