diff options
author | Magnus Damm <damm@opensource.se> | 2009-10-30 00:24:40 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-10-30 01:38:45 -0400 |
commit | bb3e0eed9dd51987c7462bae2880a3d4d750c55a (patch) | |
tree | 3e8bb7465ab8e39c7836562dccb539817fe3c5f3 /arch/sh/kernel | |
parent | 03625e7107cde46e2851557ec06426799e6ae7f2 (diff) |
sh: Add R-standby sleep mode support
Add R-standby specific bits to the SuperH Mobile sleep code.
Signed-off-by: Magnus Damm <damm@opensource.se>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r-- | arch/sh/kernel/asm-offsets.c | 3 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/shmobile/pm.c | 13 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/shmobile/sleep.S | 12 |
3 files changed, 21 insertions, 7 deletions
diff --git a/arch/sh/kernel/asm-offsets.c b/arch/sh/kernel/asm-offsets.c index 6026b0f849a1..08a2be775b6c 100644 --- a/arch/sh/kernel/asm-offsets.c +++ b/arch/sh/kernel/asm-offsets.c | |||
@@ -38,12 +38,15 @@ int main(void) | |||
38 | DEFINE(SH_SLEEP_MODE, offsetof(struct sh_sleep_data, mode)); | 38 | DEFINE(SH_SLEEP_MODE, offsetof(struct sh_sleep_data, mode)); |
39 | DEFINE(SH_SLEEP_SF_PRE, offsetof(struct sh_sleep_data, sf_pre)); | 39 | DEFINE(SH_SLEEP_SF_PRE, offsetof(struct sh_sleep_data, sf_pre)); |
40 | DEFINE(SH_SLEEP_SF_POST, offsetof(struct sh_sleep_data, sf_post)); | 40 | DEFINE(SH_SLEEP_SF_POST, offsetof(struct sh_sleep_data, sf_post)); |
41 | DEFINE(SH_SLEEP_RESUME, offsetof(struct sh_sleep_data, resume)); | ||
41 | DEFINE(SH_SLEEP_VBR, offsetof(struct sh_sleep_data, vbr)); | 42 | DEFINE(SH_SLEEP_VBR, offsetof(struct sh_sleep_data, vbr)); |
42 | DEFINE(SH_SLEEP_SPC, offsetof(struct sh_sleep_data, spc)); | 43 | DEFINE(SH_SLEEP_SPC, offsetof(struct sh_sleep_data, spc)); |
43 | DEFINE(SH_SLEEP_SR, offsetof(struct sh_sleep_data, sr)); | 44 | DEFINE(SH_SLEEP_SR, offsetof(struct sh_sleep_data, sr)); |
45 | DEFINE(SH_SLEEP_SP, offsetof(struct sh_sleep_data, sp)); | ||
44 | DEFINE(SH_SLEEP_BASE_ADDR, offsetof(struct sh_sleep_data, addr)); | 46 | DEFINE(SH_SLEEP_BASE_ADDR, offsetof(struct sh_sleep_data, addr)); |
45 | DEFINE(SH_SLEEP_BASE_DATA, offsetof(struct sh_sleep_data, data)); | 47 | DEFINE(SH_SLEEP_BASE_DATA, offsetof(struct sh_sleep_data, data)); |
46 | DEFINE(SH_SLEEP_REG_STBCR, offsetof(struct sh_sleep_regs, stbcr)); | 48 | DEFINE(SH_SLEEP_REG_STBCR, offsetof(struct sh_sleep_regs, stbcr)); |
49 | DEFINE(SH_SLEEP_REG_BAR, offsetof(struct sh_sleep_regs, bar)); | ||
47 | DEFINE(SH_SLEEP_REG_PTEH, offsetof(struct sh_sleep_regs, pteh)); | 50 | DEFINE(SH_SLEEP_REG_PTEH, offsetof(struct sh_sleep_regs, pteh)); |
48 | DEFINE(SH_SLEEP_REG_PTEL, offsetof(struct sh_sleep_regs, ptel)); | 51 | DEFINE(SH_SLEEP_REG_PTEL, offsetof(struct sh_sleep_regs, ptel)); |
49 | DEFINE(SH_SLEEP_REG_TTB, offsetof(struct sh_sleep_regs, ttb)); | 52 | DEFINE(SH_SLEEP_REG_TTB, offsetof(struct sh_sleep_regs, ttb)); |
diff --git a/arch/sh/kernel/cpu/shmobile/pm.c b/arch/sh/kernel/cpu/shmobile/pm.c index 4bd5e5302bfb..ca029a44743c 100644 --- a/arch/sh/kernel/cpu/shmobile/pm.c +++ b/arch/sh/kernel/cpu/shmobile/pm.c | |||
@@ -33,13 +33,10 @@ ATOMIC_NOTIFIER_HEAD(sh_mobile_post_sleep_notifier_list); | |||
33 | #define SUSP_MODE_SLEEP (SUSP_SH_SLEEP) | 33 | #define SUSP_MODE_SLEEP (SUSP_SH_SLEEP) |
34 | #define SUSP_MODE_SLEEP_SF (SUSP_SH_SLEEP | SUSP_SH_SF) | 34 | #define SUSP_MODE_SLEEP_SF (SUSP_SH_SLEEP | SUSP_SH_SF) |
35 | #define SUSP_MODE_STANDBY_SF (SUSP_SH_STANDBY | SUSP_SH_SF) | 35 | #define SUSP_MODE_STANDBY_SF (SUSP_SH_STANDBY | SUSP_SH_SF) |
36 | 36 | #define SUSP_MODE_RSTANDBY (SUSP_SH_RSTANDBY | SUSP_SH_MMU | SUSP_SH_SF) | |
37 | /* | 37 | /* |
38 | * The following modes are not there yet: | 38 | * U-standby mode is unsupported since it needs bootloader hacks |
39 | * | 39 | */ |
40 | * R-standby mode is unsupported, but will be added in the future | ||
41 | * U-standby mode is low priority since it needs bootloader hacks | ||
42 | */ | ||
43 | 40 | ||
44 | #ifdef CONFIG_CPU_SUBTYPE_SH7724 | 41 | #ifdef CONFIG_CPU_SUBTYPE_SH7724 |
45 | #define RAM_BASE 0xfd800000 /* RSMEM */ | 42 | #define RAM_BASE 0xfd800000 /* RSMEM */ |
@@ -90,6 +87,7 @@ void sh_mobile_register_self_refresh(unsigned long flags, | |||
90 | /* part 0: data area */ | 87 | /* part 0: data area */ |
91 | sdp = onchip_mem; | 88 | sdp = onchip_mem; |
92 | sdp->addr.stbcr = 0xa4150020; /* STBCR */ | 89 | sdp->addr.stbcr = 0xa4150020; /* STBCR */ |
90 | sdp->addr.bar = 0xa4150040; /* BAR */ | ||
93 | sdp->addr.pteh = 0xff000000; /* PTEH */ | 91 | sdp->addr.pteh = 0xff000000; /* PTEH */ |
94 | sdp->addr.ptel = 0xff000004; /* PTEL */ | 92 | sdp->addr.ptel = 0xff000004; /* PTEL */ |
95 | sdp->addr.ttb = 0xff000008; /* TTB */ | 93 | sdp->addr.ttb = 0xff000008; /* TTB */ |
@@ -124,6 +122,7 @@ void sh_mobile_register_self_refresh(unsigned long flags, | |||
124 | vp = onchip_mem + 0x600; /* located at interrupt vector */ | 122 | vp = onchip_mem + 0x600; /* located at interrupt vector */ |
125 | n = &sh_mobile_sleep_resume_end - &sh_mobile_sleep_resume_start; | 123 | n = &sh_mobile_sleep_resume_end - &sh_mobile_sleep_resume_start; |
126 | memcpy(vp, &sh_mobile_sleep_resume_start, n); | 124 | memcpy(vp, &sh_mobile_sleep_resume_start, n); |
125 | sdp->resume = (unsigned long)vp; | ||
127 | 126 | ||
128 | sh_mobile_sleep_supported |= flags; | 127 | sh_mobile_sleep_supported |= flags; |
129 | } | 128 | } |
diff --git a/arch/sh/kernel/cpu/shmobile/sleep.S b/arch/sh/kernel/cpu/shmobile/sleep.S index e620bf397af5..e9dd7fa0abd2 100644 --- a/arch/sh/kernel/cpu/shmobile/sleep.S +++ b/arch/sh/kernel/cpu/shmobile/sleep.S | |||
@@ -48,6 +48,9 @@ ENTRY(sh_mobile_sleep_enter_start) | |||
48 | stc sr, r0 | 48 | stc sr, r0 |
49 | mov.l r0, @(SH_SLEEP_SR, r5) | 49 | mov.l r0, @(SH_SLEEP_SR, r5) |
50 | 50 | ||
51 | /* save sp */ | ||
52 | mov.l r15, @(SH_SLEEP_SP, r5) | ||
53 | |||
51 | /* save stbcr */ | 54 | /* save stbcr */ |
52 | bsr save_register | 55 | bsr save_register |
53 | mov #SH_SLEEP_REG_STBCR, r0 | 56 | mov #SH_SLEEP_REG_STBCR, r0 |
@@ -125,6 +128,12 @@ test_rstandby: | |||
125 | tst #SUSP_SH_RSTANDBY, r0 | 128 | tst #SUSP_SH_RSTANDBY, r0 |
126 | bt test_ustandby | 129 | bt test_ustandby |
127 | 130 | ||
131 | /* setup BAR register */ | ||
132 | bsr get_register | ||
133 | mov #SH_SLEEP_REG_BAR, r0 | ||
134 | mov.l @(SH_SLEEP_RESUME, r5), r1 | ||
135 | mov.l r1, @r0 | ||
136 | |||
128 | /* set mode to "r-standby mode" */ | 137 | /* set mode to "r-standby mode" */ |
129 | bra do_sleep | 138 | bra do_sleep |
130 | mov #0x20, r1 | 139 | mov #0x20, r1 |
@@ -203,6 +212,9 @@ ENTRY(sh_mobile_sleep_resume_start) | |||
203 | mov.l @(SH_SLEEP_SR, r5), r0 | 212 | mov.l @(SH_SLEEP_SR, r5), r0 |
204 | ldc r0, ssr | 213 | ldc r0, ssr |
205 | 214 | ||
215 | /* restore sp */ | ||
216 | mov.l @(SH_SLEEP_SP, r5), r15 | ||
217 | |||
206 | /* restore sleep mode register */ | 218 | /* restore sleep mode register */ |
207 | bsr restore_register | 219 | bsr restore_register |
208 | mov #SH_SLEEP_REG_STBCR, r0 | 220 | mov #SH_SLEEP_REG_STBCR, r0 |