2440休眠问题解决不了

在2440中进入休眠函数
void OEMPowerOff()
{
    static UINT32 saveArea[51];
    S3C2440A_INTR_REG *pIntr = (S3C2440A_INTR_REG*)OALPAtoVA(S3C2440A_BASE_REG_PA_INTR, FALSE);
    S3C2440A_IOPORT_REG *pIOPort = (S3C2440A_IOPORT_REG*)OALPAtoVA(S3C2440A_BASE_REG_PA_IOPORT, FALSE);
    S3C2440A_LCD_REG *pLCD = (S3C2440A_LCD_REG*)OALPAtoVA(S3C2440A_BASE_REG_PA_LCD, FALSE);
    RETAILMSG(1, (TEXT(":::E:\WINCE500\PLATFORM\SMDK2440A\Src\Common\Power\off.c\r\n")));
    // First do platform specific actions
    BSPPowerOff();
    // Then save system registers
    saveArea[0]  = INPORT32(&pIOPort->GPACON);
    saveArea[1]  = INPORT32(&pIOPort->GPADAT);
    saveArea[2]  = INPORT32(&pIOPort->GPBCON);
    saveArea[3]  = INPORT32(&pIOPort->GPBDAT);
    saveArea[4]  = INPORT32(&pIOPort->GPBUP);
    saveArea[5]  = INPORT32(&pIOPort->GPCCON);
    saveArea[6]  = INPORT32(&pIOPort->GPCDAT);
    saveArea[7]  = INPORT32(&pIOPort->GPCUP);
    saveArea[8]  = INPORT32(&pIOPort->GPDCON);
    saveArea[9]  = INPORT32(&pIOPort->GPDDAT);
    saveArea[10] = INPORT32(&pIOPort->GPDUP);
    saveArea[11] = INPORT32(&pIOPort->GPECON);
    saveArea[12] = INPORT32(&pIOPort->GPEDAT);
    saveArea[13] = INPORT32(&pIOPort->GPEUP);
    saveArea[14] = INPORT32(&pIOPort->GPFCON);
    saveArea[15] = INPORT32(&pIOPort->GPFDAT);
    saveArea[16] = INPORT32(&pIOPort->GPFUP);
    saveArea[17] = INPORT32(&pIOPort->GPGCON);
    saveArea[18] = INPORT32(&pIOPort->GPGDAT);
    saveArea[19] = INPORT32(&pIOPort->GPGUP);
    saveArea[20] = INPORT32(&pIOPort->GPHCON);
    saveArea[21] = INPORT32(&pIOPort->GPHDAT);
    saveArea[22] = INPORT32(&pIOPort->GPHUP);

    saveArea[23] = INPORT32(&pIOPort->MISCCR);
    saveArea[24] = INPORT32(&pIOPort->DCLKCON);
    saveArea[25] = INPORT32(&pIOPort->EXTINT0);
    saveArea[26] = INPORT32(&pIOPort->EXTINT1);
    saveArea[27] = INPORT32(&pIOPort->EXTINT2);
    saveArea[28] = INPORT32(&pIOPort->EINTFLT0);
    saveArea[29] = INPORT32(&pIOPort->EINTFLT1);
    saveArea[30] = INPORT32(&pIOPort->EINTFLT2);
    saveArea[31] = INPORT32(&pIOPort->EINTFLT3);
    saveArea[32] = INPORT32(&pIOPort->EINTMASK);

    saveArea[33] = INPORT32(&pIntr->INTMOD);
    saveArea[34] = INPORT32(&pIntr->INTMSK);
    saveArea[35] = INPORT32(&pIntr->INTSUBMSK);

    saveArea[36] = INPORT32(&pLCD->TCONSEL);
    saveArea[37] = INPORT32(&pLCD->LCDINTMSK);
    saveArea[38] = INPORT32(&pLCD->TPAL);
    saveArea[39] = INPORT32(&pLCD->DITHMODE);
    saveArea[40] = INPORT32(&pLCD->BLUELUT);
    saveArea[41] = INPORT32(&pLCD->GREENLUT);
    saveArea[42] = INPORT32(&pLCD->REDLUT);
    saveArea[43] = INPORT32(&pLCD->LCDSADDR3);
    saveArea[44] = INPORT32(&pLCD->LCDSADDR2);
    saveArea[45] = INPORT32(&pLCD->LCDSADDR1);
    saveArea[46] = INPORT32(&pLCD->LCDCON5);
    saveArea[47] = INPORT32(&pLCD->LCDCON4);
    saveArea[48] = INPORT32(&pLCD->LCDCON3);
    saveArea[49] = INPORT32(&pLCD->LCDCON2);
    saveArea[50] = INPORT32(&pLCD->LCDCON1);

    pLCD->LCDCON1   = 0;
    pLCD->LCDCON2   = 0;
    pLCD->LCDCON3   = 0;
    pLCD->LCDCON4   = 0;
    pLCD->LCDCON5   = 0;
    pLCD->LCDSADDR1 = 0;
    pLCD->LCDSADDR2 = 0;
    pLCD->LCDSADDR3 = 0;
    pLCD->TCONSEL    = 0;
    pLCD->TPAL      = 0;

 ConfigStopGPIO();

    // Switch off power for KITL device
      OALKitlPowerOff(); // made_by_gmh
 
  ///////////////////////////GMH
  //pIOPort->GPGCON &= 0xfcff;
 // pIOPort->GPGCON |= 0x0300;
 // pIOPort->GPGDAT &=0xef;
 // RETAILMSG(1, (TEXT("::: pwr_en=0@josh915\r\n")));
   /////////////////////////////////GMH_END
  
    // Go to power off mode
     OALCPUPowerOff();//这个函数就在starup.s中

之后进入oal的starup.s中
 LEAF_ENTRY OALCPUPowerOff

;       1. Push SVC state onto our stack
 stmdb   sp!, {r4-r12}                  
 stmdb   sp!, {lr}

;       2. Save MMU & CPU Register to RAM
    ldr     r3, =SLEEPDATA_BASE_VIRTUAL     ; base of Sleep mode storage

 ldr     r2, =Awake_address              ; store Virtual return address
 str     r2, [r3], #4

 mrc     p15, 0, r2, c1, c0, 0           ; load r2 with MMU Control
 ldr     r0, =MMU_CTL_MASK               ; mask off the undefined bits
 bic     r2, r2, r0
 str     r2, [r3], #4                    ; store MMU Control data

 mrc     p15, 0, r2, c2, c0, 0           ; load r2 with TTB address.
 ldr     r0, =MMU_TTB_MASK               ; mask off the undefined bits
 bic     r2, r2, r0
 str     r2, [r3], #4                    ; store TTB address

 mrc     p15, 0, r2, c3, c0, 0           ; load r2 with domain access control.
 str     r2, [r3], #4                    ; store domain access control

 str     sp, [r3], #4                    ; store SVC stack pointer

 mrs     r2, spsr
 str     r2, [r3], #4                    ; store SVC status register

 mov     r1, #Mode_FIQ:OR:I_Bit:OR:F_Bit ; Enter FIQ mode, no interrupts
 msr     cpsr, r1
 mrs     r2, spsr
 stmia   r3!, {r2, r8-r12, sp, lr}       ; store the FIQ mode registers

 mov     r1, #Mode_ABT:OR:I_Bit:OR:F_Bit ; Enter ABT mode, no interrupts
 msr     cpsr, r1
 mrs  r0, spsr
 stmia   r3!, {r0, sp, lr}               ; store the ABT mode Registers

 mov     r1, #Mode_IRQ:OR:I_Bit:OR:F_Bit ; Enter IRQ mode, no interrupts
 msr     cpsr, r1
 mrs     r0, spsr
 stmia   r3!, {r0, sp, lr}               ; store the IRQ Mode Registers

 mov     r1, #Mode_UND:OR:I_Bit:OR:F_Bit ; Enter UND mode, no interrupts
 msr     cpsr, r1
 mrs     r0, spsr
 stmia   r3!, {r0, sp, lr}               ; store the UND mode Registers

 mov     r1, #Mode_SYS:OR:I_Bit:OR:F_Bit ; Enter SYS mode, no interrupts
 msr     cpsr, r1
 stmia   r3!, {sp, lr}                   ; store the SYS mode Registers

 mov     r1, #Mode_SVC:OR:I_Bit:OR:F_Bit ; Back to SVC mode, no interrupts
 msr     cpsr, r1

;       3. do Checksum on the Sleepdata
 ldr     r3, =SLEEPDATA_BASE_VIRTUAL ; get pointer to SLEEPDATA
 ldr     r2, =0x0
 ldr     r0, =(SLEEPDATA_SIZE-1)  ; get size of data structure (in words)
30
 ldr     r1, [r3], #4
 and     r1, r1, #0x1
 mov     r1, r1, ROR #31
 add     r2, r2, r1
 subs    r0, r0, #1
 bne     %b30

 ldr     r0, =vGPIOBASE
 ;;;add  r2, r2, #1    ; test checksum of the Sleep data error
 str     r2, [r0, #oGSTATUS3]  ; Store in Power Manager Scratch pad register

 ldr     r0, =vGPIOBASE
 ldr     r1, =0x550a
 str     r1, [r0, #oGPFCON]
 
 ldr  r1, =0x30
 str  r1, [r0, #oGPFDAT] 

;       4. Interrupt Disable
    ldr     r0, =vINTBASE
    mvn     r2, #0
 str     r2, [r0, #oINTMSK]
 str     r2, [r0, #oSRCPND]
 str     r2, [r0, #oINTPND]

;;       5. Cache Flush
 bl  OALClearUTLB
 bl  OALFlushICache
 ldr     r0, = (DCACHE_LINES_PER_SET - 1)   
 ldr     r1, = (DCACHE_NUM_SETS - 1)   
 ldr     r2, = DCACHE_SET_INDEX_BIT   
 ldr     r3, = DCACHE_LINE_SIZE    
 bl  OALFlushDCache

;       6. Setting Wakeup External Interrupt(EINT0,1,2) Mode
 ldr     r0, =vGPIOBASE

 ldr     r1, =0x550a
 str     r1, [r0, #oGPFCON]

; ldr     r1, =0x55550100
; str     r1, [r0, #oGPGCON]

;       7. Go to Power-Off Mode
 ldr  r0, =vMISCCR   ; hit the TLB
 ldr  r0, [r0]
 ldr  r0, =vCLKCON
 ldr  r0, [r0]

 ldr     r0, =vREFRESH  
 ldr     r1, [r0]  ; r1=rREFRESH 
 orr     r1, r1, #(1 << 22)

 ldr  r2, =vMISCCR
 ldr  r3, [r2]
 orr  r3, r3, #(7<<17)        ; Make sure that SCLK0:SCLK->0, SCLK1:SCLK->0, SCKE=L during boot-up
 bic  r3, r3, #(7<<20)
 orr  r3, r3, #(6<<20)

 ldr     r4, =vCLKCON
 ldr     r5, =0x1ffff8            ; Power Off Mode

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Sometimes it is not working in cache mode. So I modify to jump to ROM area.
;
;;; ldr  r6, =0x92000000  ; make address to 0x9200 0020
;;; add  r6, r6, #0x20  ;
;;; mov     pc, r6    ; jump to Power off code in ROM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 b       SelfRefreshAndPowerOff

 ALIGN   32                      ; for I-Cache Line(32Byte, 8 Word)

SelfRefreshAndPowerOff  ; run with Instruction Cache's code
 str     r1, [r0]  ; Enable SDRAM self-refresh
 str  r3, [r2]  ; MISCCR Setting
 str     r5, [r4]  ; Power Off !!
 b       .

这个汇编代码实现真正的休眠设置,系统能一步步执行下来,执行到最后,系统电流下降了100多ma,sclk0等时钟信号也变0了,但是lcd控制信号pwren由3.3降到2.3v左右,lcd没有被关闭,出现了白屏,也就是系统没有真正进入休眠中。可能有人会说,直接用io把pwren设置为0,可是系统已经设置过了,在  
BSPPowerOff();函数中:
    /* LCD Controller Disable               */
    CLRPORT32(&pIOPort->GPGDAT, 1 << 4);
已经设置过,即使强制把lcd背光关了,电流也只能再少100多ma,还有200多ma的电流,我猜想内核其实没有真正休眠下来,假如真的休眠了,lcd也会真正被关闭
对比了很多网上的bsp,基本上也差不多,没多大区别,,不知道原因出在哪里
映射地址情况如下

SLEEPDATA_BASE_VIRTUAL          EQU 0xA0028000  ; keep in sync w/ config.bib
SLEEPDATA_BASE_PHYSICAL         EQU 0x30028000

config.bib:MEMORY
    NK    80200000  02200000  RAMIMAGE
;    RAM    82400000  05c00000  RAM
    RAM    82400000  01c00000  RAM

你可能感兴趣的:(题解)