Commit 09146f81 authored by Ben Dooks's avatar Ben Dooks Committed by Russell King

[ARM PATCH] 2134/3: S3C2410 - Power Management core (1/4)

Patch from Ben Dooks

Core support for S3C2410 suspend to SDRAM

Signed-off-by: Ben Dooks 
parent 4d6e060d
......@@ -72,4 +72,31 @@ config S3C2410_DMA_DEBUG
the CPU time doing so.
config S3C2410_PM_DEBUG
bool "S3C2410 PM Suspend debug"
depends on ARCH_S3C2410 && PM
help
Say Y here if you want verbose debugging from the PM Suspend and
Resume code. See `Documentation/arm/Samsing-S3C24XX/Suspend.txt`
for more information.
config S3C2410_PM_CHECK
bool "S3C2410 PM Suspend Memory CRC"
depends on ARCH_S3C2410 && PM && CRC32
help
Enable the PM code's memory area checksum over sleep. This option
will generate CRCs of all blocks of memory, and store them before
going to sleep. The blocks are then checked on resume for any
errors.
config S3C2410_PM_CHECK_CHUNKSIZE
int "S3C2410 PM Suspend CRC Chunksize (KiB)"
depends on ARCH_S3C2410 && PM && S3C2410_PM_CHECK
default 64
help
Set the chunksize in Kilobytes of the CRC for checking memory
corruption over suspend and resume. A smaller value will mean that
the CRC data block will take more memory, but wil identify any
faults with better precision.
endif
......@@ -15,6 +15,10 @@ obj- :=
obj-$(CONFIG_CPU_S3C2410) += s3c2410.o
obj-$(CONFIG_S3C2410_DMA) += dma.o
# Power Management support
obj-$(CONFIG_PM) += pm.o sleep.o
# S3C2440 support
obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o
......
This diff is collapsed.
/* linux/arch/arm/mach-s3c2410/pm.h
*
* Copyright (c) 2004 Simtec Electronics
* Written by Ben Dooks, <ben@simtec.co.uk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
/* s3c2410_pm_init
*
* called from board at initialisation time to setup the power
* management
*/
extern __init int s3c2410_pm_init(void);
/* configuration for the IRQ mask over sleep */
extern unsigned long s3c_irqwake_intmask;
extern unsigned long s3c_irqwake_eintmask;
/* IRQ masks for IRQs allowed to go to sleep (see irq.c) */
extern unsigned long s3c_irqwake_intallow;
extern unsigned long s3c_irqwake_eintallow;
/* Flags for PM Control */
extern unsigned long s3c_pm_flags;
/* from sleep.S */
extern void s3c2410_cpu_suspend(unsigned long *saveblk);
extern void s3c2410_cpu_resume(void);
extern unsigned long s3c2410_sleep_save_phys;
/* linux/arch/arm/mach-s3c2410/sleep.S
*
* Copyright (c) 2004 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* S3C2410 Power Manager (Suspend-To-RAM) support
*
* Based on PXA/SA1100 sleep code by:
* Nicolas Pitre, (c) 2002 Monta Vista Software Inc
* Cliff Brake, (c) 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/config.h>
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm/hardware.h>
#include <asm/arch/map.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/regs-clock.h>
#include <asm/arch/regs-mem.h>
#include <asm/arch/regs-serial.h>
#define CONFIG_DEBUG_RESUME
.text
/* s3c2410_cpu_suspend
*
* put the cpu into sleep mode
*
* entry:
* r0 = sleep save block
*/
ENTRY(s3c2410_cpu_suspend)
stmfd sp!, { r4 - r12, lr }
@@ store co-processor registers
mrc p15, 0, r4, c15, c1, 0 @ CP access register
mrc p15, 0, r5, c13, c0, 0 @ PID
mrc p15, 0, r6, c3, c0, 0 @ Domain ID
mrc p15, 0, r7, c2, c0, 0 @ translation table base address
mrc p15, 0, r8, c2, c0, 0 @ auxiliary control register
mrc p15, 0, r9, c1, c0, 0 @ control register
stmia r0, { r4 - r13 }
@@ flush the caches to ensure everything is back out to
@@ SDRAM before the core powers down
bl arm920_flush_kern_cache_all
@@ prepare cpu to sleep
ldr r4, =S3C2410_REFRESH
ldr r5, =S3C2410_MISCCR
ldr r6, =S3C2410_CLKCON
ldr r7, [ r4 ] @ get REFRESH (and ensure in TLB)
ldr r8, [ r5 ] @ get MISCCR (and ensure in TLB)
ldr r9, [ r6 ] @ get CLKCON (and ensure in TLB)
orr r7, r7, #S3C2410_REFRESH_SELF @ SDRAM sleep command
orr r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals
orr r9, r9, #S3C2410_CLKCON_POWER @ power down command
teq pc, #0 @ first as a trial-run to load cache
bl s3c2410_do_sleep
teq r0, r0 @ now do it for real
b s3c2410_do_sleep @
@@ align next bit of code to cache line
.align 8
s3c2410_do_sleep:
streq r7, [ r4 ] @ SDRAM sleep command
streq r8, [ r5 ] @ SDRAM power-down config
streq r9, [ r6 ] @ CPU sleep
1: beq 1b
mov pc, r14
@@ return to the caller, after having the MMU
@@ turned on, this restores the last bits from the
@@ stack
resume_with_mmu:
ldmfd sp!, { r4 - r12, pc }
.ltorg
@@ the next bits sit in the .data segment, even though they
@@ happen to be code... the s3c2410_sleep_save_phys needs to be
@@ accessed by the resume code before it can restore the MMU.
@@ This means that the variable has to be close enough for the
@@ code to read it... since the .text segment needs to be RO,
@@ the data segment can be the only place to put this code.
.data
.global s3c2410_sleep_save_phys
s3c2410_sleep_save_phys:
.word 0
/* s3c2410_cpu_resume
*
* resume code entry for bootloader to call
*
* we must put this code here in the data segment as we have no
* other way of restoring the stack pointer after sleep, and we
* must not write to the code segment (code is read-only)
*/
ENTRY(s3c2410_cpu_resume)
mov r0, #PSR_I_BIT | PSR_F_BIT | MODE_SVC
msr cpsr_c, r0
@@ load UART to allow us to print the two characters for
@@ resume debug
mov r2, #S3C2410_PA_UART & 0xff000000
orr r2, r2, #S3C2410_PA_UART & 0xff000
#ifdef CONFIG_DEBUG_RESUME
mov r3, #'L'
strb r3, [ r2, #S3C2410_UTXH ]
1001:
ldrb r14, [ r3, #S3C2410_UTRSTAT ]
tst r14, #S3C2410_UTRSTAT_TXE
beq 1001b
#endif /* CONFIG_DEBUG_RESUME */
mov r1, #0
mcr p15, 0, r1, c8, c7, 0 @@ invalidate I & D TLBs
mcr p15, 0, r1, c7, c7, 0 @@ invalidate I & D caches
ldr r0, s3c2410_sleep_save_phys @ address of restore block
ldmia r0, { r4 - r13 }
mcr p15, 0, r4, c15, c1, 0 @ CP access register
mcr p15, 0, r5, c13, c0, 0 @ PID
mcr p15, 0, r6, c3, c0, 0 @ Domain ID
mcr p15, 0, r7, c2, c0, 0 @ translation table base
mcr p15, 0, r8, c1, c1, 0 @ auxilliary control
#ifdef CONFIG_DEBUG_RESUME
mov r3, #'R'
strb r3, [ r2, #S3C2410_UTXH ]
#endif
ldr r2, =resume_with_mmu
mcr p15, 0, r9, c1, c0, 0 @ turn on MMU, etc
nop @ second-to-last before mmu
mov pc, r2 @ go back to virtual address
.ltorg
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment