Example #1
0
/*
 *  Suspend
 */
int s3cfb_suspend(struct platform_device *dev, pm_message_t state)
{
	struct fb_info *fbinfo = platform_get_drvdata(dev);
	s3cfb_info_t *info = fbinfo->par;

	s3cfb_stop_lcd();
#if defined(CONFIG_CPU_S5P6440)
	s5p6440_pm_do_save(s3c_lcd_save, ARRAY_SIZE(s3c_lcd_save));
#else
	s5pc1xx_pm_do_save(s3c_lcd_save, ARRAY_SIZE(s3c_lcd_save));
#endif

	/* sleep before disabling the clock, we need to ensure
	 * the LCD DMA engine is not going to get back on the bus
	 * before the clock goes off again (bjd) */

	msleep(1);
	clk_disable(info->clk);

	return 0;
}
Example #2
0
static int s5pc1xx_pm_enter(suspend_state_t state)
{
	unsigned long regs_save[16];
	unsigned int tmp;

	/* ensure the debug is initialised (if enabled) */

	DBG("s5pc1xx_pm_enter(%d)\n", state);

	if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) {
		printk(KERN_ERR PFX "error: no cpu sleep functions set\n");
		return -EINVAL;
	}

	/* store the physical address of the register recovery block */
	s5pc100_sleep_save_phys = virt_to_phys(regs_save);

	DBG("s5pc1xx_sleep_save_phys=0x%08lx\n", s5pc100_sleep_save_phys);

	s5pc1xx_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save));
	s5pc1xx_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
	s5pc1xx_pm_do_save(core_save, ARRAY_SIZE(core_save));
	s5pc1xx_pm_do_save(sromc_save, ARRAY_SIZE(sromc_save));
	s5pc1xx_pm_do_save(nand_save, ARRAY_SIZE(nand_save));
	s5pc1xx_pm_do_save(uart_save, ARRAY_SIZE(uart_save));
	s5pc1xx_pm_do_save(eint_save, ARRAY_SIZE(eint_save));


	/* ensure INF_REG0  has the resume address */
	__raw_writel(virt_to_phys(s5pc100_cpu_resume), S5P_INFORM0);

	/* call cpu specific preperation */

	pm_cpu_prep();

	/* flush cache back to ram */
	flush_cache_all();

	/* send the cpu to sleep... */
	__raw_writel(0xffffffff, S5PC100_VIC0REG(VIC_INT_ENABLE_CLEAR));
	__raw_writel(0xffffffff, S5PC100_VIC1REG(VIC_INT_ENABLE_CLEAR));
	__raw_writel(0xffffffff, S5PC100_VIC2REG(VIC_INT_ENABLE_CLEAR));
	__raw_writel(0xffffffff, S5PC100_VIC0REG(VIC_INT_SOFT_CLEAR));
	__raw_writel(0xffffffff, S5PC100_VIC1REG(VIC_INT_SOFT_CLEAR));
	__raw_writel(0xffffffff, S5PC100_VIC2REG(VIC_INT_SOFT_CLEAR));

	/* Mask all wake up source */
	tmp = __raw_readl(S5P_PWR_CFG);
	tmp &= ~(0x1 << 7);
	tmp |= (0x7ff << 8);
	/* unmask alarm wakeup source */
	tmp &= ~(0x1 << 10);
	/* unmask keypad wakeup source */
	tmp &= ~(0x1 << 8);
	__raw_writel(tmp , S5P_PWR_CFG);
	__raw_writel(0xffffffff , S5P_EINT_WAKEUP_MASK);

	/* Wake up source setting */
	s5pc1xx_pm_configure_extint();

	/* : USB Power Control */
	/*   - USB PHY Disable */
	/*   - Make USB Tranceiver PAD to Suspend */
	tmp = __raw_readl(S5P_OTHERS);
   	tmp &= ~(1<<16);           	/* USB Signal Mask Clear */
   	__raw_writel(tmp, S5P_OTHERS);

	tmp = __raw_readl(S5PC1XX_UHOST);
	tmp |= (1<<0);
	__raw_writel(tmp, S5PC1XX_UHOST);

