首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

s3c2440 省电模式开发详解(2)

s3c2440 省电模式开发详解(2)

5.       进休眠前的最后汇编段程序(arch/arm/mach-s3c2410/sleep.s)
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, 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

#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
bl    arm920_flush_kern_cache_all
#endif

@@ prepare cpu to sleep

ldr   r4, =S3C2410_REFRESH
ldr   r5, =S3C24XX_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_USBSUSPND0 | S3C2410_MISCCR_USBSUSPND1) @suspend usb
orr   r8, r8, #(S3C2400_MISCCR_SPUCR_LDIS | S3C2400_MISCCR_SPUCR_HDIS) @suspend d(0-31)
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
    mov r0, #0x1000
1: subs r0, r0, #1          @wait until the SelfRefresh is released
    bne 1b
streq       r8, [ r5 ]                @ SDRAM power-down config
streq       r9, [ r6 ]                @ CPU sleep
1:     beq 1b
mov pc, r14

2、唤醒部分
1、Uboot部分(u-boot-1.1.4/cpu/arm920t/start.s)
reset:
#if 0
mrs r0, cpsr      /* Set the cpu to SVC32 mode */
bic   r0, r0, #0x1f
orr   r0, r0, #0xd3
msr cpsr, r0
#endif

/* disable watchdog timer */
mov r0, #WTCON_BASE
ldr r1, =0x0
str r1, [r0, #oWTCON]
/*
* mask all IRQs by setting all bits in the INTMR - default
*/
mov r0, #INT_BASE
ldr   r1, =0xffffffff
str    r1, [r0, #oINTMSK]

ldr   r1, =0x7ff
str    r1, [r0, #oINTSUBMSK]

mov r0, #CLK_BASE
ldr r1, =0xffffffff
str r1, [r0, #oLOCKTIME]

/* FCLK:HCLKCLK */
ldr r1, =0x0
str r1, [r0, #oCAMDIVN]

ldr r1, =_clkdivn
str r1, [r0, #oCLKDIVN]

mrc p15, 0, r1, c1, c0, 0           /* read ctrl register */
orr r1, r1, #0xc0000000           /* Asynchronous */
mcr p15, 0, r1, c1, c0, 0           /* write ctrl register */

/* UPLL setup */
ldr r1, =_upllcon
str r1, [r0, #oUPLLCON]

nop
nop
nop         /* wait until upll has the effect */
nop
nop

/* PLL setup */
ldr r1, =_mpllcon
str r1, [r0, #oMPLLCON]
/* configure memory */
bl    memset
/* Power Manage  Check if this is a wake-up from sleep */
ldr r1, PMST_ADDR
ldr r0, [r1]
@bic r0,r0,#0xfffffffd
tst r0, #(0x02)
bne WakeupStart
WakeupStart:
    /* Clear sleep reset bit */   
    ldr r0, PMST_ADDR
    mov r1, #0x0       @PMST_SMR
    str r1, [r0]
   
    ldr r0, PMCTL1_ADDR  /* Release the SDRAM signal protections */
    ldr r1, =0x00010330
   str r1, [r0]
   
    ldr r0, =0x48000024
    ldr r1, [r0]
    bic r1, r1, #0x400000
    str r1, [r0]
      
   mov r1, #0x1000
1: subs r1, r1, #1 /* wait until the SelfRefresh is released. */
    bne 1b
   
    /* Go... */   
    ldr r0, =0x560000B8 /* read a return address  go to s3c2410_cpu_resume*/
    ldr r1, [r0]
      
    mov pc, r1
    nop
    nop
1: b   1b      /* infinite loop */

2、Kernel部分

1.       唤醒程序汇编部分(arch/arm/mach-s3c2410/sleep.s)
resume_with_mmu:
ldmfd       sp!, { r4 - r12, pc }
.ltorg

.data
.global     s3c2410_sleep_save_phys
s3c2410_sleep_save_phys:
.word       0

ENTRY(s3c2410_cpu_resume)
mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
msr cpsr_c, r0

mov r2, #S3C24XX_PA_UART & 0xff000000
orr   r2, r2, #S3C24XX_PA_UART & 0xff000

#if 0
/* SMDK2440 LED set */
mov r14, #S3C24XX_PA_GPIO
ldr   r12, [ r14, #0x54 ]
bic   r12, r12, #3<<4
orr   r12, r12, #1<<7
str    r12, [ r14, #0x54 ]
#endif

#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

#ifdef CONFIG_DEBUG_RESUME
mov r3, #'R'
strb r3, [ r2, #S3C2410_UTXH ]
#endif

ldr   r2, =resume_with_mmu
mcr p15, 0, r8, c1, c0, 0              @ turn on MMU, etc
nop                              @ second-to-last before mmu
mov pc, r2                           @ go back to virtual address

.ltorg
继承事业,薪火相传
返回列表