void spm_force_lte_onoff(u8 onoff)
{
    if (onoff)
        spm_write(AP_PLL_CON7, spm_read(AP_PLL_CON7) & ~0xF);
    else
        spm_write(AP_PLL_CON7, spm_read(AP_PLL_CON7) | 0xF);
}
static void spm_kick_pcm_to_run(struct pwr_ctrl *pwrctrl)
{
    /* enable PCM WDT (normal mode) to start count if needed */
#if SPM_PCMWDT_EN
    {
        u32 con1;
        con1 = spm_read(SPM_PCM_CON1) & ~(CON1_PCM_WDT_WAKE_MODE | CON1_PCM_WDT_EN);
// PCM WDT WAKE MODE for lastPC
//	con1 = spm_read(SPM_PCM_CON1) & ~( CON1_PCM_WDT_EN) | CON1_PCM_WDT_WAKE_MODE;
        spm_write(SPM_PCM_CON1, CON1_CFG_KEY | con1);

        if (spm_read(SPM_PCM_TIMER_VAL) > PCM_TIMER_MAX)
            spm_write(SPM_PCM_TIMER_VAL, PCM_TIMER_MAX);
        spm_write(SPM_PCM_WDT_TIMER_VAL, spm_read(SPM_PCM_TIMER_VAL) + PCM_WDT_TIMEOUT);
        spm_write(SPM_PCM_CON1, con1 | CON1_CFG_KEY | CON1_PCM_WDT_EN);
    }
#endif

    /* init PCM_PASR_DPD_0 for DPD */
    spm_write(SPM_PCM_PASR_DPD_0, 0);

    /* make MD32 work in suspend: fscp_ck = CLK26M */
    clkmux_sel(MT_MUX_SCP, 0, "SPM-Sleep");

    __spm_kick_pcm_to_run(pwrctrl);
}
Esempio n. 3
0
/**************************************
 * Init and IRQ Function
 **************************************/
static irqreturn_t spm_irq0_handler(int irq, void *dev_id)
{
	u32 isr;
	unsigned long flags;
	struct twam_sig twamsig;

	spin_lock_irqsave(&__spm_lock, flags);
	/* get ISR status */
	isr = spm_read(SPM_SLEEP_ISR_STATUS);
	if (isr & ISRS_TWAM) {
		twamsig.sig0 = spm_read(SPM_SLEEP_TWAM_STATUS0);
		twamsig.sig1 = spm_read(SPM_SLEEP_TWAM_STATUS1);
		twamsig.sig2 = spm_read(SPM_SLEEP_TWAM_STATUS2);
		twamsig.sig3 = spm_read(SPM_SLEEP_TWAM_STATUS3);
	}

	/* clean ISR status */
	spm_write(SPM_SLEEP_ISR_MASK, spm_read(SPM_SLEEP_ISR_MASK) | ISRM_ALL_EXC_TWAM);
	spm_write(SPM_SLEEP_ISR_STATUS, isr);
	if (isr & ISRS_TWAM)
		udelay(100);	/* need 3T TWAM clock (32K/26M) */
	spm_write(SPM_PCM_SW_INT_CLEAR, PCM_SW_INT0);
	spin_unlock_irqrestore(&__spm_lock, flags);

	if ((isr & ISRS_TWAM) && spm_twam_handler)
		spm_twam_handler(&twamsig);

	if (isr & (ISRS_SW_INT0 | ISRS_PCM_RETURN))
		spm_err("IRQ0 HANDLER SHOULD NOT BE EXECUTED (0x%x)\n", isr);

	return IRQ_HANDLED;
}
Esempio n. 4
0
static irqreturn_t spm_irq_handler(int irq, void *dev_id)
{
    u32 isr;
    twam_sig_t twamsig;

    spin_lock(&spm_lock);
    /* get ISR status */
    isr = spm_read(SPM_SLEEP_ISR_STATUS);
    if (isr & ISR_TWAM) {
        twamsig.sig0 = spm_read(SPM_SLEEP_TWAM_STATUS0);
        twamsig.sig1 = spm_read(SPM_SLEEP_TWAM_STATUS1);
        twamsig.sig2 = spm_read(SPM_SLEEP_TWAM_STATUS2);
        twamsig.sig3 = spm_read(SPM_SLEEP_TWAM_STATUS3);
    }

    /* clean ISR status */
    spm_write(SPM_SLEEP_ISR_MASK, spm_read(SPM_SLEEP_ISR_MASK) | ISRM_ALL_EXC_TWAM);
    spm_write(SPM_SLEEP_ISR_STATUS, isr);
    if (isr & ISR_TWAM)
        udelay(100);    /* need 3T TWAM clock */
    spm_write(SPM_PCM_SW_INT_CLEAR, PCM_SW_INT0);
    spin_unlock(&spm_lock);

    if (isr == ISR_TWAM && spm_twam_handler)
        spm_twam_handler(&twamsig);
    else
        spm_error("ISR SHOULD NOT BE EXECUTED (0x%x)\n", isr);

    return IRQ_HANDLED;
}
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();
}
Esempio n. 6
0
wake_reason_t spm_let_the_dog_home(void)
{
    spm_wdt_restart();
    spm_write(SPM_PCM_SW_INT_CLEAR,0xf);
    spm_write(SPM_PCM_CON1, (spm_read(SPM_PCM_CON1) & ~CON1_PCM_WDT_EN) | CON1_CFG_KEY);
    spm_notice("spm_let_the_dog_home\n");
}
int spm_set_vcore_dvs_voltage(unsigned int opp)
{
	int r;
	unsigned long flags;

	spin_lock_irqsave(&__spm_lock, flags);
	switch (opp) {
	case OPP_0:
		spm_write(SPM_PCM_SRC_REQ, spm_read(SPM_PCM_SRC_REQ) | SR_PCM_F26M_REQ);
		r = wait_pcm_complete_dvs(get_vcore_sta() == VCORE_STA_HPM,
				3 * PER_OPP_DVS_US /* 1.15->1.05->1.15 */);
		break;
	case OPP_1:
		spm_write(SPM_PCM_SRC_REQ, spm_read(SPM_PCM_SRC_REQ) & ~SR_PCM_F26M_REQ);
		r = 0;		/* unrequest, no need to wait */
		break;
	default:
		spm_crit("[VcoreFS] *** FAILED: OPP INDEX IS INCORRECT ***\n");
		spin_unlock_irqrestore(&__spm_lock, flags);
		return -EINVAL;
	}

	if (r >= 0) {	/* DVS pass */
		r = 0;
	} else {
		spm_dump_vcore_dvs_regs(NULL);
		BUG();
	}
	spin_unlock_irqrestore(&__spm_lock, flags);

	return r;
}
Esempio n. 8
0
static void spm_clean_after_wakeup(bool pcmwdt_en)
{
    /* disable PCM WDT to stop count if needed */
#if SPM_PCMWDT_EN
    if (pcmwdt_en)
        spm_write(SPM_PCM_CON1, CON1_CFG_KEY | (spm_read(SPM_PCM_CON1) & ~CON1_PCM_WDT_EN));
#endif

    /* PCM has cleared uart_clk_off_req and now clear it in POWER_ON_VAL1 */
    spm_write(SPM_POWER_ON_VAL1, spm_read(SPM_POWER_ON_VAL1) & ~R7_UART_CLK_OFF_REQ);

    /* re-enable POWER_ON_VAL0/1 to control power */
    spm_write(SPM_PCM_PWR_IO_EN, 0);

    /* unlock INFRA DCM */
    spm_write(SPM_CLK_CON, spm_read(SPM_CLK_CON) & ~CC_LOCK_INFRA_DCM);

    /* clean PCM timer event */
    spm_write(SPM_PCM_CON1, CON1_CFG_KEY | (spm_read(SPM_PCM_CON1) & ~CON1_PCM_TIMER_EN));

    /* clean CPU wakeup event (pause abort) */
    spm_write(SPM_SLEEP_CPU_WAKEUP_EVENT, 0);

    /* clean wakeup event raw status (except THERM) */
    spm_write(SPM_SLEEP_WAKEUP_EVENT_MASK, ~WAKE_SRC_THERM);

    /* clean ISR status (except TWAM) */
    spm_write(SPM_SLEEP_ISR_MASK, spm_read(SPM_SLEEP_ISR_MASK) | ISRM_ALL_EXC_TWAM);
    spm_write(SPM_SLEEP_ISR_STATUS, ISRC_ALL_EXC_TWAM);
    spm_write(SPM_PCM_SW_INT_CLEAR, PCM_SW_INT0);
}
Esempio n. 9
0
static ssize_t ddren_debug_store(struct kobject *kobj, struct kobj_attribute *attr,
				 const char *buf, size_t count)
{
	u32 val, con;
	char cmd[32];
	unsigned long flags;

	if (sscanf(buf, "%31s %x", cmd, &val) != 2)
		return -EPERM;

	spm_debug("ddren_debug: cmd = %s, val = 0x%x\n", cmd, val);

	if (!strcmp(cmd, "ddr_en_sel")) {
		spin_lock_irqsave(&__spm_lock, flags);
		con = spm_read(SPM_AP_STANBY_CON) & ~(1U << 22);
		spm_write(SPM_AP_STANBY_CON, con | (!!val << 22));
		spin_unlock_irqrestore(&__spm_lock, flags);
	} else if (!strcmp(cmd, "md_ddr_en_out")) {
		spin_lock_irqsave(&__spm_lock, flags);
		__spm_dbgout_md_ddr_en(val);
		spin_unlock_irqrestore(&__spm_lock, flags);
	} else if (!strcmp(cmd, "mm_ddr_en_mask")) {
		spin_lock_irqsave(&__spm_lock, flags);
		spm_write(SPM_PCM_PASR_DPD_2, ~val & 0x1f);
		spin_unlock_irqrestore(&__spm_lock, flags);
	} else {
		return -EINVAL;
	}

	return count;
}
void spm_set_wakeup_src_check(void)
{
    /* clean wakeup event raw status */
    spm_write(SPM_SLEEP_WAKEUP_EVENT_MASK, 0xFFFFFFFF);

    /* set wakeup event */
    spm_write(SPM_SLEEP_WAKEUP_EVENT_MASK, ~WAKE_SRC_FOR_SUSPEND);
}
Esempio n. 11
0
void spm_wdt_restart_timer(void)
{
    unsigned long flags;

    spin_lock_irqsave(&spm_lock, flags);
    spm_write(SPM_POWER_ON_VAL1, spm_read(SPM_POWER_ON_VAL1) | R7_WDT_KICK_P);
    spm_write(SPM_POWER_ON_VAL1, spm_read(SPM_POWER_ON_VAL1) & ~R7_WDT_KICK_P);
    spin_unlock_irqrestore(&spm_lock, flags);
}
Esempio n. 12
0
void spm_twam_disable_monitor(void)
{
    unsigned long flags;

    spin_lock_irqsave(&spm_lock, flags);
    spm_write(SPM_SLEEP_TWAM_CON, spm_read(SPM_SLEEP_TWAM_CON) & ~TWAM_CON_EN);
    spm_write(SPM_SLEEP_ISR_MASK, spm_read(SPM_SLEEP_ISR_MASK) | ISR_TWAM);
    spm_write(SPM_SLEEP_ISR_STATUS, ISR_TWAM);
    spin_unlock_irqrestore(&spm_lock, flags);
}
Esempio n. 13
0
void spm_wfi_sel(bool core_wfi_sel[], u8 core_wfi_sw_mask)
{
    if( ~( core_wfi_sw_mask & SPM_CORE0_WFI_SEL_SW_MASK ) )
        spm_write(SPM_CORE0_WFI_SEL, core_wfi_sel[0]);
    if( ~( core_wfi_sw_mask & SPM_CORE1_WFI_SEL_SW_MASK ) )
        spm_write(SPM_CORE1_WFI_SEL, core_wfi_sel[1]);
    spm_write(SPM_CORE2_WFI_SEL, 0);   /*MT6572 only has 2 cores*/
    spm_write(SPM_CORE3_WFI_SEL, 0);   /*MT6572 only has 2 cores*/


}
Esempio n. 14
0
/**
 *test_spm_gpu_power_on - test whether gpu could be powered on 
 *
 *Returns 1 if power on operation succeed, 0 otherwise.
 */
