⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pm.c

📁 the attached file is the power mangement for MP201
💻 C
📖 第 1 页 / 共 3 页
字号:
static const unsigned int pmu_cmds_power_off[] = {/* SDR Pull Down */	PMU_CMD_REG_WRITE(SMU_PULLCTL_SDR, SMU_PULLCTL_SDR_PDOWN),/* SDR Floating */	PMU_CMD_REG_WRITE(SMU_PCTL_SDR, SMU_PCTL_SDR_FLOATING),/* SET MWI_SCLK_DIV for OSC */	PMU_CMD_REG_WRITE(SMU_MWI_SCLK_DIV, SMU_MWI_DIV_OSC_VAL ),/* L0 power OFF */	PMU_CMD_REG_WRITE(SMU_GCLKCTRL1_ENA, MASK_SMU_MWI_GCK),	PMU_CMD_REG_WRITE(SMU_GCLKCTRL1, SMU_GCK_ON),	PMU_CMD_REG_WRITE(MWI_INTFFCLR, MWI_FFCLR),	PMU_CMD_REG_WRITE(MWI_CONT, MWI_CONT_PWC_A8_D8_TX_OFF),	PMU_CMD_REG_WRITE(MWI_CONT, MWI_CONT_PWC_A8_D8_TX),	PMU_CMD_REG_WRITE(MWI_TXQA, (GPIOCORE_PWC_REGA << 24)),	PMU_CMD_REG_WRITE(MWI_TXQ, (PWC_REGA_L0_OFF_ECO_PS << 24)),	PMU_CMD_REG_WRITE(MWI_INTENSET, MWI_ENSET),	PMU_CMD_MWI_WRITE(MWI_START, MWI_START_FLAG),	PMU_CMD_REG_WRITE(MWI_INTFFCLR, MWI_FFCLR),	PMU_CMD_REG_WRITE(MWI_CONT, MWI_CONT_PWC_A8_D8_TX_OFF),/* Clock -> RTC */	PMU_CMD_REG_WRITE(SMU_PLLSEL, SMU_PLLSEL_RTC ),/* disable OSC */	PMU_CMD_REG_WRITE(SMU_OSC_CTRL, SMU_OSC_ENA_DISABLE ),/*  PMU_END */	PMU_CMD_PMU_END(),};static const struct intc_t intc[] = {	{	 .ien = VA_INTC + MP200_INTC_IT0_IEN0,	 .ids = VA_INTC + MP200_INTC_IT0_IDS0,	 .imn = VA_INTC + MP200_INTC_IT0_IMN0,	 },	{	 .ien = VA_INTC + MP200_INTC_IT0_IEN1,	 .ids = VA_INTC + MP200_INTC_IT0_IDS1,	 .imn = VA_INTC + MP200_INTC_IT0_IMN1,	 },};static struct {	unsigned int ia;	unsigned int imn;} gpio_state;static struct {	unsigned int ioout1;	unsigned int fmask1;	unsigned int bmask1;	unsigned int fmask3;	unsigned int bmask3;	unsigned int detmod3;} pwc_state;#if ENABLE_FRAMECACHEstatic struct {	unsigned int fif_fcctrl;	unsigned int fif_frameaaddr;	unsigned int fif_framebaddr;	unsigned int fif_framesize;	unsigned int fif_fcbaseaddr;} fif_state;#endif /* ENABLE_FRAMECACHE */static struct {	unsigned int smu_ahbclkctrl0;	unsigned int smu_ahbclkctrl1;	unsigned int smu_apbclkctrl;	unsigned int smu_clkctrl;} clkctrl_state;static struct {	unsigned int smu_gio_int_clk_sel;} smu_state;#ifdef CONFIG_MP201_RSTRESUMEstatic struct {	unsigned int smu_gclkctrl0;	unsigned int smu_gclkctrl1;	unsigned int smu_gclkctrl2;} clock_state;static struct {	unsigned int smu_resetreq1a;	unsigned int smu_resetreq1b;	unsigned int smu_resetreqdsp;} reset_state;#endif#ifdef CONFIG_MP200_WATCHDOGstatic unsigned int smu_wdt_int_reset;#endifstatic unsigned int mp200_sleep_mode = PM_SLEEP_MODE_NONE;/* * Let's power down on idle, but only if we are really * idle, because once we start down the path of * going idle we continue to do idle even if we get * a clock tick interrupt . .  */static void mp200_pm_idle(void){	local_irq_disable();	local_fiq_disable();	if (need_resched() == 0) {		cpu_do_idle();	}	local_fiq_enable();	local_irq_enable();}static int mp200_pm_set_pmu_cmds(unsigned int cnt, const unsigned int data[], int size){	int i;	for (i = 0; i < size; i++) {		outl(data[i],		     PMU_CMD_BUF_RAM + (cnt + i) * sizeof(unsigned int));	}	return i;}/* * mp200_pm_set_pmu_regs(unsigned int mode) */static void mp200_pm_set_pmu_regs(unsigned int mode){	unsigned int pow_on_pc;	unsigned int n = 0;	/* setting pmu command */	switch(mode){	case PM_SLEEP_MODE_S1:		n += SET_PMU_CMDS(n, pmu_cmds_s1_suspend);		break;	case PM_SLEEP_MODE_S2:		n += SET_PMU_CMDS(n, pmu_cmds_s2_suspend);		break;	case PM_SLEEP_MODE_S3:#ifdef PM_POWERIC_ES_SWITCH		if(lsiver_old)			n += SET_PMU_CMDS(n, pmu_cmds_s3_suspend_es1_1);		else			n += SET_PMU_CMDS(n, pmu_cmds_s3_suspend);#else		n += SET_PMU_CMDS(n, pmu_cmds_s3_suspend);#endif /* PM_POWERIC_ES_SWITCH */		break;	}	pow_on_pc = n;		switch(mode){	case PM_SLEEP_MODE_S1:		n += SET_PMU_CMDS(n, pmu_cmds_s1_resume);		break;	case PM_SLEEP_MODE_S2:		n += SET_PMU_CMDS(n, pmu_cmds_s2_resume);		break;	case PM_SLEEP_MODE_S3:#ifdef PM_POWERIC_ES_SWITCH		if(lsiver_old)			n += SET_PMU_CMDS(n, pmu_cmds_s3_resume_es1_1);		else			n += SET_PMU_CMDS(n, pmu_cmds_s3_resume);#else		n += SET_PMU_CMDS(n, pmu_cmds_s3_resume);#endif /* PM_POWERIC_ES_SWITCH */		break;	}	if (n >= PMU_CMD_BUF_RAM_SIZE) {		printk(KERN_INFO "%s(): PMU command length over. (%d word)\n",		       __FUNCTION__, n);	}	/* setting pmu regs. */	/* power off sequence start address */	outl(0, PMU_PC);	/* power on sequence start address */	outl(pow_on_pc, PMU_POWER_ON_PC);	/* disable watch dog timer */	outl(PMU_WDT_DISABLE, PMU_WDT_COUNT_EN);	/* set watch dog timer limit count */	outl(PMU_WDT_MAX_COUNT, PMU_WDT_COUNT_LMT);}static int mp200_pm_intc_mask(int mask, struct intc_state *state){	if (state == 0) {		return -EINVAL;	}	switch (mask) {	case PM_INTC_MASK_SAVE_AND_MASK:		state->mask0 = inl(intc[0].imn);		state->mask1 = inl(intc[1].imn);		outl(MASK_INTC_ALL, intc[0].ids);		outl(MASK_INTC_ALL, intc[1].ids);		break;	case PM_INTC_MASK_RESTORE:		outl(MASK_INTC_ALL, intc[0].ids);		outl(MASK_INTC_ALL, intc[1].ids);		outl(state->mask0, intc[0].ien);		outl(state->mask1, intc[1].ien);		break;	default:		return -EINVAL;	}	return 0;}static void mp200_pm_save_state(unsigned int mode){	/* save GPIO state */	gpio_state.imn = inl(VA_GIO + GPIO0_IMN);	gpio_state.ia = inl(VA_GIO + GPIO0_IA);	/* save PWC state */	pwc_read(PWC_FMASK1, &pwc_state.fmask1);	pwc_read(PWC_BMASK1, &pwc_state.bmask1);	pwc_read(PWC_IOOUT1, &pwc_state.ioout1);#ifdef PM_POWERIC_ES_SWITCH	if(lsiver_old == 0) {		pwc_read(PWC_FMASK3, &pwc_state.fmask3);		pwc_read(PWC_BMASK3, &pwc_state.bmask3);		pwc_read(PWC_DETMOD3H, &pwc_state.detmod3);	}#else	pwc_read(PWC_FMASK3, &pwc_state.fmask3);	pwc_read(PWC_BMASK3, &pwc_state.bmask3);	pwc_read(PWC_DETMOD3H, &pwc_state.detmod3);#endif /* !PM_POWERIC_ES_SWITCH */#if ENABLE_FRAMECACHE	/* save FIFO state */	fif_state.fif_frameaaddr = inl(FIF_FRAMEAADDR);	fif_state.fif_framebaddr = inl(FIF_FRAMEBADDR);	fif_state.fif_framesize = inl(FIF_FRAMESIZE);	fif_state.fif_fcbaseaddr = inl(FIF_FCBASEADDR);	fif_state.fif_fcctrl = inl(FIF_FCCTRL);#endif /* ENABLE_FRAMECACHE */#ifdef CONFIG_MP201_RSTRESUME	/* save clockgate status */	clock_state.smu_gclkctrl0 = inl(SMU_GCLKCTRL0);	clock_state.smu_gclkctrl1 = inl(SMU_GCLKCTRL1);	clock_state.smu_gclkctrl2 = inl(SMU_GCLKCTRL2);	/* save reset status */	reset_state.smu_resetreq1a = inl(SMU_RESETREQ1A);	reset_state.smu_resetreq1b = inl(SMU_RESETREQ1B);	reset_state.smu_resetreqdsp = inl(SMU_RESETREQDSP);#endif#ifdef CONFIG_MP200_WATCHDOG	/* save SMU wdt int reset state */	smu_wdt_int_reset = inl(SMU_WDT_INT_RESET);	/* SMU wdt int reset : enable TW0 */	outl(SMU_TW0_RSTREQ, SMU_WDT_INT_RESET);#endif	/* SMU other state */	smu_state.smu_gio_int_clk_sel = inl(SMU_GIO_INT_CLK_SEL);	/* gio int use RTC */	outl(SMU_GIO_INT_CLK_RTC, SMU_GIO_INT_CLK_SEL);	/* save SMU clkctrl state */	clkctrl_state.smu_ahbclkctrl0 = inl(SMU_AHBCLKCTRL0);	clkctrl_state.smu_ahbclkctrl1 = inl(SMU_AHBCLKCTRL1);	clkctrl_state.smu_apbclkctrl = inl(SMU_APBCLKCTRL);	clkctrl_state.smu_clkctrl = inl(SMU_CLKCTRL);		return;}static void mp200_pm_restore_state(void){#ifdef CONFIG_MP201_RSTRESUME	/* restore clockgate status */	outl(clock_state.smu_gclkctrl0, SMU_GCLKCTRL0_ENA);	outl(clock_state.smu_gclkctrl0, SMU_GCLKCTRL0);	outl(0, SMU_GCLKCTRL0_ENA);	outl(clock_state.smu_gclkctrl1, SMU_GCLKCTRL1_ENA);	outl(clock_state.smu_gclkctrl1, SMU_GCLKCTRL1 );	outl(0, SMU_GCLKCTRL1_ENA);	outl(clock_state.smu_gclkctrl2, SMU_GCLKCTRL2_ENA);	outl(clock_state.smu_gclkctrl2, SMU_GCLKCTRL2 );	outl(0, SMU_GCLKCTRL2_ENA);	/* resotre reset status */	outl(reset_state.smu_resetreq1a, SMU_RESETREQ1A_ENA)	outl(reset_state.smu_resetreq1a, SMU_RESETREQ1A);	outl(0, SMU_RESETREQ1A_ENA);	outl(reset_state.smu_resetreq1b, SMU_RESETREQ1B_ENA	outl(reset_state.smu_resetreq1b, SMU_RESETREQ1B);	outl(0, SMU_RESETREQ1B_ENA);	outl(reset_state.smu_resetreqdsp, SMU_RESETREQDSP_ENA);	outl(reset_state.smu_resetreqdsp, SMU_RESETREQDSP);	outl(0, SMU_RESETREQDSP_ENA);#endif	/* SMU clkctrl : PB0LP,PB1LP off */	outl(inl(SMU_AHBCLKCTRL1) & ~(SMU_CLKCTRL_PB0LP | SMU_CLKCTRL_PB1LP),	     SMU_AHBCLKCTRL1);	/* restore SMU clkctrl state */	outl(clkctrl_state.smu_clkctrl, SMU_CLKCTRL);	outl(clkctrl_state.smu_apbclkctrl, SMU_APBCLKCTRL);	outl(clkctrl_state.smu_ahbclkctrl1, SMU_AHBCLKCTRL1);	outl(clkctrl_state.smu_ahbclkctrl0, SMU_AHBCLKCTRL0);	/* SMU other state */	outl(smu_state.smu_gio_int_clk_sel, SMU_GIO_INT_CLK_SEL);#ifdef CONFIG_MP200_WATCHDOG	/* restore SMU wdt int reset state */	outl(smu_wdt_int_reset, SMU_WDT_INT_RESET);#endif#if ENABLE_FRAMECACHE	/* restore FIFO state */	outl(fif_state.fif_frameaaddr, FIF_FRAMEAADDR);	outl(fif_state.fif_framebaddr, FIF_FRAMEBADDR);	outl(fif_state.fif_framesize, FIF_FRAMESIZE);	outl(fif_state.fif_fcbaseaddr, FIF_FCBASEADDR);	outl(fif_state.fif_fcctrl, FIF_FCCTRL);#endif /* ENABLE_FRAMECACHE */	/* uWire state : enable */	mp200_pm_set_uwire_clock();	/* restore PWC state */	pwc_write(PWC_FMASK1, pwc_state.fmask1, MASK_GPIO_KEYSCAN);	pwc_write(PWC_CLRFACT1, MASK_GPIO_KEYDATA, MASK_GPIO_KEYDATA);	pwc_write(PWC_BMASK1, pwc_state.bmask1, MASK_GPIO_KEYSCAN);	pwc_write(PWC_IOOUT1, pwc_state.ioout1, MASK_GPIO_KEYSCAN);	/* USBWAKE INT state */#ifdef PM_POWERIC_ES_SWITCH	if(lsiver_old == 0) {		pwc_write(PWC_DETMOD3H, pwc_state.detmod3, MASK_DETMODE3H_USBWKM);		pwc_write(PWC_FMASK3, pwc_state.fmask3, MASK_USBWAKINT);		pwc_write(PWC_BMASK3, pwc_state.bmask3, MASK_USBWAKINT);	}#else	pwc_write(PWC_DETMOD3H, pwc_state.detmod3, MASK_DETMODE3H_USBWKM);	pwc_write(PWC_FMASK3, pwc_state.fmask3, MASK_USBWAKINT);	pwc_write(PWC_BMASK3, pwc_state.bmask3, MASK_USBWAKINT);#endif /* !PM_POWERIC_ES_SWITCH */	/* restore GPIO state */	outl(gpio_state.ia, VA_GIO + GPIO0_IA);	outl(MASK_GPIO_ALL, VA_GIO + GPIO0_IME);	outl(~gpio_state.imn, VA_GIO + GPIO0_IMN);	return;}/* * mp200_pm_do_suspend(unsigned int mode) */static void mp200_pm_do_suspend(unsigned int mode){	unsigned int sus_add;	unsigned int regval;	void (*suspend_on_sram) (void);	mp200_pm_save_state(mode);	/* on SRAM mp200_cpu_suspend() */	sus_add =	    (unsigned int)mp200_cpu_suspend - (unsigned int)warmboot_handler;	suspend_on_sram = (void (*)(void))(WARMBOOT_ADDR + sus_add);	/* WAKEWAIT disable */	if (mode == PM_SLEEP_MODE_S3) {		pwc_write(PWC_WAKECONT, WAKECONT_WAKEWAIT_DISABLE, 			  MASK_WAKECONT_WAKEWAIT);	}	/* open key interrupt mask */	/* PWC */	pwc_write(PWC_FMASK1, MASK_GPIO_KEYDATA, MASK_GPIO_KEYDATA);	pwc_write(PWC_CLRFACT1, MASK_GPIO_KEYDATA, MASK_GPIO_KEYDATA);	pwc_write(PWC_BMASK1, MASK_GPIO_KEYDATA, MASK_GPIO_KEYDATA);	pwc_write(PWC_IOOUT1, MASK_GPIO_RESUME_KEY, MASK_GPIO_KEYSCAN);	/* USB WAKINT enable */#ifdef PM_POWERIC_ES_SWITCH	if(lsiver_old == 0) {		pwc_write(PWC_FMASK3, MASK_USBWAKINT, MASK_USBWAKINT);		pwc_write(PWC_DETMOD3H, DETMODE3H_USBWKM_RISE, MASK_DETMODE3H_USBWKM);		pwc_write(PWC_CLRFACT3, MASK_USBWAKINT, MASK_USBWAKINT);		pwc_write(PWC_BMASK3, MASK_USBWAKINT, MASK_USBWAKINT);	}#else	pwc_write(PWC_FMASK3, MASK_USBWAKINT, MASK_USBWAKINT);	pwc_write(PWC_DETMOD3H, DETMODE3H_USBWKM_RISE, MASK_DETMODE3H_USBWKM);	pwc_write(PWC_CLRFACT3, MASK_USBWAKINT, MASK_USBWAKINT);	pwc_write(PWC_BMASK3, MASK_USBWAKINT, MASK_USBWAKINT);#endif /* !PM_POWERIC_ES_SWITCH */	/* GPIO */	outl(MASK_GPIO_ALL, VA_GIO + GPIO0_IME);	outl((inl(VA_GIO + GPIO0_IA) | MASK_GPIO_RESUME), 	     VA_GIO + GPIO0_IA);	outl(MASK_GPIO_RESUME, VA_GIO + GPIO0_IR);	outl(MASK_GPIO_RESUME, VA_GIO + GPIO0_IMN);	/* setting pmu registers */	mp200_pm_set_pmu_regs(mode);	outl(SMU_RESET_STATE_WARM, SMU_SMU_RESET_STATE);	/* disable uwire int */	outl(MWI_ENCLR, MWI_INTENCLR);	/* start PMU */	outl(PMU_START_SET, PMU_START);	/* wait for pmu_start */	do {		regval = inl(PMU_START);	} while (regval != PMU_START_SET);	/* save PEn regs and wait for interrupt */	suspend_on_sram();	/*	 * PEn status moves to WFI, pmu command start at that time.	 * after warm boot handler done, pc return here	 */	regval = inl(PMU_START);	if ((regval & PMU_START_SET) == PMU_START_SET) {		outl(0, PMU_START);		printk(KERN_INFO "%s(): PMU not run.\n", __FUNCTION__);	}}/* * mp200_pm_do_resume() */static void mp200_pm_do_resume(void){	outl(SMU_RESET_STATE_CLR, SMU_SMU_RESET_STATE);	mp200_pm_restore_state();}static void mp200_pm_suspend(suspend_state_t state){	struct intc_state intc_state;	unsigned int sleep_mode;	unsigned int pll_mode;	#ifdef CONFIG_MP200_RTC	struct rtc_time rt;	long rtc_offset;	unsigned long mkt;	extern void get_rtc_time(struct rtc_time *);#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -