Beispiel #1
0
wake_reason_t spm_go_to_sleep(void)
{
    wake_status_t *wakesta;
    unsigned long flags,i;
    struct mtk_irq_mask mask;
    static wake_reason_t last_wr = WR_NONE;

    if(pcm_config_suspend.reserved & SPM_SUSPEND_GET_FGUAGE)
        pcm_config_suspend.timer_val_ms = spm_get_wake_period(last_wr)*1000;
    
    mtk_wdt_suspend();

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

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

    spm_kick_pcm(&pcm_config_suspend);

    snapshot_golden_setting(__FUNCTION__, __LINE__);
    spm_trigger_wfi(&pcm_config_suspend);
    
    wakesta = spm_get_wakeup_status(&pcm_config_suspend);
    
    last_wr = wakesta->wake_reason;

    spm_clean_after_wakeup();
    
 RESTORE_IRQ:
    mt_irq_mask_restore(&mask);
    spin_unlock_irqrestore(&spm_lock, flags);
   
    mtk_wdt_resume();
       
    return last_wr;
}
Beispiel #2
0
/*
 * pwrlevel:
 *     0: CPU standby + AP sleep => legacy sleep mode
 *     1: CPU dormant (L1/L2 sleep) + AP sleep
 *     2: CPU shutdown (L1/L2 power down) + AP sleep
 */
wake_reason_t sc_go_to_sleep(unsigned int pwrlevel)
{
	u32 wakesrc, dvfscon, sec = 0;
	int i, r;
	unsigned long flags;
	struct mtk_irq_mask mask;
	static wake_reason_t last_wr = WR_NONE;

	sc_info2("pwrlevel = %u\n", pwrlevel);

	if (sc_pwake_en)
		sec = sc_get_wake_period(!!(last_wr != WR_SLP_TMR));

	mtk_wdt_suspend();

	spin_lock_irqsave(&sc_lock, flags);
	wakesrc = sc_wake_src;
	for (i = 0; i < NUM_WAKE_SRC; i++) {
		if (wakesrc & (1U << i)) {
			r = sc_enable_wake_irq(sc_wake_irq[i]);
			if (r)
				wakesrc &= ~(1U << i);
		}
	}

	mt_irq_mask_all(&mask);

	mt_irq_unmask_for_sleep(MT_SLEEP_IRQ_ID);

	/* to workaround DVFS issue due to CKDIV1 failure */
	dvfscon = sc_read(SC_AP_DVFS_CON);
	//ckdiv1 = sc_read(TOP_CKDIV1);
	sc_write(SC_AP_DVFS_CON, dvfscon | 0x3);
	sc_write_sync();

	sc_set_apmcu_pwrctl(pwrlevel);

#ifdef CONFIG_MTK_SC_DEBUG
	/* bypass CSYSPWRUPREQ to avoid keeping SRCLKENA high */
	sc_write(SC_CLK_CON, sc_read(SC_CLK_CON) | SC_CLK_CON_BYPASSDBG);
	sc_write_sync();
#endif

	last_wr = sc_enter_pause_mode(pwrlevel, sec, wakesrc);

#ifdef CONFIG_MTK_SC_DEBUG
	/* restore SC_CLK_CON */
	sc_write(SC_CLK_CON, sc_read(SC_CLK_CON) & ~SC_CLK_CON_BYPASSDBG);
	sc_write_sync();
#endif

	/* to workaround DVFS issue due to CKDIV1 failure */
	//sc_write(TOP_CKDIV1, 0x00);
	//sc_write(TOP_CKDIV1, ckdiv1);
	sc_write(SC_AP_DVFS_CON, dvfscon);
	sc_write_sync();

	mt_irq_mask_restore(&mask);
	spin_unlock_irqrestore(&sc_lock, flags);

	mtk_wdt_resume();

	return last_wr;
}