int test_spm_gpu_power_on(void)
{
    int i;
    volatile unsigned int sta1, sta2;
    volatile unsigned int val;
    unsigned long flags;
 
    sta1 = spm_read(SPM_PWR_STATUS);
    sta2 = spm_read(SPM_PWR_STATUS_S);
    if (((sta1 & MFG_PWR_STA_MASK) == MFG_PWR_STA_MASK) && 
            ((sta2 & MFG_PWR_STA_MASK) == MFG_PWR_STA_MASK)) {
        printk("[%s]: test_spm_gpu_power_on already on, return: 1.\n", __func__);
        return 1;
    }

    spm_mtcmos_noncpu_lock(flags);

    val = spm_read(SPM_MFG_PWR_CON);
    BUG_ON(!(val & PWR_ISO));

    for(i = 0; i < 5; i++) {
    
        spm_write(SPM_MFG_PWR_CON, spm_read(SPM_MFG_PWR_CON) | PWR_ON);
        spm_write(SPM_MFG_PWR_CON, spm_read(SPM_MFG_PWR_CON) | PWR_ON_S);

        udelay(5);

        sta1 = spm_read(SPM_PWR_STATUS);
        sta2 = spm_read(SPM_PWR_STATUS_S);
        if (((sta1 & MFG_PWR_STA_MASK) != MFG_PWR_STA_MASK) || 
                ((sta2 & MFG_PWR_STA_MASK) != MFG_PWR_STA_MASK)) {
            spm_mtcmos_noncpu_unlock(flags);
            printk("[%s]: test_spm_gpu_power_on return: 0.\n", __func__);
            return 0;
        }

        spm_write(SPM_MFG_PWR_CON, spm_read(SPM_MFG_PWR_CON) & ~(PWR_ON | PWR_ON_S));

        sta1 = spm_read(SPM_PWR_STATUS);
        sta2 = spm_read(SPM_PWR_STATUS_S);
        if (((sta1 & MFG_PWR_STA_MASK) == MFG_PWR_STA_MASK) || 
                ((sta2 & MFG_PWR_STA_MASK) == MFG_PWR_STA_MASK)) {
            spm_mtcmos_noncpu_unlock(flags);
            printk("[%s]: test_spm_gpu_power_on return: 0.\n", __func__);
            return 0;
        }
        mdelay(1);
    }

    spm_mtcmos_noncpu_unlock(flags);

    printk("[%s]: test_spm_gpu_power_on return: 1.\n", __func__);
    return 1;
}
Esempio n. 15
0
void spm_wdt_disable_timer(void)
{
    unsigned long flags;

    spin_lock_irqsave(&spm_lock, flags);
    spm_write(SPM_POWER_ON_VAL1, spm_read(SPM_POWER_ON_VAL1) | R7_WDT_KICK_P);
    spm_write(SPM_POWER_ON_VAL1, spm_read(SPM_POWER_ON_VAL1) & ~R7_WDT_KICK_P);

    spm_write(SPM_PCM_CON1, CON1_CFG_KEY | (spm_read(SPM_PCM_CON1) & ~CON1_PCM_WDT_EN));
    spm_write(SPM_PCM_SW_INT_CLEAR, PCM_SW_INT1);
    spin_unlock_irqrestore(&spm_lock, flags);
}
Esempio n. 16
0
irqreturn_t spm0_irq_handler(int irq, void *dev_id)
{
    spm_error("!!! SPM ISR[0] SHOULD NOT BE EXECUTED !!!\n");

    spin_lock(&spm_lock);
    /* clean ISR status */
    spm_write(SPM_SLEEP_ISR_MASK, 0x0008);
    spm_write(SPM_SLEEP_ISR_STATUS, 0x0018);
    spin_unlock(&spm_lock);

    return IRQ_HANDLED;
}
void spm_hot_plug_out_after(u32 target_core)
{
//#ifndef SPM_SODI_ONLY
    spm_notice("spm_hot_plug_out_after()........ target_core = 0x%x\n", target_core);    

    switch (target_core)
    {
        case 0 : spm_write(SPM_PCM_EVENT_VECTOR2, (spm_read(SPM_PCM_EVENT_VECTOR2) | SPM_PCM_HOTPLUG));  break;                     
        case 1 : spm_write(SPM_PCM_EVENT_VECTOR3, (spm_read(SPM_PCM_EVENT_VECTOR3) | SPM_PCM_HOTPLUG));  break;    
        default : break;
    }
//#endif
}
Esempio n. 18
0
void spm_go_to_normal(void)
{
    unsigned long flags;

    spin_lock_irqsave(&spm_lock, flags);
    /* reset PCM */
    spm_write(SPM_PCM_CON0, CON0_CFG_KEY | CON0_PCM_SW_RESET);
    spm_write(SPM_PCM_CON0, CON0_CFG_KEY);

    /* init PCM_CON1 (disable non-replace mode) */
    spm_write(SPM_PCM_CON1, CON1_CFG_KEY | CON1_SPM_SRAM_ISO_B |
                            CON1_SPM_SRAM_SLP_B | CON1_MIF_APBEN);

    /* tell IM where is PCM code */
    spm_write(SPM_PCM_IM_PTR, spm_get_base_phys(pcm_normal.base));
    spm_write(SPM_PCM_IM_LEN, pcm_normal.size - 1);

    /* unmask wakeup source */
    spm_write(SPM_SLEEP_WAKEUP_EVENT_MASK, ~WAKE_SRC_FOR_NORMAL);

    /* kick IM and PCM to run */
    spm_write(SPM_PCM_CON0, CON0_CFG_KEY | CON0_IM_KICK | CON0_PCM_KICK);
    spm_write(SPM_PCM_CON0, CON0_CFG_KEY);
    spin_unlock_irqrestore(&spm_lock, flags);
}
Esempio n. 19
0
static void spm_set_wakeup_event(u32 timer_val,u32 wdt_val, u32 wake_src)
{
    /* set PCM timer (set to max when disable) */
    //spm_write(SPM_PCM_TIMER_VAL, timer_val ? : 0xffffffff);
    //spm_write(SPM_PCM_CON1, spm_read(SPM_PCM_CON1) | CON1_CFG_KEY | CON1_PCM_TIMER_EN);
    /*Fix 32K less*/
    spm_write(SPM_PCM_TIMER_VAL, 0xffffffff);
    spm_write(SPM_PCM_CON1, spm_read(SPM_PCM_CON1) | CON1_CFG_KEY | CON1_PCM_TIMER_EN);
    
    /* set PCM WDT */
    if(wdt_val > 0){
    spm_write(SPM_PCM_WDT_TIMER_VAL, wdt_val);
    spm_write(SPM_PCM_CON1, spm_read(SPM_PCM_CON1) | CON1_CFG_KEY | CON1_PCM_WDT_EN | CON1_PCM_WDT_WAKE_MODE);
    }else{
     spm_write(SPM_PCM_WDT_TIMER_VAL, 0);
     spm_write(SPM_PCM_CON1, (spm_read(SPM_PCM_CON1)| CON1_CFG_KEY )& ~(CON1_PCM_WDT_EN | CON1_PCM_WDT_WAKE_MODE));  
    }
    

    /* unmask wakeup source */
#if SPM_BYPASS_SYSPWREQ
    wake_src &= ~WAKE_SRC_SYSPWREQ;     /* make 26M off when attach ICE */
#endif
    spm_write(SPM_SLEEP_WAKEUP_EVENT_MASK, ~wake_src);

    /* unmask SPM ISR */
    spm_write(SPM_SLEEP_ISR_MASK, 0x200);
}
Esempio n. 20
0
static void spm_kick_im_to_fetch(u32 code_base, u16 code_len)
{
    u32 con0;

    /* tell IM where is PCM code */
    BUG_ON(code_base & 0x00000003);     /* check 4-byte alignment */
    spm_write(SPM_PCM_IM_PTR, code_base);
    spm_write(SPM_PCM_IM_LEN, code_len);

    /* kick IM to fetch */
    con0 = spm_read(SPM_PCM_CON0);
    spm_write(SPM_PCM_CON0, con0 | CON0_CFG_KEY | CON0_IM_KICK);
    spm_write(SPM_PCM_CON0, con0 | CON0_CFG_KEY);
}
int spm_mtcmos_ctrl_mfg_ASYNC(int state)
{
    int err = 0;

    volatile unsigned int val;
    unsigned long flags;

    spm_mtcmos_noncpu_lock(flags);

    if (state == STA_POWER_DOWN) {

        spm_write(SPM_MFG_ASYNC_PWR_CON, spm_read(SPM_MFG_ASYNC_PWR_CON) | SRAM_PDN);

//        while ((spm_read(MFG_ASYNC_PWR_CON) & MFG_SRAM_ACK) != MFG_SRAM_ACK) {
//        }

        spm_write(SPM_MFG_ASYNC_PWR_CON, spm_read(SPM_MFG_ASYNC_PWR_CON) | PWR_ISO);

        val = spm_read(SPM_MFG_ASYNC_PWR_CON);
        val = (val & ~PWR_RST_B) | PWR_CLK_DIS;
        spm_write(SPM_MFG_ASYNC_PWR_CON, val);

        spm_write(SPM_MFG_ASYNC_PWR_CON, spm_read(SPM_MFG_ASYNC_PWR_CON) & ~(PWR_ON | PWR_ON_2ND));

        while ((spm_read(SPM_PWR_STATUS) & MFG_ASYNC_PWR_STA_MASK) 
                || (spm_read(SPM_PWR_STATUS_2ND) & MFG_ASYNC_PWR_STA_MASK)) {
        }
    } else {    /* STA_POWER_ON */
        spm_write(SPM_MFG_ASYNC_PWR_CON, spm_read(SPM_MFG_ASYNC_PWR_CON) | PWR_ON);
        spm_write(SPM_MFG_ASYNC_PWR_CON, spm_read(SPM_MFG_ASYNC_PWR_CON) | PWR_ON_2ND);

        while (!(spm_read(SPM_PWR_STATUS) & MFG_ASYNC_PWR_STA_MASK) || 
                !(spm_read(SPM_PWR_STATUS_2ND) & MFG_ASYNC_PWR_STA_MASK)) {
        }

        spm_write(SPM_MFG_ASYNC_PWR_CON, spm_read(SPM_MFG_ASYNC_PWR_CON) & ~PWR_CLK_DIS);
        spm_write(SPM_MFG_ASYNC_PWR_CON, spm_read(SPM_MFG_ASYNC_PWR_CON) & ~PWR_ISO);
        spm_write(SPM_MFG_ASYNC_PWR_CON, spm_read(SPM_MFG_ASYNC_PWR_CON) | PWR_RST_B);

        spm_write(SPM_MFG_ASYNC_PWR_CON, spm_read(SPM_MFG_ASYNC_PWR_CON) & ~SRAM_PDN);

//        while ((spm_read(MFG_ASYNC_PWR_CON) & MFG_SRAM_ACK)) {
//        }

    }

    spm_mtcmos_noncpu_unlock(flags);

    return err;
}
static void spm_set_sysclk_settle(void)
{
    u32 md_settle, settle;

    /* get MD SYSCLK settle */
    spm_write(SPM_CLK_CON, spm_read(SPM_CLK_CON) | CC_SYSSETTLE_SEL);
    spm_write(SPM_CLK_SETTLE, 0);
    md_settle = spm_read(SPM_CLK_SETTLE);

    /* SYSCLK settle = MD SYSCLK settle but set it again for MD PDN */
    spm_write(SPM_CLK_SETTLE, SPM_SYSCLK_SETTLE - md_settle);
    settle = spm_read(SPM_CLK_SETTLE);

    spm_crit2("md_settle = %u, settle = %u\n", md_settle, settle);
}
/*
 * static function
 */
static inline void cpu_enter_lowpower(unsigned int cpu)
{
	HOTPLUG_INFO("cpu_enter_lowpower\n");

	/* Cluster off */
	if ((cpu == 3 && cpu_online(2) == 0) || (cpu == 2 && cpu_online(3) == 0)) {

		/* Clear the SCTLR C bit to prevent further data cache allocation */
		__disable_dcache();
		isb();
		dsb();

		/* Clean and invalidate all data from the L1, L2 data cache */
		inner_dcache_flush_all();
		/* flush_cache_all(); */

		/* Switch the processor from SMP mode to AMP mode by clearing the ACTLR SMP bit */
		__switch_to_amp();

		isb();
		dsb();

		/* disable CA15 CCI */
		spm_write(CA15_CCI400_DVM_EN, spm_read(CA15_CCI400_DVM_EN) & ~0x3);
		/* wait cci change pending */
		while (spm_read(CCI400_STATUS) & 0x1)
			;
		/* Ensure the ACP master does not send further requests to the individual processor.
		   Assert AINACTS to idle the ACP slave interface after all responses are received. */
		/* mt65xx_reg_sync_writel( *CA15_MISC_DBG | 0x11, CA15_MISC_DBG); */
		spm_write(CA15_MISC_DBG, spm_read(CA15_MISC_DBG) | 0x11);

	} else {
		/* Clear the SCTLR C bit to prevent further data cache allocation */
		__disable_dcache();
		isb();
		dsb();
		/* Clean and invalidate all data from the L1 data cache */
		inner_dcache_flush_L1();
		/* Just flush the cache. */
		/* flush_cache_all(); */
		/* Execute a CLREX instruction */
		__asm__ __volatile__("clrex");
		/* Switch the processor from SMP mode to AMP mode by clearing the ACTLR SMP bit */
		__switch_to_amp();
	}

}
static int spm_talking_late_init(void)
{
	unsigned long flags;
	struct twam_sig twamsig = {
		.sig0 = 28,	/* md1_apsrc_req or md_ddr_en */
		.sig1 = 26,	/* md32_apsrc_req */
	};

	spin_lock_irqsave(&__spm_lock, flags);
	spm_write(SPM_AP_STANBY_CON, spm_read(SPM_AP_STANBY_CON) | ASC_MD_DDR_EN_SEL);
	spin_unlock_irqrestore(&__spm_lock, flags);

	spm_twam_register_handler(twam_handler);
	spm_twam_enable_monitor(&twamsig, true);

	return 0;
}

