2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-23 20:53:53 +08:00

Merge branch 'pm-upstream/pm-off' of ssh://master.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm into 7xx-iosplit-plat-merge

This commit is contained in:
Tony Lindgren 2009-11-11 15:20:53 -08:00
commit 4d0226042c
24 changed files with 1810 additions and 51 deletions

View File

@ -17,9 +17,125 @@
#include <plat/common.h>
#include <plat/control.h>
#include <plat/sdrc.h>
#include "cm-regbits-34xx.h"
#include "prm-regbits-34xx.h"
#include "cm.h"
#include "prm.h"
#include "sdrc.h"
static void __iomem *omap2_ctrl_base;
#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
struct omap3_scratchpad {
u32 boot_config_ptr;
u32 public_restore_ptr;
u32 secure_ram_restore_ptr;
u32 sdrc_module_semaphore;
u32 prcm_block_offset;
u32 sdrc_block_offset;
};
struct omap3_scratchpad_prcm_block {
u32 prm_clksrc_ctrl;
u32 prm_clksel;
u32 cm_clksel_core;
u32 cm_clksel_wkup;
u32 cm_clken_pll;
u32 cm_autoidle_pll;
u32 cm_clksel1_pll;
u32 cm_clksel2_pll;
u32 cm_clksel3_pll;
u32 cm_clken_pll_mpu;
u32 cm_autoidle_pll_mpu;
u32 cm_clksel1_pll_mpu;
u32 cm_clksel2_pll_mpu;
u32 prcm_block_size;
};
struct omap3_scratchpad_sdrc_block {
u16 sysconfig;
u16 cs_cfg;
u16 sharing;
u16 err_type;
u32 dll_a_ctrl;
u32 dll_b_ctrl;
u32 power;
u32 cs_0;
u32 mcfg_0;
u16 mr_0;
u16 emr_1_0;
u16 emr_2_0;
u16 emr_3_0;
u32 actim_ctrla_0;
u32 actim_ctrlb_0;
u32 rfr_ctrl_0;
u32 cs_1;
u32 mcfg_1;
u16 mr_1;
u16 emr_1_1;
u16 emr_2_1;
u16 emr_3_1;
u32 actim_ctrla_1;
u32 actim_ctrlb_1;
u32 rfr_ctrl_1;
u16 dcdl_1_ctrl;
u16 dcdl_2_ctrl;
u32 flags;
u32 block_size;
};
void *omap3_secure_ram_storage;
/*
* This is used to store ARM registers in SDRAM before attempting
* an MPU OFF. The save and restore happens from the SRAM sleep code.
* The address is stored in scratchpad, so that it can be used
* during the restore path.
*/
u32 omap3_arm_context[128];
struct omap3_control_regs {
u32 sysconfig;
u32 devconf0;
u32 mem_dftrw0;
u32 mem_dftrw1;
u32 msuspendmux_0;
u32 msuspendmux_1;
u32 msuspendmux_2;
u32 msuspendmux_3;
u32 msuspendmux_4;
u32 msuspendmux_5;
u32 sec_ctrl;
u32 devconf1;
u32 csirxfe;
u32 iva2_bootaddr;
u32 iva2_bootmod;
u32 debobs_0;
u32 debobs_1;
u32 debobs_2;
u32 debobs_3;
u32 debobs_4;
u32 debobs_5;
u32 debobs_6;
u32 debobs_7;
u32 debobs_8;
u32 prog_io0;
u32 prog_io1;
u32 dss_dpll_spreading;
u32 core_dpll_spreading;
u32 per_dpll_spreading;
u32 usbhost_dpll_spreading;
u32 pbias_lite;
u32 temp_sensor;
u32 sramldo4;
u32 sramldo5;
u32 csi;
};
static struct omap3_control_regs control_context;
#endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */
#define OMAP_CTRL_REGADDR(reg) (omap2_ctrl_base + (reg))
void __init omap2_set_globals_control(struct omap_globals *omap2_globals)
@ -62,3 +178,268 @@ void omap_ctrl_writel(u32 val, u16 offset)
__raw_writel(val, OMAP_CTRL_REGADDR(offset));
}
#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
/*
* Clears the scratchpad contents in case of cold boot-
* called during bootup
*/
void omap3_clear_scratchpad_contents(void)
{
u32 max_offset = OMAP343X_SCRATCHPAD_ROM_OFFSET;
u32 *v_addr;
u32 offset = 0;
v_addr = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD_ROM);
if (prm_read_mod_reg(OMAP3430_GR_MOD, OMAP3_PRM_RSTST_OFFSET) &
OMAP3430_GLOBAL_COLD_RST) {
for ( ; offset <= max_offset; offset += 0x4)
__raw_writel(0x0, (v_addr + offset));
prm_set_mod_reg_bits(OMAP3430_GLOBAL_COLD_RST, OMAP3430_GR_MOD,
OMAP3_PRM_RSTST_OFFSET);
}
}
/* Populate the scratchpad structure with restore structure */
void omap3_save_scratchpad_contents(void)
{
void * __iomem scratchpad_address;
u32 arm_context_addr;
struct omap3_scratchpad scratchpad_contents;
struct omap3_scratchpad_prcm_block prcm_block_contents;
struct omap3_scratchpad_sdrc_block sdrc_block_contents;
/* Populate the Scratchpad contents */
scratchpad_contents.boot_config_ptr = 0x0;
if (omap_rev() != OMAP3430_REV_ES3_0 &&
omap_rev() != OMAP3430_REV_ES3_1)
scratchpad_contents.public_restore_ptr =
virt_to_phys(get_restore_pointer());
else
scratchpad_contents.public_restore_ptr =
virt_to_phys(get_es3_restore_pointer());
if (omap_type() == OMAP2_DEVICE_TYPE_GP)
scratchpad_contents.secure_ram_restore_ptr = 0x0;
else
scratchpad_contents.secure_ram_restore_ptr =
(u32) __pa(omap3_secure_ram_storage);
scratchpad_contents.sdrc_module_semaphore = 0x0;
scratchpad_contents.prcm_block_offset = 0x2C;
scratchpad_contents.sdrc_block_offset = 0x64;
/* Populate the PRCM block contents */
prcm_block_contents.prm_clksrc_ctrl = prm_read_mod_reg(OMAP3430_GR_MOD,
OMAP3_PRM_CLKSRC_CTRL_OFFSET);
prcm_block_contents.prm_clksel = prm_read_mod_reg(OMAP3430_CCR_MOD,
OMAP3_PRM_CLKSEL_OFFSET);
prcm_block_contents.cm_clksel_core =
cm_read_mod_reg(CORE_MOD, CM_CLKSEL);
prcm_block_contents.cm_clksel_wkup =
cm_read_mod_reg(WKUP_MOD, CM_CLKSEL);
prcm_block_contents.cm_clken_pll =
cm_read_mod_reg(PLL_MOD, CM_CLKEN);
prcm_block_contents.cm_autoidle_pll =
cm_read_mod_reg(PLL_MOD, OMAP3430_CM_AUTOIDLE_PLL);
prcm_block_contents.cm_clksel1_pll =
cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL1_PLL);
prcm_block_contents.cm_clksel2_pll =
cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL2_PLL);
prcm_block_contents.cm_clksel3_pll =
cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL3);
prcm_block_contents.cm_clken_pll_mpu =
cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKEN_PLL);
prcm_block_contents.cm_autoidle_pll_mpu =
cm_read_mod_reg(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL);
prcm_block_contents.cm_clksel1_pll_mpu =
cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL);
prcm_block_contents.cm_clksel2_pll_mpu =
cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL);
prcm_block_contents.prcm_block_size = 0x0;
/* Populate the SDRC block contents */
sdrc_block_contents.sysconfig =
(sdrc_read_reg(SDRC_SYSCONFIG) & 0xFFFF);
sdrc_block_contents.cs_cfg =
(sdrc_read_reg(SDRC_CS_CFG) & 0xFFFF);
sdrc_block_contents.sharing =
(sdrc_read_reg(SDRC_SHARING) & 0xFFFF);
sdrc_block_contents.err_type =
(sdrc_read_reg(SDRC_ERR_TYPE) & 0xFFFF);
sdrc_block_contents.dll_a_ctrl = sdrc_read_reg(SDRC_DLLA_CTRL);
sdrc_block_contents.dll_b_ctrl = 0x0;
/*
* Due to a OMAP3 errata (1.142), on EMU/HS devices SRDC should
* be programed to issue automatic self refresh on timeout
* of AUTO_CNT = 1 prior to any transition to OFF mode.
*/
if ((omap_type() != OMAP2_DEVICE_TYPE_GP)
&& (omap_rev() >= OMAP3430_REV_ES3_0))
sdrc_block_contents.power = (sdrc_read_reg(SDRC_POWER) &
~(SDRC_POWER_AUTOCOUNT_MASK|
SDRC_POWER_CLKCTRL_MASK)) |
(1 << SDRC_POWER_AUTOCOUNT_SHIFT) |
SDRC_SELF_REFRESH_ON_AUTOCOUNT;
else
sdrc_block_contents.power = sdrc_read_reg(SDRC_POWER);
sdrc_block_contents.cs_0 = 0x0;
sdrc_block_contents.mcfg_0 = sdrc_read_reg(SDRC_MCFG_0);
sdrc_block_contents.mr_0 = (sdrc_read_reg(SDRC_MR_0) & 0xFFFF);
sdrc_block_contents.emr_1_0 = 0x0;
sdrc_block_contents.emr_2_0 = 0x0;
sdrc_block_contents.emr_3_0 = 0x0;
sdrc_block_contents.actim_ctrla_0 =
sdrc_read_reg(SDRC_ACTIM_CTRL_A_0);
sdrc_block_contents.actim_ctrlb_0 =
sdrc_read_reg(SDRC_ACTIM_CTRL_B_0);
sdrc_block_contents.rfr_ctrl_0 =
sdrc_read_reg(SDRC_RFR_CTRL_0);
sdrc_block_contents.cs_1 = 0x0;
sdrc_block_contents.mcfg_1 = sdrc_read_reg(SDRC_MCFG_1);
sdrc_block_contents.mr_1 = sdrc_read_reg(SDRC_MR_1) & 0xFFFF;
sdrc_block_contents.emr_1_1 = 0x0;
sdrc_block_contents.emr_2_1 = 0x0;
sdrc_block_contents.emr_3_1 = 0x0;
sdrc_block_contents.actim_ctrla_1 =
sdrc_read_reg(SDRC_ACTIM_CTRL_A_1);
sdrc_block_contents.actim_ctrlb_1 =
sdrc_read_reg(SDRC_ACTIM_CTRL_B_1);
sdrc_block_contents.rfr_ctrl_1 =
sdrc_read_reg(SDRC_RFR_CTRL_1);
sdrc_block_contents.dcdl_1_ctrl = 0x0;
sdrc_block_contents.dcdl_2_ctrl = 0x0;
sdrc_block_contents.flags = 0x0;
sdrc_block_contents.block_size = 0x0;
arm_context_addr = virt_to_phys(omap3_arm_context);
/* Copy all the contents to the scratchpad location */
scratchpad_address = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD);
memcpy_toio(scratchpad_address, &scratchpad_contents,
sizeof(scratchpad_contents));
/* Scratchpad contents being 32 bits, a divide by 4 done here */
memcpy_toio(scratchpad_address +
scratchpad_contents.prcm_block_offset,
&prcm_block_contents, sizeof(prcm_block_contents));
memcpy_toio(scratchpad_address +
scratchpad_contents.sdrc_block_offset,
&sdrc_block_contents, sizeof(sdrc_block_contents));
/*
* Copies the address of the location in SDRAM where ARM
* registers get saved during a MPU OFF transition.
*/
memcpy_toio(scratchpad_address +
scratchpad_contents.sdrc_block_offset +
sizeof(sdrc_block_contents), &arm_context_addr, 4);
}
void omap3_control_save_context(void)
{
control_context.sysconfig = omap_ctrl_readl(OMAP2_CONTROL_SYSCONFIG);
control_context.devconf0 = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
control_context.mem_dftrw0 =
omap_ctrl_readl(OMAP343X_CONTROL_MEM_DFTRW0);
control_context.mem_dftrw1 =
omap_ctrl_readl(OMAP343X_CONTROL_MEM_DFTRW1);
control_context.msuspendmux_0 =
omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_0);
control_context.msuspendmux_1 =
omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_1);
control_context.msuspendmux_2 =
omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_2);
control_context.msuspendmux_3 =
omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_3);
control_context.msuspendmux_4 =
omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_4);
control_context.msuspendmux_5 =
omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_5);
control_context.sec_ctrl = omap_ctrl_readl(OMAP2_CONTROL_SEC_CTRL);
control_context.devconf1 = omap_ctrl_readl(OMAP343X_CONTROL_DEVCONF1);
control_context.csirxfe = omap_ctrl_readl(OMAP343X_CONTROL_CSIRXFE);
control_context.iva2_bootaddr =
omap_ctrl_readl(OMAP343X_CONTROL_IVA2_BOOTADDR);
control_context.iva2_bootmod =
omap_ctrl_readl(OMAP343X_CONTROL_IVA2_BOOTMOD);
control_context.debobs_0 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(0));
control_context.debobs_1 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(1));
control_context.debobs_2 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(2));
control_context.debobs_3 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(3));
control_context.debobs_4 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(4));
control_context.debobs_5 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(5));
control_context.debobs_6 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(6));
control_context.debobs_7 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(7));
control_context.debobs_8 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(8));
control_context.prog_io0 = omap_ctrl_readl(OMAP343X_CONTROL_PROG_IO0);
control_context.prog_io1 = omap_ctrl_readl(OMAP343X_CONTROL_PROG_IO1);
control_context.dss_dpll_spreading =
omap_ctrl_readl(OMAP343X_CONTROL_DSS_DPLL_SPREADING);
control_context.core_dpll_spreading =
omap_ctrl_readl(OMAP343X_CONTROL_CORE_DPLL_SPREADING);
control_context.per_dpll_spreading =
omap_ctrl_readl(OMAP343X_CONTROL_PER_DPLL_SPREADING);
control_context.usbhost_dpll_spreading =
omap_ctrl_readl(OMAP343X_CONTROL_USBHOST_DPLL_SPREADING);
control_context.pbias_lite =
omap_ctrl_readl(OMAP343X_CONTROL_PBIAS_LITE);
control_context.temp_sensor =
omap_ctrl_readl(OMAP343X_CONTROL_TEMP_SENSOR);
control_context.sramldo4 = omap_ctrl_readl(OMAP343X_CONTROL_SRAMLDO4);
control_context.sramldo5 = omap_ctrl_readl(OMAP343X_CONTROL_SRAMLDO5);
control_context.csi = omap_ctrl_readl(OMAP343X_CONTROL_CSI);
return;
}
void omap3_control_restore_context(void)
{
omap_ctrl_writel(control_context.sysconfig, OMAP2_CONTROL_SYSCONFIG);
omap_ctrl_writel(control_context.devconf0, OMAP2_CONTROL_DEVCONF0);
omap_ctrl_writel(control_context.mem_dftrw0,
OMAP343X_CONTROL_MEM_DFTRW0);
omap_ctrl_writel(control_context.mem_dftrw1,
OMAP343X_CONTROL_MEM_DFTRW1);
omap_ctrl_writel(control_context.msuspendmux_0,
OMAP2_CONTROL_MSUSPENDMUX_0);
omap_ctrl_writel(control_context.msuspendmux_1,
OMAP2_CONTROL_MSUSPENDMUX_1);
omap_ctrl_writel(control_context.msuspendmux_2,
OMAP2_CONTROL_MSUSPENDMUX_2);
omap_ctrl_writel(control_context.msuspendmux_3,
OMAP2_CONTROL_MSUSPENDMUX_3);
omap_ctrl_writel(control_context.msuspendmux_4,
OMAP2_CONTROL_MSUSPENDMUX_4);
omap_ctrl_writel(control_context.msuspendmux_5,
OMAP2_CONTROL_MSUSPENDMUX_5);
omap_ctrl_writel(control_context.sec_ctrl, OMAP2_CONTROL_SEC_CTRL);
omap_ctrl_writel(control_context.devconf1, OMAP343X_CONTROL_DEVCONF1);
omap_ctrl_writel(control_context.csirxfe, OMAP343X_CONTROL_CSIRXFE);
omap_ctrl_writel(control_context.iva2_bootaddr,
OMAP343X_CONTROL_IVA2_BOOTADDR);
omap_ctrl_writel(control_context.iva2_bootmod,
OMAP343X_CONTROL_IVA2_BOOTMOD);
omap_ctrl_writel(control_context.debobs_0, OMAP343X_CONTROL_DEBOBS(0));
omap_ctrl_writel(control_context.debobs_1, OMAP343X_CONTROL_DEBOBS(1));
omap_ctrl_writel(control_context.debobs_2, OMAP343X_CONTROL_DEBOBS(2));
omap_ctrl_writel(control_context.debobs_3, OMAP343X_CONTROL_DEBOBS(3));
omap_ctrl_writel(control_context.debobs_4, OMAP343X_CONTROL_DEBOBS(4));
omap_ctrl_writel(control_context.debobs_5, OMAP343X_CONTROL_DEBOBS(5));
omap_ctrl_writel(control_context.debobs_6, OMAP343X_CONTROL_DEBOBS(6));
omap_ctrl_writel(control_context.debobs_7, OMAP343X_CONTROL_DEBOBS(7));
omap_ctrl_writel(control_context.debobs_8, OMAP343X_CONTROL_DEBOBS(8));
omap_ctrl_writel(control_context.prog_io0, OMAP343X_CONTROL_PROG_IO0);
omap_ctrl_writel(control_context.prog_io1, OMAP343X_CONTROL_PROG_IO1);
omap_ctrl_writel(control_context.dss_dpll_spreading,
OMAP343X_CONTROL_DSS_DPLL_SPREADING);
omap_ctrl_writel(control_context.core_dpll_spreading,
OMAP343X_CONTROL_CORE_DPLL_SPREADING);
omap_ctrl_writel(control_context.per_dpll_spreading,
OMAP343X_CONTROL_PER_DPLL_SPREADING);
omap_ctrl_writel(control_context.usbhost_dpll_spreading,
OMAP343X_CONTROL_USBHOST_DPLL_SPREADING);
omap_ctrl_writel(control_context.pbias_lite,
OMAP343X_CONTROL_PBIAS_LITE);
omap_ctrl_writel(control_context.temp_sensor,
OMAP343X_CONTROL_TEMP_SENSOR);
omap_ctrl_writel(control_context.sramldo4, OMAP343X_CONTROL_SRAMLDO4);
omap_ctrl_writel(control_context.sramldo5, OMAP343X_CONTROL_SRAMLDO5);
omap_ctrl_writel(control_context.csi, OMAP343X_CONTROL_CSI);
return;
}
#endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */

