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>
This commit is contained in:
@@ -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 {
|
|||||||
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)
|
|||||||
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);
|
|||||||
#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,
|
|||||||
/* 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,
|
|||||||
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)
|
|||||||
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:
|
|||||||
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)
|
|||||||
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
|
||||||
|
Reference in New Issue
Block a user