/*init global regs for pm */ static void init_gr(void) { int val; /* remap iram to 0x00000000*/ sci_glb_set(REG_AHB_REMAP, BIT(0)); #ifdef CONFIG_NKERNEL /*force close cp*/ __raw_writel(0x00000001, REG_AHB_CP_SLEEP_CTRL); #endif /* AHB_PAUSE */ val = sci_glb_read(REG_AHB_AHB_PAUSE, -1UL); val &= ~(MCU_CORE_SLEEP | MCU_DEEP_SLEEP_EN | MCU_SYS_SLEEP_EN); sci_glb_write(REG_AHB_AHB_PAUSE, val, -1UL ); /* AHB_CTL1 */ val = sci_glb_read(REG_AHB_AHB_CTL1, -1UL); val |= (AHB_CTRL1_EMC_CH_AUTO_GATE_EN | AHB_CTRL1_ARM_AUTO_GATE_EN | AHB_CTRL1_AHB_AUTO_GATE_EN | AHB_CTRL1_MCU_AUTO_GATE_EN | AHB_CTRL1_ARM_DAHB_SLEEP_EN | AHB_CTRL1_MSTMTX_AUTO_GATE_EN); val &= ~AHB_CTRL1_EMC_AUTO_GATE_EN; sci_glb_write(REG_AHB_AHB_CTL1, val, -1UL ); /* enable XTL auto power down, set bufon_ctrl[17:16] 0 */ val = sci_glb_read(REG_GLB_CLK_EN, -1UL); val |= MCU_XTLEN_AUTOPD_EN; val |= BUFON_CTRL_HI; sci_glb_write(REG_GLB_CLK_EN, val, -1UL ); }
static int syssleep_write_proc(struct file *file, const char __user *buffer, unsigned long count, void *data) { sci_glb_write(REG_PMU_APB_PD_CP0_ARM9_0_CFG, BIT(24) | BIT(25), -1UL); sci_glb_write(REG_PMU_APB_PD_CP0_HU3GE_CFG, BIT(24) | BIT(25), -1UL); sci_glb_write(REG_PMU_APB_PD_CP0_GSM_CFG, BIT(24) | BIT(25), -1UL); sci_glb_write(REG_PMU_APB_PD_CP0_L1RAM_CFG, BIT(24) | BIT(25), -1UL); sci_glb_write(REG_PMU_APB_PD_CP0_SYS_CFG, BIT(25) | BIT(28), -1UL); //sci_glb_write(REG_PMU_APB_CP_SOFT_RST,0x7,-1UL); //msleep(1000); //sci_glb_write(REG_PMU_APB_CP_SOFT_RST,0x6,-1UL); return count; }
/* arm core + arm sys */ static void mcu_sleep(void) { u32 val; SAVE_GLOBAL_REG; disable_audio_module(); disable_ahb_module(); /* FIXME: whether enable emc auto gate or not in mcu sleep val = sci_glb_read(REG_AHB_AHB_CTL1, -1UL); val |= AHB_CTRL1_EMC_AUTO_GATE_EN; sci_glb_write(REG_AHB_AHB_CTL1, val, -1UL ); */ val = sci_glb_read(REG_AHB_AHB_PAUSE, -1UL); val &= ~( MCU_CORE_SLEEP | MCU_DEEP_SLEEP_EN | MCU_SYS_SLEEP_EN ); /* FIXME: enable sys sleep in final version val |= MCU_SYS_SLEEP_EN; */ sci_glb_write(REG_AHB_AHB_PAUSE, val, -1UL ); pm_debug_save_ahb_glb_regs( ); cpu_do_idle(); hard_irq_set(); RESTORE_GLOBAL_REG; }
void sc8825_pm_init(void) { unsigned int cpu1_jump_addrss; unsigned int val; init_reset_vector(); pm_power_off = sc8825_power_off; arm_pm_restart = sc8825_machine_restart; pr_info("power off %pf, restart %pf\n", pm_power_off, arm_pm_restart); #ifdef FORCE_DISABLE_DSP /* FPGA ONLY */ fpga_dbg_init(); #endif init_gr(); cpu1_jump_addrss = virt_to_phys(secondary_startup); sci_glb_write(REG_AHB_JMP_ADDR_CPU1, cpu1_jump_addrss, -1UL); setup_autopd_mode(); gic_save_init(); pm_ana_ldo_config(); init_led(); emc_repower_init(); #ifndef CONFIG_SPRD_PM_DEBUG pm_debug_init(); #endif val = __raw_readl(sprd_get_scu_base()); val |= (INTC_DYNAMIC_CLK_GATE_EN | SCU_DYNAMIC_CLK_GATE_EN); __raw_writel(val, sprd_get_scu_base()); }
void adie_efuse_workaround(void) { #define REG_ADI_GSSI_CFG0 (SPRD_ADI_PHYS + 0x1C) /** BIT_RF_GSSI_SCK_ALL_IN * 0: sclk auto gate * 1: sclk always on */ #define BIT_RF_GSSI_SCK_ALL_IN BIT(30) sci_glb_write(REG_ADI_GSSI_CFG0, BIT_RF_GSSI_SCK_ALL_IN, BIT_RF_GSSI_SCK_ALL_IN); }
static void dphy_init_common(u32 bps_per_lane, u32 phy_id, u32 rx_mode) { u8 temp = 0; struct csi_pclk_cfg csi_pclk_cfg_val = {0, 0, 0, 0}; csi_core_write_part(PHY_SHUTDOWNZ, 0, 0, 1); csi_core_write_part(DPHY_RSTZ, 0, 0, 1); csi_core_write_part(PHY_TST_CRTL0, 1, PHY_TESTCLR, 1); udelay(1); csi_core_write_part(PHY_TST_CRTL0, 0, PHY_TESTCLR, 1); udelay(1); dphy_cfg_start(); #if defined(CONFIG_MACH_SP7720EA) #if defined(CONFIG_SC_FPGA) sci_glb_write(SPRD_GPIO_BASE + 0x0008, 0xd, -1UL); dphy_write(0x30, 0xc0, &temp); #endif dphy_write(0x37, 0x03, &temp); //LOG_DEBUG2 ("%04x default reg value: %04x\r\n", 0x37, temp); dphy_write(0x47, 0x03, &temp); //LOG_DEBUG2 ("%04x default reg value: %04x\r\n", 0x47, temp); dphy_write(0x57, 0x03, &temp); //LOG_DEBUG2 ("%04x default reg value: %04x\r\n", 0x57, temp); dphy_write(0x67, 0x03, &temp); dphy_write(0x77, 0x03, &temp); #else csi_get_pclk_cfg(bps_per_lane, &csi_pclk_cfg_val); #if IS_ENABLED(VERSION3L) || IS_ENABLED(VERSION3T) || IS_ENABLED(VERSION3D) if (0x03 == phy_id) { if (0x00 == rx_mode) { dphy_write(0x34, 0x14, &temp); } else { dphy_write(0x34, 0xA0, &temp); } } else { dphy_write(0x34, 0x14, &temp); } #else dphy_write(0x34, 0x14, &temp); #endif dphy_write(0x44, (((csi_pclk_cfg_val.hsfreqrange & 0x3F) << 1) & 0x7E), &temp); dphy_write(0x75, (0x80 | (csi_pclk_cfg_val.hsrxthssettle & 0x7F)), &temp); dphy_write(0x54, 0x14, &temp); dphy_write(0x64, 0x14, &temp); dphy_write(0x74, 0x14, &temp); #endif dphy_cfg_done(); }
static int emc_repower_init(void) { repower_param = (struct emc_repower_param *)(SPRD_IRAM_BASE + 15 * 1024); set_emc_repower_param(repower_param, SPRD_LPDDR2C_BASE, SPRD_LPDDR2C_BASE + 0x1000); repower_param->cs0_training_addr_v = (u32)ioremap(repower_param->cs0_training_addr_p, 4*1024); if(repower_param->cs_number == 2) { repower_param->cs1_training_addr_v = (u32)ioremap(repower_param->cs1_training_addr_p, 4*1024); } /*close emc retention*/ sci_glb_write(0x80 + REGS_GLB_BASE, 0, -1UL); return 0; }
static void aux_clk_config(u32 clk_sel) { u32 reg_val; if(clk_sel < aux_clk_max){ /*select pin function to func 0*/ reg_val = sci_glb_read(clk_cfg_info.aux_pin,-1UL); reg_val &= ~(0x3 << 4); sci_glb_write(clk_cfg_info.aux_pin,reg_val,-1UL); /*enable aux clock*/ sci_glb_set(clk_cfg_info.aux_ena,0x1 << 2); /*select aux clock source*/ sci_glb_set(clk_cfg_info.aux_sel,clk_sel); } }
static void dsi_core_and_function(unsigned int addr,unsigned int data) { sci_glb_write(addr,(sci_glb_read(addr, 0xffffffff) & data), 0xffffffff); }
static void dsi_core_write_function(uint32_t addr, uint32_t offset, uint32_t data) { sci_glb_write((addr + offset), data, 0xffffffff); }
/* chip sleep*/ int deep_sleep(void) { u32 val, ret = 0; u32 holding; wait_until_uart1_tx_done(); SAVE_GLOBAL_REG; disable_audio_module(); disable_apb_module(); disable_ahb_module(); /* for dsp wake-up */ val = __raw_readl(INT0_IRQ_ENB); val |= SCI_INTC_IRQ_BIT(IRQ_DSP0_INT); val |= SCI_INTC_IRQ_BIT(IRQ_DSP1_INT); __raw_writel(val, INT0_IRQ_ENB); val = __raw_readl(INT0_FIQ_ENB); val |= SCI_INTC_IRQ_BIT(IRQ_DSP0_INT); val |= SCI_INTC_IRQ_BIT(IRQ_DSP1_INT); __raw_writel(val, INT0_FIQ_ENB); /* prevent uart1 */ __raw_writel(INT0_IRQ_MASK, INT0_IRQ_DIS); /*L2X0_POWER_CTRL, auto_clock_gate, standby_mode_enable*/ __raw_writel(0x3, SPRD_L2_BASE+0xF80); #ifdef FORCE_DISABLE_DSP /* close debug modules, only for fpga or debug */ /* dbg_module_close(); */ dsp_and_modem_force_close(); #endif /* * pm_debug_set_wakeup_timer(); */ /* FIXME: enable emc auto gate in final version val = sci_glb_read(REG_AHB_AHB_CTL1, -1UL); val |= AHB_CTRL1_EMC_AUTO_GATE_EN; sci_glb_write(REG_AHB_AHB_CTL1, val, -1UL); */ /*go deepsleep when all PD auto poweroff en*/ val = sci_glb_read(REG_AHB_AHB_PAUSE, -1UL); val &= ~( MCU_CORE_SLEEP | MCU_DEEP_SLEEP_EN | MCU_SYS_SLEEP_EN ); val |= (MCU_SYS_SLEEP_EN | MCU_DEEP_SLEEP_EN); sci_glb_write(REG_AHB_AHB_PAUSE, val, -1UL); /* set entry when deepsleep return*/ save_reset_vector(); set_reset_vector(); /* check globle key registers */ pm_debug_save_ahb_glb_regs( ); /* indicate cpu stopped */ holding = sci_glb_read(REG_AHB_HOLDING_PEN, -1UL); sci_glb_write(REG_AHB_HOLDING_PEN, (holding | AP_ENTER_DEEP_SLEEP) , -1UL ); save_emc_trainig_data(repower_param); ret = sp_pm_collapse(0, 1); hard_irq_set(); /*clear dsp fiq, for dsp wakeup*/ __raw_writel(ICLR_DSP_FRQ0_CLR, SPRD_IPI_ICLR); __raw_writel(ICLR_DSP_FIQ1_CLR, SPRD_IPI_ICLR); /*disable dsp fiq*/ val = SCI_INTC_IRQ_BIT(IRQ_DSP0_INT) | SCI_INTC_IRQ_BIT(IRQ_DSP1_INT); __raw_writel(val , INT0_FIQ_DIS); /*clear the deep sleep status*/ sci_glb_write(REG_AHB_HOLDING_PEN, (holding & ~AP_ENTER_DEEP_SLEEP), -1UL ); /* FIXME: clear emc auto gate in final version val = sci_glb_read(REG_AHB_AHB_CTL1, -1UL); val &= ~AHB_CTRL1_EMC_AUTO_GATE_EN; sci_glb_write(REG_AHB_AHB_CTL1, val, -1UL); */ restore_reset_vector(); RESTORE_GLOBAL_REG; udelay(5); if (ret) cpu_init(); return ret; }
static void setup_autopd_mode(void) { #if 0 //debug only sci_glb_write(REG_GLB_POWCTL0, 0x01000a20|(1<<23), -1UL); #endif #if 1 sci_glb_write(REG_GLB_MM_PWR_CTL, 0x06000320|PD_AUTO_EN, -1UL); /*MM*/ sci_glb_write(REG_GLB_G3D_PWR_CTL, 0x06000320|PD_AUTO_EN, -1UL);/*GPU*/ sci_glb_write(REG_GLB_CEVA_L1RAM_PWR_CTL, 0x04000720/*|PD_AUTO_EN*/, -1UL); sci_glb_write(REG_GLB_GSM_PWR_CTL, 0x05000520/*|PD_AUTO_EN*/, -1UL);/*GSM*/ sci_glb_write(REG_GLB_TD_PWR_CTL, 0x05000520/*|PD_AUTO_EN*/, -1UL);/*TD*/ sci_glb_write(REG_GLB_PERI_PWR_CTL, 0x03000920/*|PD_AUTO_EN*/, -1UL); if (sci_glb_read(REG_AHB_CHIP_ID, -1UL) == CHIP_ID_VER_0) { sci_glb_write(REG_GLB_ARM_SYS_PWR_CTL, 0x02000f20 |PD_AUTO_EN, -1UL); sci_glb_write(REG_GLB_POWCTL0, 0x07000a20|(1<<23), -1UL ); }else { sci_glb_write(REG_GLB_ARM_SYS_PWR_CTL, 0x02000f20|PD_AUTO_EN, -1UL); sci_glb_write(REG_GLB_POWCTL0, 0x07000a20|(1<<23), -1UL); /* sci_glb_set(REG_GLB_POWCTL1, DSP_ROM_SLP_PD_EN|MCU_ROM_SLP_PD_EN); */ } #endif }
void dsi_core_or_function(unsigned int addr,unsigned int data) { sci_glb_write(addr,(dispc_glb_read(addr) | data), 0xffffffff); }