#include <linux/linkage.h>
#include <asm/reg.h>
#include <asm/ppc_asm.h>
#include <asm/processor.h>
#include <asm/cache.h>
#define SDRAM_CTRL 0x104
#define SC_MODE_EN (1<<31)
#define SC_CKE (1<<30)
#define SC_REF_EN (1<<28)
#define SC_SOFT_PRE (1<<1)
#define GPIOW_GPIOE 0xc00
#define GPIOW_DDR 0xc08
#define GPIOW_DVO 0xc0c
#define CDM_CE 0x214
#define CDM_SDRAM (1<<3)
#define SAVE_SPRN(reg, addr) \
mfspr r10, SPRN_##reg; \
stw r10, ((addr)*4)(r4);
#define LOAD_SPRN(reg, addr) \
lwz r10, ((addr)*4)(r4); \
mtspr SPRN_##reg, r10; \
sync; \
isync;
.data
registers:
.space 0x5c*4
.text
.globl lite5200_low_power
lite5200_low_power:
mr r7, r3
mr r8, r4
lis r3, CONFIG_KERNEL_START@h
lis r4, lite5200_wakeup@h
ori r4, r4, lite5200_wakeup@l
sub r4, r4, r3
stw r4, 0(r3)
lis r4, registers@h
ori r4, r4, registers@l
lwz r10, 0xf0(r3)
stw r10, (0x1d*4)(r4)
SAVE_SPRN(LR, 0x1c)
bl save_regs
bl flush_data_cache
mr r4, r7
li r3, (sram_code_end - sram_code)/4
mtctr r3
lis r3, sram_code@h
ori r3, r3, sram_code@l
1:
lwz r5, 0(r3)
stw r5, 0(r4)
addi r3, r3, 4
addi r4, r4, 4
bdnz 1b
lis r3, tb_ticks_per_usec@h
lwz r11, tb_ticks_per_usec@l(r3)
mfspr r3, SPRN_HID0
ori r3, r3, HID0_ICE | HID0_DCE
xori r3, r3, HID0_ICE | HID0_DCE
sync; isync;
mtspr SPRN_HID0, r3
sync; isync;
mtlr r7
blrl
sram_code:
lwz r4, SDRAM_CTRL(r8)
oris r4, r4, SC_MODE_EN@h
stw r4, SDRAM_CTRL(r8)
sync
ori r4, r4, SC_SOFT_PRE
stw r4, SDRAM_CTRL(r8)
sync
xori r4, r4, SC_SOFT_PRE
xoris r4, r4, SC_MODE_EN@h
stw r4, SDRAM_CTRL(r8)
sync
li r12, 1
bl udelay
oris r4, r4, (SC_REF_EN | SC_CKE)@h
xoris r4, r4, (SC_CKE)@h
stw r4, SDRAM_CTRL(r8)
sync
li r12, 1
bl udelay
lwz r4, CDM_CE(r8)
ori r4, r4, CDM_SDRAM
xori r4, r4, CDM_SDRAM
stw r4, CDM_CE(r8)
sync
li r12, 1
bl udelay
li r4, 0x02
stb r4, GPIOW_GPIOE(r8)
sync
stb r4, GPIOW_DVO(r8)
sync
stb r4, GPIOW_DDR(r8)
sync
stb r4, GPIOW_DVO(r8)
sync
li r12, 10
bl udelay
li r4, 0
stb r4, GPIOW_DVO(r8)
sync
1:
b 1b
SYM_FUNC_START_LOCAL(udelay)
mullw r12, r12, r11
mftb r13
add r12, r13, r12
1:
mftb r13
cmp cr0, r13, r12
blt 1b
blr
SYM_FUNC_END(udelay)
sram_code_end:
lite5200_wakeup:
bl restore_regs
LOAD_SPRN(HID1, 0x19)
LOAD_SPRN(HID2_750FX, 0x1a)
mfmsr r10
ori r10, r10, MSR_DR | MSR_IR
mtspr SPRN_SRR1, r10
lis r10, mmu_on@h
ori r10, r10, mmu_on@l
mtspr SPRN_SRR0, r10
sync
rfi
mmu_on:
addis r4, r4, CONFIG_KERNEL_START@h
lwz r10, (4*0x1b)(r4)
mtmsr r10
sync; isync;
mfspr r10, SPRN_HID0
ori r5, r10, HID0_ICFI | HID0_DCI
mtspr SPRN_HID0, r5
sync; isync;
mtspr SPRN_HID0, r10
sync; isync;
lwz r10, (4*0x18)(r4)
mtspr SPRN_HID0, r10
sync
isync
lis r3, CONFIG_KERNEL_START@h
lwz r10, (0x1d*4)(r4)
stw r10, 0xf0(r3)
LOAD_SPRN(LR, 0x1c)
blr
_ASM_NOKPROBE_SYMBOL(lite5200_wakeup)
#define SAVE_BAT(n, addr) \
SAVE_SPRN(DBAT##n##L, addr); \
SAVE_SPRN(DBAT##n##U, addr+1); \
SAVE_SPRN(IBAT##n##L, addr+2); \
SAVE_SPRN(IBAT##n##U, addr+3);
#define SAVE_SR(n, addr) \
mfsr r10, n; \
stw r10, ((addr)*4)(r4);
#define SAVE_4SR(n, addr) \
SAVE_SR(n, addr); \
SAVE_SR(n+1, addr+1); \
SAVE_SR(n+2, addr+2); \
SAVE_SR(n+3, addr+3);
SYM_FUNC_START_LOCAL(save_regs)
stw r0, 0(r4)
stw r1, 0x4(r4)
stw r2, 0x8(r4)
stmw r11, 0xc(r4)
SAVE_SPRN(HID0, 0x18)
SAVE_SPRN(HID1, 0x19)
SAVE_SPRN(HID2_750FX, 0x1a)
mfmsr r10
stw r10, (4*0x1b)(r4)
SAVE_SPRN(RPA, 0x1e)
SAVE_SPRN(SDR1, 0x1f)
SAVE_BAT(0, 0x20)
SAVE_BAT(1, 0x24)
SAVE_BAT(2, 0x28)
SAVE_BAT(3, 0x2c)
SAVE_BAT(4, 0x30)
SAVE_BAT(5, 0x34)
SAVE_BAT(6, 0x38)
SAVE_BAT(7, 0x3c)
SAVE_4SR(0, 0x40)
SAVE_4SR(4, 0x44)
SAVE_4SR(8, 0x48)
SAVE_4SR(12, 0x4c)
SAVE_SPRN(SPRG0, 0x50)
SAVE_SPRN(SPRG1, 0x51)
SAVE_SPRN(SPRG2, 0x52)
SAVE_SPRN(SPRG3, 0x53)
SAVE_SPRN(SPRG4, 0x54)
SAVE_SPRN(SPRG5, 0x55)
SAVE_SPRN(SPRG6, 0x56)
SAVE_SPRN(SPRG7, 0x57)
SAVE_SPRN(IABR, 0x58)
SAVE_SPRN(DABR, 0x59)
SAVE_SPRN(TBRL, 0x5a)
SAVE_SPRN(TBRU, 0x5b)
blr
SYM_FUNC_END(save_regs)
#define LOAD_BAT(n, addr) \
LOAD_SPRN(DBAT##n##L, addr); \
LOAD_SPRN(DBAT##n##U, addr+1); \
LOAD_SPRN(IBAT##n##L, addr+2); \
LOAD_SPRN(IBAT##n##U, addr+3);
#define LOAD_SR(n, addr) \
lwz r10, ((addr)*4)(r4); \
mtsr n, r10;
#define LOAD_4SR(n, addr) \
LOAD_SR(n, addr); \
LOAD_SR(n+1, addr+1); \
LOAD_SR(n+2, addr+2); \
LOAD_SR(n+3, addr+3);
SYM_FUNC_START_LOCAL(restore_regs)
lis r4, registers@h
ori r4, r4, registers@l
subis r4, r4, CONFIG_KERNEL_START@h
lwz r0, 0(r4)
lwz r1, 0x4(r4)
lwz r2, 0x8(r4)
lmw r11, 0xc(r4)
LOAD_SPRN(RPA, 0x1e);
LOAD_SPRN(SDR1, 0x1f);
LOAD_BAT(0, 0x20)
LOAD_BAT(1, 0x24)
LOAD_BAT(2, 0x28)
LOAD_BAT(3, 0x2c)
LOAD_BAT(4, 0x30)
LOAD_BAT(5, 0x34)
LOAD_BAT(6, 0x38)
LOAD_BAT(7, 0x3c)
LOAD_4SR(0, 0x40)
LOAD_4SR(4, 0x44)
LOAD_4SR(8, 0x48)
LOAD_4SR(12, 0x4c)
LOAD_SPRN(SPRG0, 0x50);
LOAD_SPRN(SPRG1, 0x51);
LOAD_SPRN(SPRG2, 0x52);
LOAD_SPRN(SPRG3, 0x53);
LOAD_SPRN(SPRG4, 0x54);
LOAD_SPRN(SPRG5, 0x55);
LOAD_SPRN(SPRG6, 0x56);
LOAD_SPRN(SPRG7, 0x57);
LOAD_SPRN(IABR, 0x58);
LOAD_SPRN(DABR, 0x59);
LOAD_SPRN(TBWL, 0x5a);
LOAD_SPRN(TBWU, 0x5b);
blr
_ASM_NOKPROBE_SYMBOL(restore_regs)
SYM_FUNC_END(restore_regs)
#define NUM_CACHE_LINES (128*8)
SYM_FUNC_START_LOCAL(flush_data_cache)
lis r3,CONFIG_KERNEL_START@h
ori r3,r3,CONFIG_KERNEL_START@l
li r4,NUM_CACHE_LINES
mtctr r4
1:
lwz r4,0(r3)
addi r3,r3,L1_CACHE_BYTES
bdnz 1b
blr
SYM_FUNC_END(flush_data_cache)