#define BIT(nr) (1 << (nr))
#include <linux/linkage.h>
#include <asm/assembler.h>
#include "psc.h"
#include "ddr2.h"
#include "clock.h"
#define PHYRDY_CYCLES 0x1000
#define PLL_BYPASS_CYCLES (PLL_BYPASS_TIME * 25)
#define PLL_RESET_CYCLES (PLL_RESET_TIME * 25)
#define PLL_LOCK_CYCLES (PLL_LOCK_TIME * 25)
#define DEEPSLEEP_SLEEPENABLE_BIT BIT(31)
.text
.arch armv5te
ENTRY(davinci_cpu_suspend)
stmfd sp!, {r0-r12, lr} @ save registers on stack
ldr ip, CACHE_FLUSH
blx ip
ldmia r0, {r0-r4}
ldr ip, [r0, #DDR2_SDRCR_OFFSET]
bic ip, ip, #DDR2_SRPD_BIT
orr ip, ip, #DDR2_LPMODEN_BIT
str ip, [r0, #DDR2_SDRCR_OFFSET]
ldr ip, [r0, #DDR2_SDRCR_OFFSET]
orr ip, ip, #DDR2_MCLKSTOPEN_BIT
str ip, [r0, #DDR2_SDRCR_OFFSET]
mov ip, #PHYRDY_CYCLES
1: subs ip, ip, #0x1
bne 1b
mov r7, r0
mov r0, #0x2
bl davinci_ddr_psc_config
mov r0, r7
ldr ip, [r3, #PLLDIV1]
bic ip, ip, #PLLDIV_EN
str ip, [r3, #PLLDIV1]
ldr ip, [r3, #PLLCTL]
bic ip, ip, #PLLCTL_PLLENSRC
bic ip, ip, #PLLCTL_PLLEN
str ip, [r3, #PLLCTL]
mov ip, #PLL_BYPASS_CYCLES
2: subs ip, ip, #0x1
bne 2b
ldr ip, [r3, #PLLCTL]
orr ip, ip, #PLLCTL_PLLPWRDN
str ip, [r3, #PLLCTL]
ldr ip, [r4]
orr ip, ip, #DEEPSLEEP_SLEEPENABLE_BIT
str ip, [r4]
ldr ip, [r4]
bic ip, ip, #DEEPSLEEP_SLEEPENABLE_BIT
str ip, [r4]
ldr ip, [r3, #PLLCTL]
bic ip, ip, #PLLCTL_PLLRST
str ip, [r3, #PLLCTL]
ldr ip, [r3, #PLLCTL]
bic ip, ip, #PLLCTL_PLLPWRDN
str ip, [r3, #PLLCTL]
mov ip, #PLL_RESET_CYCLES
3: subs ip, ip, #0x1
bne 3b
ldr ip, [r3, #PLLCTL]
orr ip, ip, #PLLCTL_PLLRST
str ip, [r3, #PLLCTL]
mov ip, #PLL_LOCK_CYCLES
4: subs ip, ip, #0x1
bne 4b
ldr ip, [r3, #PLLCTL]
bic ip, ip, #PLLCTL_PLLENSRC
orr ip, ip, #PLLCTL_PLLEN
str ip, [r3, #PLLCTL]
ldr ip, [r3, #PLLDIV1]
orr ip, ip, #PLLDIV_EN
str ip, [r3, #PLLDIV1]
mov r7, r0
mov r0, #0x3
bl davinci_ddr_psc_config
mov r0, r7
ldr ip, [r0, #DDR2_SDRCR_OFFSET]
bic ip, ip, #DDR2_MCLKSTOPEN_BIT
str ip, [r0, #DDR2_SDRCR_OFFSET]
ldr ip, [r0, #DDR2_SDRCR_OFFSET]
bic ip, ip, #DDR2_LPMODEN_BIT
str ip, [r0, #DDR2_SDRCR_OFFSET]
ldmfd sp!, {r0-r12, pc}
ENDPROC(davinci_cpu_suspend)
ENTRY(davinci_ddr_psc_config)
mov r6, #MDCTL
add r6, r6, r2, lsl #2
ldr ip, [r1, r6]
bic ip, ip, #MDSTAT_STATE_MASK
orr ip, ip, r0
str ip, [r1, r6]
ldr ip, [r1, #PTCMD]
orr ip, ip, #0x1
str ip, [r1, #PTCMD]
ptstat_done:
ldr ip, [r1, #PTSTAT]
and ip, ip, #0x1
cmp ip, #0x0
bne ptstat_done
mov r6, #MDSTAT
add r6, r6, r2, lsl #2
ddr2clk_stop_done:
ldr ip, [r1, r6]
and ip, ip, #MDSTAT_STATE_MASK
cmp ip, r0
bne ddr2clk_stop_done
ret lr
ENDPROC(davinci_ddr_psc_config)
CACHE_FLUSH:
#ifdef CONFIG_CPU_V6
.word v6_flush_kern_cache_all
#else
.word arm926_flush_kern_cache_all
#endif
ENTRY(davinci_cpu_suspend_sz)
.word . - davinci_cpu_suspend
ENDPROC(davinci_cpu_suspend_sz)