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); }
/************************************** * 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; }
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(); }
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; }
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); }
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); }
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); }
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); }
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*/ }
/** *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; }
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); }
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 }
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); }
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); }
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");
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");
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); }
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 }
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 }