View File

@ -62,6 +62,33 @@
#define ENABLE_PREFETCH (0x1 << 7)
#define DMA_MPU_MODE 2
/* Structure to save gpmc cs context */
struct gpmc_cs_config {
u32 config1;
u32 config2;
u32 config3;
u32 config4;
u32 config5;
u32 config6;
u32 config7;
int is_valid;
};
/*
* Structure to save/restore gpmc context
* to support core off on OMAP3
*/
struct omap3_gpmc_regs {
u32 sysconfig;
u32 irqenable;
u32 timeout_ctrl;
u32 config;
u32 prefetch_config1;
u32 prefetch_config2;
u32 prefetch_control;
struct gpmc_cs_config cs_context[GPMC_CS_NUM];
};
static struct resource gpmc_mem_root;
static struct resource gpmc_cs_mem[GPMC_CS_NUM];
static DEFINE_SPINLOCK(gpmc_mem_lock);
@ -261,7 +288,7 @@ static void gpmc_cs_enable_mem(int cs, u32 base, u32 size)
l = (base >> GPMC_CHUNK_SHIFT) & 0x3f;
l &= ~(0x0f << 8);
l |= ((mask >> GPMC_CHUNK_SHIFT) & 0x0f) << 8;
l |= 1 << 6; /* CSVALID */
l |= GPMC_CONFIG7_CSVALID;
gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l);
}
@ -270,7 +297,7 @@ static void gpmc_cs_disable_mem(int cs)
u32 l;
l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
l &= ~(1 << 6); /* CSVALID */
l &= ~GPMC_CONFIG7_CSVALID;
gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l);
}
@ -290,7 +317,7 @@ static int gpmc_cs_mem_enabled(int cs)
u32 l;
l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
return l & (1 << 6);
return l & GPMC_CONFIG7_CSVALID;
}
int gpmc_cs_set_reserved(int cs, int reserved)
@ -516,3 +543,68 @@ void __init gpmc_init(void)
gpmc_write_reg(GPMC_SYSCONFIG, l);
gpmc_mem_init();
}
#ifdef CONFIG_ARCH_OMAP3
static struct omap3_gpmc_regs gpmc_context;
void omap3_gpmc_save_context()
{
int i;
gpmc_context.sysconfig = gpmc_read_reg(GPMC_SYSCONFIG);
gpmc_context.irqenable = gpmc_read_reg(GPMC_IRQENABLE);
gpmc_context.timeout_ctrl = gpmc_read_reg(GPMC_TIMEOUT_CONTROL);
gpmc_context.config = gpmc_read_reg(GPMC_CONFIG);
gpmc_context.prefetch_config1 = gpmc_read_reg(GPMC_PREFETCH_CONFIG1);
gpmc_context.prefetch_config2 = gpmc_read_reg(GPMC_PREFETCH_CONFIG2);
gpmc_context.prefetch_control = gpmc_read_reg(GPMC_PREFETCH_CONTROL);
for (i = 0; i < GPMC_CS_NUM; i++) {
gpmc_context.cs_context[i].is_valid = gpmc_cs_mem_enabled(i);
if (gpmc_context.cs_context[i].is_valid) {
gpmc_context.cs_context[i].config1 =
gpmc_cs_read_reg(i, GPMC_CS_CONFIG1);
gpmc_context.cs_context[i].config2 =
gpmc_cs_read_reg(i, GPMC_CS_CONFIG2);
gpmc_context.cs_context[i].config3 =
gpmc_cs_read_reg(i, GPMC_CS_CONFIG3);
gpmc_context.cs_context[i].config4 =
gpmc_cs_read_reg(i, GPMC_CS_CONFIG4);
gpmc_context.cs_context[i].config5 =
gpmc_cs_read_reg(i, GPMC_CS_CONFIG5);
gpmc_context.cs_context[i].config6 =
gpmc_cs_read_reg(i, GPMC_CS_CONFIG6);
gpmc_context.cs_context[i].config7 =
gpmc_cs_read_reg(i, GPMC_CS_CONFIG7);
}
}
}
void omap3_gpmc_restore_context()
{
int i;
gpmc_write_reg(GPMC_SYSCONFIG, gpmc_context.sysconfig);
gpmc_write_reg(GPMC_IRQENABLE, gpmc_context.irqenable);
gpmc_write_reg(GPMC_TIMEOUT_CONTROL, gpmc_context.timeout_ctrl);
gpmc_write_reg(GPMC_CONFIG, gpmc_context.config);
gpmc_write_reg(GPMC_PREFETCH_CONFIG1, gpmc_context.prefetch_config1);
gpmc_write_reg(GPMC_PREFETCH_CONFIG2, gpmc_context.prefetch_config2);
gpmc_write_reg(GPMC_PREFETCH_CONTROL, gpmc_context.prefetch_control);
for (i = 0; i < GPMC_CS_NUM; i++) {
if (gpmc_context.cs_context[i].is_valid) {
gpmc_cs_write_reg(i, GPMC_CS_CONFIG1,
gpmc_context.cs_context[i].config1);
gpmc_cs_write_reg(i, GPMC_CS_CONFIG2,
gpmc_context.cs_context[i].config2);
gpmc_cs_write_reg(i, GPMC_CS_CONFIG3,
gpmc_context.cs_context[i].config3);
gpmc_cs_write_reg(i, GPMC_CS_CONFIG4,
gpmc_context.cs_context[i].config4);
gpmc_cs_write_reg(i, GPMC_CS_CONFIG5,
gpmc_context.cs_context[i].config5);
gpmc_cs_write_reg(i, GPMC_CS_CONFIG6,
gpmc_context.cs_context[i].config6);
gpmc_cs_write_reg(i, GPMC_CS_CONFIG7,
gpmc_context.cs_context[i].config7);
}
}
}
#endif /* CONFIG_ARCH_OMAP3 */

View File

@ -25,6 +25,10 @@
#define INTC_SYSSTATUS 0x0014
#define INTC_SIR 0x0040
#define INTC_CONTROL 0x0048
#define INTC_PROTECTION 0x004C
#define INTC_IDLE 0x0050
#define INTC_THRESHOLD 0x0068
#define INTC_MIR0 0x0084
#define INTC_MIR_CLEAR0 0x0088
#define INTC_MIR_SET0 0x008c
#define INTC_PENDING_IRQ0 0x0098
@ -48,6 +52,18 @@ static struct omap_irq_bank {
},
};
/* Structure to save interrupt controller context */
struct omap3_intc_regs {
u32 sysconfig;
u32 protection;
u32 idle;
u32 threshold;
u32 ilr[INTCPS_NR_IRQS];
u32 mir[INTCPS_NR_MIR_REGS];
};
static struct omap3_intc_regs intc_context[ARRAY_SIZE(irq_banks)];
/* INTC bank register get/set */
static void intc_bank_write_reg(u32 val, struct omap_irq_bank *bank, u16 reg)
@ -209,3 +225,53 @@ void __init omap_init_irq(void)
}
}
#ifdef CONFIG_ARCH_OMAP3
void omap_intc_save_context(void)
{
int ind = 0, i = 0;
for (ind = 0; ind < ARRAY_SIZE(irq_banks); ind++) {
struct omap_irq_bank *bank = irq_banks + ind;
intc_context[ind].sysconfig =
intc_bank_read_reg(bank, INTC_SYSCONFIG);
intc_context[ind].protection =
intc_bank_read_reg(bank, INTC_PROTECTION);
intc_context[ind].idle =
intc_bank_read_reg(bank, INTC_IDLE);
intc_context[ind].threshold =
intc_bank_read_reg(bank, INTC_THRESHOLD);
for (i = 0; i < INTCPS_NR_IRQS; i++)
intc_context[ind].ilr[i] =
intc_bank_read_reg(bank, (0x100 + 0x4*i));
for (i = 0; i < INTCPS_NR_MIR_REGS; i++)
intc_context[ind].mir[i] =
intc_bank_read_reg(&irq_banks[0], INTC_MIR0 +
(0x20 * i));
}
}
void omap_intc_restore_context(void)
{
int ind = 0, i = 0;
for (ind = 0; ind < ARRAY_SIZE(irq_banks); ind++) {
struct omap_irq_bank *bank = irq_banks + ind;
intc_bank_write_reg(intc_context[ind].sysconfig,
bank, INTC_SYSCONFIG);
intc_bank_write_reg(intc_context[ind].sysconfig,
bank, INTC_SYSCONFIG);
intc_bank_write_reg(intc_context[ind].protection,
bank, INTC_PROTECTION);
intc_bank_write_reg(intc_context[ind].idle,
bank, INTC_IDLE);
intc_bank_write_reg(intc_context[ind].threshold,
bank, INTC_THRESHOLD);
for (i = 0; i < INTCPS_NR_IRQS; i++)
intc_bank_write_reg(intc_context[ind].ilr[i],
bank, (0x100 + 0x4*i));
for (i = 0; i < INTCPS_NR_MIR_REGS; i++)
intc_bank_write_reg(intc_context[ind].mir[i],
&irq_banks[0], INTC_MIR0 + (0x20 * i));
}
/* MIRs are saved and restore with other PRCM registers */
}
#endif /* CONFIG_ARCH_OMAP3 */

View File

@ -527,6 +527,29 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *dir)
return 0;
}
static int option_get(void *data, u64 *val)
{
u32 *option = data;
*val = *option;
return 0;
}
static int option_set(void *data, u64 val)
{
u32 *option = data;
*option = val;
if (option == &enable_off_mode)
omap3_pm_off_mode_enable(val);
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(pm_dbg_option_fops, option_get, option_set, "%llu\n");
static int __init pm_dbg_init(void)
{
int i;
@ -569,6 +592,12 @@ static int __init pm_dbg_init(void)
}
(void) debugfs_create_file("enable_off_mode", S_IRUGO | S_IWUGO, d,
&enable_off_mode, &pm_dbg_option_fops);
(void) debugfs_create_file("sleep_while_idle", S_IRUGO | S_IWUGO, d,
&sleep_while_idle, &pm_dbg_option_fops);
(void) debugfs_create_file("wakeup_timer_seconds", S_IRUGO | S_IWUGO, d,
&wakeup_timer_seconds, &pm_dbg_option_fops);
pm_dbg_init_done = 1;
return 0;

View File

@ -13,9 +13,18 @@
#include <plat/powerdomain.h>
extern u32 enable_off_mode;
extern u32 sleep_while_idle;
extern void *omap3_secure_ram_storage;
extern void omap3_pm_off_mode_enable(int);
extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm);
extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state);
extern u32 wakeup_timer_seconds;
extern struct omap_dm_timer *gptimer_wakeup;
#ifdef CONFIG_PM_DEBUG
extern void omap2_pm_dump(int mode, int resume, unsigned int us);
extern int omap2_pm_debug;
@ -36,6 +45,7 @@ extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl,
void __iomem *sdrc_power);
extern void omap34xx_cpu_suspend(u32 *addr, int save_state);
extern void save_secure_ram_context(u32 *addr);
extern void omap3_save_scratchpad_contents(void);
extern unsigned int omap24xx_idle_loop_suspend_sz;
extern unsigned int omap34xx_suspend_sz;

View File

@ -5,6 +5,9 @@
* Tony Lindgren <tony@atomide.com>
* Jouni Hogander
*
* Copyright (C) 2007 Texas Instruments, Inc.
* Rajendra Nayak <rnayak@ti.com>
*
* Copyright (C) 2005 Texas Instruments, Inc.
* Richard Woodruff <r-woodruff2@ti.com>
*
@ -22,12 +25,20 @@
#include <linux/list.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/clk.h>
#include <plat/sram.h>
#include <plat/clockdomain.h>
#include <plat/powerdomain.h>
#include <plat/control.h>
#include <plat/serial.h>
#include <plat/sdrc.h>
#include <plat/prcm.h>
#include <plat/gpmc.h>
#include <plat/dma.h>
#include <plat/dmtimer.h>
#include <asm/tlbflush.h>
#include "cm.h"
#include "cm-regbits-34xx.h"
@ -35,6 +46,16 @@
#include "prm.h"
#include "pm.h"
#include "sdrc.h"
/* Scratchpad offsets */
#define OMAP343X_TABLE_ADDRESS_OFFSET 0x31
#define OMAP343X_TABLE_VALUE_OFFSET 0x30
#define OMAP343X_CONTROL_REG_VALUE_OFFSET 0x32
u32 enable_off_mode;
u32 sleep_while_idle;
u32 wakeup_timer_seconds;
struct power_state {
struct powerdomain *pwrdm;
@ -49,7 +70,114 @@ static LIST_HEAD(pwrst_list);
static void (*_omap_sram_idle)(u32 *addr, int save_state);
static struct powerdomain *mpu_pwrdm;
static int (*_omap_save_secure_sram)(u32 *addr);
static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
static struct powerdomain *core_pwrdm, *per_pwrdm;
static struct powerdomain *cam_pwrdm;
static int set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
static inline void omap3_per_save_context(void)
{
omap_gpio_save_context();
}
static inline void omap3_per_restore_context(void)
{
omap_gpio_restore_context();
}
static void omap3_enable_io_chain(void)
{
int timeout = 0;
if (omap_rev() >= OMAP3430_REV_ES3_1) {
prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN, WKUP_MOD, PM_WKEN);
/* Do a readback to assure write has been done */
prm_read_mod_reg(WKUP_MOD, PM_WKEN);
while (!(prm_read_mod_reg(WKUP_MOD, PM_WKST) &
OMAP3430_ST_IO_CHAIN)) {
timeout++;
if (timeout > 1000) {
printk(KERN_ERR "Wake up daisy chain "
"activation failed.\n");
return;
}
prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN,
WKUP_MOD, PM_WKST);
}
}
}
static void omap3_disable_io_chain(void)
{
if (omap_rev() >= OMAP3430_REV_ES3_1)
prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN, WKUP_MOD, PM_WKEN);
}
static void omap3_core_save_context(void)
{
u32 control_padconf_off;
/* Save the padconf registers */
control_padconf_off = omap_ctrl_readl(OMAP343X_CONTROL_PADCONF_OFF);
control_padconf_off |= START_PADCONF_SAVE;
omap_ctrl_writel(control_padconf_off, OMAP343X_CONTROL_PADCONF_OFF);
/* wait for the save to complete */
while (!omap_ctrl_readl(OMAP343X_CONTROL_GENERAL_PURPOSE_STATUS)
& PADCONF_SAVE_DONE)
;
/* Save the Interrupt controller context */
omap_intc_save_context();
/* Save the GPMC context */
omap3_gpmc_save_context();
/* Save the system control module context, padconf already save above*/
omap3_control_save_context();
omap_dma_global_context_save();
}
static void omap3_core_restore_context(void)
{
/* Restore the control module context, padconf restored by h/w */
omap3_control_restore_context();
/* Restore the GPMC context */
omap3_gpmc_restore_context();
/* Restore the interrupt controller context */
omap_intc_restore_context();
omap_dma_global_context_restore();
}
/*
* FIXME: This function should be called before entering off-mode after
* OMAP3 secure services have been accessed. Currently it is only called
* once during boot sequence, but this works as we are not using secure
* services.
*/
static void omap3_save_secure_ram_context(u32 target_mpu_state)
{
u32 ret;
if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
/*
* MPU next state must be set to POWER_ON temporarily,
* otherwise the WFI executed inside the ROM code
* will hang the system.
*/
pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
ret = _omap_save_secure_sram((u32 *)
__pa(omap3_secure_ram_storage));
pwrdm_set_next_pwrst(mpu_pwrdm, target_mpu_state);
/* Following is for error tracking, it should not happen */
if (ret) {
printk(KERN_ERR "save_secure_sram() returns %08x\n",
ret);
while (1)
;
}
}
}
/*
* PRCM Interrupt Handler Helper Function
@ -161,6 +289,35 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
return IRQ_HANDLED;
}
static void restore_control_register(u32 val)
{
__asm__ __volatile__ ("mcr p15, 0, %0, c1, c0, 0" : : "r" (val));
}
/* Function to restore the table entry that was modified for enabling MMU */
static void restore_table_entry(void)
{
u32 *scratchpad_address;
u32 previous_value, control_reg_value;
u32 *address;
scratchpad_address = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD);
/* Get address of entry that was modified */
address = (u32 *)__raw_readl(scratchpad_address +
OMAP343X_TABLE_ADDRESS_OFFSET);
/* Get the previous value which needs to be restored */
previous_value = __raw_readl(scratchpad_address +
OMAP343X_TABLE_VALUE_OFFSET);
address = __va(address);
*address = previous_value;
flush_tlb_all();
control_reg_value = __raw_readl(scratchpad_address
+ OMAP343X_CONTROL_REG_VALUE_OFFSET);
/* This will enable caches and prediction */
restore_control_register(control_reg_value);
}
static void omap_sram_idle(void)
{
/* Variable to tell what needs to be saved and restored
@ -169,17 +326,32 @@ static void omap_sram_idle(void)
/* save_state = 1 => Only L1 and logic lost */
/* save_state = 2 => Only L2 lost */
/* save_state = 3 => L1, L2 and logic lost */
int save_state = 0, mpu_next_state;
int save_state = 0;
int mpu_next_state = PWRDM_POWER_ON;
int per_next_state = PWRDM_POWER_ON;
int core_next_state = PWRDM_POWER_ON;
int core_prev_state, per_prev_state;
u32 sdrc_pwr = 0;
int per_state_modified = 0;
if (!_omap_sram_idle)
return;
pwrdm_clear_all_prev_pwrst(mpu_pwrdm);
pwrdm_clear_all_prev_pwrst(neon_pwrdm);
pwrdm_clear_all_prev_pwrst(core_pwrdm);
pwrdm_clear_all_prev_pwrst(per_pwrdm);
mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
switch (mpu_next_state) {
case PWRDM_POWER_ON:
case PWRDM_POWER_RET:
/* No need to save context */
save_state = 0;
break;
case PWRDM_POWER_OFF:
save_state = 3;
break;
default:
/* Invalid state */
printk(KERN_ERR "Invalid mpu state in sram_idle\n");
@ -187,21 +359,108 @@ static void omap_sram_idle(void)
}
pwrdm_pre_transition();
omap2_gpio_prepare_for_retention();
omap_uart_prepare_idle(0);
omap_uart_prepare_idle(1);
omap_uart_prepare_idle(2);
/* NEON control */
if (pwrdm_read_pwrst(neon_pwrdm) == PWRDM_POWER_ON)
set_pwrdm_state(neon_pwrdm, mpu_next_state);
_omap_sram_idle(NULL, save_state);
/* PER */
per_next_state = pwrdm_read_next_pwrst(per_pwrdm);
core_next_state = pwrdm_read_next_pwrst(core_pwrdm);
if (per_next_state < PWRDM_POWER_ON) {
omap_uart_prepare_idle(2);
omap2_gpio_prepare_for_retention();
if (per_next_state == PWRDM_POWER_OFF) {
if (core_next_state == PWRDM_POWER_ON) {
per_next_state = PWRDM_POWER_RET;
pwrdm_set_next_pwrst(per_pwrdm, per_next_state);
per_state_modified = 1;
} else
omap3_per_save_context();
}
}
if (pwrdm_read_pwrst(cam_pwrdm) == PWRDM_POWER_ON)
omap2_clkdm_deny_idle(mpu_pwrdm->pwrdm_clkdms[0]);
/* CORE */
if (core_next_state < PWRDM_POWER_ON) {
omap_uart_prepare_idle(0);
omap_uart_prepare_idle(1);
if (core_next_state == PWRDM_POWER_OFF) {
omap3_core_save_context();
omap3_prcm_save_context();
}
/* Enable IO-PAD and IO-CHAIN wakeups */
prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN);
omap3_enable_io_chain();
}
/*
* On EMU/HS devices ROM code restores a SRDC value
* from scratchpad which has automatic self refresh on timeout
* of AUTO_CNT = 1 enabled. This takes care of errata 1.142.
* Hence store/restore the SDRC_POWER register here.
*/
if (omap_rev() >= OMAP3430_REV_ES3_0 &&
omap_type() != OMAP2_DEVICE_TYPE_GP &&
core_next_state == PWRDM_POWER_OFF)
sdrc_pwr = sdrc_read_reg(SDRC_POWER);
/*
* omap3_arm_context is the location where ARM registers
* get saved. The restore path then reads from this
* location and restores them back.
*/
_omap_sram_idle(omap3_arm_context, save_state);
cpu_init();
omap_uart_resume_idle(2);
omap_uart_resume_idle(1);
omap_uart_resume_idle(0);
omap2_gpio_resume_after_retention();
/* Restore normal SDRC POWER settings */
if (omap_rev() >= OMAP3430_REV_ES3_0 &&
omap_type() != OMAP2_DEVICE_TYPE_GP &&
core_next_state == PWRDM_POWER_OFF)
sdrc_write_reg(sdrc_pwr, SDRC_POWER);
/* Restore table entry modified during MMU restoration */
if (pwrdm_read_prev_pwrst(mpu_pwrdm) == PWRDM_POWER_OFF)
restore_table_entry();
/* CORE */
if (core_next_state < PWRDM_POWER_ON) {
core_prev_state = pwrdm_read_prev_pwrst(core_pwrdm);
if (core_prev_state == PWRDM_POWER_OFF) {
omap3_core_restore_context();
omap3_prcm_restore_context();
omap3_sram_restore_context();
omap2_sms_restore_context();
}
omap_uart_resume_idle(0);
omap_uart_resume_idle(1);
if (core_next_state == PWRDM_POWER_OFF)
prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF,
OMAP3430_GR_MOD,
OMAP3_PRM_VOLTCTRL_OFFSET);
}
/* PER */
if (per_next_state < PWRDM_POWER_ON) {
per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm);
if (per_prev_state == PWRDM_POWER_OFF)
omap3_per_restore_context();
omap2_gpio_resume_after_retention();
omap_uart_resume_idle(2);
if (per_state_modified)
pwrdm_set_next_pwrst(per_pwrdm, PWRDM_POWER_OFF);
}
/* Disable IO-PAD and IO-CHAIN wakeup */
if (core_next_state < PWRDM_POWER_ON) {
prm_clear_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN);
omap3_disable_io_chain();
}
pwrdm_post_transition();
omap2_clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]);
}
/*
@ -246,6 +505,8 @@ static int omap3_fclks_active(void)
static int omap3_can_sleep(void)
{
if (!sleep_while_idle)
return 0;
if (!omap_uart_can_sleep())
return 0;
if (omap3_fclks_active())
@ -319,6 +580,22 @@ out:
#ifdef CONFIG_SUSPEND
static suspend_state_t suspend_state;
static void omap2_pm_wakeup_on_timer(u32 seconds)
{
u32 tick_rate, cycles;
if (!seconds)
return;
tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup));
cycles = tick_rate * seconds;
omap_dm_timer_stop(gptimer_wakeup);
omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles);
pr_info("PM: Resume timer in %d secs (%d ticks at %d ticks/sec.)\n",
seconds, cycles, tick_rate);
}
static int omap3_pm_prepare(void)
{
disable_hlt();
@ -330,6 +607,9 @@ static int omap3_pm_suspend(void)
struct power_state *pwrst;
int state, ret = 0;
if (wakeup_timer_seconds)
omap2_pm_wakeup_on_timer(wakeup_timer_seconds);
/* Read current next_pwrsts */
list_for_each_entry(pwrst, &pwrst_list, node)
pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm);
@ -690,6 +970,22 @@ static void __init prcm_setup_regs(void)
omap3_d2d_idle();
}
void omap3_pm_off_mode_enable(int enable)
{
struct power_state *pwrst;
u32 state;
if (enable)
state = PWRDM_POWER_OFF;
else
state = PWRDM_POWER_RET;
list_for_each_entry(pwrst, &pwrst_list, node) {
pwrst->next_state = state;
set_pwrdm_state(pwrst->pwrdm, state);
}
}
int omap3_pm_get_suspend_state(struct powerdomain *pwrdm)
{
struct power_state *pwrst;
@ -749,6 +1045,15 @@ static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
return 0;
}
void omap_push_sram_idle(void)
{
_omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend,
omap34xx_cpu_suspend_sz);
if (omap_type() != OMAP2_DEVICE_TYPE_GP)
_omap_save_secure_sram = omap_sram_push(save_secure_ram_context,
save_secure_ram_context_sz);
}
static int __init omap3_pm_init(void)
{
struct power_state *pwrst, *tmp;
@ -786,15 +1091,46 @@ static int __init omap3_pm_init(void)
goto err2;
}
_omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend,
omap34xx_cpu_suspend_sz);
neon_pwrdm = pwrdm_lookup("neon_pwrdm");
per_pwrdm = pwrdm_lookup("per_pwrdm");
core_pwrdm = pwrdm_lookup("core_pwrdm");
cam_pwrdm = pwrdm_lookup("cam_pwrdm");
omap_push_sram_idle();
#ifdef CONFIG_SUSPEND
suspend_set_ops(&omap_pm_ops);
#endif /* CONFIG_SUSPEND */
pm_idle = omap3_pm_idle;
pwrdm_add_wkdep(neon_pwrdm, mpu_pwrdm);
/*
* REVISIT: This wkdep is only necessary when GPIO2-6 are enabled for
* IO-pad wakeup. Otherwise it will unnecessarily waste power
* waking up PER with every CORE wakeup - see
* http://marc.info/?l=linux-omap&m=121852150710062&w=2
*/
pwrdm_add_wkdep(per_pwrdm, core_pwrdm);
if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
omap3_secure_ram_storage =
kmalloc(0x803F, GFP_KERNEL);
if (!omap3_secure_ram_storage)
printk(KERN_ERR "Memory allocation failed when"
"allocating for secure sram context\n");
local_irq_disable();
local_fiq_disable();
omap_dma_global_context_save();
omap3_save_secure_ram_context(PWRDM_POWER_ON);
omap_dma_global_context_restore();
local_irq_enable();
local_fiq_enable();
}
omap3_save_scratchpad_contents();
err1:
return ret;
err2:

View File

@ -338,7 +338,13 @@ static struct powerdomain usbhost_pwrdm = {
.sleepdep_srcs = dss_per_usbhost_sleepdeps,
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRDM_POWER_RET,
.flags = PWRDM_HAS_HDWR_SAR, /* for USBHOST ctrlr only */
/*
* REVISIT: Enabling usb host save and restore mechanism seems to
* leave the usb host domain permanently in ACTIVE mode after
* changing the usb host power domain state from OFF to active once.
* Disabling for now.
*/
/*.flags = PWRDM_HAS_HDWR_SAR,*/ /* for USBHOST ctrlr only */
.banks = 1,
.pwrsts_mem_ret = {
[0] = PWRDM_POWER_RET, /* MEMRETSTATE */

View File

@ -7,6 +7,9 @@
*
* Written by Tony Lindgren <tony.lindgren@nokia.com>
*
* Copyright (C) 2007 Texas Instruments, Inc.
* Rajendra Nayak <rnayak@ti.com>
*
* Some pieces of code Copyright (C) 2005 Texas Instruments, Inc.
*
* This program is free software; you can redistribute it and/or modify
@ -21,8 +24,11 @@
#include <plat/common.h>
#include <plat/prcm.h>
#include <plat/irqs.h>
#include <plat/control.h>
#include "clock.h"
#include "cm.h"
#include "prm.h"
#include "prm-regbits-24xx.h"
@ -31,6 +37,89 @@ static void __iomem *cm_base;
#define MAX_MODULE_ENABLE_WAIT 100000
struct omap3_prcm_regs {
u32 control_padconf_sys_nirq;
u32 iva2_cm_clksel1;
u32 iva2_cm_clksel2;
u32 cm_sysconfig;
u32 sgx_cm_clksel;
u32 wkup_cm_clksel;
u32 dss_cm_clksel;
u32 cam_cm_clksel;
u32 per_cm_clksel;
u32 emu_cm_clksel;
u32 emu_cm_clkstctrl;
u32 pll_cm_autoidle2;
u32 pll_cm_clksel4;
u32 pll_cm_clksel5;
u32 pll_cm_clken;
u32 pll_cm_clken2;
u32 cm_polctrl;
u32 iva2_cm_fclken;
u32 iva2_cm_clken_pll;
u32 core_cm_fclken1;
u32 core_cm_fclken3;
u32 sgx_cm_fclken;
u32 wkup_cm_fclken;
u32 dss_cm_fclken;
u32 cam_cm_fclken;
u32 per_cm_fclken;
u32 usbhost_cm_fclken;
u32 core_cm_iclken1;
u32 core_cm_iclken2;
u32 core_cm_iclken3;
u32 sgx_cm_iclken;
u32 wkup_cm_iclken;
u32 dss_cm_iclken;
u32 cam_cm_iclken;
u32 per_cm_iclken;
u32 usbhost_cm_iclken;
u32 iva2_cm_autiidle2;
u32 mpu_cm_autoidle2;
u32 pll_cm_autoidle;
u32 iva2_cm_clkstctrl;
u32 mpu_cm_clkstctrl;
u32 core_cm_clkstctrl;
u32 sgx_cm_clkstctrl;
u32 dss_cm_clkstctrl;
u32 cam_cm_clkstctrl;
u32 per_cm_clkstctrl;
u32 neon_cm_clkstctrl;
u32 usbhost_cm_clkstctrl;
u32 core_cm_autoidle1;
u32 core_cm_autoidle2;
u32 core_cm_autoidle3;
u32 wkup_cm_autoidle;
u32 dss_cm_autoidle;
u32 cam_cm_autoidle;
u32 per_cm_autoidle;
u32 usbhost_cm_autoidle;
u32 sgx_cm_sleepdep;
u32 dss_cm_sleepdep;
u32 cam_cm_sleepdep;
u32 per_cm_sleepdep;
u32 usbhost_cm_sleepdep;
u32 cm_clkout_ctrl;
u32 prm_clkout_ctrl;
u32 sgx_pm_wkdep;
u32 dss_pm_wkdep;
u32 cam_pm_wkdep;
u32 per_pm_wkdep;
u32 neon_pm_wkdep;
u32 usbhost_pm_wkdep;
u32 core_pm_mpugrpsel1;
u32 iva2_pm_ivagrpsel1;
u32 core_pm_mpugrpsel3;
u32 core_pm_ivagrpsel3;
u32 wkup_pm_mpugrpsel;
u32 wkup_pm_ivagrpsel;
u32 per_pm_mpugrpsel;
u32 per_pm_ivagrpsel;
u32 wkup_pm_wken;
};
struct omap3_prcm_regs prcm_context;
u32 omap_prcm_get_reset_sources(void)
{
/* XXX This presumably needs modification for 34XX */
@ -46,9 +135,18 @@ void omap_prcm_arch_reset(char mode)
if (cpu_is_omap24xx())
prcm_offs = WKUP_MOD;
else if (cpu_is_omap34xx())
else if (cpu_is_omap34xx()) {
u32 l;
prcm_offs = OMAP3430_GR_MOD;
else
l = ('B' << 24) | ('M' << 16) | mode;
/* Reserve the first word in scratchpad for communicating
* with the boot ROM. A pointer to a data structure
* describing the boot process can be stored there,
* cf. OMAP34xx TRM, Initialization / Software Booting
* Configuration. */
omap_writel(l, OMAP343X_SCRATCHPAD + 4);
} else
WARN_ON(1);
prm_set_mod_reg_bits(OMAP_RST_DPLL3, prcm_offs, RM_RSTCTRL);
@ -168,3 +266,308 @@ void __init omap2_set_globals_prcm(struct omap_globals *omap2_globals)
prm_base = omap2_globals->prm;
cm_base = omap2_globals->cm;
}
#ifdef CONFIG_ARCH_OMAP3
void omap3_prcm_save_context(void)
{
prcm_context.control_padconf_sys_nirq =
omap_ctrl_readl(OMAP343X_CONTROL_PADCONF_SYSNIRQ);
prcm_context.iva2_cm_clksel1 =
cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL1);
prcm_context.iva2_cm_clksel2 =
cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL2);
prcm_context.cm_sysconfig = __raw_readl(OMAP3430_CM_SYSCONFIG);
prcm_context.sgx_cm_clksel =
cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_CLKSEL);
prcm_context.wkup_cm_clksel = cm_read_mod_reg(WKUP_MOD, CM_CLKSEL);
prcm_context.dss_cm_clksel =
cm_read_mod_reg(OMAP3430_DSS_MOD, CM_CLKSEL);
prcm_context.cam_cm_clksel =
cm_read_mod_reg(OMAP3430_CAM_MOD, CM_CLKSEL);
prcm_context.per_cm_clksel =
cm_read_mod_reg(OMAP3430_PER_MOD, CM_CLKSEL);
prcm_context.emu_cm_clksel =
cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSEL1);
prcm_context.emu_cm_clkstctrl =
cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSTCTRL);
prcm_context.pll_cm_autoidle2 =
cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE2);
prcm_context.pll_cm_clksel4 =
cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL4);
prcm_context.pll_cm_clksel5 =
cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL5);
prcm_context.pll_cm_clken =
cm_read_mod_reg(PLL_MOD, CM_CLKEN);
prcm_context.pll_cm_clken2 =
cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKEN2);
prcm_context.cm_polctrl = __raw_readl(OMAP3430_CM_POLCTRL);
prcm_context.iva2_cm_fclken =
cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_FCLKEN);
prcm_context.iva2_cm_clken_pll = cm_read_mod_reg(OMAP3430_IVA2_MOD,
OMAP3430_CM_CLKEN_PLL);
prcm_context.core_cm_fclken1 =
cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
prcm_context.core_cm_fclken3 =
cm_read_mod_reg(CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
prcm_context.sgx_cm_fclken =
cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_FCLKEN);
prcm_context.wkup_cm_fclken =
cm_read_mod_reg(WKUP_MOD, CM_FCLKEN);
prcm_context.dss_cm_fclken =
cm_read_mod_reg(OMAP3430_DSS_MOD, CM_FCLKEN);
prcm_context.cam_cm_fclken =
cm_read_mod_reg(OMAP3430_CAM_MOD, CM_FCLKEN);
prcm_context.per_cm_fclken =
cm_read_mod_reg(OMAP3430_PER_MOD, CM_FCLKEN);
prcm_context.usbhost_cm_fclken =
cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN);
prcm_context.core_cm_iclken1 =
cm_read_mod_reg(CORE_MOD, CM_ICLKEN1);
prcm_context.core_cm_iclken2 =
cm_read_mod_reg(CORE_MOD, CM_ICLKEN2);
prcm_context.core_cm_iclken3 =
cm_read_mod_reg(CORE_MOD, CM_ICLKEN3);
prcm_context.sgx_cm_iclken =
cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_ICLKEN);
prcm_context.wkup_cm_iclken =
cm_read_mod_reg(WKUP_MOD, CM_ICLKEN);
prcm_context.dss_cm_iclken =
cm_read_mod_reg(OMAP3430_DSS_MOD, CM_ICLKEN);
prcm_context.cam_cm_iclken =
cm_read_mod_reg(OMAP3430_CAM_MOD, CM_ICLKEN);
prcm_context.per_cm_iclken =
cm_read_mod_reg(OMAP3430_PER_MOD, CM_ICLKEN);
prcm_context.usbhost_cm_iclken =
cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN);
prcm_context.iva2_cm_autiidle2 =
cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_AUTOIDLE2);
prcm_context.mpu_cm_autoidle2 =
cm_read_mod_reg(MPU_MOD, CM_AUTOIDLE2);
prcm_context.pll_cm_autoidle =
cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
prcm_context.iva2_cm_clkstctrl =
cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSTCTRL);
prcm_context.mpu_cm_clkstctrl =
cm_read_mod_reg(MPU_MOD, CM_CLKSTCTRL);
prcm_context.core_cm_clkstctrl =
cm_read_mod_reg(CORE_MOD, CM_CLKSTCTRL);
prcm_context.sgx_cm_clkstctrl =
cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_CLKSTCTRL);
prcm_context.dss_cm_clkstctrl =
cm_read_mod_reg(OMAP3430_DSS_MOD, CM_CLKSTCTRL);
prcm_context.cam_cm_clkstctrl =
cm_read_mod_reg(OMAP3430_CAM_MOD, CM_CLKSTCTRL);
prcm_context.per_cm_clkstctrl =
cm_read_mod_reg(OMAP3430_PER_MOD, CM_CLKSTCTRL);
prcm_context.neon_cm_clkstctrl =
cm_read_mod_reg(OMAP3430_NEON_MOD, CM_CLKSTCTRL);
prcm_context.usbhost_cm_clkstctrl =
cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_CLKSTCTRL);
prcm_context.core_cm_autoidle1 =
cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE1);
prcm_context.core_cm_autoidle2 =
cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE2);
prcm_context.core_cm_autoidle3 =
cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE3);
prcm_context.wkup_cm_autoidle =
cm_read_mod_reg(WKUP_MOD, CM_AUTOIDLE);
prcm_context.dss_cm_autoidle =
cm_read_mod_reg(OMAP3430_DSS_MOD, CM_AUTOIDLE);
prcm_context.cam_cm_autoidle =
cm_read_mod_reg(OMAP3430_CAM_MOD, CM_AUTOIDLE);
prcm_context.per_cm_autoidle =
cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
prcm_context.usbhost_cm_autoidle =
cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE);
prcm_context.sgx_cm_sleepdep =
cm_read_mod_reg(OMAP3430ES2_SGX_MOD, OMAP3430_CM_SLEEPDEP);
prcm_context.dss_cm_sleepdep =
cm_read_mod_reg(OMAP3430_DSS_MOD, OMAP3430_CM_SLEEPDEP);
prcm_context.cam_cm_sleepdep =
cm_read_mod_reg(OMAP3430_CAM_MOD, OMAP3430_CM_SLEEPDEP);
prcm_context.per_cm_sleepdep =
cm_read_mod_reg(OMAP3430_PER_MOD, OMAP3430_CM_SLEEPDEP);
prcm_context.usbhost_cm_sleepdep =
cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, OMAP3430_CM_SLEEPDEP);
prcm_context.cm_clkout_ctrl = cm_read_mod_reg(OMAP3430_CCR_MOD,
OMAP3_CM_CLKOUT_CTRL_OFFSET);
prcm_context.prm_clkout_ctrl = prm_read_mod_reg(OMAP3430_CCR_MOD,
OMAP3_PRM_CLKOUT_CTRL_OFFSET);
prcm_context.sgx_pm_wkdep =
prm_read_mod_reg(OMAP3430ES2_SGX_MOD, PM_WKDEP);
prcm_context.dss_pm_wkdep =
prm_read_mod_reg(OMAP3430_DSS_MOD, PM_WKDEP);
prcm_context.cam_pm_wkdep =
prm_read_mod_reg(OMAP3430_CAM_MOD, PM_WKDEP);
prcm_context.per_pm_wkdep =
prm_read_mod_reg(OMAP3430_PER_MOD, PM_WKDEP);
prcm_context.neon_pm_wkdep =
prm_read_mod_reg(OMAP3430_NEON_MOD, PM_WKDEP);
prcm_context.usbhost_pm_wkdep =
prm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, PM_WKDEP);
prcm_context.core_pm_mpugrpsel1 =
prm_read_mod_reg(CORE_MOD, OMAP3430_PM_MPUGRPSEL1);
prcm_context.iva2_pm_ivagrpsel1 =
prm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP3430_PM_IVAGRPSEL1);
prcm_context.core_pm_mpugrpsel3 =
prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_MPUGRPSEL3);
prcm_context.core_pm_ivagrpsel3 =
prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3);
prcm_context.wkup_pm_mpugrpsel =
prm_read_mod_reg(WKUP_MOD, OMAP3430_PM_MPUGRPSEL);
prcm_context.wkup_pm_ivagrpsel =
prm_read_mod_reg(WKUP_MOD, OMAP3430_PM_IVAGRPSEL);
prcm_context.per_pm_mpugrpsel =
prm_read_mod_reg(OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL);
prcm_context.per_pm_ivagrpsel =
prm_read_mod_reg(OMAP3430_PER_MOD, OMAP3430_PM_IVAGRPSEL);
prcm_context.wkup_pm_wken = prm_read_mod_reg(WKUP_MOD, PM_WKEN);
return;
}
void omap3_prcm_restore_context(void)
{
omap_ctrl_writel(prcm_context.control_padconf_sys_nirq,
OMAP343X_CONTROL_PADCONF_SYSNIRQ);
cm_write_mod_reg(prcm_context.iva2_cm_clksel1, OMAP3430_IVA2_MOD,
CM_CLKSEL1);
cm_write_mod_reg(prcm_context.iva2_cm_clksel2, OMAP3430_IVA2_MOD,
CM_CLKSEL2);
__raw_writel(prcm_context.cm_sysconfig, OMAP3430_CM_SYSCONFIG);
cm_write_mod_reg(prcm_context.sgx_cm_clksel, OMAP3430ES2_SGX_MOD,
CM_CLKSEL);
cm_write_mod_reg(prcm_context.wkup_cm_clksel, WKUP_MOD, CM_CLKSEL);
cm_write_mod_reg(prcm_context.dss_cm_clksel, OMAP3430_DSS_MOD,
CM_CLKSEL);
cm_write_mod_reg(prcm_context.cam_cm_clksel, OMAP3430_CAM_MOD,
CM_CLKSEL);
cm_write_mod_reg(prcm_context.per_cm_clksel, OMAP3430_PER_MOD,
CM_CLKSEL);
cm_write_mod_reg(prcm_context.emu_cm_clksel, OMAP3430_EMU_MOD,
CM_CLKSEL1);
cm_write_mod_reg(prcm_context.emu_cm_clkstctrl, OMAP3430_EMU_MOD,
CM_CLKSTCTRL);
cm_write_mod_reg(prcm_context.pll_cm_autoidle2, PLL_MOD,
CM_AUTOIDLE2);
cm_write_mod_reg(prcm_context.pll_cm_clksel4, PLL_MOD,
OMAP3430ES2_CM_CLKSEL4);
cm_write_mod_reg(prcm_context.pll_cm_clksel5, PLL_MOD,
OMAP3430ES2_CM_CLKSEL5);
cm_write_mod_reg(prcm_context.pll_cm_clken, PLL_MOD, CM_CLKEN);
cm_write_mod_reg(prcm_context.pll_cm_clken2, PLL_MOD,
OMAP3430ES2_CM_CLKEN2);
__raw_writel(prcm_context.cm_polctrl, OMAP3430_CM_POLCTRL);
cm_write_mod_reg(prcm_context.iva2_cm_fclken, OMAP3430_IVA2_MOD,
CM_FCLKEN);
cm_write_mod_reg(prcm_context.iva2_cm_clken_pll, OMAP3430_IVA2_MOD,
OMAP3430_CM_CLKEN_PLL);
cm_write_mod_reg(prcm_context.core_cm_fclken1, CORE_MOD, CM_FCLKEN1);
cm_write_mod_reg(prcm_context.core_cm_fclken3, CORE_MOD,
OMAP3430ES2_CM_FCLKEN3);
cm_write_mod_reg(prcm_context.sgx_cm_fclken, OMAP3430ES2_SGX_MOD,
CM_FCLKEN);
cm_write_mod_reg(prcm_context.wkup_cm_fclken, WKUP_MOD, CM_FCLKEN);
cm_write_mod_reg(prcm_context.dss_cm_fclken, OMAP3430_DSS_MOD,
CM_FCLKEN);
cm_write_mod_reg(prcm_context.cam_cm_fclken, OMAP3430_CAM_MOD,
CM_FCLKEN);
cm_write_mod_reg(prcm_context.per_cm_fclken, OMAP3430_PER_MOD,
CM_FCLKEN);
cm_write_mod_reg(prcm_context.usbhost_cm_fclken,
OMAP3430ES2_USBHOST_MOD, CM_FCLKEN);
cm_write_mod_reg(prcm_context.core_cm_iclken1, CORE_MOD, CM_ICLKEN1);
cm_write_mod_reg(prcm_context.core_cm_iclken2, CORE_MOD, CM_ICLKEN2);
cm_write_mod_reg(prcm_context.core_cm_iclken3, CORE_MOD, CM_ICLKEN3);
cm_write_mod_reg(prcm_context.sgx_cm_iclken, OMAP3430ES2_SGX_MOD,
CM_ICLKEN);
cm_write_mod_reg(prcm_context.wkup_cm_iclken, WKUP_MOD, CM_ICLKEN);
cm_write_mod_reg(prcm_context.dss_cm_iclken, OMAP3430_DSS_MOD,
CM_ICLKEN);
cm_write_mod_reg(prcm_context.cam_cm_iclken, OMAP3430_CAM_MOD,
CM_ICLKEN);
cm_write_mod_reg(prcm_context.per_cm_iclken, OMAP3430_PER_MOD,
CM_ICLKEN);
cm_write_mod_reg(prcm_context.usbhost_cm_iclken,
OMAP3430ES2_USBHOST_MOD, CM_ICLKEN);
cm_write_mod_reg(prcm_context.iva2_cm_autiidle2, OMAP3430_IVA2_MOD,
CM_AUTOIDLE2);
cm_write_mod_reg(prcm_context.mpu_cm_autoidle2, MPU_MOD, CM_AUTOIDLE2);
cm_write_mod_reg(prcm_context.pll_cm_autoidle, PLL_MOD, CM_AUTOIDLE);
cm_write_mod_reg(prcm_context.iva2_cm_clkstctrl, OMAP3430_IVA2_MOD,
CM_CLKSTCTRL);
cm_write_mod_reg(prcm_context.mpu_cm_clkstctrl, MPU_MOD, CM_CLKSTCTRL);
cm_write_mod_reg(prcm_context.core_cm_clkstctrl, CORE_MOD,
CM_CLKSTCTRL);
cm_write_mod_reg(prcm_context.sgx_cm_clkstctrl, OMAP3430ES2_SGX_MOD,
CM_CLKSTCTRL);
cm_write_mod_reg(prcm_context.dss_cm_clkstctrl, OMAP3430_DSS_MOD,
CM_CLKSTCTRL);
cm_write_mod_reg(prcm_context.cam_cm_clkstctrl, OMAP3430_CAM_MOD,
CM_CLKSTCTRL);
cm_write_mod_reg(prcm_context.per_cm_clkstctrl, OMAP3430_PER_MOD,
CM_CLKSTCTRL);
cm_write_mod_reg(prcm_context.neon_cm_clkstctrl, OMAP3430_NEON_MOD,
CM_CLKSTCTRL);
cm_write_mod_reg(prcm_context.usbhost_cm_clkstctrl,
OMAP3430ES2_USBHOST_MOD, CM_CLKSTCTRL);
cm_write_mod_reg(prcm_context.core_cm_autoidle1, CORE_MOD,
CM_AUTOIDLE1);
cm_write_mod_reg(prcm_context.core_cm_autoidle2, CORE_MOD,
CM_AUTOIDLE2);
cm_write_mod_reg(prcm_context.core_cm_autoidle3, CORE_MOD,
CM_AUTOIDLE3);
cm_write_mod_reg(prcm_context.wkup_cm_autoidle, WKUP_MOD, CM_AUTOIDLE);
cm_write_mod_reg(prcm_context.dss_cm_autoidle, OMAP3430_DSS_MOD,
CM_AUTOIDLE);
cm_write_mod_reg(prcm_context.cam_cm_autoidle, OMAP3430_CAM_MOD,
CM_AUTOIDLE);
cm_write_mod_reg(prcm_context.per_cm_autoidle, OMAP3430_PER_MOD,
CM_AUTOIDLE);
cm_write_mod_reg(prcm_context.usbhost_cm_autoidle,
OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE);
cm_write_mod_reg(prcm_context.sgx_cm_sleepdep, OMAP3430ES2_SGX_MOD,
OMAP3430_CM_SLEEPDEP);
cm_write_mod_reg(prcm_context.dss_cm_sleepdep, OMAP3430_DSS_MOD,
OMAP3430_CM_SLEEPDEP);
cm_write_mod_reg(prcm_context.cam_cm_sleepdep, OMAP3430_CAM_MOD,
OMAP3430_CM_SLEEPDEP);
cm_write_mod_reg(prcm_context.per_cm_sleepdep, OMAP3430_PER_MOD,
OMAP3430_CM_SLEEPDEP);
cm_write_mod_reg(prcm_context.usbhost_cm_sleepdep,
OMAP3430ES2_USBHOST_MOD, OMAP3430_CM_SLEEPDEP);
cm_write_mod_reg(prcm_context.cm_clkout_ctrl, OMAP3430_CCR_MOD,
OMAP3_CM_CLKOUT_CTRL_OFFSET);
prm_write_mod_reg(prcm_context.prm_clkout_ctrl, OMAP3430_CCR_MOD,
OMAP3_PRM_CLKOUT_CTRL_OFFSET);
prm_write_mod_reg(prcm_context.sgx_pm_wkdep, OMAP3430ES2_SGX_MOD,
PM_WKDEP);
prm_write_mod_reg(prcm_context.dss_pm_wkdep, OMAP3430_DSS_MOD,
PM_WKDEP);
prm_write_mod_reg(prcm_context.cam_pm_wkdep, OMAP3430_CAM_MOD,
PM_WKDEP);
prm_write_mod_reg(prcm_context.per_pm_wkdep, OMAP3430_PER_MOD,
PM_WKDEP);
prm_write_mod_reg(prcm_context.neon_pm_wkdep, OMAP3430_NEON_MOD,
PM_WKDEP);
prm_write_mod_reg(prcm_context.usbhost_pm_wkdep,
OMAP3430ES2_USBHOST_MOD, PM_WKDEP);
prm_write_mod_reg(prcm_context.core_pm_mpugrpsel1, CORE_MOD,
OMAP3430_PM_MPUGRPSEL1);
prm_write_mod_reg(prcm_context.iva2_pm_ivagrpsel1, OMAP3430_IVA2_MOD,
OMAP3430_PM_IVAGRPSEL1);
prm_write_mod_reg(prcm_context.core_pm_mpugrpsel3, CORE_MOD,
OMAP3430ES2_PM_MPUGRPSEL3);
prm_write_mod_reg(prcm_context.core_pm_ivagrpsel3, CORE_MOD,
OMAP3430ES2_PM_IVAGRPSEL3);
prm_write_mod_reg(prcm_context.wkup_pm_mpugrpsel, WKUP_MOD,
OMAP3430_PM_MPUGRPSEL);
prm_write_mod_reg(prcm_context.wkup_pm_ivagrpsel, WKUP_MOD,
OMAP3430_PM_IVAGRPSEL);
prm_write_mod_reg(prcm_context.per_pm_mpugrpsel, OMAP3430_PER_MOD,
OMAP3430_PM_MPUGRPSEL);
prm_write_mod_reg(prcm_context.per_pm_ivagrpsel, OMAP3430_PER_MOD,
OMAP3430_PM_IVAGRPSEL);
prm_write_mod_reg(prcm_context.wkup_pm_wken, WKUP_MOD, PM_WKEN);
return;
}
#endif

View File

@ -365,6 +365,7 @@
/* PM_PREPWSTST_GFX specific bits */
/* PM_WKEN_WKUP specific bits */
#define OMAP3430_EN_IO_CHAIN (1 << 16)
#define OMAP3430_EN_IO (1 << 8)
#define OMAP3430_EN_GPIO1 (1 << 3)
@ -373,6 +374,7 @@
/* PM_IVA2GRPSEL_WKUP specific bits */
/* PM_WKST_WKUP specific bits */
#define OMAP3430_ST_IO_CHAIN (1 << 16)
#define OMAP3430_ST_IO (1 << 8)
/* PRM_CLKSEL */

View File

@ -37,11 +37,37 @@ static struct omap_sdrc_params *sdrc_init_params_cs0, *sdrc_init_params_cs1;
void __iomem *omap2_sdrc_base;
void __iomem *omap2_sms_base;
struct omap2_sms_regs {
u32 sms_sysconfig;
};
static struct omap2_sms_regs sms_context;
/* SDRC_POWER register bits */
#define SDRC_POWER_EXTCLKDIS_SHIFT 3
#define SDRC_POWER_PWDENA_SHIFT 2
#define SDRC_POWER_PAGEPOLICY_SHIFT 0
/**
* omap2_sms_save_context - Save SMS registers
*
* Save SMS registers that need to be restored after off mode.
*/
void omap2_sms_save_context(void)
{
sms_context.sms_sysconfig = sms_read_reg(SMS_SYSCONFIG);
}
/**
* omap2_sms_restore_context - Restore SMS registers
*
* Restore SMS registers that need to be Restored after off mode.
*/
void omap2_sms_restore_context(void)
{
sms_write_reg(sms_context.sms_sysconfig, SMS_SYSCONFIG);
}
/**
* omap2_sdrc_get_params - return SDRC register values for a given clock rate
* @r: SDRC clock rate (in Hz)
@ -132,4 +158,5 @@ void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
l = (1 << SDRC_POWER_EXTCLKDIS_SHIFT) |
(1 << SDRC_POWER_PAGEPOLICY_SHIFT);
sdrc_write_reg(l, SDRC_POWER);
omap2_sms_save_context();
}

View File

@ -155,8 +155,6 @@ static inline void __init omap_uart_reset(struct omap_uart_state *uart)
#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
static int enable_off_mode; /* to be removed by full off-mode patches */
static void omap_uart_save_context(struct omap_uart_state *uart)
{
u16 lcr = 0;

View File

@ -29,20 +29,33 @@
#include <mach/io.h>
#include <plat/control.h>
#include "cm.h"
#include "prm.h"
#include "sdrc.h"
#define PM_PREPWSTST_CORE_V OMAP34XX_PRM_REGADDR(CORE_MOD, \
OMAP3430_PM_PREPWSTST)
#define PM_PREPWSTST_CORE_P 0x48306AE8
#define PM_PREPWSTST_MPU_V OMAP34XX_PRM_REGADDR(MPU_MOD, \
OMAP3430_PM_PREPWSTST)
#define PM_PWSTCTRL_MPU_P OMAP34XX_PRM_REGADDR(MPU_MOD, PM_PWSTCTRL)
#define PM_PWSTCTRL_MPU_P OMAP3430_PRM_BASE + MPU_MOD + PM_PWSTCTRL
#define CM_IDLEST1_CORE_V OMAP34XX_CM_REGADDR(CORE_MOD, CM_IDLEST1)
#define SRAM_BASE_P 0x40200000
#define CONTROL_STAT 0x480022F0
#define SCRATCHPAD_MEM_OFFS 0x310 /* Move this as correct place is
* available */
#define SCRATCHPAD_BASE_P OMAP343X_CTRL_REGADDR(\
OMAP343X_CONTROL_MEM_WKUP +\
SCRATCHPAD_MEM_OFFS)
#define SCRATCHPAD_BASE_P (OMAP343X_CTRL_BASE + OMAP343X_CONTROL_MEM_WKUP\
+ SCRATCHPAD_MEM_OFFS)
#define SDRC_POWER_V OMAP34XX_SDRC_REGADDR(SDRC_POWER)
#define SDRC_SYSCONFIG_P (OMAP343X_SDRC_BASE + SDRC_SYSCONFIG)
#define SDRC_MR_0_P (OMAP343X_SDRC_BASE + SDRC_MR_0)
#define SDRC_EMR2_0_P (OMAP343X_SDRC_BASE + SDRC_EMR2_0)
#define SDRC_MANUAL_0_P (OMAP343X_SDRC_BASE + SDRC_MANUAL_0)
#define SDRC_MR_1_P (OMAP343X_SDRC_BASE + SDRC_MR_1)
#define SDRC_EMR2_1_P (OMAP343X_SDRC_BASE + SDRC_EMR2_1)
#define SDRC_MANUAL_1_P (OMAP343X_SDRC_BASE + SDRC_MANUAL_1)
#define SDRC_DLLA_STATUS_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS)
#define SDRC_DLLA_CTRL_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL)
.text
/* Function call to get the restore pointer for resume from OFF */
@ -51,7 +64,93 @@ ENTRY(get_restore_pointer)
adr r0, restore
ldmfd sp!, {pc} @ restore regs and return
ENTRY(get_restore_pointer_sz)
.word . - get_restore_pointer_sz
.word . - get_restore_pointer
.text
/* Function call to get the restore pointer for for ES3 to resume from OFF */
ENTRY(get_es3_restore_pointer)
stmfd sp!, {lr} @ save registers on stack
adr r0, restore_es3
ldmfd sp!, {pc} @ restore regs and return
ENTRY(get_es3_restore_pointer_sz)
.word . - get_es3_restore_pointer
ENTRY(es3_sdrc_fix)
ldr r4, sdrc_syscfg @ get config addr
ldr r5, [r4] @ get value
tst r5, #0x100 @ is part access blocked
it eq
biceq r5, r5, #0x100 @ clear bit if set
str r5, [r4] @ write back change
ldr r4, sdrc_mr_0 @ get config addr
ldr r5, [r4] @ get value
str r5, [r4] @ write back change
ldr r4, sdrc_emr2_0 @ get config addr
ldr r5, [r4] @ get value
str r5, [r4] @ write back change
ldr r4, sdrc_manual_0 @ get config addr
mov r5, #0x2 @ autorefresh command
str r5, [r4] @ kick off refreshes
ldr r4, sdrc_mr_1 @ get config addr
ldr r5, [r4] @ get value
str r5, [r4] @ write back change
ldr r4, sdrc_emr2_1 @ get config addr
ldr r5, [r4] @ get value
str r5, [r4] @ write back change
ldr r4, sdrc_manual_1 @ get config addr
mov r5, #0x2 @ autorefresh command
str r5, [r4] @ kick off refreshes
bx lr
sdrc_syscfg:
.word SDRC_SYSCONFIG_P
sdrc_mr_0:
.word SDRC_MR_0_P
sdrc_emr2_0:
.word SDRC_EMR2_0_P
sdrc_manual_0:
.word SDRC_MANUAL_0_P
sdrc_mr_1:
.word SDRC_MR_1_P
sdrc_emr2_1:
.word SDRC_EMR2_1_P
sdrc_manual_1:
.word SDRC_MANUAL_1_P
ENTRY(es3_sdrc_fix_sz)
.word . - es3_sdrc_fix
/* Function to call rom code to save secure ram context */
ENTRY(save_secure_ram_context)
stmfd sp!, {r1-r12, lr} @ save registers on stack
save_secure_ram_debug:
/* b save_secure_ram_debug */ @ enable to debug save code
adr r3, api_params @ r3 points to parameters
str r0, [r3,#0x4] @ r0 has sdram address
ldr r12, high_mask
and r3, r3, r12
ldr r12, sram_phy_addr_mask
orr r3, r3, r12
mov r0, #25 @ set service ID for PPA
mov r12, r0 @ copy secure service ID in r12
mov r1, #0 @ set task id for ROM code in r1
mov r2, #4 @ set some flags in r2, r6
mov r6, #0xff
mcr p15, 0, r0, c7, c10, 4 @ data write barrier
mcr p15, 0, r0, c7, c10, 5 @ data memory barrier
.word 0xE1600071 @ call SMI monitor (smi #1)
nop
nop
nop
nop
ldmfd sp!, {r1-r12, pc}
sram_phy_addr_mask:
.word SRAM_BASE_P
high_mask:
.word 0xffff
api_params:
.word 0x4, 0x0, 0x0, 0x1, 0x1
ENTRY(save_secure_ram_context_sz)
.word . - save_secure_ram_context
/*
* Forces OMAP into idle state
*
@ -92,11 +191,29 @@ loop:
nop
nop
nop
bl i_dll_wait
bl wait_sdrc_ok
ldmfd sp!, {r0-r12, pc} @ restore regs and return
restore_es3:
/*b restore_es3*/ @ Enable to debug restore code
ldr r5, pm_prepwstst_core_p
ldr r4, [r5]
and r4, r4, #0x3
cmp r4, #0x0 @ Check if previous power state of CORE is OFF
bne restore
adr r0, es3_sdrc_fix
ldr r1, sram_base
ldr r2, es3_sdrc_fix_sz
mov r2, r2, ror #2
copy_to_sram:
ldmia r0!, {r3} @ val = *src
stmia r1!, {r3} @ *dst = val
subs r2, r2, #0x1 @ num_words--
bne copy_to_sram
ldr r1, sram_base
blx r1
restore:
/* b restore*/ @ Enable to debug restore code
/* b restore*/ @ Enable to debug restore code
/* Check what was the reason for mpu reset and store the reason in r9*/
/* 1 - Only L1 and logic lost */
/* 2 - Only L2 lost - In this case, we wont be here */
@ -108,9 +225,44 @@ restore:
moveq r9, #0x3 @ MPU OFF => L1 and L2 lost
movne r9, #0x1 @ Only L1 and L2 lost => avoid L2 invalidation
bne logic_l1_restore
ldr r0, control_stat
ldr r1, [r0]
and r1, #0x700
cmp r1, #0x300
beq l2_inv_gp
mov r0, #40 @ set service ID for PPA
mov r12, r0 @ copy secure Service ID in r12
mov r1, #0 @ set task id for ROM code in r1
mov r2, #4 @ set some flags in r2, r6
mov r6, #0xff
adr r3, l2_inv_api_params @ r3 points to dummy parameters
mcr p15, 0, r0, c7, c10, 4 @ data write barrier
mcr p15, 0, r0, c7, c10, 5 @ data memory barrier
.word 0xE1600071 @ call SMI monitor (smi #1)
/* Write to Aux control register to set some bits */
mov r0, #42 @ set service ID for PPA
mov r12, r0 @ copy secure Service ID in r12
mov r1, #0 @ set task id for ROM code in r1
mov r2, #4 @ set some flags in r2, r6
mov r6, #0xff
adr r3, write_aux_control_params @ r3 points to parameters
mcr p15, 0, r0, c7, c10, 4 @ data write barrier
mcr p15, 0, r0, c7, c10, 5 @ data memory barrier
.word 0xE1600071 @ call SMI monitor (smi #1)
b logic_l1_restore
l2_inv_api_params:
.word 0x1, 0x00
write_aux_control_params:
.word 0x1, 0x72
l2_inv_gp:
/* Execute smi to invalidate L2 cache */
mov r12, #0x1 @ set up to invalide L2
smi: .word 0xE1600070 @ Call SMI monitor (smieq)
smi: .word 0xE1600070 @ Call SMI monitor (smieq)
/* Write to Aux control register to set some bits */
mov r0, #0x72
mov r12, #0x3
.word 0xE1600070 @ Call SMI monitor (smieq)
logic_l1_restore:
mov r1, #0
/* Invalidate all instruction caches to PoU
@ -391,33 +543,55 @@ skip_l2_inval:
nop
nop
nop
bl i_dll_wait
bl wait_sdrc_ok
/* restore regs and return */
ldmfd sp!, {r0-r12, pc}
i_dll_wait:
ldr r4, clk_stabilize_delay
/* Make sure SDRC accesses are ok */
wait_sdrc_ok:
ldr r4, cm_idlest1_core
ldr r5, [r4]
and r5, r5, #0x2
cmp r5, #0
bne wait_sdrc_ok
ldr r4, sdrc_power
ldr r5, [r4]
bic r5, r5, #0x40
str r5, [r4]
wait_dll_lock:
/* Is dll in lock mode? */
ldr r4, sdrc_dlla_ctrl
ldr r5, [r4]
tst r5, #0x4
bxne lr
/* wait till dll locks */
ldr r4, sdrc_dlla_status
ldr r5, [r4]
and r5, r5, #0x4
cmp r5, #0x4
bne wait_dll_lock
bx lr
i_dll_delay:
subs r4, r4, #0x1
bne i_dll_delay
ldr r4, sdrc_power
ldr r5, [r4]
bic r5, r5, #0x40
str r5, [r4]
bx lr
cm_idlest1_core:
.word CM_IDLEST1_CORE_V
sdrc_dlla_status:
.word SDRC_DLLA_STATUS_V
sdrc_dlla_ctrl:
.word SDRC_DLLA_CTRL_V
pm_prepwstst_core:
.word PM_PREPWSTST_CORE_V
pm_prepwstst_core_p:
.word PM_PREPWSTST_CORE_P
pm_prepwstst_mpu:
.word PM_PREPWSTST_MPU_V
pm_pwstctrl_mpu:
.word PM_PWSTCTRL_MPU_P
scratchpad_base:
.word SCRATCHPAD_BASE_P
sram_base:
.word SRAM_BASE_P + 0x8000
sdrc_power:
.word SDRC_POWER_V
context_mem:
.word 0x803E3E14
clk_stabilize_delay:
.word 0x000001FF
assoc_mask:
@ -432,5 +606,7 @@ table_entry:
.word 0x00000C02
cache_pred_disable_mask:
.word 0xFFFFE7FB
control_stat:
.word CONTROL_STAT
ENTRY(omap34xx_cpu_suspend_sz)
.word . - omap34xx_cpu_suspend

View File

@ -47,6 +47,7 @@ static struct omap_dm_timer *gptimer;
static struct clock_event_device clockevent_gpt;
static u8 __initdata gptimer_id = 1;
static u8 __initdata inited;
struct omap_dm_timer *gptimer_wakeup;
static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
{
@ -134,6 +135,7 @@ static void __init omap2_gp_clockevent_init(void)
gptimer = omap_dm_timer_request_specific(gptimer_id);
BUG_ON(gptimer == NULL);
gptimer_wakeup = gptimer;
#if defined(CONFIG_OMAP_32K_TIMER)
src = OMAP_TIMER_SRC_32_KHZ;

View File

@ -54,6 +54,12 @@ enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED };
static int enable_1510_mode;
static struct omap_dma_global_context_registers {
u32 dma_irqenable_l0;
u32 dma_ocp_sysconfig;
u32 dma_gcr;
} omap_dma_global_context;
struct omap_dma_lch {
int next_lch;
int dev_id;
@ -2341,6 +2347,39 @@ void omap_stop_lcd_dma(void)
}
EXPORT_SYMBOL(omap_stop_lcd_dma);
void omap_dma_global_context_save(void)
{
omap_dma_global_context.dma_irqenable_l0 =
dma_read(IRQENABLE_L0);
omap_dma_global_context.dma_ocp_sysconfig =
dma_read(OCP_SYSCONFIG);
omap_dma_global_context.dma_gcr = dma_read(GCR);
}
void omap_dma_global_context_restore(void)
{
int ch;
dma_write(omap_dma_global_context.dma_gcr, GCR);
dma_write(omap_dma_global_context.dma_ocp_sysconfig,
OCP_SYSCONFIG);
dma_write(omap_dma_global_context.dma_irqenable_l0,
IRQENABLE_L0);
/*
* A bug in ROM code leaves IRQ status for channels 0 and 1 uncleared
* after secure sram context save and restore. Hence we need to
* manually clear those IRQs to avoid spurious interrupts. This
* affects only secure devices.
*/
if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
dma_write(0x3 , IRQSTATUS_L0);
for (ch = 0; ch < dma_chan_count; ch++)
if (dma_chan[ch].dev_id != -1)
omap_clear_dma(ch);
}
/*----------------------------------------------------------------------------*/
static int __init omap_init_dma(void)
@ -2476,8 +2515,8 @@ static int __init omap_init_dma(void)
setup_irq(irq, &omap24xx_dma_irq);
}
/* Enable smartidle idlemodes and autoidle */
if (cpu_is_omap34xx()) {
/* Enable smartidle idlemodes and autoidle */
u32 v = dma_read(OCP_SYSCONFIG);
v &= ~(DMA_SYSCONFIG_MIDLEMODE_MASK |
DMA_SYSCONFIG_SIDLEMODE_MASK |
@ -2486,6 +2525,13 @@ static int __init omap_init_dma(void)
DMA_SYSCONFIG_SIDLEMODE(DMA_IDLEMODE_SMARTIDLE) |
DMA_SYSCONFIG_AUTOIDLE);
dma_write(v , OCP_SYSCONFIG);
/* reserve dma channels 0 and 1 in high security devices */
if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
printk(KERN_INFO "Reserving DMA channels 0 and 1 for "
"HS ROM code\n");
dma_chan[0].dev_id = 0;
dma_chan[1].dev_id = 1;
}
}

View File

@ -290,6 +290,23 @@ static struct gpio_bank gpio_bank_34xx[6] = {
METHOD_GPIO_24XX },
};
struct omap3_gpio_regs {
u32 sysconfig;
u32 irqenable1;
u32 irqenable2;
u32 wake_en;
u32 ctrl;
u32 oe;
u32 leveldetect0;
u32 leveldetect1;
u32 risingdetect;
u32 fallingdetect;
u32 dataout;
u32 setwkuena;
u32 setdataout;
};
static struct omap3_gpio_regs gpio_context[OMAP34XX_NR_GPIOS];
#endif
#ifdef CONFIG_ARCH_OMAP4
@ -2036,6 +2053,81 @@ void omap2_gpio_resume_after_retention(void)
#endif
#ifdef CONFIG_ARCH_OMAP34XX
/* save the registers of bank 2-6 */
void omap_gpio_save_context(void)
{
int i;
/* saving banks from 2-6 only since GPIO1 is in WKUP */
for (i = 1; i < gpio_bank_count; i++) {
struct gpio_bank *bank = &gpio_bank[i];
gpio_context[i].sysconfig =
__raw_readl(bank->base + OMAP24XX_GPIO_SYSCONFIG);
gpio_context[i].irqenable1 =
__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE1);
gpio_context[i].irqenable2 =
__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE2);
gpio_context[i].wake_en =
__raw_readl(bank->base + OMAP24XX_GPIO_WAKE_EN);
gpio_context[i].ctrl =
__raw_readl(bank->base + OMAP24XX_GPIO_CTRL);
gpio_context[i].oe =
__raw_readl(bank->base + OMAP24XX_GPIO_OE);
gpio_context[i].leveldetect0 =
__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0);
gpio_context[i].leveldetect1 =
__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
gpio_context[i].risingdetect =
__raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT);
gpio_context[i].fallingdetect =
__raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT);
gpio_context[i].dataout =
__raw_readl(bank->base + OMAP24XX_GPIO_DATAOUT);
gpio_context[i].setwkuena =
__raw_readl(bank->base + OMAP24XX_GPIO_SETWKUENA);
gpio_context[i].setdataout =
__raw_readl(bank->base + OMAP24XX_GPIO_SETDATAOUT);
}
}
/* restore the required registers of bank 2-6 */
void omap_gpio_restore_context(void)
{
int i;
for (i = 1; i < gpio_bank_count; i++) {
struct gpio_bank *bank = &gpio_bank[i];
__raw_writel(gpio_context[i].sysconfig,
bank->base + OMAP24XX_GPIO_SYSCONFIG);
__raw_writel(gpio_context[i].irqenable1,
bank->base + OMAP24XX_GPIO_IRQENABLE1);
__raw_writel(gpio_context[i].irqenable2,
bank->base + OMAP24XX_GPIO_IRQENABLE2);
__raw_writel(gpio_context[i].wake_en,
bank->base + OMAP24XX_GPIO_WAKE_EN);
__raw_writel(gpio_context[i].ctrl,
bank->base + OMAP24XX_GPIO_CTRL);
__raw_writel(gpio_context[i].oe,
bank->base + OMAP24XX_GPIO_OE);
__raw_writel(gpio_context[i].leveldetect0,
bank->base + OMAP24XX_GPIO_LEVELDETECT0);
__raw_writel(gpio_context[i].leveldetect1,
bank->base + OMAP24XX_GPIO_LEVELDETECT1);
__raw_writel(gpio_context[i].risingdetect,
bank->base + OMAP24XX_GPIO_RISINGDETECT);
__raw_writel(gpio_context[i].fallingdetect,
bank->base + OMAP24XX_GPIO_FALLINGDETECT);
__raw_writel(gpio_context[i].dataout,
bank->base + OMAP24XX_GPIO_DATAOUT);
__raw_writel(gpio_context[i].setwkuena,
bank->base + OMAP24XX_GPIO_SETWKUENA);
__raw_writel(gpio_context[i].setdataout,
bank->base + OMAP24XX_GPIO_SETDATAOUT);
}
}
#endif
/*
* This may get called early from board specific init
* for boards that have interrupts routed via FPGA.

View File

@ -112,6 +112,8 @@
#define OMAP24XX_CONTROL_TEST_KEY_8 (OMAP2_CONTROL_GENERAL + 0x00e0)
#define OMAP24XX_CONTROL_TEST_KEY_9 (OMAP2_CONTROL_GENERAL + 0x00e4)
#define OMAP343X_CONTROL_PADCONF_SYSNIRQ (OMAP2_CONTROL_INTERFACE + 0x01b0)
/* 34xx-only CONTROL_GENERAL register offsets */
#define OMAP343X_CONTROL_PADCONF_OFF (OMAP2_CONTROL_GENERAL + 0x0000)
#define OMAP343X_CONTROL_MEM_DFTRW0 (OMAP2_CONTROL_GENERAL + 0x0008)
@ -144,8 +146,51 @@
#define OMAP343X_CONTROL_TEST_KEY_13 (OMAP2_CONTROL_GENERAL + 0x00fc)
#define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190)
#define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194)
#define OMAP343X_CONTROL_PBIAS_LITE (OMAP2_CONTROL_GENERAL + 0x02b0)
#define OMAP343X_CONTROL_TEMP_SENSOR (OMAP2_CONTROL_GENERAL + 0x02b4)
#define OMAP343X_CONTROL_DEBOBS(i) (OMAP2_CONTROL_GENERAL + 0x01B0 \
+ ((i) >> 1) * 4 + (!(i) & 1) * 2)
#define OMAP343X_CONTROL_PROG_IO0 (OMAP2_CONTROL_GENERAL + 0x01D4)
#define OMAP343X_CONTROL_PROG_IO1 (OMAP2_CONTROL_GENERAL + 0x01D8)
#define OMAP343X_CONTROL_DSS_DPLL_SPREADING (OMAP2_CONTROL_GENERAL + 0x01E0)
#define OMAP343X_CONTROL_CORE_DPLL_SPREADING (OMAP2_CONTROL_GENERAL + 0x01E4)
#define OMAP343X_CONTROL_PER_DPLL_SPREADING (OMAP2_CONTROL_GENERAL + 0x01E8)
#define OMAP343X_CONTROL_USBHOST_DPLL_SPREADING (OMAP2_CONTROL_GENERAL + 0x01EC)
#define OMAP343X_CONTROL_PBIAS_LITE (OMAP2_CONTROL_GENERAL + 0x02B0)
#define OMAP343X_CONTROL_TEMP_SENSOR (OMAP2_CONTROL_GENERAL + 0x02B4)
#define OMAP343X_CONTROL_SRAMLDO4 (OMAP2_CONTROL_GENERAL + 0x02B8)
#define OMAP343X_CONTROL_SRAMLDO5 (OMAP2_CONTROL_GENERAL + 0x02C0)
#define OMAP343X_CONTROL_CSI (OMAP2_CONTROL_GENERAL + 0x02C4)
/* 34xx PADCONF register offsets */
#define OMAP343X_PADCONF_ETK(i) (OMAP2_CONTROL_PADCONFS + 0x5a8 + \
(i)*2)
#define OMAP343X_PADCONF_ETK_CLK OMAP343X_PADCONF_ETK(0)
#define OMAP343X_PADCONF_ETK_CTL OMAP343X_PADCONF_ETK(1)
#define OMAP343X_PADCONF_ETK_D0 OMAP343X_PADCONF_ETK(2)
#define OMAP343X_PADCONF_ETK_D1 OMAP343X_PADCONF_ETK(3)
#define OMAP343X_PADCONF_ETK_D2 OMAP343X_PADCONF_ETK(4)
#define OMAP343X_PADCONF_ETK_D3 OMAP343X_PADCONF_ETK(5)
#define OMAP343X_PADCONF_ETK_D4 OMAP343X_PADCONF_ETK(6)
#define OMAP343X_PADCONF_ETK_D5 OMAP343X_PADCONF_ETK(7)
#define OMAP343X_PADCONF_ETK_D6 OMAP343X_PADCONF_ETK(8)
#define OMAP343X_PADCONF_ETK_D7 OMAP343X_PADCONF_ETK(9)
#define OMAP343X_PADCONF_ETK_D8 OMAP343X_PADCONF_ETK(10)
#define OMAP343X_PADCONF_ETK_D9 OMAP343X_PADCONF_ETK(11)
#define OMAP343X_PADCONF_ETK_D10 OMAP343X_PADCONF_ETK(12)
#define OMAP343X_PADCONF_ETK_D11 OMAP343X_PADCONF_ETK(13)
#define OMAP343X_PADCONF_ETK_D12 OMAP343X_PADCONF_ETK(14)
#define OMAP343X_PADCONF_ETK_D13 OMAP343X_PADCONF_ETK(15)
#define OMAP343X_PADCONF_ETK_D14 OMAP343X_PADCONF_ETK(16)
#define OMAP343X_PADCONF_ETK_D15 OMAP343X_PADCONF_ETK(17)
/* 34xx GENERAL_WKUP regist offsets */
#define OMAP343X_CONTROL_WKUP_DEBOBSMUX(i) (OMAP343X_CONTROL_GENERAL_WKUP + \
0x008 + (i))
#define OMAP343X_CONTROL_WKUP_DEBOBS0 (OMAP343X_CONTROL_GENERAL_WKUP + 0x008)
#define OMAP343X_CONTROL_WKUP_DEBOBS1 (OMAP343X_CONTROL_GENERAL_WKUP + 0x00C)
#define OMAP343X_CONTROL_WKUP_DEBOBS2 (OMAP343X_CONTROL_GENERAL_WKUP + 0x010)
#define OMAP343X_CONTROL_WKUP_DEBOBS3 (OMAP343X_CONTROL_GENERAL_WKUP + 0x014)
#define OMAP343X_CONTROL_WKUP_DEBOBS4 (OMAP343X_CONTROL_GENERAL_WKUP + 0x018)
/* 34xx D2D idle-related pins, handled by PM core */
#define OMAP3_PADCONF_SAD2D_MSTANDBY 0x250
@ -205,6 +250,10 @@
#define OMAP3_PADCONF_WAKEUPEVENT0 (1 << 15)
#define OMAP3_PADCONF_WAKEUPENABLE0 (1 << 14)
#define OMAP343X_SCRATCHPAD_ROM (OMAP343X_CTRL_BASE + 0x860)
#define OMAP343X_SCRATCHPAD (OMAP343X_CTRL_BASE + 0x910)
#define OMAP343X_SCRATCHPAD_ROM_OFFSET 0x19C
#ifndef __ASSEMBLY__
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
defined(CONFIG_ARCH_OMAP4)
@ -215,6 +264,15 @@ extern u32 omap_ctrl_readl(u16 offset);
extern void omap_ctrl_writeb(u8 val, u16 offset);
extern void omap_ctrl_writew(u16 val, u16 offset);
extern void omap_ctrl_writel(u32 val, u16 offset);
extern void omap3_save_scratchpad_contents(void);
extern void omap3_clear_scratchpad_contents(void);
extern u32 *get_restore_pointer(void);
extern u32 *get_es3_restore_pointer(void);
extern u32 omap3_arm_context[128];
extern void omap3_control_save_context(void);
extern void omap3_control_restore_context(void);
#else
#define omap_ctrl_base_get() 0
#define omap_ctrl_readb(x) 0

