#include <linux/sys.h>
#include <linux/errno.h>
#include <linux/linkage.h>
#include <asm/asm-offsets.h>
#include <asm/suspend.h>
#define k0 r0
#define k1 r1
.balign 4
ENTRY(sh_mobile_sleep_enter_start)
mov.l r4, @(SH_SLEEP_MODE, r5)
stc vbr, r0
mov.l r0, @(SH_SLEEP_VBR, r5)
ldc r5, vbr
sts pr, r0
mov.l r0, @(SH_SLEEP_SPC, r5)
stc sr, r0
mov.l r0, @(SH_SLEEP_SR, r5)
mov.l @(SH_SLEEP_MODE, r5), r0
tst #SUSP_SH_REGS, r0
bt skip_regs_save
sts.l pr, @-r15
mov.l r14, @-r15
mov.l r13, @-r15
mov.l r12, @-r15
mov.l r11, @-r15
mov.l r10, @-r15
mov.l r9, @-r15
mov.l r8, @-r15
mov.l rb_bit, r9
not r9, r9
bsr set_sr
mov #0, r10
bsr save_low_regs
nop
mov.l rb_bit, r10
bsr set_sr
mov #-1, r9
bsr save_low_regs
nop
mov.l rb_bit, r9
not r9, r9
bsr set_sr
mov #0, r10
skip_regs_save:
mov.l r15, @(SH_SLEEP_SP, r5)
mov r5, r15
bsr save_register
mov #SH_SLEEP_REG_STBCR, r0
mov.l @(SH_SLEEP_MODE, r5), r0
tst #SUSP_SH_MMU, r0
bt skip_mmu_save_disable
bsr save_register
mov #SH_SLEEP_REG_PTEH, r0
bsr save_register
mov #SH_SLEEP_REG_PTEL, r0
bsr save_register
mov #SH_SLEEP_REG_TTB, r0
bsr save_register
mov #SH_SLEEP_REG_TEA, r0
bsr save_register
mov #SH_SLEEP_REG_MMUCR, r0
bsr save_register
mov #SH_SLEEP_REG_PTEA, r0
bsr save_register
mov #SH_SLEEP_REG_PASCR, r0
bsr save_register
mov #SH_SLEEP_REG_IRMCR, r0
bsr get_register
mov #SH_SLEEP_REG_MMUCR, r0
mov #4, r1
mov.l r1, @r0
icbi @r0
bsr save_register
mov #SH_SLEEP_REG_CCR, r0
bsr save_register
mov #SH_SLEEP_REG_RAMCR, r0
bsr get_register
mov #SH_SLEEP_REG_CCR, r0
mov #0, r1
mov.l r1, @r0
icbi @r0
skip_mmu_save_disable:
mov.l @(SH_SLEEP_MODE, r5), r0
tst #SUSP_SH_SF, r0
bt skip_set_sf
mov.l @(SH_SLEEP_SF_PRE, r5), r0
jsr @r0
nop
skip_set_sf:
mov.l @(SH_SLEEP_MODE, r5), r0
tst #SUSP_SH_STANDBY, r0
bt test_rstandby
bra do_sleep
mov #0x80, r1
test_rstandby:
tst #SUSP_SH_RSTANDBY, r0
bt test_ustandby
bsr get_register
mov #SH_SLEEP_REG_BAR, r0
mov.l @(SH_SLEEP_RESUME, r5), r1
mov.l r1, @r0
bra do_sleep
mov #0x20, r1
test_ustandby:
tst #SUSP_SH_USTANDBY, r0
bt force_sleep
bra do_sleep
mov #0x10, r1
force_sleep:
mov #0x00, r1
do_sleep:
bsr get_register
mov #SH_SLEEP_REG_STBCR, r0
mov.l r1, @r0
again:
sleep
bra again
nop
save_register:
add #SH_SLEEP_BASE_ADDR, r0
mov.l @(r0, r5), r1
add #-SH_SLEEP_BASE_ADDR, r0
mov.l @r1, r1
add #SH_SLEEP_BASE_DATA, r0
mov.l r1, @(r0, r5)
add #-SH_SLEEP_BASE_DATA, r0
rts
nop
get_register:
add #SH_SLEEP_BASE_ADDR, r0
mov.l @(r0, r5), r0
rts
nop
set_sr:
stc sr, r8
and r9, r8
or r10, r8
ldc r8, sr
rts
nop
save_low_regs:
mov.l r7, @-r15
mov.l r6, @-r15
mov.l r5, @-r15
mov.l r4, @-r15
mov.l r3, @-r15
mov.l r2, @-r15
mov.l r1, @-r15
rts
mov.l r0, @-r15
.balign 4
rb_bit: .long 0x20000000 ! RB=1
ENTRY(sh_mobile_sleep_enter_end)
.balign 4
ENTRY(sh_mobile_sleep_resume_start)
bsr 0f
nop
0:
sts pr, k1
mov.l 1f, k0
and k0, k1
ldc k1, vbr
mov.l @(SH_SLEEP_SR, k1), k0
ldc k0, sr
stc vbr, r5
mov.l @(SH_SLEEP_SPC, r5), r0
ldc r0, spc
mov.l @(SH_SLEEP_VBR, r5), r0
ldc r0, vbr
mov.l @(SH_SLEEP_SR, r5), r0
ldc r0, ssr
mov.l @(SH_SLEEP_SP, r5), r15
bsr restore_register
mov #SH_SLEEP_REG_STBCR, r0
mov.l @(SH_SLEEP_MODE, r5), r0
tst #SUSP_SH_SF, r0
bt skip_restore_sf
mov.l @(SH_SLEEP_SF_POST, r5), r0
jsr @r0
nop
skip_restore_sf:
mov.l @(SH_SLEEP_MODE, r5), r0
tst #SUSP_SH_MMU, r0
bt skip_restore_mmu
bsr restore_register
mov #SH_SLEEP_REG_PTEH, r0
bsr restore_register
mov #SH_SLEEP_REG_PTEL, r0
bsr restore_register
mov #SH_SLEEP_REG_TTB, r0
bsr restore_register
mov #SH_SLEEP_REG_TEA, r0
bsr restore_register
mov #SH_SLEEP_REG_PTEA, r0
bsr restore_register
mov #SH_SLEEP_REG_PASCR, r0
bsr restore_register
mov #SH_SLEEP_REG_IRMCR, r0
bsr restore_register
mov #SH_SLEEP_REG_MMUCR, r0
icbi @r0
bsr restore_register
mov #SH_SLEEP_REG_RAMCR, r0
icbi @r0
bsr restore_register
mov #SH_SLEEP_REG_CCR, r0
icbi @r0
skip_restore_mmu:
mov.l @(SH_SLEEP_MODE, r5), r0
tst #SUSP_SH_REGS, r0
bt skip_restore_regs
mov.l _rb_bit, r10
bsr _set_sr
mov #-1, r9
bsr restore_low_regs
nop
mov.l _rb_bit, r9
not r9, r9
bsr _set_sr
mov #0, r10
bsr restore_low_regs
nop
mov.l @r15+, r8
mov.l @r15+, r9
mov.l @r15+, r10
mov.l @r15+, r11
mov.l @r15+, r12
mov.l @r15+, r13
mov.l @r15+, r14
lds.l @r15+, pr
skip_restore_regs:
rte
nop
restore_register:
add #SH_SLEEP_BASE_DATA, r0
mov.l @(r0, r5), r1
add #-SH_SLEEP_BASE_DATA, r0
add #SH_SLEEP_BASE_ADDR, r0
mov.l @(r0, r5), r0
mov.l r1, @r0
rts
nop
_set_sr:
stc sr, r8
and r9, r8
or r10, r8
ldc r8, sr
rts
nop
restore_low_regs:
mov.l @r15+, r0
mov.l @r15+, r1
mov.l @r15+, r2
mov.l @r15+, r3
mov.l @r15+, r4
mov.l @r15+, r5
mov.l @r15+, r6
rts
mov.l @r15+, r7
.balign 4
_rb_bit: .long 0x20000000 ! RB=1
1: .long ~0x7ff
ENTRY(sh_mobile_sleep_resume_end)