Exemplo n.º 1
0
void mstar_restore_context(void)
{
    sleep_restore_neon_regs(&MStar_Suspend_Buffer[SLEEPSTATE_NEONREG/WORD_SIZE]);
    restore_a9_scu((appf_u32 *)a9_scu_save,PERI_ADDRESS(PERI_PHYS));
    restore_pl310((appf_u32*)&pl310_context_save,L2_CACHE_ADDRESS(L2_CACHE_PHYS), 0);
    restore_mmu(mmu_data);
    restore_control_registers(control_data, 1);
    restore_gic_distributor_shared((appf_u32 *)gic_distributor_shared_save,(unsigned)_gic_dist_base_addr,1);
    gic_distributor_set_enabled(TRUE, (unsigned)_gic_dist_base_addr);
    restore_gic_distributor_private((appf_u32 *)gic_distributor_private_save,(unsigned)_gic_dist_base_addr,1);
    restore_gic_interface((appf_u32 *)gic_interface_save,(unsigned)_gic_cpu_base_addr,1);
    restore_a9_other((appf_u32 *)a9_other_save,1);
    restore_cp15((appf_u32 *)cp15_save);
    restore_a9_timers((appf_u32*)&a9_timer_save, PERI_ADDRESS(PERI_PHYS));
    restore_a9_global_timer((appf_u32 *)a9_global_timer_save,PERI_ADDRESS(PERI_PHYS));
    restore_performance_monitors((appf_u32 *)performance_monitor_save);
    mstar_restore_int_mask();
#if defined(CONFIG_SMP)
    platform_smp_boot_secondary_init(1);
#endif
#if defined(CONFIG_MP_PLATFORM_ARM)
#ifdef CONFIG_ARM
    {
        extern int __init init_irq_fiq_merge(void);
        init_irq_fiq_merge();
    }
#endif
#endif /* CONFIG_MP_PLATFORM_ARM */
    mstar_sleep_cur_cpu_flush();
}
Exemplo n.º 2
0
/** 
 * This function restores all the context that was lost 
 * when a CPU and cluster entered a low power state. It is called shortly after
 * reset, with the MMU and data cache off.
 *
 * This function is called with cluster->context->lock held
 */
int appf_platform_restore_context(struct appf_cluster *cluster, struct appf_cpu *cpu)
{
    struct appf_cpu_context *context;
    struct appf_cluster_context *cluster_context;
    int cluster_init;
    appf_u32 saved_items, cluster_saved_items = 0;
    /*
     * At this point we may not write to any static data, and we may
     * only read the data that we explicitly cleaned from the L2 above.
     */
    cluster_context = cluster->context;
    context = cpu->context;

    /* Should we initialize the cluster: are we the first CPU back on, and has the cluster been off? */
    cluster_init = (cluster->active_cpus == 0 && cluster->power_state >= 2);
    saved_items = context->saved_items;
    
    /* First set up the SCU & L2, if necessary */
  //  if (cluster_init)
    {
        cluster_saved_items = cluster_context->saved_items;
        if(cluster->scu_address)
        	restore_a9_scu(cluster_context->scu_data, cluster->scu_address);
        if (cluster_saved_items & SAVED_L2)
        {
            restore_pl310(cluster_context->l2_data, cluster->l2_address, cluster->power_state == 2);
        }
    }

    /* Next get the MMU back on */
    restore_mmu(context->mmu_data);
    restore_control_registers(context);
        
    /* 
     * MMU and L1 and L2 caches are on, we may now read/write any data.
     * Now we need to restore the rest of this CPU's context 
     */

    /* Get the debug registers restored, so we can debug most of the APPF code sensibly! */    
    if (saved_items & SAVED_DEBUG)
    {
        restore_a9_debug(context->debug_data);
    }

    /* Restore shared items if necessary */
//    if (cluster_init)
    {
        restore_gic_distributor_shared(cluster_context->gic_dist_shared_data, cluster->ic_address);
        if (cluster_saved_items & SAVED_GLOBAL_TIMER)
        {
            restore_a9_global_timer(cluster_context->global_timer_data, cluster->scu_address);
        }
    }

		if(cluster->ic_address)
    	restore_gic_distributor_private(context->gic_dist_private_data, cluster->ic_address);
    if(cluster->ic_address)
    	restore_gic_interface(context->gic_interface_data, cluster->ic_address);
    if(context->other_data)
    	restore_a9_other(context->other_data);
    if(context->cp15_data)
    	restore_cp15(context->cp15_data);
    if(context->banked_registers)
    	restore_banked_registers(context->banked_registers);

    if (saved_items & SAVED_VFP)
    {
        restore_vfp(context->vfp_data);
    }

    if (saved_items & SAVED_TIMERS)
    {
        restore_a9_timers(context->timer_data, cluster->scu_address);
    }

    if (saved_items & SAVED_PMU)
    {
        restore_performance_monitors(context->pmu_data);
    }

    /* Return to OS */
    return APPF_OK;
}
Exemplo n.º 3
0
/*------------------------------------------------------------------------------
    Function: mstar_pm_enter

    Description:
        Actually enter sleep state
    Input: (The arguments were used by caller to input data.)
        state - suspend state (not used)
    Output: (The arguments were used by caller to receive data.)
        None.
    Return:
        0
    Remark:
        None.
-------------------------------------------------------------------------------*/
static int mstar_pm_enter(suspend_state_t state)
{
    void *pWakeup=0;
    __asm__ volatile (
        "ldr r1, =MSTAR_WAKEUP_ENTRY\n"
        "str r1, %0"
        :"=m"(pWakeup)::"r1"
        );
    if(pre_str_max_cnt!=get_str_max_cnt())
    {
        pre_str_max_cnt=get_str_max_cnt();
        mstr_cnt=0;
    }
    mstr_cnt++;

    mstar_save_int_mask();
    save_performance_monitors((appf_u32 *)performance_monitor_save);
    save_a9_timers((appf_u32*)&a9_timer_save, PERI_ADDRESS(PERI_PHYS));
    save_a9_global_timer((appf_u32 *)a9_global_timer_save,PERI_ADDRESS(PERI_PHYS));

    save_gic_interface((appf_u32 *)gic_interface_save,(unsigned)_gic_cpu_base_addr,1);
    save_gic_distributor_private((appf_u32 *)gic_distributor_private_save,(unsigned)_gic_dist_base_addr,1);

    save_cp15((appf_u32 *)cp15_save);// CSSELR
    //save_a9_other((appf_u32 *)a9_other_save,1);

    //save_v7_debug((appf_u32 *)&a9_dbg_data_save);

    save_gic_distributor_shared((appf_u32 *)gic_distributor_shared_save,(unsigned)_gic_dist_base_addr,1);
    //start add
    save_control_registers(control_data, 1);
    save_mmu(mmu_data);
    //end add
    save_a9_scu((appf_u32 *)a9_scu_save,PERI_ADDRESS(PERI_PHYS));
    save_pl310((appf_u32*)&pl310_context_save,L2_CACHE_ADDRESS(L2_CACHE_PHYS));

    sleep_save_neon_regs(&MStar_Suspend_Buffer[SLEEPSTATE_NEONREG/WORD_SIZE]);
    sleep_save_cpu_registers(MStar_Suspend_Buffer);
    sleep_set_wakeup_save_addr_phy(mstar_virt_to_phy((void*)WAKEUP_SAVE_ADDR),(void*)WAKEUP_SAVE_ADDR);

    sleep_prepare_last(mstar_virt_to_phy(pWakeup));
    write_actlr(read_actlr() & ~A9_SMP_BIT);//add
    SerPrintf("\nMStar STR waiting power off...\n");
    __asm__ volatile (
        "nop\n"
        :::"r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","r10","r12"
        );
    //__asm__ volatile(
    //    "SUSPEND_WAIT:\n"
    //    "nop\n"
    //    "nop\n"
    //    "b SUSPEND_WAIT\n"
    //    );
    // pass different password to do ac onoff
    if(get_str_max_cnt()>0 &&mstr_cnt>=get_str_max_cnt())
    {
        SerPrintf("Max Cnt Ac off...\n");
        mstar_str_notifypmmaxcnt_off();
    }
    else
    {
#ifdef CONFIG_MSTAR_STR_CRC
        if(get_str_crc())
        {
            MDrv_MBX_NotifyPMtoCrcCheck(false);
            MDrv_MBX_write_kernel_info();
            MDrv_MBX_NotifyPMtoCrcCheck(true);
            while(!MDrv_MBX_recviceAck());
        }
#endif
        MDrv_MBX_NotifyPMtoSetPowerOff();
    }
    __asm__ volatile(
        "WAIT_SLEEP:\n"
        "nop\n"
        "nop\n"
        "b WAIT_SLEEP\n"
        );

    //////////////////////////////////////////////////////////////
    __asm__ volatile(
        "MSTAR_WAKEUP_ENTRY:\n"
        "bl ensure_environment\n"
        "bl use_tmp_stack\n"
        "mov r0, #'K'\n"
        "bl __PUTCHAR\n"
        "ldr r1, =exit_addr\n"
        "sub r0, pc,#4 \n"
        "b   sleep_wakeup_first\n"          //sleep_wakeup_first();
        "exit_addr: \n"
        "mov r0, #'L'\n"
        "bl PUTCHAR_VIRT\n"
        "ldr r0,=MStar_Suspend_Buffer\n"
        "bl sleep_restore_cpu_registers\n"  //sleep_restore_cpu_registers(MStar_Suspend_Buffer)
        :::"r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","r10","r12"
    );
    SerPrintf("\nMStar STR Resuming...\n");
    sleep_restore_neon_regs(&MStar_Suspend_Buffer[SLEEPSTATE_NEONREG/WORD_SIZE]);
    restore_a9_scu((appf_u32 *)a9_scu_save,PERI_ADDRESS(PERI_PHYS));
    restore_pl310((appf_u32*)&pl310_context_save,L2_CACHE_ADDRESS(L2_CACHE_PHYS), 0); //means power off
    //start add
    restore_mmu(mmu_data);
    restore_control_registers(control_data, 1);
    //end add
    //restore_v7_debug((appf_u32 *)&a9_dbg_data_save);
    restore_gic_distributor_shared((appf_u32 *)gic_distributor_shared_save,(unsigned)_gic_dist_base_addr,1);
    gic_distributor_set_enabled(TRUE, (unsigned)_gic_dist_base_addr);//add
    restore_gic_distributor_private((appf_u32 *)gic_distributor_private_save,(unsigned)_gic_dist_base_addr,1);
    restore_gic_interface((appf_u32 *)gic_interface_save,(unsigned)_gic_cpu_base_addr,1);

    //restore_a9_other((appf_u32 *)a9_other_save,1);
    restore_cp15((appf_u32 *)cp15_save);

    restore_a9_timers((appf_u32*)&a9_timer_save, PERI_ADDRESS(PERI_PHYS));
    restore_a9_global_timer((appf_u32 *)a9_global_timer_save,PERI_ADDRESS(PERI_PHYS));
    restore_performance_monitors((appf_u32 *)performance_monitor_save);

    mstar_restore_int_mask();

    sleep_clear_wakeup_save_addr_phy(mstar_virt_to_phy((void*)WAKEUP_SAVE_ADDR),(void*)WAKEUP_SAVE_ADDR);
    platform_smp_boot_secondary_init(1);
    mstar_sleep_cur_cpu_flush();

#if defined(CONFIG_MP_PLATFORM_ARM)
    {
        extern int __init init_irq_fiq_merge(void);
        init_irq_fiq_merge();
    }
#endif /* CONFIG_MP_PLATFORM_ARM */

	return 0;
}
Exemplo n.º 4
0
/**
 * This function restores all the context that was lost
 * when a CPU and cluster entered a low power state. It is called shortly after
 * reset, with the MMU and data cache off.
 *
 */
static void platform_restore_context(struct cpu_cluster *cluster, struct cpu *pcpu)
{
    struct cpu_context *context;
    struct cpu_cluster_context *cluster_context;
#if MAX_CPUS != 1
    int cluster_init;
#endif
    int *chip_ver = (int *)__pa(&e1_chip);

    /*
     * At this point we may not write to any data, and we may
     * only read the data that we explicitly cleaned from the L2 above.
     */
    cluster_context = &(cluster->context);
    context = &(pcpu->context);

    restore_cp15(context->cp15_data);

    /* Should we initialize the cluster: are we the first CPU back on, and has the cluster been off? */
#if MAX_CPUS != 1
    cluster_init = (cluster->active_cpus == 0 && cluster->power_state >= STATUS_DORMANT);
#endif


    /* First set up the SCU & L2, if necessary */
#if MAX_CPUS != 1
    if (cluster_init) {
#endif
        restore_a9_scu(cluster_context->scu_data, IO_VIRT_TO_PHYS(cluster->scu_address));

        restore_pl310(cluster_context->l2_data, IO_VIRT_TO_PHYS(cluster->l2_address), cluster->power_state == STATUS_DORMANT);
#if MAX_CPUS != 1
    }
#endif


    /* Next get the MMU back on */
    restore_mmu(context->mmu_data);


    if (cluster->power_state == STATUS_SHUTDOWN) {
        invalidate_icache_v7();
        invalidate_dcache_v7();
    } else {
        //E2 L1 cache still has HW issue
        if (*chip_ver != 1) {
            invalidate_icache_v7();
            invalidate_dcache_v7();
        }
    }

    restore_control_registers(context);

    //now MMU is restored, welcome to virtual world
    isb();
    dsb();


    enable_pl310(cpu_cluster.l2_address);
    enable_cache_v7_l1();

   /*
     * MMU and L1 and L2 caches are on, we may now read/write any data.
     * Now we need to restore the rest of this CPU's context
     */

#if 0 //wschen 2011-07-28
    /* Get the debug registers restored, so we can debug most of the code sensibly! */
    restore_a9_debug(cpu.context.debug_data);
#endif

    /* Restore shared items if necessary */
#if MAX_CPUS != 1
    if ((cpu_cluster.active_cpus == 0) && (cpu_cluster.power_state >= STATUS_DORMANT)) {
#endif
        restore_gic_distributor_shared((u32 *)cpu_cluster.context.gic_dist_shared_data, cpu_cluster.ic_address);
        restore_a9_global_timer((u32 *)cpu_cluster.context.global_timer_data, cpu_cluster.scu_address);
#if MAX_CPUS != 1
    }
#endif

    restore_gic_distributor_private((u32 *)cpu.context.gic_dist_private_data, cpu_cluster.ic_address);
    restore_gic_interface((u32 *)cpu.context.gic_interface_data, cpu.ic_address);

    restore_a9_other((u32 *)cpu.context.other_data);

    restore_vfp((u32 *)cpu.context.vfp_data);

    restore_a9_timers((u32 *)cpu.context.timer_data, cpu_cluster.scu_address);

    restore_performance_monitors((u32 *)cpu.context.pmu_data);

    dormant_ret_flag = 1;

    restore_banked_registers((u32 *)cpu.context.banked_registers);
}