Example #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;
}
static int golden_test_proc_show(struct seq_file *m, void *v)
{
	static int buf_golden_setting_idx = 0;
	// static off_t page_len = 0;
	// static off_t used_off = 0;

	// char *start_p;
	// int len = 0;
	int i = 0;

	ENTER_FUNC(FUNC_LV_BODY);

	if (1) { // (0 == off) {
		buf_golden_setting_idx = 0;
		// page_len = 0;
		// used_off = 0;
	}

	if (1) { // (0 == page_len) {
		if (FALSE == _golden.is_golden_log) {
			if (1) { // (0 == off) {
				for (i = 0; i < _golden.nr_golden_setting; i++) {
					seq_printf(m, ""HEX_FMT" "HEX_FMT" "HEX_FMT"\n",
						   _golden.buf_golden_setting[i].addr,
						   _golden.buf_golden_setting[i].mask,
						   _golden.buf_golden_setting[i].golden_val
						  );
				}
			}
		}

		if (0 == _golden.nr_golden_setting) {
			if (1) { // (0 == off) {
				seq_printf(m, "\n********** golden_test help *********\n");
				seq_printf(m, "1.   disable snapshot:                  echo disable > /proc/clkmgr/golden_test\n");
				seq_printf(m, "2.   insert golden setting (tool mode): echo 0x10000000 (addr) 0bxxxx_xxxx_xxxx_xxxx_0001_0100_1001_0100 (mask & golden value) > /proc/clkmgr/golden_test\n");
				seq_printf(m, "(2.) insert golden setting (hex mode):  echo 0x10000000 (addr) 0xFFFF (mask) 0x1494 (golden value) > /proc/clkmgr/golden_test\n");
				seq_printf(m, "(2.) insert golden setting (dec mode):  echo 268435456 (addr) 65535 (mask) 5268 (golden value) > /proc/clkmgr/golden_test\n");
				seq_printf(m, "3.   set filter:                        echo filter func_name [line_num] > /proc/clkmgr/golden_test\n");
				seq_printf(m, "(3.) disable filter:                    echo filter > /proc/clkmgr/golden_test\n");
				seq_printf(m, "4.   enable snapshot:                   echo enable > /proc/clkmgr/golden_test\n");
				seq_printf(m, "5.   set compare mode:                  echo compare > /proc/clkmgr/golden_test\n");
				seq_printf(m, "(5.) set apply mode:                    echo apply > /proc/clkmgr/golden_test\n");
				seq_printf(m, "(5.) set color mode:                    echo color > /proc/clkmgr/golden_test\n");
				seq_printf(m, "(5.) set diff mode:                     echo color > /proc/clkmgr/golden_test\n");
				seq_printf(m, "(5.) disable compare/apply/color mode:  echo normal > /proc/clkmgr/golden_test\n");
				seq_printf(m, "6.   set register value (normal mode):  echo set 0x10000000 (addr) 0x13201494 (reg val) > /proc/clkmgr/golden_test\n");
				seq_printf(m, "(6.) set register value (mask mode):    echo set 0x10000000 (addr) 0xffff (mask) 0x13201494 (reg val) > /proc/clkmgr/golden_test\n");
				seq_printf(m, "(6.) set register value (bit mode):     echo set 0x10000000 (addr) 0 (bit num) 1 (reg val) > /proc/clkmgr/golden_test\n");
			}
		} else {
			static struct snapshot *snapshot;

			if (0 == 0 // off    // buf_golden_setting_idx
			    && !strcmp(_golden.func, __FUNCTION__) && (_golden.line == 0)) {
				snapshot_golden_setting(__FUNCTION__, 0);
			}

			while ((0 != buf_golden_setting_idx) || (NULL != (snapshot = _snapshot_consume(&_golden)))) {
				if (0 == buf_golden_setting_idx) {
					seq_printf(m, "// @ %s():%d\n", snapshot->func, snapshot->line);
					pr_debug("// @ %s():%d\n", snapshot->func, snapshot->line);
				}


				// start_p = p;

				for (i = buf_golden_setting_idx, buf_golden_setting_idx = 0; i < _golden.nr_golden_setting; i++) {
					// start_p = p;

					if (MODE_NORMAL == _golden.mode
					    || ((_golden.buf_golden_setting[i].mask & _golden.buf_golden_setting[i].golden_val)
						!= (_golden.buf_golden_setting[i].mask & snapshot->reg_val[i])
					       )
					   ) {
						if (MODE_COLOR == _golden.mode) {
							seq_printf(m, HEX_FMT"\t"HEX_FMT"\t"HEX_FMT"\t%s\n",
								   _golden.buf_golden_setting[i].addr,
								   _golden.buf_golden_setting[i].mask,
								   snapshot->reg_val[i],
								   _gen_color_str(_golden.buf_golden_setting[i].mask, _golden.buf_golden_setting[i].golden_val, snapshot->reg_val[i])
								  );
							pr_debug(HEX_FMT"\t"HEX_FMT"\t"HEX_FMT"\t%s\n",
								   _golden.buf_golden_setting[i].addr,
								   _golden.buf_golden_setting[i].mask,
								   snapshot->reg_val[i],
								   _gen_color_str(_golden.buf_golden_setting[i].mask, _golden.buf_golden_setting[i].golden_val, snapshot->reg_val[i])
								  );
						} else if (MODE_DIFF == _golden.mode) {
							seq_printf(m, HEX_FMT"\t"HEX_FMT"\t"HEX_FMT"\t%s\n",
								   _golden.buf_golden_setting[i].addr,
								   _golden.buf_golden_setting[i].mask,
								   snapshot->reg_val[i],
								   _gen_mask_str(_golden.buf_golden_setting[i].mask, snapshot->reg_val[i])
								  );
							pr_debug(HEX_FMT"\t"HEX_FMT"\t"HEX_FMT"\t%s\n",
								   _golden.buf_golden_setting[i].addr,
								   _golden.buf_golden_setting[i].mask,
								   snapshot->reg_val[i],
								   _gen_mask_str(_golden.buf_golden_setting[i].mask, snapshot->reg_val[i])
								  );

							seq_printf(m, HEX_FMT"\t"HEX_FMT"\t"HEX_FMT"\t%s\n",
								   _golden.buf_golden_setting[i].addr,
								   _golden.buf_golden_setting[i].mask,
								   _golden.buf_golden_setting[i].golden_val,
								   _gen_diff_str(_golden.buf_golden_setting[i].mask, _golden.buf_golden_setting[i].golden_val, snapshot->reg_val[i])
								  );
							pr_debug(HEX_FMT"\t"HEX_FMT"\t"HEX_FMT"\t%s\n",
								   _golden.buf_golden_setting[i].addr,
								   _golden.buf_golden_setting[i].mask,
								   _golden.buf_golden_setting[i].golden_val,
								   _gen_diff_str(_golden.buf_golden_setting[i].mask, _golden.buf_golden_setting[i].golden_val, snapshot->reg_val[i])
								  );
						} else
							seq_printf(m, HEX_FMT"\t"HEX_FMT"\t"HEX_FMT"\n", _golden.buf_golden_setting[i].addr, _golden.buf_golden_setting[i].mask, snapshot->reg_val[i]);
							pr_debug(HEX_FMT"\t"HEX_FMT"\t"HEX_FMT"\n", _golden.buf_golden_setting[i].addr, _golden.buf_golden_setting[i].mask, snapshot->reg_val[i]);
						}

					if (0) { // ((p - start_p) + (p - page) >= PAGE_SIZE) {
						buf_golden_setting_idx = i + 1;
						break;
					}
				}

				if (0) // ((p - start_p) + (p - page) >= PAGE_SIZE)
					break;
			}
		}

		// page_len = p - page;
	} else {
		// p = page + page_len;
	}

#if 0
	*start = page + (off - used_off);

	len = p - page;

	if (len > (off - used_off))
		len -= (off - used_off);
	else {
		len = 0;
		used_off += page_len;
		page_len = 0;
	}

	*eof = (0 == buf_golden_setting_idx && 0 == len) ? 1 : 0;
#endif
	EXIT_FUNC(FUNC_LV_BODY);

	return 0; // len < count ? len : count;
}
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;
}
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;
}