78818e477b
Patch from Vitaly Wool This patch adds basic chip support for PNX4008 ARM platform. It's basically the same as the previous one, but with the rmk's comments taken into account. Signed-off-by: Vitaly Wool <vwool@ru.mvista.com> Signed-off-by: Dmitry Pervushin <dpervushin@gmail.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
196 lines
4.9 KiB
ArmAsm
196 lines
4.9 KiB
ArmAsm
/*
|
|
* linux/arch/arm/mach-pnx4008/sleep.S
|
|
*
|
|
* PNX4008 support for STOP mode and SDRAM self-refresh
|
|
*
|
|
* Authors: Dmitry Chigirev, Vitaly Wool <source@mvista.com>
|
|
*
|
|
* 2005 (c) MontaVista Software, Inc. This file is licensed under
|
|
* the terms of the GNU General Public License version 2. This program
|
|
* is licensed "as is" without any warranty of any kind, whether express
|
|
* or implied.
|
|
*/
|
|
|
|
#include <linux/config.h>
|
|
#include <linux/linkage.h>
|
|
#include <asm/assembler.h>
|
|
#include <asm/hardware.h>
|
|
|
|
#define PWRMAN_VA_BASE IO_ADDRESS(PNX4008_PWRMAN_BASE)
|
|
#define PWR_CTRL_REG_OFFS 0x44
|
|
|
|
#define SDRAM_CFG_VA_BASE IO_ADDRESS(PNX4008_SDRAM_CFG_BASE)
|
|
#define MPMC_STATUS_REG_OFFS 0x4
|
|
|
|
.text
|
|
|
|
ENTRY(pnx4008_cpu_suspend)
|
|
@this function should be entered in Direct run mode.
|
|
|
|
@ save registers on stack
|
|
stmfd sp!, {r0 - r6, lr}
|
|
|
|
@ setup Power Manager base address in r4
|
|
@ and put it's value in r5
|
|
mov r4, #(PWRMAN_VA_BASE & 0xff000000)
|
|
orr r4, r4, #(PWRMAN_VA_BASE & 0x00ff0000)
|
|
orr r4, r4, #(PWRMAN_VA_BASE & 0x0000ff00)
|
|
orr r4, r4, #(PWRMAN_VA_BASE & 0x000000ff)
|
|
ldr r5, [r4, #PWR_CTRL_REG_OFFS]
|
|
|
|
@ setup SDRAM controller base address in r2
|
|
@ and put it's value in r3
|
|
mov r2, #(SDRAM_CFG_VA_BASE & 0xff000000)
|
|
orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x00ff0000)
|
|
orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x0000ff00)
|
|
orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x000000ff)
|
|
ldr r3, [r2, #MPMC_STATUS_REG_OFFS] @extra read - HW bug workaround
|
|
|
|
@ clear SDRAM self-refresh bit latch
|
|
and r5, r5, #(~(1 << 8))
|
|
@ clear SDRAM self-refresh bit
|
|
and r5, r5, #(~(1 << 9))
|
|
str r5, [r4, #PWR_CTRL_REG_OFFS]
|
|
|
|
@ do save current bit settings in r1
|
|
mov r1, r5
|
|
|
|
@ set SDRAM self-refresh bit
|
|
orr r5, r5, #(1 << 9)
|
|
str r5, [r4, #PWR_CTRL_REG_OFFS]
|
|
|
|
@ set SDRAM self-refresh bit latch
|
|
orr r5, r5, #(1 << 8)
|
|
str r5, [r4, #PWR_CTRL_REG_OFFS]
|
|
|
|
@ clear SDRAM self-refresh bit latch
|
|
and r5, r5, #(~(1 << 8))
|
|
str r5, [r4, #PWR_CTRL_REG_OFFS]
|
|
|
|
@ clear SDRAM self-refresh bit
|
|
and r5, r5, #(~(1 << 9))
|
|
str r5, [r4, #PWR_CTRL_REG_OFFS]
|
|
|
|
@ wait for SDRAM to get into self-refresh mode
|
|
2: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
|
|
tst r3, #(1 << 2)
|
|
beq 2b
|
|
|
|
@ to prepare SDRAM to get out of self-refresh mode after wakeup
|
|
orr r5, r5, #(1 << 7)
|
|
str r5, [r4, #PWR_CTRL_REG_OFFS]
|
|
|
|
@ do enter stop mode
|
|
orr r5, r5, #(1 << 0)
|
|
str r5, [r4, #PWR_CTRL_REG_OFFS]
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
|
|
@ sleeping now...
|
|
|
|
@ coming out of STOP mode into Direct Run mode
|
|
@ clear STOP mode and SDRAM self-refresh bits
|
|
str r1, [r4, #PWR_CTRL_REG_OFFS]
|
|
|
|
@ wait for SDRAM to get out self-refresh mode
|
|
3: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
|
|
tst r3, #5
|
|
bne 3b
|
|
|
|
@ restore regs and return
|
|
ldmfd sp!, {r0 - r6, pc}
|
|
|
|
ENTRY(pnx4008_cpu_suspend_sz)
|
|
.word . - pnx4008_cpu_suspend
|
|
|
|
ENTRY(pnx4008_cpu_standby)
|
|
@ save registers on stack
|
|
stmfd sp!, {r0 - r6, lr}
|
|
|
|
@ setup Power Manager base address in r4
|
|
@ and put it's value in r5
|
|
mov r4, #(PWRMAN_VA_BASE & 0xff000000)
|
|
orr r4, r4, #(PWRMAN_VA_BASE & 0x00ff0000)
|
|
orr r4, r4, #(PWRMAN_VA_BASE & 0x0000ff00)
|
|
orr r4, r4, #(PWRMAN_VA_BASE & 0x000000ff)
|
|
ldr r5, [r4, #PWR_CTRL_REG_OFFS]
|
|
|
|
@ setup SDRAM controller base address in r2
|
|
@ and put it's value in r3
|
|
mov r2, #(SDRAM_CFG_VA_BASE & 0xff000000)
|
|
orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x00ff0000)
|
|
orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x0000ff00)
|
|
orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x000000ff)
|
|
ldr r3, [r2, #MPMC_STATUS_REG_OFFS] @extra read - HW bug workaround
|
|
|
|
@ clear SDRAM self-refresh bit latch
|
|
and r5, r5, #(~(1 << 8))
|
|
@ clear SDRAM self-refresh bit
|
|
and r5, r5, #(~(1 << 9))
|
|
str r5, [r4, #PWR_CTRL_REG_OFFS]
|
|
|
|
@ do save current bit settings in r1
|
|
mov r1, r5
|
|
|
|
@ set SDRAM self-refresh bit
|
|
orr r5, r5, #(1 << 9)
|
|
str r5, [r4, #PWR_CTRL_REG_OFFS]
|
|
|
|
@ set SDRAM self-refresh bit latch
|
|
orr r5, r5, #(1 << 8)
|
|
str r5, [r4, #PWR_CTRL_REG_OFFS]
|
|
|
|
@ clear SDRAM self-refresh bit latch
|
|
and r5, r5, #(~(1 << 8))
|
|
str r5, [r4, #PWR_CTRL_REG_OFFS]
|
|
|
|
@ clear SDRAM self-refresh bit
|
|
and r5, r5, #(~(1 << 9))
|
|
str r5, [r4, #PWR_CTRL_REG_OFFS]
|
|
|
|
@ wait for SDRAM to get into self-refresh mode
|
|
2: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
|
|
tst r3, #(1 << 2)
|
|
beq 2b
|
|
|
|
@ set 'get out of self-refresh mode after wakeup' bit
|
|
orr r5, r5, #(1 << 7)
|
|
str r5, [r4, #PWR_CTRL_REG_OFFS]
|
|
|
|
mcr p15, 0, r0, c7, c0, 4 @ kinda sleeping now...
|
|
|
|
@ set SDRAM self-refresh bit latch
|
|
orr r5, r5, #(1 << 8)
|
|
str r5, [r4, #PWR_CTRL_REG_OFFS]
|
|
|
|
@ clear SDRAM self-refresh bit latch
|
|
and r5, r5, #(~(1 << 8))
|
|
str r5, [r4, #PWR_CTRL_REG_OFFS]
|
|
|
|
@ wait for SDRAM to get out self-refresh mode
|
|
3: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
|
|
tst r3, #5
|
|
bne 3b
|
|
|
|
@ restore regs and return
|
|
ldmfd sp!, {r0 - r6, pc}
|
|
|
|
ENTRY(pnx4008_cpu_standby_sz)
|
|
.word . - pnx4008_cpu_standby
|
|
|
|
ENTRY(pnx4008_cache_clean_invalidate)
|
|
stmfd sp!, {r0 - r6, lr}
|
|
#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
|
|
mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
|
|
#else
|
|
1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate
|
|
bne 1b
|
|
#endif
|
|
ldmfd sp!, {r0 - r6, pc}
|