/* * Static Power Management support for Freescale STMP37XX/STMP378X * * Author: Vitaly Wool * * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved. * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. */ /* * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License * Version 2 or later at the following locations: * * http://www.opensource.org/licenses/gpl-license.html * http://www.gnu.org/copyleft/gpl.html */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //#include "clock.h" #include "sleep.h" #define PENDING_IRQ_RETRY 100 static void *saved_sram; static int saved_sleep_state; #define WAIT_DC_OK_CYCLES 24000 #define WAIT_CYCLE(n) for (i = 0; i < n; i++); #define LOWER_VDDIO 10 #define LOWER_VDDA 9 #define LOWER_VDDD 0xa #define MAX_POWEROFF_CODE_SIZE (6 * 1024) static void stmp378x_standby(void) { int i; u32 reg_vddd, reg_vdda, reg_vddio; /* DDR EnterSelfrefreshMode */ __raw_writel( BM_DRAM_CTL08_SREFRESH | __raw_readl(REGS_DRAM_BASE + HW_DRAM_CTL08), REGS_DRAM_BASE + HW_DRAM_CTL08); /* Gating EMI CLock */ __raw_writel(BM_CLKCTRL_EMI_CLKGATE | __raw_readl(REGS_CLKCTRL_BASE + HW_CLKCTRL_EMI), REGS_CLKCTRL_BASE + HW_CLKCTRL_EMI); /* Disable PLL */ __raw_writel(BM_CLKCTRL_PLLCTRL0_POWER, REGS_CLKCTRL_BASE + HW_CLKCTRL_PLLCTRL0_CLR); /* Reduce the VDDIO (3.050 volt) */ reg_vddio = __raw_readl(REGS_POWER_BASE + HW_POWER_VDDIOCTRL); __raw_writel(reg_vddio | BM_POWER_VDDIOCTRL_BO_OFFSET, REGS_POWER_BASE + HW_POWER_VDDIOCTRL); __raw_writel((__raw_readl(REGS_POWER_BASE + HW_POWER_VDDIOCTRL) & ~BM_POWER_VDDIOCTRL_TRG) | LOWER_VDDIO, REGS_POWER_BASE + HW_POWER_VDDIOCTRL); WAIT_CYCLE(WAIT_DC_OK_CYCLES) while (!(__raw_readl(REGS_POWER_BASE + HW_POWER_STS) & BM_POWER_STS_DC_OK)) ; /* Reduce VDDA 1.725volt */ reg_vdda = __raw_readl(REGS_POWER_BASE + HW_POWER_VDDACTRL); __raw_writel(reg_vdda | BM_POWER_VDDACTRL_BO_OFFSET, REGS_POWER_BASE + HW_POWER_VDDACTRL); __raw_writel((__raw_readl(REGS_POWER_BASE + HW_POWER_VDDACTRL) & ~BM_POWER_VDDACTRL_TRG) | LOWER_VDDA, REGS_POWER_BASE + HW_POWER_VDDACTRL); WAIT_CYCLE(WAIT_DC_OK_CYCLES) /* wait for DC_OK */ while (!(__raw_readl(REGS_POWER_BASE + HW_POWER_STS) & BM_POWER_STS_DC_OK)) ; /* Reduce VDDD 1.000 volt */ reg_vddd = __raw_readl(REGS_POWER_BASE + HW_POWER_VDDDCTRL); __raw_writel(reg_vddd | BM_POWER_VDDDCTRL_BO_OFFSET, REGS_POWER_BASE + HW_POWER_VDDDCTRL); __raw_writel((__raw_readl(REGS_POWER_BASE + HW_POWER_VDDDCTRL) & ~BM_POWER_VDDDCTRL_TRG) | LOWER_VDDD, REGS_POWER_BASE + HW_POWER_VDDDCTRL); WAIT_CYCLE(WAIT_DC_OK_CYCLES) while (!(__raw_readl(REGS_POWER_BASE + HW_POWER_STS) & BM_POWER_STS_DC_OK)) ; /* optimize the DCDC loop gain */ __raw_writel((__raw_readl(REGS_POWER_BASE + HW_POWER_LOOPCTRL) & ~BM_POWER_LOOPCTRL_EN_RCSCALE), REGS_POWER_BASE + HW_POWER_LOOPCTRL); __raw_writel((__raw_readl(REGS_POWER_BASE + HW_POWER_LOOPCTRL) & ~BM_POWER_LOOPCTRL_DC_R) | (2<