コード例 #1
0
ファイル: mt_spm.c プロジェクト: Scorpio92/mediatek
void spm_module_init(void)
{
    int r;
    unsigned long flags;
    struct wd_api *wd_api;

    spin_lock_irqsave(&spm_lock, flags);
    /* enable register control */
    spm_write(SPM_POWERON_CONFIG_SET, (SPM_PROJECT_CODE << 16) | (1U << 0));

    /* init power control register (select PCM clock to 26M) */
    spm_write(SPM_POWER_ON_VAL0, 0);
    spm_write(SPM_POWER_ON_VAL1, 0x00015820);
    spm_write(SPM_PCM_PWR_IO_EN, 0);

    /* reset PCM */
    spm_write(SPM_PCM_CON0, CON0_CFG_KEY | CON0_PCM_SW_RESET);
    spm_write(SPM_PCM_CON0, CON0_CFG_KEY);

    /* init PCM control register */
    spm_write(SPM_PCM_CON0, CON0_CFG_KEY | CON0_IM_SLEEP_DVS);
    spm_write(SPM_PCM_CON1, CON1_CFG_KEY | CON1_SPM_SRAM_ISO_B |
                            CON1_SPM_SRAM_SLP_B | CON1_IM_NONRP_EN | CON1_MIF_APBEN);
    spm_write(SPM_PCM_IM_PTR, 0);
    spm_write(SPM_PCM_IM_LEN, 0);

    /* SRCLKENA: POWER_ON_VAL1 (PWR_IO_EN[7]=0) or POWER_ON_VAL1|r7 (PWR_IO_EN[7]=1) */
    /* CLKSQ: POWER_ON_VAL0 (PWR_IO_EN[0]=0) or r0 (PWR_IO_EN[0]=1) */
    /* SRCLKENAI will trigger 26M-wake/sleep event */
    spm_write(SPM_CLK_CON, CC_CXO32K_RM_EN_MD);
    spm_write(SPM_PCM_SRC_REQ, (1U << 1));

    /* clean wakeup event raw status */
    spm_write(SPM_SLEEP_WAKEUP_EVENT_MASK, 0xffffffff);

    /* clean ISR status */
    spm_write(SPM_SLEEP_ISR_MASK, ISRM_ALL);
    spm_write(SPM_SLEEP_ISR_STATUS, ISRC_ALL);
    spm_write(SPM_PCM_SW_INT_CLEAR, PCM_SW_INT_ALL);
    spin_unlock_irqrestore(&spm_lock, flags);

    r = request_irq(MT_SPM_IRQ_ID, spm_irq_handler, IRQF_TRIGGER_LOW | IRQF_NO_SUSPEND,
                    "mt-spm", NULL);
    if (r) {
        spm_error("FAILED TO REQUEST SPM IRQ (%d)\n", r);
        WARN_ON(1);
    }

    get_wd_api(&wd_api);
    if (wd_api->wd_spmwdt_mode_config && wd_api->wd_thermal_mode_config) {
        wd_api->wd_spmwdt_mode_config(WD_REQ_EN, WD_REQ_RST_MODE);
        wd_api->wd_thermal_mode_config(WD_REQ_EN, WD_REQ_RST_MODE);
    } else {
        spm_error("FAILED TO GET WD API\n");
        WARN_ON(1);
    }

    spm_go_to_normal();     /* let PCM help to do thermal protection */
}
コード例 #2
0
ファイル: mt_idle.c プロジェクト: JustAndroids/ZTEBladeL2
void arch_idle(void)
{
    int cpu = smp_processor_id();
    int i;
#if defined(SPM_MCDI_FUNC)
    /*Only core0 onload & offload MCDI*/
    if(cpu==0)//only core0 offload mcdi
    {
        if(SPM_MCDI_isKICK==1)
        {
            if((atomic_read(&hotplug_cpu_count) == 1)||(SPM_MCDI_Enable==0))
            {
                printk("start leave mcdi\n");
                spm_leave_MCDI(); 
                spm_go_to_normal();
            }
                
        }
        else if ((SPM_MCDI_isKICK==0)&&(SPM_MCDI_Enable))
        {
            if((atomic_read(&hotplug_cpu_count)!=1)&&(atomic_read(&is_in_hotplug) < 1) )
            {
                if(is_ext_buck_exist() == 0)
                    mcidle_time_critera = 19500;//1.5ms for internal buck
                else
                    mcidle_time_critera = 39000;//3ms for external buck         
                spm_go_to_mcdi(1);        
        }
        }

            
    }
#endif
    for (i = 0; i < NR_TYPES; i++) {
        if (idle_handlers[i](cpu))
            break;
    }
}
コード例 #3
0
/*
    status
    RESERVED[0] :  mcusys dormant 
    RESERVED[1] :  APSRCSLEEP - (pass CHECK_APSRCWAKE)
    RESERVED[2] :  EMI self-refresh & mem ck off
     
    Options
    RESERVED[16] :  skip arm pll cg/pd 
    RESERVED[17] :  skip arm pll pd 
    RESERVED[18] :  skip AXI 26 SWITCH 
    RESERVED[19] :  skip EMI self-refresh & mem ck off                         
    RESERVED[20] :  skip mem ck off
                                                                    
    RESERVED[24] :  stop after cpu power down / cpu pll off
    RESERVED[25] :  stop after emi  down / mem ck off

*/
wake_reason_t spm_go_to_sodi(bool sodi_en,int cpu)
{
    wake_status_t *wakesta;
    unsigned long flags;
    struct mtk_irq_mask mask;
    wake_reason_t wr = WR_NONE;
    u32 con0;

    spin_lock_irqsave(&spm_lock, flags);
    spm_stop_normal();    

    mt_irq_mask_all(&mask);
    mt_irq_unmask_for_sleep(MT_SPM0_IRQ_ID);    
    mt_cirq_clone_gic();
    mt_cirq_enable();
    spm_direct_enable_sodi();

    spm_write(SPM_PCM_RESERVE,pcm_config_sodi.pcm_reserved);

#ifdef SPM_SODI_SECONDARY_KICK_IMPROVE
    if( spm_last_senario != pcm_config_sodi.scenario)//MCDI SPM Initialize
#endif
    {
        //spm_direct_enable_sodi();
        if (spm_init_pcm(&pcm_config_sodi)==false)
            goto  RESTORE_IRQ;
        
        spm_write(SPM_SLEEP_CPU_IRQ_MASK,0x1); 

        spm_write(SPM_PCM_CON1,(spm_read(SPM_PCM_CON1)| CON1_CFG_KEY )&0xffffffdf);//temporary disable pcm timer

        spm_wfi_sel(pcm_config_sodi.wfi_sel, SPM_CORE0_WFI_SEL_SW_MASK );
        spm_wfi_sel(pcm_config_sodi.wfi_sel, SPM_CORE1_WFI_SEL_SW_MASK ); 

        spm_kick_pcm(&pcm_config_sodi);

        spm_change_fw = 1;
    }
#ifdef SPM_SODI_SECONDARY_KICK_IMPROVE
    else
    {
        spm_write(SPM_SLEEP_CPU_IRQ_MASK,0x1);
        spm_wfi_sel(pcm_config_sodi.wfi_sel, SPM_CORE0_WFI_SEL_SW_MASK );
        spm_wfi_sel(pcm_config_sodi.wfi_sel, SPM_CORE1_WFI_SEL_SW_MASK ); 
        if( spm_secondary_kick(&pcm_config_sodi)==false)
            goto RESTORE_IRQ;

        spm_change_fw = 0;
    }
#endif    

    //gpiodbg_infra_dbg_out();//measure bus clock to LPD15
    soidle_before_wfi();

    spm_trigger_wfi_for_dpidle(1);//SODI with cpu dormant

    soidle_after_wfi(sodi_en);

    wakesta = spm_get_wakeup_status(&pcm_config_sodi);

    wr = wakesta->wake_reason;

    spm_clean_after_wakeup();
      
    spm_write(SPM_PCM_CON1,(spm_read(SPM_PCM_CON1)| CON1_CFG_KEY )|(CON1_PCM_TIMER_EN)); 

RESTORE_IRQ:
    mt_cirq_flush();
    mt_cirq_disable();
    mt_irq_mask_restore(&mask);
    spm_go_to_normal();
    spin_unlock_irqrestore(&spm_lock, flags);
    return wr;

}
wake_reason_t spm_go_to_dpidle(bool cpu_pdn, u8 pwrlevel)
{
    wake_status_t *wakesta;
    unsigned long flags;
    struct mtk_irq_mask mask;
    wake_reason_t wr = WR_NONE;
    u32 con0;
    u32 top_ckgen_val = 0;

    spin_lock_irqsave(&spm_lock, flags);
    spm_stop_normal();
    mt_irq_mask_all(&mask);
    mt_irq_unmask_for_sleep(MT_SPM0_IRQ_ID);
    mt_cirq_clone_gic();
    mt_cirq_enable();

#ifdef SPM_DPIDLE_SECONDARY_KICK_IMPROVE
    if( spm_last_senario != pcm_config_dpidle.scenario)//dpidle SPM Initialize
#endif    
    {   
        if(pwrlevel>2) 
        {
            spm_crit2("Hey!! wrong PWR Level: %x",pwrlevel);//ASSERT Wrong Para!!
            goto RESTORE_IRQ;
        }
        pcm_config_dpidle.pcm_pwrlevel = 1 << pwrlevel ;
        pcm_config_dpidle.spm_request_uart_sleep = (pwrlevel == 0 ? true : false);
        pcm_config_dpidle.cpu_pdn = cpu_pdn;

        if (spm_init_pcm(&pcm_config_dpidle)==false)
            goto  RESTORE_IRQ;

#ifdef SPM_CLOCK_INIT
        enable_clock(MT_CG_MEMSLP_DLYER_SW_CG, "SPM_DPIDLE");
        enable_clock(MT_CG_SPM_SW_CG, "SPM_DPIDLE");
#endif

#ifdef SPM_DPIDLE_CLK_DBG_OUT
        //gpiodbg_monitor();
        gpiodbg_emi_dbg_out();
        gpiodbg_armcore_dbg_out();
#endif

        spm_kick_pcm(&pcm_config_dpidle);
        //spm_change_fw = 1;

    }
#ifdef SPM_DPIDLE_SECONDARY_KICK_IMPROVE    
    else       
    {
        if( spm_secondary_kick(&pcm_config_dpidle)==false)
            goto RESTORE_IRQ;

        //spm_change_fw = 0;
    }  
#endif     
        
    spm_dpidle_before_wfi();

    //hopping 33M-->fixed 26M, 20130902 HG.Wei
    top_ckgen_val = spm_read(TOPCKGEN_BASE);
    spm_write(TOPCKGEN_BASE,top_ckgen_val&(~(1<<26)));
        
    snapshot_golden_setting(__FUNCTION__, __LINE__);

    spm_trigger_wfi(&pcm_config_dpidle);

    //hopping fixed 26M-->hopping 33M, 20130902 HG.Wei
    spm_write(TOPCKGEN_BASE,top_ckgen_val);

    spm_dpidle_after_wfi();

    wakesta = spm_get_wakeup_status(&pcm_config_dpidle);

    wr = wakesta->wake_reason;

    spm_clean_after_wakeup();

#ifdef SPM_CLOCK_INIT
    disable_clock(MT_CG_SPM_SW_CG, "SPM_DPIDLE");
    disable_clock(MT_CG_MEMSLP_DLYER_SW_CG, "SPM_DPIDLE");
#endif

RESTORE_IRQ:
    mt_cirq_flush();
    mt_cirq_disable();
    mt_irq_mask_restore(&mask);
    spm_go_to_normal();
    spin_unlock_irqrestore(&spm_lock, flags);
    return wr;
}