/* ********************************************************************************************************* * 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; }
/* ********************************************************************************************************* * 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; }
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; }