Example #1
0
/*
*********************************************************************************************************
*                           aw_early_suspend
*
*Description: prepare necessary info for suspend&resume;
*
*Return     : return 0 is process successed;
*
*Notes      : -1: data is ok;
*           -2: data has been destory.
*********************************************************************************************************
*/
static int aw_early_suspend(void)
{
#define MAX_RETRY_TIMES (5)

    __s32 retry = MAX_RETRY_TIMES;
    
    //backup device state
    mem_ccu_save((__ccmu_reg_list_t *)(SW_VA_CCM_IO_BASE));
    mem_gpio_save(&(saved_gpio_state));
    mem_tmr_save(&(saved_tmr_state));
    mem_twi_save(&(saved_twi_state));
    mem_sram_save(&(saved_sram_state));    

    if (likely(mem_para_info.axp_enable))
    {
        //backup volt and freq state, after backup device state
        mem_twi_init(AXP_IICBUS);
        /* backup voltages */
        while(-1 == (mem_para_info.suspend_dcdc2 = mem_get_voltage(POWER_VOL_DCDC2)) && --retry){
            ;
        }
        if(0 == retry){
            print_call_info();
            return -1;
        }else{
            retry = MAX_RETRY_TIMES;
        }   
        
        while(-1 == (mem_para_info.suspend_dcdc3 = mem_get_voltage(POWER_VOL_DCDC3)) && --retry){
            ;
        }
        if(0 == retry){
            print_call_info();
            return -1;
        }else{
            retry = MAX_RETRY_TIMES;
        }   
    }
    else
    {
        mem_para_info.suspend_dcdc2 = -1;
        mem_para_info.suspend_dcdc3 = -1;
    }
    printk("dcdc2:%d, dcdc3:%d\n", mem_para_info.suspend_dcdc2, mem_para_info.suspend_dcdc3);

    /*backup bus ratio*/
    mem_clk_getdiv(&mem_para_info.clk_div);
    /*backup pll ratio*/
    mem_clk_get_pll_factor(&mem_para_info.pll_factor);
    
    //backup mmu
    save_mmu_state(&(mem_para_info.saved_mmu_state));
    //backup cpu state
//    __save_processor_state(&(mem_para_info.saved_cpu_context));
    //backup 0x0000,0000 page entry, size?
//    save_mapping(MEM_SW_VA_SRAM_BASE);
//    mem_para_info.saved_cpu_context.ttb_1r = DRAM_STANDBY_PGD_PA;
    memcpy((void*)(DRAM_STANDBY_PGD_ADDR + 0x3000), (void*)0xc0007000, 0x1000);
	__cpuc_coherent_kern_range(DRAM_STANDBY_PGD_ADDR + 0x3000, DRAM_STANDBY_PGD_ADDR + 0x4000 - 1);
    mem_para_info.saved_mmu_state.ttb_1r = DRAM_STANDBY_PGD_PA;

    //prepare resume0 code for resume

    if((DRAM_BACKUP_SIZE1) < sizeof(mem_para_info)){
        //judge the reserved space for mem para is enough or not.
        print_call_info();
        return -1;
    }

    //clean all the data into dram
    memcpy((void *)DRAM_BACKUP_BASE_ADDR1, (void *)&mem_para_info, sizeof(mem_para_info));
    dmac_flush_range((void *)DRAM_BACKUP_BASE_ADDR1, (void *)(DRAM_BACKUP_BASE_ADDR1 + DRAM_BACKUP_SIZE1 - 1));

    //prepare dram training area data
    memcpy((void *)DRAM_BACKUP_BASE_ADDR2, (void *)DRAM_BASE_ADDR, DRAM_TRANING_SIZE);
    dmac_flush_range((void *)DRAM_BACKUP_BASE_ADDR2, (void *)(DRAM_BACKUP_BASE_ADDR2 + DRAM_BACKUP_SIZE2 - 1));
    
    mem_arch_suspend();
    save_processor_state(); 
    
    //before creating mapping, build the coherent between cache and memory
    __cpuc_flush_kern_all();
    __cpuc_coherent_kern_range(0xc0000000, 0xffffffff-1);
    //create 0x0000,0000 mapping table: 0x0000,0000 -> 0x0000,0000 
    //create_mapping();

    //clean and flush
    mem_flush_tlb();
    
#ifdef PRE_DISABLE_MMU
    //jump to sram: dram enter selfresh, and power off.
    mem = (super_standby_func)SRAM_FUNC_START_PA;
#else
    //jump to sram: dram enter selfresh, and power off.
    mem = (super_standby_func)SRAM_FUNC_START;
#endif
    //move standby code to sram
    memcpy((void *)SRAM_FUNC_START, (void *)&suspend_bin_start, (int)&suspend_bin_end - (int)&suspend_bin_start);

#ifdef CONFIG_AW_FPGA_PLATFORM
*(unsigned int *)(0xf0007000 - 0x4) = 0x12345678;
printk("%s,%d:%d\n",__FILE__,__LINE__, *(unsigned int *)(0xf0007000 - 0x4));
#endif 
#ifdef PRE_DISABLE_MMU
    //enable the mapping and jump
    //invalidate tlb? maybe, but now, at this situation,  0x0000 <--> 0x0000 mapping never stay in tlb before this.
    //busy_waiting();
    jump_to_suspend(mem_para_info.saved_mmu_state.ttb_1r, mem);
#else
    mem();
#endif

    return -2;

}
Example #2
0
/*
*********************************************************************************************************
*                           aw_early_suspend
*
*Description: prepare necessary info for suspend&resume;
*
*Return     : return 0 is process successed;
*
*Notes      : 
*********************************************************************************************************
*/
static int aw_super_standby(suspend_state_t state)
{
    int result = 0;
    suspend_status_flag = 0;
    mem_para_info.axp_enable = standby_axp_enable;
    
mem_enter:
    if( 1 == mem_para_info.mem_flag){
        invalidate_branch_predictor();
        //must be called to invalidate I-cache inner shareable?
        // I+BTB cache invalidate
        __cpuc_flush_icache_all();
        //disable 0x0000 <---> 0x0000 mapping
        restore_processor_state();
        mem_flush_tlb();
        //destroy 0x0000 <---> 0x0000 mapping
        //restore_mapping(MEM_SW_VA_SRAM_BASE);
        mem_arch_resume();
        goto resume;
    }

    save_runtime_context(mem_para_info.saved_runtime_context_svc);
    mem_para_info.mem_flag = 1;
    standby_level = STANDBY_WITH_POWER_OFF;
    mem_para_info.resume_pointer = (void *)&&mem_enter;
    mem_para_info.debug_mask = debug_mask;
    mem_para_info.suspend_delay_ms = suspend_delay_ms;
    //busy_waiting();
    if(unlikely(debug_mask&PM_STANDBY_PRINT_STANDBY)){
        pr_info("resume_pointer = 0x%x. \n", (unsigned int)(mem_para_info.resume_pointer));
    }
    
    
#if 1
    /* config system wakeup evetn type */
    if(PM_SUSPEND_MEM == state || PM_SUSPEND_STANDBY == state){
        mem_para_info.axp_event = AXP_MEM_WAKEUP | AXP_WAKEUP_PIO_ANY;
    }else if(PM_SUSPEND_BOOTFAST == state){
        mem_para_info.axp_event = AXP_BOOTFAST_WAKEUP;
    }
#endif  

    result = aw_early_suspend();
    if(-2 == result){
        //mem_para_info.mem_flag = 1;
        //busy_waiting();
        suspend_status_flag = 2;
        goto mem_enter;
    }else if(-1 == result){
        suspend_status_flag = 1;
        mem_para_info.mem_flag = 0;
        goto suspend_err;
    }
    
resume:
    aw_late_resume();
    //have been disable dcache in resume1
    //enable_cache();
    
suspend_err:
    if(unlikely(debug_mask&PM_STANDBY_PRINT_RESUME)){
        pr_info("suspend_status_flag = %d. \n", suspend_status_flag);
    }

    return 0;

}
Example #3
0
int main(void)
{
    /* clear bss segment */
    do{*tmpPtr ++ = 0;}while(tmpPtr <= (char *)&__bss_end);
    
    
#ifdef MMU_OPENED
    //move other storage to sram: saved_resume_pointer(virtual addr), saved_mmu_state
    mem_memcpy((void *)&mem_para_info, (void *)(DRAM_BACKUP_BASE_ADDR1), sizeof(mem_para_info));
#else
    mem_preload_tlb_nommu();
    /*switch stack*/
    //save_mem_status_nommu(RESUME1_START |0x02);
    //move other storage to sram: saved_resume_pointer(virtual addr), saved_mmu_state
    mem_memcpy((void *)&mem_para_info, (void *)(DRAM_BACKUP_BASE_ADDR1_PA), sizeof(mem_para_info));
    /*restore mmu configuration*/
    restore_mmu_state(&(mem_para_info.saved_mmu_state));
    //disable_dcache();

#endif
    //serial_init();
    if(unlikely((mem_para_info.debug_mask)&PM_STANDBY_PRINT_RESUME)){
        serial_puts("after restore mmu. \n");
    }
    if (unlikely((mem_para_info.debug_mask)&PM_STANDBY_PRINT_CHECK_CRC))
    {
        standby_dram_crc(1);
    }


//after open mmu mapping
#ifdef FLUSH_TLB
    //busy_waiting();
    mem_flush_tlb();
    mem_preload_tlb();
#endif

#ifdef FLUSH_ICACHE
    //clean i cache
    flush_icache();
#endif
    
    //twi freq?
    setup_twi_env();
    mem_twi_init(AXP_IICBUS);

#ifdef POWER_OFF
    restore_ccmu();
#endif

    /*restore pmu config*/
#ifdef POWER_OFF
    if (likely(mem_para_info.axp_enable))
    {
        mem_power_exit(mem_para_info.axp_event);
    }

    /* disable watch-dog: coresponding with boot0 */
    mem_tmr_disable_watchdog();
#endif

//before jump to late_resume    
#ifdef FLUSH_TLB
    mem_flush_tlb();
#endif

#ifdef FLUSH_ICACHE
    //clean i cache
    flush_icache();
#endif

    if (unlikely((mem_para_info.debug_mask)&PM_STANDBY_PRINT_CHECK_CRC))
    {
        serial_puts("before jump_to_resume. \n");
    }
    //before jump, invalidate data
    jump_to_resume((void *)mem_para_info.resume_pointer, mem_para_info.saved_runtime_context_svc);
    
    return;
}