diff options
author | Manuel Lauss <mano@roarinelk.homelinux.net> | 2008-12-21 03:26:26 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2009-01-11 04:57:27 -0500 |
commit | ac15dad061d351281b0bafbae1ecdd84e601435a (patch) | |
tree | dc5536f68f14e3a07f3af1105cfc23a2c317f21f /arch | |
parent | 564365b0fc3395ed55501ef25705664888cebdbc (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')
-rw-r--r-- | arch/mips/alchemy/common/dbdma.c | 65 | ||||
-rw-r--r-- | arch/mips/alchemy/common/power.c | 11 | ||||
-rw-r--r-- | arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h | 5 |
3 files changed, 81 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 | ||
178 | static u32 au1xxx_dbdma_pm_regs[NUM_DBDMA_CHANS + 1][8]; | ||
179 | #endif | ||
180 | |||
181 | |||
177 | static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS]; | 182 | static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS]; |
178 | 183 | ||
179 | static dbdev_tab_t *find_dbdev_id(u32 id) | 184 | static 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 | ||
984 | void 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 | |||
1018 | void 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 | ||
161 | static void restore_core_regs(void) | 168 | static 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 | ||
226 | unsigned long suspend_mode; | 237 | unsigned long suspend_mode; |
diff --git a/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h b/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h index 44a67bf05dc1..06f68f43800a 100644 --- a/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h +++ b/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h | |||
@@ -357,6 +357,11 @@ u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr); | |||
357 | u32 au1xxx_ddma_add_device(dbdev_tab_t *dev); | 357 | u32 au1xxx_ddma_add_device(dbdev_tab_t *dev); |
358 | extern void au1xxx_ddma_del_device(u32 devid); | 358 | extern void au1xxx_ddma_del_device(u32 devid); |
359 | void *au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp); | 359 | void *au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp); |
360 | #ifdef CONFIG_PM | ||
361 | void au1xxx_dbdma_suspend(void); | ||
362 | void au1xxx_dbdma_resume(void); | ||
363 | #endif | ||
364 | |||
360 | 365 | ||
361 | /* | 366 | /* |
362 | * Some compatibilty macros -- needed to make changes to API | 367 | * Some compatibilty macros -- needed to make changes to API |