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

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

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

s3c2410_cpu_suspend(regs_save); //调用汇编函数s3c2410_cpu_suspend 进入sleep。
/************************************************************************/
上为进入休眠部分,下为唤醒部分。
/************************************************************************/
cpu_init(); //CPU初始化

tmp = __raw_readl(S3C2410_GSTATUS2);
tmp &= S3C2410_GSTATUS2_OFFRESET;
__raw_writel(tmp, S3C2410_GSTATUS2); //清除唤醒复位标记

s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save)); //恢复核心配置
s3c2410_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save));       //恢复io口配置
s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));            //恢复中断配置
s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save));         //恢复串口配置

s3c2410_pm_debug_init(); //串口调试函数初始化

DBG("post sleep: IRQs 0x%08x, 0x%08x\n",
    __raw_readl(S3C2410_SRCPND),
    __raw_readl(S3C2410_EINTPEND)); //打印信息

s3c2410_pm_show_resume_irqs(IRQ_EINT0, __raw_readl(S3C2410_SRCPND),
                          s3c_irqwake_intmask); //查看中断唤醒源信息
s3c2410_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND),
                          s3c_irqwake_eintmask); //查看中断唤醒源信息

DBG("post sleep, preparing to return\n");

s3c2410_pm_check_restore();//如果需要在sleep前检查ram则此函数会运行,否则此函数为空,即如果CONFIG_S3C2410_PM_CHECK被定义。

DBG("S3C2410 PM Resume (post-restore)\n");
return 0;
}

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]
继承事业,薪火相传
返回列表