late_initcall(spm_talking_late_init);
#endif

void spm_talking_init(void)
{
	if (mt_get_chip_sw_ver() == CHIP_SW_VER_01 && SPM_CTRL_BIG_CPU)
		__spm_talking.pcmdesc = &talking_pcm_big;
}

MODULE_DESCRIPTION("SPM-Talking Driver v1.0");
Esempio n. 25
0
static void spm_reset_and_init_pcm(void)
{
    u32 con1;

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

    /* init PCM_CON0 (disable event vector) */
    spm_write(SPM_PCM_CON0, CON0_CFG_KEY | CON0_IM_SLEEP_DVS);

    /* init PCM_CON1 (disable PCM timer but keep PCM WDT setting) */
    con1 = spm_read(SPM_PCM_CON1) & (CON1_PCM_WDT_WAKE_MODE | CON1_PCM_WDT_EN);
    spm_write(SPM_PCM_CON1, con1 | CON1_CFG_KEY | CON1_SPM_SRAM_ISO_B |
                            CON1_SPM_SRAM_SLP_B | CON1_IM_NONRP_EN | CON1_MIF_APBEN);
}
void spm_sodi_init(void)
{
#if SPM_USE_TWAM_DEBUG
	unsigned long flags;
	struct twam_sig twamsig = {
		.sig0 = 10,	/* disp_req */
		.sig1 = 23,	/* self-refresh */
		.sig2 = 25,	/* md2_srcclkena */
		.sig3 = 21,	/* md2_apsrc_req_mux */		
	};
#endif

#if SPM_AEE_RR_REC
    spm_sodi_aee_init();
#endif

#if SPM_USE_TWAM_DEBUG	
    #if 0
	spin_lock_irqsave(&__spm_lock, flags);
	spm_write(SPM_AP_STANBY_CON, spm_read(SPM_AP_STANBY_CON) | ASC_MD_DDR_EN_SEL);
	spin_unlock_irqrestore(&__spm_lock, flags);
    #endif
    
	spm_twam_register_handler(twam_handler);
	spm_twam_enable_monitor(&twamsig, false,SPM_TWAM_MONITOR_TICK);
#endif
}

