Commit bb3e0eed authored by Magnus Damm's avatar Magnus Damm Committed by Paul Mundt

sh: Add R-standby sleep mode support

Add R-standby specific bits to the SuperH Mobile sleep code.
Signed-off-by: default avatarMagnus Damm <damm@opensource.se>
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent 03625e71
...@@ -38,6 +38,7 @@ void sh_mobile_register_self_refresh(unsigned long flags, ...@@ -38,6 +38,7 @@ void sh_mobile_register_self_refresh(unsigned long flags,
/* register structure for address/data information */ /* register structure for address/data information */
struct sh_sleep_regs { struct sh_sleep_regs {
unsigned long stbcr; unsigned long stbcr;
unsigned long bar;
/* MMU */ /* MMU */
unsigned long pteh; unsigned long pteh;
...@@ -63,10 +64,14 @@ struct sh_sleep_data { ...@@ -63,10 +64,14 @@ struct sh_sleep_data {
unsigned long sf_pre; unsigned long sf_pre;
unsigned long sf_post; unsigned long sf_post;
/* address of resume code */
unsigned long resume;
/* register state saved and restored by the assembly code */ /* register state saved and restored by the assembly code */
unsigned long vbr; unsigned long vbr;
unsigned long spc; unsigned long spc;
unsigned long sr; unsigned long sr;
unsigned long sp;
/* structure for keeping register addresses */ /* structure for keeping register addresses */
struct sh_sleep_regs addr; struct sh_sleep_regs addr;
......
...@@ -38,12 +38,15 @@ int main(void) ...@@ -38,12 +38,15 @@ int main(void)
DEFINE(SH_SLEEP_MODE, offsetof(struct sh_sleep_data, mode)); DEFINE(SH_SLEEP_MODE, offsetof(struct sh_sleep_data, mode));
DEFINE(SH_SLEEP_SF_PRE, offsetof(struct sh_sleep_data, sf_pre)); DEFINE(SH_SLEEP_SF_PRE, offsetof(struct sh_sleep_data, sf_pre));
DEFINE(SH_SLEEP_SF_POST, offsetof(struct sh_sleep_data, sf_post)); DEFINE(SH_SLEEP_SF_POST, offsetof(struct sh_sleep_data, sf_post));
DEFINE(SH_SLEEP_RESUME, offsetof(struct sh_sleep_data, resume));
DEFINE(SH_SLEEP_VBR, offsetof(struct sh_sleep_data, vbr)); DEFINE(SH_SLEEP_VBR, offsetof(struct sh_sleep_data, vbr));
DEFINE(SH_SLEEP_SPC, offsetof(struct sh_sleep_data, spc)); DEFINE(SH_SLEEP_SPC, offsetof(struct sh_sleep_data, spc));
DEFINE(SH_SLEEP_SR, offsetof(struct sh_sleep_data, sr)); DEFINE(SH_SLEEP_SR, offsetof(struct sh_sleep_data, sr));
DEFINE(SH_SLEEP_SP, offsetof(struct sh_sleep_data, sp));
DEFINE(SH_SLEEP_BASE_ADDR, offsetof(struct sh_sleep_data, addr)); DEFINE(SH_SLEEP_BASE_ADDR, offsetof(struct sh_sleep_data, addr));
DEFINE(SH_SLEEP_BASE_DATA, offsetof(struct sh_sleep_data, data)); DEFINE(SH_SLEEP_BASE_DATA, offsetof(struct sh_sleep_data, data));
DEFINE(SH_SLEEP_REG_STBCR, offsetof(struct sh_sleep_regs, stbcr)); DEFINE(SH_SLEEP_REG_STBCR, offsetof(struct sh_sleep_regs, stbcr));
DEFINE(SH_SLEEP_REG_BAR, offsetof(struct sh_sleep_regs, bar));
DEFINE(SH_SLEEP_REG_PTEH, offsetof(struct sh_sleep_regs, pteh)); DEFINE(SH_SLEEP_REG_PTEH, offsetof(struct sh_sleep_regs, pteh));
DEFINE(SH_SLEEP_REG_PTEL, offsetof(struct sh_sleep_regs, ptel)); DEFINE(SH_SLEEP_REG_PTEL, offsetof(struct sh_sleep_regs, ptel));
DEFINE(SH_SLEEP_REG_TTB, offsetof(struct sh_sleep_regs, ttb)); DEFINE(SH_SLEEP_REG_TTB, offsetof(struct sh_sleep_regs, ttb));
......
...@@ -33,13 +33,10 @@ ATOMIC_NOTIFIER_HEAD(sh_mobile_post_sleep_notifier_list); ...@@ -33,13 +33,10 @@ ATOMIC_NOTIFIER_HEAD(sh_mobile_post_sleep_notifier_list);
#define SUSP_MODE_SLEEP (SUSP_SH_SLEEP) #define SUSP_MODE_SLEEP (SUSP_SH_SLEEP)
#define SUSP_MODE_SLEEP_SF (SUSP_SH_SLEEP | SUSP_SH_SF) #define SUSP_MODE_SLEEP_SF (SUSP_SH_SLEEP | SUSP_SH_SF)
#define SUSP_MODE_STANDBY_SF (SUSP_SH_STANDBY | SUSP_SH_SF) #define SUSP_MODE_STANDBY_SF (SUSP_SH_STANDBY | SUSP_SH_SF)
#define SUSP_MODE_RSTANDBY (SUSP_SH_RSTANDBY | SUSP_SH_MMU | SUSP_SH_SF)
/* /*
* The following modes are not there yet: * U-standby mode is unsupported since it needs bootloader hacks
* */
* R-standby mode is unsupported, but will be added in the future
* U-standby mode is low priority since it needs bootloader hacks
*/
#ifdef CONFIG_CPU_SUBTYPE_SH7724 #ifdef CONFIG_CPU_SUBTYPE_SH7724
#define RAM_BASE 0xfd800000 /* RSMEM */ #define RAM_BASE 0xfd800000 /* RSMEM */
...@@ -90,6 +87,7 @@ void sh_mobile_register_self_refresh(unsigned long flags, ...@@ -90,6 +87,7 @@ void sh_mobile_register_self_refresh(unsigned long flags,
/* part 0: data area */ /* part 0: data area */
sdp = onchip_mem; sdp = onchip_mem;
sdp->addr.stbcr = 0xa4150020; /* STBCR */ sdp->addr.stbcr = 0xa4150020; /* STBCR */
sdp->addr.bar = 0xa4150040; /* BAR */
sdp->addr.pteh = 0xff000000; /* PTEH */ sdp->addr.pteh = 0xff000000; /* PTEH */
sdp->addr.ptel = 0xff000004; /* PTEL */ sdp->addr.ptel = 0xff000004; /* PTEL */
sdp->addr.ttb = 0xff000008; /* TTB */ sdp->addr.ttb = 0xff000008; /* TTB */
...@@ -124,6 +122,7 @@ void sh_mobile_register_self_refresh(unsigned long flags, ...@@ -124,6 +122,7 @@ void sh_mobile_register_self_refresh(unsigned long flags,
vp = onchip_mem + 0x600; /* located at interrupt vector */ vp = onchip_mem + 0x600; /* located at interrupt vector */
n = &sh_mobile_sleep_resume_end - &sh_mobile_sleep_resume_start; n = &sh_mobile_sleep_resume_end - &sh_mobile_sleep_resume_start;
memcpy(vp, &sh_mobile_sleep_resume_start, n); memcpy(vp, &sh_mobile_sleep_resume_start, n);
sdp->resume = (unsigned long)vp;
sh_mobile_sleep_supported |= flags; sh_mobile_sleep_supported |= flags;
} }
......
...@@ -48,6 +48,9 @@ ENTRY(sh_mobile_sleep_enter_start) ...@@ -48,6 +48,9 @@ ENTRY(sh_mobile_sleep_enter_start)
stc sr, r0 stc sr, r0
mov.l r0, @(SH_SLEEP_SR, r5) mov.l r0, @(SH_SLEEP_SR, r5)
/* save sp */
mov.l r15, @(SH_SLEEP_SP, r5)
/* save stbcr */ /* save stbcr */
bsr save_register bsr save_register
mov #SH_SLEEP_REG_STBCR, r0 mov #SH_SLEEP_REG_STBCR, r0
...@@ -125,6 +128,12 @@ test_rstandby: ...@@ -125,6 +128,12 @@ test_rstandby:
tst #SUSP_SH_RSTANDBY, r0 tst #SUSP_SH_RSTANDBY, r0
bt test_ustandby bt test_ustandby
/* setup BAR register */
bsr get_register
mov #SH_SLEEP_REG_BAR, r0
mov.l @(SH_SLEEP_RESUME, r5), r1
mov.l r1, @r0
/* set mode to "r-standby mode" */ /* set mode to "r-standby mode" */
bra do_sleep bra do_sleep
mov #0x20, r1 mov #0x20, r1
...@@ -203,6 +212,9 @@ ENTRY(sh_mobile_sleep_resume_start) ...@@ -203,6 +212,9 @@ ENTRY(sh_mobile_sleep_resume_start)
mov.l @(SH_SLEEP_SR, r5), r0 mov.l @(SH_SLEEP_SR, r5), r0
ldc r0, ssr ldc r0, ssr
/* restore sp */
mov.l @(SH_SLEEP_SP, r5), r15
/* restore sleep mode register */ /* restore sleep mode register */
bsr restore_register bsr restore_register
mov #SH_SLEEP_REG_STBCR, r0 mov #SH_SLEEP_REG_STBCR, r0
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment