aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/alchemy
diff options
context:
space:
mode:
authorManuel Lauss <mano@roarinelk.homelinux.net>2008-12-21 03:26:26 -0500
committerRalf Baechle <ralf@linux-mips.org>2009-01-11 04:57:27 -0500
commitac15dad061d351281b0bafbae1ecdd84e601435a (patch)
treedc5536f68f14e3a07f3af1105cfc23a2c317f21f /arch/mips/alchemy
parent564365b0fc3395ed55501ef25705664888cebdbc (diff)
MIPS: Alchemy: dbdma suspend/resume support.
Implement suspend/resume for DBDMA controller and its channels. Signed-off-by: Manuel Lauss <mano@roarinelk.homelinux.net> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/alchemy')
-rw-r--r--arch/mips/alchemy/common/dbdma.c65
-rw-r--r--arch/mips/alchemy/common/power.c11
2 files changed, 76 insertions, 0 deletions
diff --git a/arch/mips/alchemy/common/dbdma.c b/arch/mips/alchemy/common/dbdma.c
index 601ee9180ee4..3ab6d80d150d 100644
--- a/arch/mips/alchemy/common/dbdma.c
+++ b/arch/mips/alchemy/common/dbdma.c
@@ -174,6 +174,11 @@ static dbdev_tab_t dbdev_tab[] = {
174 174
175#define DBDEV_TAB_SIZE ARRAY_SIZE(dbdev_tab) 175#define DBDEV_TAB_SIZE ARRAY_SIZE(dbdev_tab)
176 176
177#ifdef CONFIG_PM
178static u32 au1xxx_dbdma_pm_regs[NUM_DBDMA_CHANS + 1][8];
179#endif
180
181
177static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS]; 182static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS];
178 183
179static dbdev_tab_t *find_dbdev_id(u32 id) 184static dbdev_tab_t *find_dbdev_id(u32 id)
@@ -975,4 +980,64 @@ u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr)
975 return nbytes; 980 return nbytes;
976} 981}
977 982
983#ifdef CONFIG_PM
984void au1xxx_dbdma_suspend(void)
985{
986 int i;
987 u32 addr;
988
989 addr = DDMA_GLOBAL_BASE;
990 au1xxx_dbdma_pm_regs[0][0] = au_readl(addr + 0x00);
991 au1xxx_dbdma_pm_regs[0][1] = au_readl(addr + 0x04);
992 au1xxx_dbdma_pm_regs[0][2] = au_readl(addr + 0x08);
993 au1xxx_dbdma_pm_regs[0][3] = au_readl(addr + 0x0c);
994
995 /* save channel configurations */
996 for (i = 1, addr = DDMA_CHANNEL_BASE; i < NUM_DBDMA_CHANS; i++) {
997 au1xxx_dbdma_pm_regs[i][0] = au_readl(addr + 0x00);
998 au1xxx_dbdma_pm_regs[i][1] = au_readl(addr + 0x04);
999 au1xxx_dbdma_pm_regs[i][2] = au_readl(addr + 0x08);
1000 au1xxx_dbdma_pm_regs[i][3] = au_readl(addr + 0x0c);
1001 au1xxx_dbdma_pm_regs[i][4] = au_readl(addr + 0x10);
1002 au1xxx_dbdma_pm_regs[i][5] = au_readl(addr + 0x14);
1003 au1xxx_dbdma_pm_regs[i][6] = au_readl(addr + 0x18);
1004
1005 /* halt channel */
1006 au_writel(au1xxx_dbdma_pm_regs[i][0] & ~1, addr + 0x00);
1007 au_sync();
1008 while (!(au_readl(addr + 0x14) & 1))
1009 au_sync();
1010
1011 addr += 0x100; /* next channel base */
1012 }
1013 /* disable channel interrupts */
1014 au_writel(0, DDMA_GLOBAL_BASE + 0x0c);
1015 au_sync();
1016}
1017
1018void au1xxx_dbdma_resume(void)
1019{
1020 int i;
1021 u32 addr;
1022
1023 addr = DDMA_GLOBAL_BASE;
1024 au_writel(au1xxx_dbdma_pm_regs[0][0], addr + 0x00);
1025 au_writel(au1xxx_dbdma_pm_regs[0][1], addr + 0x04);
1026 au_writel(au1xxx_dbdma_pm_regs[0][2], addr + 0x08);
1027 au_writel(au1xxx_dbdma_pm_regs[0][3], addr + 0x0c);
1028
1029 /* restore channel configurations */
1030 for (i = 1, addr = DDMA_CHANNEL_BASE; i < NUM_DBDMA_CHANS; i++) {
1031 au_writel(au1xxx_dbdma_pm_regs[i][0], addr + 0x00);
1032 au_writel(au1xxx_dbdma_pm_regs[i][1], addr + 0x04);
1033 au_writel(au1xxx_dbdma_pm_regs[i][2], addr + 0x08);
1034 au_writel(au1xxx_dbdma_pm_regs[i][3], addr + 0x0c);
1035 au_writel(au1xxx_dbdma_pm_regs[i][4], addr + 0x10);
1036 au_writel(au1xxx_dbdma_pm_regs[i][5], addr + 0x14);
1037 au_writel(au1xxx_dbdma_pm_regs[i][6], addr + 0x18);
1038 au_sync();
1039 addr += 0x100; /* next channel base */
1040 }
1041}
1042#endif /* CONFIG_PM */
978#endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */ 1043#endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */
diff --git a/arch/mips/alchemy/common/power.c b/arch/mips/alchemy/common/power.c
index f08312b10d04..f58e151b38d4 100644
--- a/arch/mips/alchemy/common/power.c
+++ b/arch/mips/alchemy/common/power.c
@@ -36,6 +36,9 @@
36 36
37#include <asm/uaccess.h> 37#include <asm/uaccess.h>
38#include <asm/mach-au1x00/au1000.h> 38#include <asm/mach-au1x00/au1000.h>
39#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
40#include <asm/mach-au1x00/au1xxx_dbdma.h>
41#endif
39 42
40#ifdef CONFIG_PM 43#ifdef CONFIG_PM
41 44
@@ -156,6 +159,10 @@ static void save_core_regs(void)
156 sleep_static_memctlr[3][0] = au_readl(MEM_STCFG3); 159 sleep_static_memctlr[3][0] = au_readl(MEM_STCFG3);
157 sleep_static_memctlr[3][1] = au_readl(MEM_STTIME3); 160 sleep_static_memctlr[3][1] = au_readl(MEM_STTIME3);
158 sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3); 161 sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3);
162
163#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
164 au1xxx_dbdma_suspend();
165#endif
159} 166}
160 167
161static void restore_core_regs(void) 168static void restore_core_regs(void)
@@ -221,6 +228,10 @@ static void restore_core_regs(void)
221 } 228 }
222 229
223 restore_au1xxx_intctl(); 230 restore_au1xxx_intctl();
231
232#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
233 au1xxx_dbdma_resume();
234#endif
224} 235}
225 236
226unsigned long suspend_mode; 237unsigned long suspend_mode;