View File

@ -633,6 +633,11 @@ extern void omap_set_dma_dst_endian_type(int lch, enum end_type etype);
extern void omap_set_dma_src_endian_type(int lch, enum end_type etype);
extern int omap_get_dma_index(int lch, int *ei, int *fi);
void omap_dma_global_context_save(void);
void omap_dma_global_context_restore(void);
extern void omap_dma_disable_irq(int lch);
/* Chaining APIs */
#ifndef CONFIG_ARCH_OMAP1
extern int omap_request_dma_chain(int dev_id, const char *dev_name,

View File

@ -76,7 +76,8 @@ extern void omap2_gpio_prepare_for_retention(void);
extern void omap2_gpio_resume_after_retention(void);
extern void omap_set_gpio_debounce(int gpio, int enable);
extern void omap_set_gpio_debounce_time(int gpio, int enable);
extern void omap_gpio_save_context(void);
extern void omap_gpio_restore_context(void);
/*-------------------------------------------------------------------------*/
/* Wrappers for "new style" GPIO calls, using the new infrastructure

View File

@ -52,6 +52,7 @@
#define GPMC_CONFIG1_FCLK_DIV2 (GPMC_CONFIG1_FCLK_DIV(1))
#define GPMC_CONFIG1_FCLK_DIV3 (GPMC_CONFIG1_FCLK_DIV(2))
#define GPMC_CONFIG1_FCLK_DIV4 (GPMC_CONFIG1_FCLK_DIV(3))
#define GPMC_CONFIG7_CSVALID (1 << 6)
/*
* Note that all values in this struct are in nanoseconds, while
@ -107,6 +108,8 @@ extern int gpmc_prefetch_enable(int cs, int dma_mode,
unsigned int u32_count, int is_write);
extern void gpmc_prefetch_reset(void);
extern int gpmc_prefetch_status(void);
extern void omap3_gpmc_save_context(void);
extern void omap3_gpmc_restore_context(void);
extern void __init gpmc_init(void);
#endif

View File

@ -477,9 +477,14 @@
#define OMAP_IRQ_BIT(irq) (1 << ((irq) % 32))
#define INTCPS_NR_MIR_REGS 3
#define INTCPS_NR_IRQS 96
#ifndef __ASSEMBLY__
extern void omap_init_irq(void);
extern int omap_irq_pending(void);
void omap_intc_save_context(void);
void omap_intc_restore_context(void);
#endif
#include <mach/hardware.h>

View File

@ -27,9 +27,13 @@ u32 omap_prcm_get_reset_sources(void);
void omap_prcm_arch_reset(char mode);
int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, const char *name);
#define START_PADCONF_SAVE 0x2
#define PADCONF_SAVE_DONE 0x1
void omap3_prcm_save_context(void);
void omap3_prcm_restore_context(void);
#endif

View File

@ -44,6 +44,12 @@
#define SDRC_RFR_CTRL_1 0x0D4
#define SDRC_MANUAL_1 0x0D8
#define SDRC_POWER_AUTOCOUNT_SHIFT 8
#define SDRC_POWER_AUTOCOUNT_MASK (0xffff << SDRC_POWER_AUTOCOUNT_SHIFT)
#define SDRC_POWER_CLKCTRL_SHIFT 4
#define SDRC_POWER_CLKCTRL_MASK (0x3 << SDRC_POWER_CLKCTRL_SHIFT)
#define SDRC_SELF_REFRESH_ON_AUTOCOUNT (0x2 << SDRC_POWER_CLKCTRL_SHIFT)
/*
* These values represent the number of memory clock cycles between
* autorefresh initiation. They assume 1 refresh per 64 ms (JEDEC), 8192
@ -120,6 +126,8 @@ void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
int omap2_sdrc_get_params(unsigned long r,
struct omap_sdrc_params **sdrc_cs0,
struct omap_sdrc_params **sdrc_cs1);
void omap2_sms_save_context(void);
void omap2_sms_restore_context(void);
#ifdef CONFIG_ARCH_OMAP2

View File

@ -27,6 +27,7 @@ extern u32 omap3_configure_core_dpll(
u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0,
u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1,
u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1);
extern void omap3_sram_restore_context(void);
/* Do not use these */
extern void omap1_sram_reprogram_clock(u32 ckctl, u32 dpllctl);
@ -68,4 +69,10 @@ extern u32 omap3_sram_configure_core_dpll(
u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1);
extern unsigned long omap3_sram_configure_core_dpll_sz;
#ifdef CONFIG_PM
extern void omap_push_sram_idle(void);
#else
static inline void omap_push_sram_idle(void) {}
#endif /* CONFIG_PM */
#endif

View File

@ -396,22 +396,24 @@ u32 omap3_configure_core_dpll(u32 m2, u32 unlock_dll, u32 f, u32 inc,
sdrc_actim_ctrl_b_1, sdrc_mr_1);
}
/* REVISIT: Should this be same as omap34xx_sram_init() after off-idle? */
void restore_sram_functions(void)
#ifdef CONFIG_PM
void omap3_sram_restore_context(void)
{
omap_sram_ceil = omap_sram_base + omap_sram_size;
_omap3_sram_configure_core_dpll =
omap_sram_push(omap3_sram_configure_core_dpll,
omap3_sram_configure_core_dpll_sz);
omap_push_sram_idle();
}
#endif /* CONFIG_PM */
int __init omap34xx_sram_init(void)
{
_omap3_sram_configure_core_dpll =
omap_sram_push(omap3_sram_configure_core_dpll,
omap3_sram_configure_core_dpll_sz);
omap_push_sram_idle();
return 0;
}
#else