MODULE_DESCRIPTION("SPM-SODI Driver v0.1");
Esempio n. 27
0
int spm_dvfs_ctrl_volt(u32 value)
{
    u32 ap_dvfs_con;
    int retry = 0;

    ap_dvfs_con = spm_read(SPM_AP_DVFS_CON_SET);
    spm_write(SPM_AP_DVFS_CON_SET, (ap_dvfs_con & ~(0x7)) | value);
    udelay(5);

    while ((spm_read(SPM_AP_DVFS_CON_SET) & (0x1 << 31)) == 0)
    {
        if (retry >= MAX_RETRY_COUNT)
        {
            printk("FAIL: no response from PMIC wrapper\n");
            return -1;
        }

        retry++;
        printk("wait for ACK signal from PMIC wrapper, retry = %d\n", retry);

        udelay(5);
    }

    return 0;
}
/**************************************
 * Function and API
 **************************************/
void __spm_reset_and_init_pcm(const struct pcm_desc *pcmdesc)
{
	u32 con1;

#ifdef SPM_VCORE_EN
	if (spm_read(SPM_PCM_REG1_DATA) == 0x1) {
		/* SPM code swapping (force high voltage) */
		spm_write(SPM_SLEEP_CPU_WAKEUP_EVENT, 1);
		while (spm_read(SPM_PCM_REG11_DATA) != 0x55AA55AA) {udelay(1);}
		spm_write(SPM_SLEEP_CPU_WAKEUP_EVENT, 0);
		spm_write(SPM_PCM_SRC_REQ, spm_read(SPM_PCM_SRC_REQ) & ~SR_PCM_F26M_REQ);
	}
#endif

	/* reset PCM */
	spm_write(SPM_PCM_CON0, CON0_CFG_KEY | CON0_PCM_SW_RESET);
	spm_write(SPM_PCM_CON0, CON0_CFG_KEY);
	BUG_ON((spm_read(SPM_PCM_FSM_STA)&0x3fffff) != PCM_FSM_STA_DEF);	/* PCM reset failed */

	/* init PCM_CON0 (disable event vector) */
	spm_write(SPM_PCM_CON0, CON0_CFG_KEY | CON0_IM_SLEEP_DVS);

	/* init PCM_CON1 (disable PCM timer but keep PCM WDT setting) */
	con1 = spm_read(SPM_PCM_CON1) & (CON1_PCM_WDT_WAKE_MODE | CON1_PCM_WDT_EN);
	spm_write(SPM_PCM_CON1, con1 | CON1_CFG_KEY | CON1_EVENT_LOCK_EN |
				CON1_SPM_SRAM_ISO_B | CON1_SPM_SRAM_SLP_B |
				(pcmdesc->replace ? 0 : CON1_IM_NONRP_EN) |
				CON1_MIF_APBEN | CON1_MD32_APB_INTERNAL_EN);
}
Esempio n. 29
0
static void spm_trigger_wfi_for_dpidle(bool cpu_pdn)
{
#if SPM_CTRL_33VCORE || SPM_CTRL_33VRF18
    u32 pdn0;
    pdn0 = spm_read(PERI_PDN0_STA) & (1U << 22);
    spm_write(PERI_PDN0_CLR, pdn0);     /* power on I2C1 */
    spm_write(0xF1008010, 0);           /* init I2C1_CONTROL */
    spm_write(0xF1008018, 0x1);         /* init I2C1_TRANSAC_LEN */
    spm_write(0xF1008028, 0x1800);      /* init I2C1_EXT_CONF */
    spm_write(0xF1008040, 0x3);         /* init I2C1_IO_CONFIG */
    spm_write(0xF1008048, 0x102);       /* init I2C1_HS */
#endif

    if (cpu_pdn) {
        if (!cpu_power_down(DORMANT_MODE)) {
            switch_to_amp();
            wfi_with_sync();
        }
        switch_to_smp();
        cpu_check_dormant_abort();
    } else {
        wfi_with_sync();
    }

#if SPM_CTRL_33VCORE || SPM_CTRL_33VRF18
    spm_write(PERI_PDN0_SET, pdn0);     /* restore I2C1 power */
#endif
}
Esempio n. 30
0
static void spm_sodi_pre_process(void)
{
    /* set PMIC WRAP table for deepidle power control */
    mt_cpufreq_set_pmic_phase(PMIC_WRAP_PHASE_DEEPIDLE);	

    vsram_vosel_on_lb = pmic_get_register_value(PMIC_VSRAM_VOSEL_ON_LB);
    spm_write(SPM_PCM_RESERVE3,(pmic_get_register_value(PMIC_VSRAM_VOSEL_OFFSET)<<8)|pmic_get_register_value(PMIC_VSRAM_VOSEL_DELTA));//delta = 0v
    pmic_set_register_value(PMIC_VSRAM_VOSEL_ON_LB,(vsram_vosel_on_lb&0xff80)|0x28);//0.85v
}