static void spm_trigger_wfi_for_sleep(struct pwr_ctrl *pwrctrl)
{
//    sync_hw_gating_value();     /* for Vcore DVFS */

    if (is_cpu_pdn(pwrctrl->pcm_flags)) {
        spm_dormant_sta = mt_cpu_dormant(CPU_SHUTDOWN_MODE/* | DORMANT_SKIP_WFI*/);
        switch (spm_dormant_sta)
        {
            case MT_CPU_DORMANT_RESET:
                break;
            case MT_CPU_DORMANT_ABORT:
                break;
            case MT_CPU_DORMANT_BREAK:
                break;
            case MT_CPU_DORMANT_BYPASS:
                break;
        }
    } else {
        spm_dormant_sta = -1;
        spm_write(CA7_BUS_CONFIG, spm_read(CA7_BUS_CONFIG) | 0x10);
        wfi_with_sync();
        spm_write(CA7_BUS_CONFIG, spm_read(CA7_BUS_CONFIG) & ~0x10);
    }

    if (is_infra_pdn(pwrctrl->pcm_flags))
        mtk_uart_restore();
}
static void spm_trigger_wfi_for_sleep(struct pwr_ctrl *pwrctrl)
{
//FIXME: for K2 fpga early porting
#if 0
    sync_hw_gating_value();     /* for Vcore DVFS */
#endif

    if (is_cpu_pdn(pwrctrl->pcm_flags)) {
        spm_dormant_sta = mt_cpu_dormant(CPU_SHUTDOWN_MODE/* | DORMANT_SKIP_WFI*/);
        switch (spm_dormant_sta)
        {
            case MT_CPU_DORMANT_RESET:
                break;
            case MT_CPU_DORMANT_ABORT:
                break;
            case MT_CPU_DORMANT_BREAK:
                break;
            case MT_CPU_DORMANT_BYPASS:
                break;
        }
    } else {
        spm_dormant_sta = -1;
		//spm_write(MP0_AXI_CONFIG, spm_read(MP0_AXI_CONFIG) | ACINACTM);
        wfi_with_sync();
      //  spm_write(MP0_AXI_CONFIG, spm_read(MP0_AXI_CONFIG) & ~ACINACTM);
    }

    if (is_infra_pdn(pwrctrl->pcm_flags))
        mtk_uart_restore();
}
Esempio n. 3
0
static int slp_suspend_ops_begin(suspend_state_t state)
{
    /* legacy log */
    slp_notice("@@@@@@@@@@@@@@@@@@@@\n");
    slp_notice("Chip_pm_begin(%u)(%u)\n", is_cpu_pdn(slp_spm_flags), is_infra_pdn(slp_spm_flags));
    slp_notice("@@@@@@@@@@@@@@@@@@@@\n");

    slp_wake_reason = WR_NONE;

    return 0;
}
/*
 * go_to_sleep_before_wfi() - trigger SPM to enter suspend scenario
 */
static void go_to_sleep_before_wfi(const unsigned int spm_flags)
{
	struct pwr_ctrl *pwrctrl;

	pwrctrl = &spm_ctrl;

	set_pwrctrl_pcm_flags(pwrctrl, spm_flags);

	spm_set_sysclk_settle();

	INFO("sec = %u, wakesrc = 0x%x (%u)(%u)\n",
	     pwrctrl->timer_val, pwrctrl->wake_src,
	     is_cpu_pdn(pwrctrl->pcm_flags),
	     is_infra_pdn(pwrctrl->pcm_flags));

	spm_reset_and_init_pcm();
	spm_init_pcm_register();
	spm_set_power_control(pwrctrl);
	spm_set_wakeup_event(pwrctrl);
	spm_kick_pcm_to_run(pwrctrl);
	spm_init_event_vector(&suspend_pcm_ca7);
	spm_kick_im_to_fetch(&suspend_pcm_ca7);
}
Esempio n. 5
0
bool slp_will_infra_pdn(void)
{
    return is_infra_pdn(slp_spm_flags);
}
Esempio n. 6
0
static int slp_suspend_ops_enter(suspend_state_t state)
{
    int ret = 0;

#ifdef CONFIG_MTK_TC1_FM_AT_SUSPEND
    int fm_radio_is_playing = 0;
    if ( ConditionEnterSuspend() == true )
    	fm_radio_is_playing = 0;
    else
    	fm_radio_is_playing = 1;
#endif /* CONFIG_MTK_TC1_FM_AT_SUSPEND */ 
#ifdef CONFIG_MTKPASR
    /* PASR SW operations */
    enter_pasrdpd();
#endif

    /* legacy log */
    slp_notice("@@@@@@@@@@@@@@@@@@@@\n");
    slp_crit2("Chip_pm_enter\n");
    slp_notice("@@@@@@@@@@@@@@@@@@@@\n");

//FIXME: for K2 bring up
    if (slp_dump_gpio)
        gpio_dump_regs();
#if 0
    if (slp_dump_regs)
        slp_dump_pm_regs();
#endif

    if (slp_check_mtcmos_pll)
        slp_check_pm_mtcmos_pll();

    if (!spm_cpusys0_can_power_down()) {
        slp_error("CANNOT SLEEP DUE TO CPU1~x PON, SPM_PWR_STATUS = 0x%x, SPM_PWR_STATUS_2ND = 0x%x\n",
                  slp_read(SPM_PWR_STATUS), slp_read(SPM_PWR_STATUS_2ND));
        //return -EPERM;
        ret = -EPERM;
        goto LEAVE_SLEEP;
    }

    if (is_infra_pdn(slp_spm_flags) && !is_cpu_pdn(slp_spm_flags)) {
        slp_error("CANNOT SLEEP DUE TO INFRA PDN BUT CPU PON\n");
        //return -EPERM;
        ret = -EPERM;
        goto LEAVE_SLEEP;
    }

    
    /* only for test */
    #if 0
    slp_pasr_en(1, 0x0);
    slp_dpd_en(1);
    #endif

#if SLP_SLEEP_DPIDLE_EN
#ifdef CONFIG_MTK_TC1_FM_AT_SUSPEND
    if (slp_ck26m_on | fm_radio_is_playing)
#else
    if (slp_ck26m_on)
#endif
        slp_wake_reason = spm_go_to_sleep_dpidle(slp_spm_deepidle_flags, slp_spm_data);
    else
#endif
        slp_wake_reason = spm_go_to_sleep(slp_spm_flags, slp_spm_data);

LEAVE_SLEEP:
#ifdef CONFIG_MTKPASR
    /* PASR SW operations */
    leave_pasrdpd();
#endif

#ifdef CONFIG_MTK_SYSTRACKER
    systracker_enable();
#endif

    return ret;
}
wake_reason_t spm_go_to_sleep(u32 spm_flags, u32 spm_data)
{
    u32 sec = 0;
    int wd_ret;
    struct wake_status wakesta;
    unsigned long flags;
    struct mtk_irq_mask mask;
    struct wd_api *wd_api;
    static wake_reason_t last_wr = WR_NONE;
    struct pcm_desc *pcmdesc = __spm_suspend.pcmdesc;
    struct pwr_ctrl *pwrctrl = __spm_suspend.pwrctrl;
    struct spm_lp_scen *lpscen;

    lpscen = spm_check_talking_get_lpscen(&__spm_suspend, &spm_flags);
    pcmdesc = lpscen->pcmdesc;
    pwrctrl = lpscen->pwrctrl;

    set_pwrctrl_pcm_flags(pwrctrl, spm_flags);
    set_pwrctrl_pcm_data(pwrctrl, spm_data);

#if SPM_PWAKE_EN
    sec = spm_get_wake_period(-1 /* FIXME */, last_wr);
#endif
    pwrctrl->timer_val = sec * 32768;

    wd_ret = get_wd_api(&wd_api);
    if (!wd_ret)
        wd_api->wd_suspend_notify();

    spm_suspend_pre_process(pwrctrl);

    spin_lock_irqsave(&__spm_lock, flags);
    mt_irq_mask_all(&mask);
    mt_irq_unmask_for_sleep(MT_SPM_IRQ_ID);
    mt_cirq_clone_gic();
    mt_cirq_enable();

    spm_set_sysclk_settle();

    spm_crit2("sec = %u, wakesrc = 0x%x (%u)(%u)\n",
              sec, pwrctrl->wake_src, is_cpu_pdn(pwrctrl->pcm_flags), is_infra_pdn(pwrctrl->pcm_flags));

    if (request_uart_to_sleep()) {
        last_wr = WR_UART_BUSY;
        goto RESTORE_IRQ;
    }

    __spm_reset_and_init_pcm(pcmdesc);

    __spm_kick_im_to_fetch(pcmdesc);

    __spm_init_pcm_register();

    __spm_init_event_vector(pcmdesc);

    __spm_set_power_control(pwrctrl);

    __spm_set_wakeup_event(pwrctrl);

    spm_kick_pcm_to_run(pwrctrl);

#if 0
    if (1 == spm_snapshot_golden_setting)
    {
        snapshot_golden_setting(__FUNCTION__, __LINE__);
        spm_snapshot_golden_setting = 2;
    }
#endif

    spm_trigger_wfi_for_sleep(pwrctrl);

    __spm_get_wakeup_status(&wakesta);

    spm_clean_after_wakeup();

    request_uart_to_wakeup();

    last_wr = spm_output_wake_reason(&wakesta, pcmdesc);

RESTORE_IRQ:
    mt_cirq_flush();
    mt_cirq_disable();
    mt_irq_mask_restore(&mask);
    spin_unlock_irqrestore(&__spm_lock, flags);

    spm_suspend_post_process(pwrctrl);

    if (!wd_ret)
        wd_api->wd_resume_notify();

    return last_wr;
}