#ifdef CONFIG_S5P_DEEP_IDLE_TEST
	__raw_writel(((0x1 << 0) | (0x1a0 << 16)) ,S5P_CLAMP_STABLE);
#endif

	/* Set WFI instruction to SLEEP mode */
	tmp = __raw_readl(S5P_PWR_CFG);
	tmp &= S5P_CFG_WFI_CLEAN;

#ifdef CONFIG_S5P_DEEP_IDLE_TEST
	tmp &= ~(0x1f << 27);
	tmp |= S5P_CFG_WFI_DEEPIDLE | (1 << 31) | (0xbff << 7) | (1 << 29);
	tmp &= ~(1<<17);
	DBG("Deep Idle mode\n");
#else
	tmp |= (S5P_CFG_WFI_SLEEP);
	printk("normal sleep mode\n");
#endif
		
	__raw_writel(tmp, S5P_PWR_CFG);

	/* Clear WAKEUP_STAT register for next wakeup */
	tmp = __raw_readl(S5P_WAKEUP_STAT);
	__raw_writel(tmp, S5P_WAKEUP_STAT);

	/* Set Power Stable Count */
	tmp = __raw_readl(S5P_OTHERS);
	tmp &=~(1 << S5P_OTHER_STA_TYPE);
	tmp |= (STA_TYPE_SFR << S5P_OTHER_STA_TYPE);
	__raw_writel(tmp , S5P_OTHERS);
	__raw_writel(((S5P_PWR_STABLE_COUNT << S5P_PWR_STA_CNT) | (1 << S5P_PWR_STA_EXP_SCALE)), S5P_PWR_STABLE);

	/* Set Syscon Interrupt */
	tmp = __raw_readl(S5P_OTHERS);
	tmp |= (1 << S5P_OTHER_SYS_INT);
	__raw_writel(tmp, S5P_OTHERS);

#ifndef CONFIG_S5P_DEEP_IDLE_TEST
	tmp = __raw_readl(S5P_SLEEP_CFG);
	tmp &= ~(1 << 0);
	__raw_writel(tmp, S5P_SLEEP_CFG);
#endif

	/* s5pc1xx_cpu_save will also act as our return point from when
	 * we resume as it saves its own register state, so use the return
	 * code to differentiate return from save and return from sleep */

	if (s5pc100_cpu_save(regs_save) == 0) {
		flush_cache_all();
		/* This function for Chip bug on EVT0 */
		pm_cpu_sleep();
	}

	/* restore the cpu state */
	cpu_init();

	/* MTC IO OFF |  MTC IO SD-MMC OFF | USB Phy Enable */
	tmp = __raw_readl(S5P_OTHERS);
   	tmp |= (1<<31);
	__raw_writel(tmp, S5P_OTHERS);

	tmp = __raw_readl(S5P_OTHERS);
   	tmp |= ((1<<22)|(1<<16));
	__raw_writel(tmp, S5P_OTHERS);

	tmp = __raw_readl(S5PC1XX_UHOST);
	tmp &= ~(1<<0);
	__raw_writel(tmp, S5PC1XX_UHOST);

	
	s5pc1xx_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save));
	s5pc1xx_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
	s5pc1xx_pm_do_restore(core_save, ARRAY_SIZE(core_save));
	s5pc1xx_pm_do_restore(sromc_save, ARRAY_SIZE(sromc_save));
	s5pc1xx_pm_do_restore(nand_save, ARRAY_SIZE(nand_save));
	s5pc1xx_pm_do_restore(uart_save, ARRAY_SIZE(uart_save));
	s5pc1xx_pm_do_restore(eint_save, ARRAY_SIZE(eint_save));

	tmp = readl(weint_base + S5P_APM_WEINT1_PEND);
	writel(tmp , weint_base + S5P_APM_WEINT1_PEND);

	DBG("post sleep, preparing to return\n");

	s5pc1xx_pm_check_restore();
	
#ifdef CONFIG_S5P_DEEP_IDLE_TEST
	tmp = __raw_readl(S5P_OTHERS);
   	tmp |= (1<<30);
	__raw_writel(tmp, S5P_OTHERS);
#endif

	/* ok, let's return from sleep */
	DBG("S3C6410 PM Resume (post-restore)\n");
	return 0;
}