linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/32] OMAP3: PM: base off-mode support
@ 2009-10-22 23:09 Kevin Hilman
  2009-10-22 23:09 ` [PATCH v2 01/32] OMAP3: PM: GPMC context save/restore Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

This series adds the base off-mode support to the OMAP3 PM core.
The code originates from the OMAP PM branch[1] and has been tested
broadly on a variety of OMAP3 platforms.

It is currently based on Tony's for-next branch since it depends
on the IO address space rework series and the omap-headers rework

This series is also available in the branch 'pm-upstream/pm-off' in
my linux-omap-pm git repo at
git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm.git

Differences from v1
- Added descriptive changelogs to all patches
- Incorporated a handful of smaller off-mode fixups from PM branch

Kevin

Aaro Koskinen (2):
  OMAP: PM: Clear DMA channel state after a wakeup
  OMAP3: PM: Fix INTC context save/restore

Jouni Hogander (1):
  OMAP3: PM: Save and restore also CM_CLKSEL1_PLL_IVA2

Juha Yrjola (1):
  OMAP: Store reboot mode in scratchpad on OMAP34xx

Kalle Jokiniemi (5):
  OMAP3: PM: Fix secure SRAM context save/restore
  ARM: OMAP: SMS: save/restore of SMS_SYSCONFIG for off-mode
  OMAP3: PM: Fix PLL_MOD CLKEN offset in scratchpad
  PM: Disable usb host HW save and restore
  OMAP3: PM: Enable IO-CHAIN wakeup

Kevin Hilman (3):
  OMAP3: PM debug: allow runtime toggle of PM features
  PM debug: allow configurable wakeup from suspend on OMAP GPtimer
  OMAP3: PM: decouple PER and CORE context save and restore

Peter 'p2' De Schrijver (1):
  OMAP3: PM: Wait for SDRC ready iso a blind delay

Rajendra Nayak (12):
  OMAP3: PM: GPMC context save/restore
  OMAP3: PM: GPIO context save/restore
  OMAP3: PM: INTC context save/restore
  OMAP3: PM: PRCM context save/restore
  OMAP3: PM: Populate scratchpad contents
  OMAP3: PM: SCM context save/restore
  OMAP3: PM: restore SRAM functions after off-mode.
  OMAP3: PM: handle PER/NEON/CORE in idle
  OMAP3: PM: Restore MMU table entry
  OMAP3: PM: MPU off-mode support
  OMAP3: PM: CORE domain off-mode support
  OMAP3: PM: Program SDRC to send self refresh on timeout of AUTO_CNT

Tero Kristo (7):
  OMAP: PM: DMA context save/restore for off-mode support
  OMAP3 PM: off-mode support for HS/EMU devices
  OMAP3: PM: save secure RAM only during init
  OMAP3: PM: Enable SDRAM auto-refresh during sleep
  OMAP3: PM: SDRC auto-refresh workaround for off-mode
  OMAP3: PM: Prevent PER from going OFF when CORE is going INA
  OMAP3: PM: MPU and CORE should stay awake if there is CAM domain
    ACTIVE

 arch/arm/mach-omap2/control.c             |  381 +++++++++++++++++++++++++++
 arch/arm/mach-omap2/gpmc.c                |   98 +++++++-
 arch/arm/mach-omap2/irq.c                 |   66 +++++
 arch/arm/mach-omap2/pm-debug.c            |   29 ++
 arch/arm/mach-omap2/pm.h                  |   10 +
 arch/arm/mach-omap2/pm34xx.c              |  362 +++++++++++++++++++++++++-
 arch/arm/mach-omap2/powerdomains34xx.h    |    8 +-
 arch/arm/mach-omap2/prcm.c                |  407 ++++++++++++++++++++++++++++-
 arch/arm/mach-omap2/prm-regbits-34xx.h    |    2 +
 arch/arm/mach-omap2/sdrc.c                |   27 ++
 arch/arm/mach-omap2/serial.c              |    2 -
 arch/arm/mach-omap2/sleep34xx.S           |  218 ++++++++++++++--
 arch/arm/mach-omap2/timer-gp.c            |    2 +
 arch/arm/plat-omap/dma.c                  |   62 +++++-
 arch/arm/plat-omap/gpio.c                 |   92 +++++++
 arch/arm/plat-omap/include/plat/control.h |   61 +++++-
 arch/arm/plat-omap/include/plat/dma.h     |    5 +
 arch/arm/plat-omap/include/plat/gpio.h    |    3 +-
 arch/arm/plat-omap/include/plat/gpmc.h    |    3 +
 arch/arm/plat-omap/include/plat/irqs.h    |    5 +
 arch/arm/plat-omap/include/plat/prcm.h    |    6 +-
 arch/arm/plat-omap/include/plat/sdrc.h    |    8 +
 arch/arm/plat-omap/include/plat/sram.h    |    7 +
 arch/arm/plat-omap/sram.c                 |    8 +-
 24 files changed, 1822 insertions(+), 50 deletions(-)
 mode change 100644 => 100755 arch/arm/plat-omap/include/plat/dma.h

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v2 01/32] OMAP3: PM: GPMC context save/restore
  2009-10-22 23:09 [PATCH v2 00/32] OMAP3: PM: base off-mode support Kevin Hilman
@ 2009-10-22 23:09 ` Kevin Hilman
  2009-10-22 23:09   ` [PATCH v2 02/32] OMAP3: PM: GPIO " Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rajendra Nayak <rnayak@ti.com>

This patch adds the context save and restore functions for GPMC to
enable off-mode.

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/gpmc.c             |   98 +++++++++++++++++++++++++++++++-
 arch/arm/plat-omap/include/plat/gpmc.h |    3 +
 2 files changed, 98 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 004da69..7d68784 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -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 */
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
index 9c99cda..696e0ca 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -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
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 02/32] OMAP3: PM: GPIO context save/restore
  2009-10-22 23:09 ` [PATCH v2 01/32] OMAP3: PM: GPMC context save/restore Kevin Hilman
@ 2009-10-22 23:09   ` Kevin Hilman
  2009-10-22 23:09     ` [PATCH v2 03/32] OMAP3: PM: INTC " Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rajendra Nayak <rnayak@ti.com>

Add context save and restore to enable off-mode.

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/plat-omap/gpio.c              |   92 ++++++++++++++++++++++++++++++++
 arch/arm/plat-omap/include/plat/gpio.h |    3 +-
 2 files changed, 94 insertions(+), 1 deletions(-)

diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 487bea7..4f81ea3 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -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.
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index 633ff68..de7c547 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -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
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 03/32] OMAP3: PM: INTC context save/restore
  2009-10-22 23:09   ` [PATCH v2 02/32] OMAP3: PM: GPIO " Kevin Hilman
@ 2009-10-22 23:09     ` Kevin Hilman
  2009-10-22 23:09       ` [PATCH v2 04/32] OMAP3: PM: PRCM " Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rajendra Nayak <rnayak@ti.com>

Add context save and restore for the INTC module to support off-mode.

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/irq.c              |   66 ++++++++++++++++++++++++++++++++
 arch/arm/plat-omap/include/plat/irqs.h |    5 ++
 2 files changed, 71 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index 1db121f..ebd3538 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -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*ind));
+		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*ind));
+		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 */
diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h
index 6a6d028..ce5dd2d 100644
--- a/arch/arm/plat-omap/include/plat/irqs.h
+++ b/arch/arm/plat-omap/include/plat/irqs.h
@@ -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>
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 04/32] OMAP3: PM: PRCM context save/restore
  2009-10-22 23:09     ` [PATCH v2 03/32] OMAP3: PM: INTC " Kevin Hilman
@ 2009-10-22 23:09       ` Kevin Hilman
  2009-10-22 23:09         ` [PATCH v2 05/32] OMAP3: PM: Populate scratchpad contents Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rajendra Nayak <rnayak@ti.com>

Add context save and restore for PRCM module to support off-mode.
Additional registers (CM_CLKSEL4, CM_CLKEN, CM_CLKEN2) added by Tero
Kristo.

Missing CM_CLKEN_PLL_IVA2 register added by Kalle Jokiniemi.

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
Signed-off-by: Kalle Jokiniemi <kalle.jokiniemi@digia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/prcm.c                |  389 +++++++++++++++++++++++++++++
 arch/arm/plat-omap/include/plat/control.h |    2 +
 arch/arm/plat-omap/include/plat/prcm.h    |    6 +-
 3 files changed, 396 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c
index b0d3ad0..56f77df 100644
--- a/arch/arm/mach-omap2/prcm.c
+++ b/arch/arm/mach-omap2/prcm.c
@@ -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,88 @@ static void __iomem *cm_base;
 
 #define MAX_MODULE_ENABLE_WAIT		100000
 
+struct omap3_prcm_regs {
+	u32 control_padconf_sys_nirq;
+	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 */
@@ -168,3 +256,304 @@ 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_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_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
diff --git a/arch/arm/plat-omap/include/plat/control.h b/arch/arm/plat-omap/include/plat/control.h
index fdb6300..3cdfe31 100644
--- a/arch/arm/plat-omap/include/plat/control.h
+++ b/arch/arm/plat-omap/include/plat/control.h
@@ -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)
diff --git a/arch/arm/plat-omap/include/plat/prcm.h b/arch/arm/plat-omap/include/plat/prcm.h
index cda2a70..e63e94e 100644
--- a/arch/arm/plat-omap/include/plat/prcm.h
+++ b/arch/arm/plat-omap/include/plat/prcm.h
@@ -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);
 
-#endif
+#define START_PADCONF_SAVE 0x2
+#define PADCONF_SAVE_DONE  0x1
 
+void omap3_prcm_save_context(void);
+void omap3_prcm_restore_context(void);
 
+#endif
 
 
 
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 05/32] OMAP3: PM: Populate scratchpad contents
  2009-10-22 23:09       ` [PATCH v2 04/32] OMAP3: PM: PRCM " Kevin Hilman
@ 2009-10-22 23:09         ` Kevin Hilman
  2009-10-22 23:09           ` [PATCH v2 06/32] OMAP3: PM: SCM context save/restore Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rajendra Nayak <rnayak@ti.com>

This patch populates the scratchpad contents as expected by the
bootROM code.

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/control.c             |  203 +++++++++++++++++++++++++++++
 arch/arm/plat-omap/include/plat/control.h |    9 ++
 2 files changed, 212 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index 6adb360..03e1bce 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -17,9 +17,81 @@
 
 #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;
 
+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;
+};
+
+/*
+ * 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];
+
 #define OMAP_CTRL_REGADDR(reg)		(omap2_ctrl_base + (reg))
 
 void __init omap2_set_globals_control(struct omap_globals *omap2_globals)
@@ -62,3 +134,134 @@ void omap_ctrl_writel(u32 val, u16 offset)
 	__raw_writel(val, OMAP_CTRL_REGADDR(offset));
 }
 
+#ifdef CONFIG_ARCH_OMAP3
+/*
+ * 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;
+	scratchpad_contents.public_restore_ptr =
+			 virt_to_phys(get_restore_pointer());
+	scratchpad_contents.secure_ram_restore_ptr = 0x0;
+	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, OMAP3430_CM_CLKEN_PLL);
+	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;
+	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);
+}
+
+#endif /* CONFIG_ARCH_OMAP3 */
diff --git a/arch/arm/plat-omap/include/plat/control.h b/arch/arm/plat-omap/include/plat/control.h
index 3cdfe31..7297829 100644
--- a/arch/arm/plat-omap/include/plat/control.h
+++ b/arch/arm/plat-omap/include/plat/control.h
@@ -240,6 +240,9 @@
 #define		FEAT_NEON		0
 #define		FEAT_NEON_NONE		1
 
+#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) || \
@@ -251,6 +254,12 @@ 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 omap3_arm_context[128];
+
 #else
 #define omap_ctrl_base_get()		0
 #define omap_ctrl_readb(x)		0
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 06/32] OMAP3: PM: SCM context save/restore
  2009-10-22 23:09         ` [PATCH v2 05/32] OMAP3: PM: Populate scratchpad contents Kevin Hilman
@ 2009-10-22 23:09           ` Kevin Hilman
  2009-10-22 23:09             ` [PATCH v2 07/32] OMAP3: PM: restore SRAM functions after off-mode Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rajendra Nayak <rnayak@ti.com>

Add context save and restore for the System Control Module to suport
off-mode.

ETK and debobs definitions added by Peter De Schrijver.

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/control.c             |  157 ++++++++++++++++++++++++++++-
 arch/arm/plat-omap/include/plat/control.h |   49 +++++++++-
 2 files changed, 202 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index 03e1bce..3ea417d 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -26,6 +26,7 @@
 
 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;
@@ -92,6 +93,47 @@ struct omap3_scratchpad_sdrc_block {
  */
 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)
@@ -134,7 +176,7 @@ void omap_ctrl_writel(u32 val, u16 offset)
 	__raw_writel(val, OMAP_CTRL_REGADDR(offset));
 }
 
-#ifdef CONFIG_ARCH_OMAP3
+#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
 /*
  * Clears the scratchpad contents in case of cold boot-
  * called during bootup
@@ -264,4 +306,115 @@ void omap3_save_scratchpad_contents(void)
 		sizeof(sdrc_block_contents), &arm_context_addr, 4);
 }
 
-#endif /* CONFIG_ARCH_OMAP3 */
+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 */
diff --git a/arch/arm/plat-omap/include/plat/control.h b/arch/arm/plat-omap/include/plat/control.h
index 7297829..0308e3f 100644
--- a/arch/arm/plat-omap/include/plat/control.h
+++ b/arch/arm/plat-omap/include/plat/control.h
@@ -146,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
@@ -259,6 +302,8 @@ extern void omap3_save_scratchpad_contents(void);
 extern void omap3_clear_scratchpad_contents(void);
 extern u32 *get_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
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 07/32] OMAP3: PM: restore SRAM functions after off-mode.
  2009-10-22 23:09           ` [PATCH v2 06/32] OMAP3: PM: SCM context save/restore Kevin Hilman
@ 2009-10-22 23:09             ` Kevin Hilman
  2009-10-22 23:09               ` [PATCH v2 08/32] OMAP3: PM: handle PER/NEON/CORE in idle Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rajendra Nayak <rnayak@ti.com>

Generalize the copy of SRAM functions into omap_push_sram_idle()
so it can be used on init but also after off-mode transitions.

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/pm34xx.c           |   10 +++++++---
 arch/arm/plat-omap/include/plat/sram.h |    6 ++++++
 arch/arm/plat-omap/sram.c              |    8 +++++---
 3 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 3910549..b88da1b 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -749,6 +749,12 @@ 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);
+}
+
 static int __init omap3_pm_init(void)
 {
 	struct power_state *pwrst, *tmp;
@@ -786,9 +792,7 @@ static int __init omap3_pm_init(void)
 		goto err2;
 	}
 
-	_omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend,
-					 omap34xx_cpu_suspend_sz);
-
+	omap_push_sram_idle();
 #ifdef CONFIG_SUSPEND
 	suspend_set_ops(&omap_pm_ops);
 #endif /* CONFIG_SUSPEND */
diff --git a/arch/arm/plat-omap/include/plat/sram.h b/arch/arm/plat-omap/include/plat/sram.h
index 8974e3f..77799d5 100644
--- a/arch/arm/plat-omap/include/plat/sram.h
+++ b/arch/arm/plat-omap/include/plat/sram.h
@@ -68,4 +68,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
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index a53aa85..3e92366 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -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
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 08/32] OMAP3: PM: handle PER/NEON/CORE in idle
  2009-10-22 23:09             ` [PATCH v2 07/32] OMAP3: PM: restore SRAM functions after off-mode Kevin Hilman
@ 2009-10-22 23:09               ` Kevin Hilman
  2009-10-22 23:09                 ` [PATCH v2 09/32] OMAP3: PM: Restore MMU table entry Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rajendra Nayak <rnayak@ti.com>

Expand the powerdomains handled in the idle path to include PER, NEON
and CORE.  This includes properly clearing the previous powerstates,
linking NEON state to MPU state and calling the UART prepare functions
for only the appropraite powerdomain transitions (CORE for UART1,2,
PER for UART3.)

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/pm34xx.c |   64 +++++++++++++++++++++++++++++++++++------
 1 files changed, 54 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index b88da1b..05ee05f 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -49,7 +49,10 @@ static LIST_HEAD(pwrst_list);
 
 static void (*_omap_sram_idle)(u32 *addr, int save_state);
 
-static struct powerdomain *mpu_pwrdm;
+static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
+static struct powerdomain *core_pwrdm, *per_pwrdm;
+
+static int set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
 
 /*
  * PRCM Interrupt Handler Helper Function
@@ -169,13 +172,22 @@ 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;
 
 	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;
@@ -187,18 +199,37 @@ 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);
+
+	/* CORE & PER */
+	core_next_state = pwrdm_read_next_pwrst(core_pwrdm);
+	if (core_next_state < PWRDM_POWER_ON) {
+		omap2_gpio_prepare_for_retention();
+		omap_uart_prepare_idle(0);
+		omap_uart_prepare_idle(1);
+		/* PER changes only with core */
+		per_next_state = pwrdm_read_next_pwrst(per_pwrdm);
+		if (per_next_state < PWRDM_POWER_ON)
+			omap_uart_prepare_idle(2);
+		/* Enable IO-PAD wakeup */
+		prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN);
+	}
 
 	_omap_sram_idle(NULL, save_state);
 	cpu_init();
 
-	omap_uart_resume_idle(2);
-	omap_uart_resume_idle(1);
-	omap_uart_resume_idle(0);
-	omap2_gpio_resume_after_retention();
+	if (core_next_state < PWRDM_POWER_ON) {
+		if (per_next_state < PWRDM_POWER_ON)
+			omap_uart_resume_idle(2);
+		omap_uart_resume_idle(1);
+		omap_uart_resume_idle(0);
+
+		/* Disable IO-PAD wakeup */
+		prm_clear_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN);
+		omap2_gpio_resume_after_retention();
+	}
 
 	pwrdm_post_transition();
 
@@ -792,6 +823,10 @@ static int __init omap3_pm_init(void)
 		goto err2;
 	}
 
+	neon_pwrdm = pwrdm_lookup("neon_pwrdm");
+	per_pwrdm = pwrdm_lookup("per_pwrdm");
+	core_pwrdm = pwrdm_lookup("core_pwrdm");
+
 	omap_push_sram_idle();
 #ifdef CONFIG_SUSPEND
 	suspend_set_ops(&omap_pm_ops);
@@ -799,6 +834,15 @@ static int __init omap3_pm_init(void)
 
 	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);
+
 err1:
 	return ret;
 err2:
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 09/32] OMAP3: PM: Restore MMU table entry
  2009-10-22 23:09               ` [PATCH v2 08/32] OMAP3: PM: handle PER/NEON/CORE in idle Kevin Hilman
@ 2009-10-22 23:09                 ` Kevin Hilman
  2009-10-22 23:09                   ` [PATCH v2 10/32] OMAP3: PM: MPU off-mode support Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rajendra Nayak <rnayak@ti.com>

During the MMU restoration on the restore path from MPU OFF, the page
table entry for the page consisting of the code being executed is
modified to make MMU return VA=PA.

The MMU is then enabled and the original entry is being stored in
scratchpad.  This patch reads the original values stored in
scratchpad, and restores them back.

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/pm34xx.c |   35 +++++++++++++++++++++++++++++++++++
 1 files changed, 35 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 05ee05f..8b5bf91 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -29,6 +29,8 @@
 #include <plat/control.h>
 #include <plat/serial.h>
 
+#include <asm/tlbflush.h>
+
 #include "cm.h"
 #include "cm-regbits-34xx.h"
 #include "prm-regbits-34xx.h"
@@ -164,6 +166,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
@@ -220,6 +251,10 @@ static void omap_sram_idle(void)
 	_omap_sram_idle(NULL, save_state);
 	cpu_init();
 
+	/* Restore table entry modified during MMU restoration */
+	if (pwrdm_read_prev_pwrst(mpu_pwrdm) == PWRDM_POWER_OFF)
+		restore_table_entry();
+
 	if (core_next_state < PWRDM_POWER_ON) {
 		if (per_next_state < PWRDM_POWER_ON)
 			omap_uart_resume_idle(2);
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 10/32] OMAP3: PM: MPU off-mode support
  2009-10-22 23:09                 ` [PATCH v2 09/32] OMAP3: PM: Restore MMU table entry Kevin Hilman
@ 2009-10-22 23:09                   ` Kevin Hilman
  2009-10-22 23:09                     ` [PATCH v2 11/32] OMAP3: PM: CORE domain " Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rajendra Nayak <rnayak@ti.com>

Adds a 'save_state' option when calling into SRAM idle function
and adds some minor cleanups of SRAM asm code.

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/pm34xx.c    |   11 ++++++++++-
 arch/arm/mach-omap2/sleep34xx.S |   11 ++++-------
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 8b5bf91..9fb0876 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -28,6 +28,7 @@
 #include <plat/powerdomain.h>
 #include <plat/control.h>
 #include <plat/serial.h>
+#include <plat/sdrc.h>
 
 #include <asm/tlbflush.h>
 
@@ -223,6 +224,9 @@ static void omap_sram_idle(void)
 		/* 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");
@@ -248,7 +252,12 @@ static void omap_sram_idle(void)
 		prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN);
 	}
 
-	_omap_sram_idle(NULL, save_state);
+	/*
+	 * 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();
 
 	/* Restore table entry modified during MMU restoration */
diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
index 6a749f2..f8d3834 100644
--- a/arch/arm/mach-omap2/sleep34xx.S
+++ b/arch/arm/mach-omap2/sleep34xx.S
@@ -36,12 +36,11 @@
 				OMAP3430_PM_PREPWSTST)
 #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 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)
 
 	.text
@@ -96,7 +95,7 @@ loop:
 
 	ldmfd	sp!, {r0-r12, pc}		@ restore regs and return
 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 */
@@ -416,8 +415,6 @@ scratchpad_base:
 	.word	SCRATCHPAD_BASE_P
 sdrc_power:
 	.word SDRC_POWER_V
-context_mem:
-	.word	0x803E3E14
 clk_stabilize_delay:
 	.word 0x000001FF
 assoc_mask:
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 11/32] OMAP3: PM: CORE domain off-mode support
  2009-10-22 23:09                   ` [PATCH v2 10/32] OMAP3: PM: MPU off-mode support Kevin Hilman
@ 2009-10-22 23:09                     ` Kevin Hilman
  2009-10-22 23:09                       ` [PATCH v2 12/32] OMAP: PM: DMA context save/restore for " Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rajendra Nayak <rnayak@ti.com>

Add context save and restore for CORE powerdomain resources in order
to support off-mode.

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/pm34xx.c           |   73 +++++++++++++++++++++++++++++++-
 arch/arm/plat-omap/include/plat/sram.h |    1 +
 2 files changed, 73 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 9fb0876..bab9b48 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -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>
  *
@@ -29,6 +32,8 @@
 #include <plat/control.h>
 #include <plat/serial.h>
 #include <plat/sdrc.h>
+#include <plat/prcm.h>
+#include <plat/gpmc.h>
 
 #include <asm/tlbflush.h>
 
@@ -39,6 +44,11 @@
 #include "prm.h"
 #include "pm.h"
 
+/* Scratchpad offsets */
+#define OMAP343X_TABLE_ADDRESS_OFFSET	   0x31
+#define OMAP343X_TABLE_VALUE_OFFSET	   0x30
+#define OMAP343X_CONTROL_REG_VALUE_OFFSET  0x32
+
 struct power_state {
 	struct powerdomain *pwrdm;
 	u32 next_state;
@@ -57,6 +67,46 @@ static struct powerdomain *core_pwrdm, *per_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_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();
+}
+
+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();
+}
+
 /*
  * PRCM Interrupt Handler Helper Function
  *
@@ -208,6 +258,7 @@ static void omap_sram_idle(void)
 	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;
 
 	if (!_omap_sram_idle)
 		return;
@@ -246,8 +297,15 @@ static void omap_sram_idle(void)
 		omap_uart_prepare_idle(1);
 		/* PER changes only with core */
 		per_next_state = pwrdm_read_next_pwrst(per_pwrdm);
-		if (per_next_state < PWRDM_POWER_ON)
+		if (per_next_state < PWRDM_POWER_ON) {
 			omap_uart_prepare_idle(2);
+			if (per_next_state == PWRDM_POWER_OFF)
+				omap3_per_save_context();
+		}
+		if (core_next_state == PWRDM_POWER_OFF) {
+			omap3_core_save_context();
+			omap3_prcm_save_context();
+		}
 		/* Enable IO-PAD wakeup */
 		prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN);
 	}
@@ -272,6 +330,18 @@ static void omap_sram_idle(void)
 
 		/* Disable IO-PAD wakeup */
 		prm_clear_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN);
+		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();
+		}
+		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();
 	}
 
@@ -843,6 +913,7 @@ static int __init omap3_pm_init(void)
 	/* XXX prcm_setup_regs needs to be before enabling hw
 	 * supervised mode for powerdomains */
 	prcm_setup_regs();
+	omap3_save_scratchpad_contents();
 
 	ret = request_irq(INT_34XX_PRCM_MPU_IRQ,
 			  (irq_handler_t)prcm_interrupt_handler,
diff --git a/arch/arm/plat-omap/include/plat/sram.h b/arch/arm/plat-omap/include/plat/sram.h
index 77799d5..16a1b45 100644
--- a/arch/arm/plat-omap/include/plat/sram.h
+++ b/arch/arm/plat-omap/include/plat/sram.h
@@ -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);
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 12/32] OMAP: PM: DMA context save/restore for off-mode support
  2009-10-22 23:09                     ` [PATCH v2 11/32] OMAP3: PM: CORE domain " Kevin Hilman
@ 2009-10-22 23:09                       ` Kevin Hilman
  2009-10-22 23:09                         ` [PATCH v2 13/32] OMAP3 PM: off-mode support for HS/EMU devices Kevin Hilman
                                           ` (2 more replies)
  0 siblings, 3 replies; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Tero Kristo <tero.kristo@nokia.com>

For HS/EMU devices, these additional features are also used:

- DMA interrupt disable routine added
- Added DMA controller reset to DMA context restore

Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/pm34xx.c          |    3 ++
 arch/arm/plat-omap/dma.c              |   41 +++++++++++++++++++++++++++++++++
 arch/arm/plat-omap/include/plat/dma.h |    5 ++++
 3 files changed, 49 insertions(+), 0 deletions(-)
 mode change 100644 => 100755 arch/arm/plat-omap/include/plat/dma.h

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index bab9b48..54fea79 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -34,6 +34,7 @@
 #include <plat/sdrc.h>
 #include <plat/prcm.h>
 #include <plat/gpmc.h>
+#include <plat/dma.h>
 
 #include <asm/tlbflush.h>
 
@@ -95,6 +96,7 @@ static void omap3_core_save_context(void)
 	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)
@@ -105,6 +107,7 @@ static void omap3_core_restore_context(void)
 	omap3_gpmc_restore_context();
 	/* Restore the interrupt controller context */
 	omap_intc_restore_context();
+	omap_dma_global_context_restore();
 }
 
 /*
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 3edffde..c0a6060 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -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,41 @@ 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);
+}
+EXPORT_SYMBOL(omap_dma_global_context_save);
+
+void omap_dma_global_context_restore(void)
+{
+	dma_write(0x2, OCP_SYSCONFIG);
+	while (!__raw_readl(omap_dma_base + OMAP_DMA4_SYSSTATUS))
+		;
+	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);
+}
+EXPORT_SYMBOL(omap_dma_global_context_restore);
+
+void omap_dma_disable_irq(int lch)
+{
+	u32 val;
+
+	if (cpu_class_is_omap2()) {
+		/* Disable interrupts */
+		val = dma_read(IRQENABLE_L0);
+		val &= ~(1 << lch);
+		dma_write(val, IRQENABLE_L0);
+	}
+}
+
 /*----------------------------------------------------------------------------*/
 
 static int __init omap_init_dma(void)
diff --git a/arch/arm/plat-omap/include/plat/dma.h b/arch/arm/plat-omap/include/plat/dma.h
old mode 100644
new mode 100755
index 72f680b..1c017b2
--- a/arch/arm/plat-omap/include/plat/dma.h
+++ b/arch/arm/plat-omap/include/plat/dma.h
@@ -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,
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 13/32] OMAP3 PM: off-mode support for HS/EMU devices
  2009-10-22 23:09                       ` [PATCH v2 12/32] OMAP: PM: DMA context save/restore for " Kevin Hilman
@ 2009-10-22 23:09                         ` Kevin Hilman
  2009-10-22 23:09                           ` [PATCH v2 14/32] OMAP3: PM: save secure RAM only during init Kevin Hilman
  2009-10-23  8:32                         ` [PATCH v2 12/32] OMAP: PM: DMA context save/restore for off-mode support Grazvydas Ignotas
  2009-10-23 13:54                         ` Venkatraman S
  2 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Tero Kristo <tero.kristo@nokia.com>

For HS/EMU devices, some additional resources need to be
saved/restored for off-mode support.  Namely, saving the secure RAM
and a pointer to it in the scratchpad.

Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/control.c   |    8 ++++-
 arch/arm/mach-omap2/pm.h        |    3 ++
 arch/arm/mach-omap2/pm34xx.c    |   43 ++++++++++++++++++++++-
 arch/arm/mach-omap2/sleep34xx.S |   75 ++++++++++++++++++++++++++++++++++++++-
 4 files changed, 126 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index 3ea417d..b84cff7 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -85,6 +85,8 @@ struct omap3_scratchpad_sdrc_block {
 	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.
@@ -209,7 +211,11 @@ void omap3_save_scratchpad_contents(void)
 	scratchpad_contents.boot_config_ptr = 0x0;
 	scratchpad_contents.public_restore_ptr =
 			 virt_to_phys(get_restore_pointer());
-	scratchpad_contents.secure_ram_restore_ptr = 0x0;
+	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;
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 85b6fac..45cafac 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -13,6 +13,8 @@
 
 #include <plat/powerdomain.h>
 
+extern void *omap3_secure_ram_storage;
+
 extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm);
 extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state);
 
@@ -36,6 +38,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;
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 54fea79..ebb88f3 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -63,6 +63,8 @@ static LIST_HEAD(pwrst_list);
 
 static void (*_omap_sram_idle)(u32 *addr, int save_state);
 
+static int (*_omap_save_secure_sram)(u32 *addr);
+
 static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
 static struct powerdomain *core_pwrdm, *per_pwrdm;
 
@@ -110,6 +112,33 @@ static void omap3_core_restore_context(void)
 	omap_dma_global_context_restore();
 }
 
+static void omap3_save_secure_ram_context(u32 target_mpu_state)
+{
+	u32 ret;
+
+	if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
+		/* Disable dma irq before calling secure rom code API */
+		omap_dma_disable_irq(0);
+		omap_dma_disable_irq(1);
+		/*
+		 * 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
  *
@@ -308,6 +337,7 @@ static void omap_sram_idle(void)
 		if (core_next_state == PWRDM_POWER_OFF) {
 			omap3_core_save_context();
 			omap3_prcm_save_context();
+			omap3_save_secure_ram_context(mpu_next_state);
 		}
 		/* Enable IO-PAD wakeup */
 		prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN);
@@ -901,6 +931,9 @@ 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)
@@ -916,7 +949,6 @@ static int __init omap3_pm_init(void)
 	/* XXX prcm_setup_regs needs to be before enabling hw
 	 * supervised mode for powerdomains */
 	prcm_setup_regs();
-	omap3_save_scratchpad_contents();
 
 	ret = request_irq(INT_34XX_PRCM_MPU_IRQ,
 			  (irq_handler_t)prcm_interrupt_handler,
@@ -961,6 +993,15 @@ static int __init omap3_pm_init(void)
 	*/
 	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");
+	}
+	omap3_save_scratchpad_contents();
+
 err1:
 	return ret;
 err2:
diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
index f8d3834..db75167 100644
--- a/arch/arm/mach-omap2/sleep34xx.S
+++ b/arch/arm/mach-omap2/sleep34xx.S
@@ -37,6 +37,8 @@
 #define PM_PREPWSTST_MPU_V	OMAP34XX_PRM_REGADDR(MPU_MOD, \
 				OMAP3430_PM_PREPWSTST)
 #define PM_PWSTCTRL_MPU_P	OMAP3430_PRM_BASE + MPU_MOD + PM_PWSTCTRL
+#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_BASE + OMAP343X_CONTROL_MEM_WKUP\
@@ -51,6 +53,40 @@ ENTRY(get_restore_pointer)
         ldmfd   sp!, {pc}     @ restore regs and return
 ENTRY(get_restore_pointer_sz)
         .word   . - get_restore_pointer_sz
+
+/* 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, #7			@ 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
  *
@@ -107,9 +143,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
@@ -429,5 +500,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
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 14/32] OMAP3: PM: save secure RAM only during init
  2009-10-22 23:09                         ` [PATCH v2 13/32] OMAP3 PM: off-mode support for HS/EMU devices Kevin Hilman
@ 2009-10-22 23:09                           ` Kevin Hilman
  2009-10-22 23:09                             ` [PATCH v2 15/32] OMAP3: PM: Enable SDRAM auto-refresh during sleep Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Tero Kristo <tero.kristo@nokia.com>

The function omap3_save_secure_ram() is now called only once during
the initialization of the device and consequent sleep cycles will
re-use the same saved contents for secure RAM. Users who need secure
services should do secure RAM saving before entering off-mode, if a
secure service has been accessed after last save.

There are both latency and reliability issues with saving secure RAM
context in the idle path. The context save uses a hardware resource
which takes an order of hundreds of milliseconds to initialize after a
wake up from off-mode, and also there is no way of checking whether it
is ready from kernel side or not. It just crashes if you use it too
quickly

Additional fix to ensure scratchpad save is done after secure
RAM by Roger Quadros.

Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
Signed-off-by: Roger Quadros <ext-roger.quadros@nokia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/pm34xx.c |   19 +++++++++++++++++--
 1 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index ebb88f3..310c189 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -112,6 +112,12 @@ static void omap3_core_restore_context(void)
 	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;
@@ -337,7 +343,6 @@ static void omap_sram_idle(void)
 		if (core_next_state == PWRDM_POWER_OFF) {
 			omap3_core_save_context();
 			omap3_prcm_save_context();
-			omap3_save_secure_ram_context(mpu_next_state);
 		}
 		/* Enable IO-PAD wakeup */
 		prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN);
@@ -999,9 +1004,19 @@ static int __init omap3_pm_init(void)
 		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();
 
+	omap3_save_scratchpad_contents();
 err1:
 	return ret;
 err2:
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 15/32] OMAP3: PM: Enable SDRAM auto-refresh during sleep
  2009-10-22 23:09                           ` [PATCH v2 14/32] OMAP3: PM: save secure RAM only during init Kevin Hilman
@ 2009-10-22 23:09                             ` Kevin Hilman
  2009-10-22 23:09                               ` [PATCH v2 16/32] OMAP3: PM: Save and restore also CM_CLKSEL1_PLL_IVA2 Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Tero Kristo <tero.kristo@nokia.com>

Fix for ES3.0 bug: SDRC not sending auto-refresh when OMAP wakes-up
from OFF mode (warning for HS devices.)

Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/pm34xx.c |   29 +++++++++++++++++++++++++++++
 1 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 310c189..3f1f656 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -44,6 +44,13 @@
 
 #include "prm.h"
 #include "pm.h"
+#include "sdrc.h"
+
+#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)
 
 /* Scratchpad offsets */
 #define OMAP343X_TABLE_ADDRESS_OFFSET	   0x31
@@ -297,6 +304,7 @@ static void omap_sram_idle(void)
 	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;
 
 	if (!_omap_sram_idle)
 		return;
@@ -349,6 +357,21 @@ static void omap_sram_idle(void)
 	}
 
 	/*
+	 * Force SDRAM controller to self-refresh mode after timeout on
+	 * autocount. This is needed on ES3.0 to avoid SDRAM controller
+	 * hang-ups.
+	 */
+	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);
+		sdrc_write_reg((sdrc_pwr &
+			~(SDRC_POWER_AUTOCOUNT_MASK|SDRC_POWER_CLKCTRL_MASK)) |
+			(1 << SDRC_POWER_AUTOCOUNT_SHIFT) |
+			SDRC_SELF_REFRESH_ON_AUTOCOUNT, 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.
@@ -356,6 +379,12 @@ static void omap_sram_idle(void)
 	_omap_sram_idle(omap3_arm_context, save_state);
 	cpu_init();
 
+	/* Restore normal SDRAM 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();
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 16/32] OMAP3: PM: Save and restore also CM_CLKSEL1_PLL_IVA2
  2009-10-22 23:09                             ` [PATCH v2 15/32] OMAP3: PM: Enable SDRAM auto-refresh during sleep Kevin Hilman
@ 2009-10-22 23:09                               ` Kevin Hilman
  2009-10-22 23:09                                 ` [PATCH v2 17/32] OMAP3: PM: Fix secure SRAM context save/restore Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jouni Hogander <jouni.hogander@nokia.com>

CM_CLKSEL1_PLL_IVA2 is not saved/restored currently. This patch is
adding save and restore for it.

Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/prcm.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c
index 56f77df..221eed1 100644
--- a/arch/arm/mach-omap2/prcm.c
+++ b/arch/arm/mach-omap2/prcm.c
@@ -39,6 +39,7 @@ static void __iomem *cm_base;
 
 struct omap3_prcm_regs {
 	u32 control_padconf_sys_nirq;
+	u32 iva2_cm_clksel1;
 	u32 iva2_cm_clksel2;
 	u32 cm_sysconfig;
 	u32 sgx_cm_clksel;
@@ -262,6 +263,8 @@ 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);
@@ -417,6 +420,8 @@ 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);
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 17/32] OMAP3: PM: Fix secure SRAM context save/restore
  2009-10-22 23:09                               ` [PATCH v2 16/32] OMAP3: PM: Save and restore also CM_CLKSEL1_PLL_IVA2 Kevin Hilman
@ 2009-10-22 23:09                                 ` Kevin Hilman
  2009-10-22 23:09                                   ` [PATCH v2 18/32] ARM: OMAP: SMS: save/restore of SMS_SYSCONFIG for off-mode Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Kalle Jokiniemi <kalle.jokiniemi@digia.com>

The secure sram context save uses dma channels 0 and 1.
In order to avoid collision between kernel DMA transfers and
ROM code dma transfers, we need to reserve DMA channels 0
1 on high security devices.

A bug in ROM code leaves dma irq status bits uncleared.
Hence those irq status bits need to be cleared when restoring
DMA context after off mode.

There was also a faulty parameter given to PPA in the secure
ram context save assembly code, which caused interrupts to
be enabled during secure ram context save. This caused the
save to fail sometimes, which resulted the saved context
to be corrupted, but also left DMA channels in secure mode.
The secure mode DMA channels caused "DMA secure error with
device 0" errors to be displayed.

Signed-off-by: Kalle Jokiniemi <kalle.jokiniemi@digia.com>
Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/pm34xx.c    |    3 ---
 arch/arm/mach-omap2/sleep34xx.S |    2 +-
 arch/arm/plat-omap/dma.c        |   21 +++++++++++++++++----
 3 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 3f1f656..a9f4034 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -130,9 +130,6 @@ static void omap3_save_secure_ram_context(u32 target_mpu_state)
 	u32 ret;
 
 	if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
-		/* Disable dma irq before calling secure rom code API */
-		omap_dma_disable_irq(0);
-		omap_dma_disable_irq(1);
 		/*
 		 * MPU next state must be set to POWER_ON temporarily,
 		 * otherwise the WFI executed inside the ROM code
diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
index db75167..b6abadc 100644
--- a/arch/arm/mach-omap2/sleep34xx.S
+++ b/arch/arm/mach-omap2/sleep34xx.S
@@ -68,7 +68,7 @@ save_secure_ram_debug:
 	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, #7			@ set some flags in r2, r6
+	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
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index c0a6060..3b91fd3 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -2359,14 +2359,20 @@ EXPORT_SYMBOL(omap_dma_global_context_save);
 
 void omap_dma_global_context_restore(void)
 {
-	dma_write(0x2, OCP_SYSCONFIG);
-	while (!__raw_readl(omap_dma_base + OMAP_DMA4_SYSSTATUS))
-		;
 	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);
 }
 EXPORT_SYMBOL(omap_dma_global_context_restore);
 
@@ -2517,8 +2523,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 |
@@ -2527,6 +2533,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;
+		}
 	}
 
 
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 18/32] ARM: OMAP: SMS: save/restore of SMS_SYSCONFIG for off-mode
  2009-10-22 23:09                                 ` [PATCH v2 17/32] OMAP3: PM: Fix secure SRAM context save/restore Kevin Hilman
@ 2009-10-22 23:09                                   ` Kevin Hilman
  2009-10-22 23:09                                     ` [PATCH v2 19/32] OMAP3: PM: Fix PLL_MOD CLKEN offset in scratchpad Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Kalle Jokiniemi <kalle.jokiniemi@digia.com>

The SMS_SYSCONFIG register gets reset in off mode, added a
save/restore mechanism for that.

Signed-off-by: Kalle Jokiniemi <kalle.jokiniemi@digia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/pm34xx.c           |    1 +
 arch/arm/mach-omap2/sdrc.c             |   27 +++++++++++++++++++++++++++
 arch/arm/plat-omap/include/plat/sdrc.h |    2 ++
 3 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index a9f4034..90d1dc5 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -399,6 +399,7 @@ static void omap_sram_idle(void)
 			omap3_core_restore_context();
 			omap3_prcm_restore_context();
 			omap3_sram_restore_context();
+			omap2_sms_restore_context();
 		}
 		if (per_next_state < PWRDM_POWER_ON) {
 			per_prev_state =
diff --git a/arch/arm/mach-omap2/sdrc.c b/arch/arm/mach-omap2/sdrc.c
index 07000de..9a59219 100644
--- a/arch/arm/mach-omap2/sdrc.c
+++ b/arch/arm/mach-omap2/sdrc.c
@@ -37,12 +37,38 @@ 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)
  * @sdrc_cs0: chip select 0 ram timings **
@@ -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();
 }
diff --git a/arch/arm/plat-omap/include/plat/sdrc.h b/arch/arm/plat-omap/include/plat/sdrc.h
index 7b58a5f..772b71e 100644
--- a/arch/arm/plat-omap/include/plat/sdrc.h
+++ b/arch/arm/plat-omap/include/plat/sdrc.h
@@ -120,6 +120,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
 
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 19/32] OMAP3: PM: Fix PLL_MOD CLKEN offset in scratchpad
  2009-10-22 23:09                                   ` [PATCH v2 18/32] ARM: OMAP: SMS: save/restore of SMS_SYSCONFIG for off-mode Kevin Hilman
@ 2009-10-22 23:09                                     ` Kevin Hilman
  2009-10-22 23:09                                       ` [PATCH v2 20/32] OMAP: PM: Clear DMA channel state after a wakeup Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Kalle Jokiniemi <kalle.jokiniemi@digia.com>

The CM_CLKEN_PLL register saved in scratchpad memory
was wrongly using offset of 0x0004 instead of 0x0000.

The effect of this was that boot ROM code would
restore the wrong value when waking up from off mode.
This wrong value, however, will be overwritten by
prcm context restore. Still, a short period of wrong
clock settings in CM_CLKEN_PLL remained between ROM
code and prcm context restore. This is fixed by the
patch.

Problem reported by: Jouni Hogander <jouni.hogander@nokia.com>

Signed-off-by: Kalle Jokiniemi <kalle.jokiniemi@digia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/control.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index b84cff7..c41565e 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -230,7 +230,7 @@ void omap3_save_scratchpad_contents(void)
 	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, OMAP3430_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 =
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 20/32] OMAP: PM: Clear DMA channel state after a wakeup
  2009-10-22 23:09                                     ` [PATCH v2 19/32] OMAP3: PM: Fix PLL_MOD CLKEN offset in scratchpad Kevin Hilman
@ 2009-10-22 23:09                                       ` Kevin Hilman
  2009-10-22 23:09                                         ` [PATCH v2 21/32] OMAP: Store reboot mode in scratchpad on OMAP34xx Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Aaro Koskinen <aaro.koskinen@nokia.com>

Clear DMA channel states so that users can assume a known initial
state.

Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/plat-omap/dma.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 3b91fd3..f716234 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -2359,6 +2359,8 @@ EXPORT_SYMBOL(omap_dma_global_context_save);
 
 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);
@@ -2373,6 +2375,10 @@ void omap_dma_global_context_restore(void)
 	 */
 	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);
 }
 EXPORT_SYMBOL(omap_dma_global_context_restore);
 
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 21/32] OMAP: Store reboot mode in scratchpad on OMAP34xx
  2009-10-22 23:09                                       ` [PATCH v2 20/32] OMAP: PM: Clear DMA channel state after a wakeup Kevin Hilman
@ 2009-10-22 23:09                                         ` Kevin Hilman
  2009-10-22 23:09                                           ` [PATCH v2 22/32] OMAP3: PM: SDRC auto-refresh workaround for off-mode Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Juha Yrjola <juha.yrjola@solidboot.com>

The reboot mode can be communicated to a bootloader (or the
kernel itself) with a scratchpad register. This functionality
is especially useful, if userspace is allowed to change
the reboot mode.

Signed-off-by: Juha Yrjola <juha.yrjola@solidboot.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/prcm.c |   13 +++++++++++--
 1 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c
index 221eed1..029d376 100644
--- a/arch/arm/mach-omap2/prcm.c
+++ b/arch/arm/mach-omap2/prcm.c
@@ -135,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);
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 22/32] OMAP3: PM: SDRC auto-refresh workaround for off-mode
  2009-10-22 23:09                                         ` [PATCH v2 21/32] OMAP: Store reboot mode in scratchpad on OMAP34xx Kevin Hilman
@ 2009-10-22 23:09                                           ` Kevin Hilman
  2009-10-22 23:09                                             ` [PATCH v2 23/32] OMAP3: PM: Fix INTC context save/restore Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Tero Kristo <tero.kristo@nokia.com>

Errata: ES3.0, ES3.1 SDRC not sending auto-refresh when OMAP wakes-up
from OFF mode

Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
Signed-off-by: Kalle Jokiniemi <kalle.jokiniemi@digia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/control.c             |    9 +++-
 arch/arm/mach-omap2/sleep34xx.S           |   84 ++++++++++++++++++++++++++++-
 arch/arm/plat-omap/include/plat/control.h |    1 +
 3 files changed, 91 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index c41565e..2ff8d7c 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -209,8 +209,13 @@ void omap3_save_scratchpad_contents(void)
 
 	/* Populate the Scratchpad contents */
 	scratchpad_contents.boot_config_ptr = 0x0;
-	scratchpad_contents.public_restore_ptr =
-			 virt_to_phys(get_restore_pointer());
+	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
diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
index b6abadc..dedfa0e 100644
--- a/arch/arm/mach-omap2/sleep34xx.S
+++ b/arch/arm/mach-omap2/sleep34xx.S
@@ -34,6 +34,7 @@
 
 #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	OMAP3430_PRM_BASE + MPU_MOD + PM_PWSTCTRL
@@ -44,6 +45,13 @@
 #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)
 
 	.text
 /* Function call to get the restore pointer for resume from OFF */
@@ -52,7 +60,59 @@ 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)
@@ -130,6 +190,24 @@ loop:
 	bl i_dll_wait
 
 	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
         /* Check what was the reason for mpu reset and store the reason in r9*/
@@ -478,12 +556,16 @@ i_dll_delay:
 	bx	lr
 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
 clk_stabilize_delay:
diff --git a/arch/arm/plat-omap/include/plat/control.h b/arch/arm/plat-omap/include/plat/control.h
index 0308e3f..81c3e1e 100644
--- a/arch/arm/plat-omap/include/plat/control.h
+++ b/arch/arm/plat-omap/include/plat/control.h
@@ -301,6 +301,7 @@ 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);
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 23/32] OMAP3: PM: Fix INTC context save/restore
  2009-10-22 23:09                                           ` [PATCH v2 22/32] OMAP3: PM: SDRC auto-refresh workaround for off-mode Kevin Hilman
@ 2009-10-22 23:09                                             ` Kevin Hilman
  2009-10-22 23:09                                               ` [PATCH v2 24/32] PM: Disable usb host HW save and restore Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Aaro Koskinen <Aaro.Koskinen@nokia.com>

Wrong index was used for ILR.

Signed-off-by: Aaro Koskinen <Aaro.Koskinen@nokia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/irq.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index ebd3538..e9bc782 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -241,7 +241,7 @@ void omap_intc_save_context(void)
 			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*ind));
+				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 +
@@ -267,7 +267,7 @@ void omap_intc_restore_context(void)
 					bank, INTC_THRESHOLD);
 		for (i = 0; i < INTCPS_NR_IRQS; i++)
 			intc_bank_write_reg(intc_context[ind].ilr[i],
-				bank, (0x100 + 0x4*ind));
+				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));
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 24/32] PM: Disable usb host HW save and restore
  2009-10-22 23:09                                             ` [PATCH v2 23/32] OMAP3: PM: Fix INTC context save/restore Kevin Hilman
@ 2009-10-22 23:09                                               ` Kevin Hilman
  2009-10-22 23:09                                                 ` [PATCH v2 25/32] OMAP3: PM: Wait for SDRC ready iso a blind delay Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Kalle Jokiniemi <kalle.jokiniemi@digia.com>

The hardware SAVEANDRESTORE mechanism seems to leave
USB HOST power domain permanently into active state
after one transition from off to active state.
Disabling for now.

Signed-off-by: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/powerdomains34xx.h |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomains34xx.h b/arch/arm/mach-omap2/powerdomains34xx.h
index f70eb2d..fd09b08 100644
--- a/arch/arm/mach-omap2/powerdomains34xx.h
+++ b/arch/arm/mach-omap2/powerdomains34xx.h
@@ -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 */
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 25/32] OMAP3: PM: Wait for SDRC ready iso a blind delay
  2009-10-22 23:09                                               ` [PATCH v2 24/32] PM: Disable usb host HW save and restore Kevin Hilman
@ 2009-10-22 23:09                                                 ` Kevin Hilman
  2009-10-22 23:09                                                   ` [PATCH v2 26/32] OMAP3: PM debug: allow runtime toggle of PM features Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com>

This patch improves the wakeup SRAM code polling the SDRC to become ready
instead of just waiting for a fixed amount of time.

Signed-off-by: Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/sleep34xx.S |   48 +++++++++++++++++++++++++++++---------
 1 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
index dedfa0e..15268f8 100644
--- a/arch/arm/mach-omap2/sleep34xx.S
+++ b/arch/arm/mach-omap2/sleep34xx.S
@@ -29,6 +29,7 @@
 #include <mach/io.h>
 #include <plat/control.h>
 
+#include "cm.h"
 #include "prm.h"
 #include "sdrc.h"
 
@@ -38,6 +39,7 @@
 #define PM_PREPWSTST_MPU_V	OMAP34XX_PRM_REGADDR(MPU_MOD, \
 				OMAP3430_PM_PREPWSTST)
 #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
@@ -52,6 +54,8 @@
 #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 */
@@ -187,7 +191,7 @@ loop:
 	nop
 	nop
 	nop
-	bl i_dll_wait
+	bl wait_sdrc_ok
 
 	ldmfd	sp!, {r0-r12, pc}		@ restore regs and return
 restore_es3:
@@ -539,21 +543,41 @@ 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:
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 26/32] OMAP3: PM debug: allow runtime toggle of PM features
  2009-10-22 23:09                                                 ` [PATCH v2 25/32] OMAP3: PM: Wait for SDRC ready iso a blind delay Kevin Hilman
@ 2009-10-22 23:09                                                   ` Kevin Hilman
  2009-10-22 23:09                                                     ` [PATCH v2 27/32] PM debug: allow configurable wakeup from suspend on OMAP GPtimer Kevin Hilman
  2009-11-13 10:05                                                     ` [PATCH v2 26/32] OMAP3: PM debug: allow runtime toggle of PM features Gopinath, Thara
  0 siblings, 2 replies; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

Allow enable/disable of low-power states during idle.  To
enable low-power idle:

   echo 1 > /debug/pm_debug/sleep_while_idle

 to disable:

   echo 0 > /debug/pm_debug/sleep_while_idle

Also allow enable/disable of OFF-mode.  To enable:

   echo 1 > /debug/pm_debug/enable_off_mode

 to disable:

   echo 0 > /debug/pm_debug/enable_off_mode

Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/pm-debug.c |   27 +++++++++++++++++++++++++++
 arch/arm/mach-omap2/pm.h       |    4 ++++
 arch/arm/mach-omap2/pm34xx.c   |   22 ++++++++++++++++++++++
 arch/arm/mach-omap2/serial.c   |    2 --
 4 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 7eb2c12..1725da3 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -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,10 @@ 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);
 	pm_dbg_init_done = 1;
 
 	return 0;
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 45cafac..9582793 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -13,7 +13,11 @@
 
 #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);
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 90d1dc5..ade2e4a 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -25,6 +25,7 @@
 #include <linux/list.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
+#include <linux/clk.h>
 
 #include <plat/sram.h>
 #include <plat/clockdomain.h>
@@ -57,6 +58,9 @@
 #define OMAP343X_TABLE_VALUE_OFFSET	   0x30
 #define OMAP343X_CONTROL_REG_VALUE_OFFSET  0x32
 
+u32 enable_off_mode;
+u32 sleep_while_idle;
+
 struct power_state {
 	struct powerdomain *pwrdm;
 	u32 next_state;
@@ -456,6 +460,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())
@@ -900,6 +906,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;
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index dabc089..2e17b57 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -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;
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 27/32] PM debug: allow configurable wakeup from suspend on OMAP GPtimer
  2009-10-22 23:09                                                   ` [PATCH v2 26/32] OMAP3: PM debug: allow runtime toggle of PM features Kevin Hilman
@ 2009-10-22 23:09                                                     ` Kevin Hilman
  2009-10-22 23:09                                                       ` [PATCH v2 28/32] OMAP3: PM: decouple PER and CORE context save and restore Kevin Hilman
  2009-11-13 10:05                                                     ` [PATCH v2 26/32] OMAP3: PM debug: allow runtime toggle of PM features Gopinath, Thara
  1 sibling, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

Using debugfs, export a configurable wakeup timer to be used to
wakeup system from suspend.

If a non-zero value is written to
/debug/pm_debug/wakeup_timer_seconds, A timer wakeup event will wake
the system and resume after the configured number of seconds.

Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/pm-debug.c |    2 ++
 arch/arm/mach-omap2/pm.h       |    3 +++
 arch/arm/mach-omap2/pm34xx.c   |   21 +++++++++++++++++++++
 arch/arm/mach-omap2/timer-gp.c |    2 ++
 4 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 1725da3..8baa30d 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -596,6 +596,8 @@ static int __init pm_dbg_init(void)
 				   &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;
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 9582793..7eb769f 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -22,6 +22,9 @@ 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;
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index ade2e4a..ff818aa 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -36,6 +36,7 @@
 #include <plat/prcm.h>
 #include <plat/gpmc.h>
 #include <plat/dma.h>
+#include <plat/dmtimer.h>
 
 #include <asm/tlbflush.h>
 
@@ -60,6 +61,7 @@
 
 u32 enable_off_mode;
 u32 sleep_while_idle;
+u32 wakeup_timer_seconds;
 
 struct power_state {
 	struct powerdomain *pwrdm;
@@ -535,6 +537,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();
@@ -546,6 +564,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);
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
index df2b709..cd04dea 100644
--- a/arch/arm/mach-omap2/timer-gp.c
+++ b/arch/arm/mach-omap2/timer-gp.c
@@ -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;
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 28/32] OMAP3: PM: decouple PER and CORE context save and restore
  2009-10-22 23:09                                                     ` [PATCH v2 27/32] PM debug: allow configurable wakeup from suspend on OMAP GPtimer Kevin Hilman
@ 2009-10-22 23:09                                                       ` Kevin Hilman
  2009-10-22 23:09                                                         ` [PATCH v2 29/32] OMAP3: PM: Prevent PER from going OFF when CORE is going INA Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/pm34xx.c |   51 +++++++++++++++++++++++------------------
 1 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index ff818aa..d8a6e10 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -338,19 +338,20 @@ static void omap_sram_idle(void)
 	if (pwrdm_read_pwrst(neon_pwrdm) == PWRDM_POWER_ON)
 		set_pwrdm_state(neon_pwrdm, mpu_next_state);
 
-	/* CORE & PER */
+	/* PER */
+	per_next_state = pwrdm_read_next_pwrst(per_pwrdm);
+	if (per_next_state < PWRDM_POWER_ON) {
+		omap2_gpio_prepare_for_retention();
+		omap_uart_prepare_idle(2);
+		if (per_next_state == PWRDM_POWER_OFF)
+			omap3_per_save_context();
+	}
+
+	/* CORE */
 	core_next_state = pwrdm_read_next_pwrst(core_pwrdm);
 	if (core_next_state < PWRDM_POWER_ON) {
-		omap2_gpio_prepare_for_retention();
 		omap_uart_prepare_idle(0);
 		omap_uart_prepare_idle(1);
-		/* PER changes only with core */
-		per_next_state = pwrdm_read_next_pwrst(per_pwrdm);
-		if (per_next_state < PWRDM_POWER_ON) {
-			omap_uart_prepare_idle(2);
-			if (per_next_state == PWRDM_POWER_OFF)
-				omap3_per_save_context();
-		}
 		if (core_next_state == PWRDM_POWER_OFF) {
 			omap3_core_save_context();
 			omap3_prcm_save_context();
@@ -392,14 +393,8 @@ static void omap_sram_idle(void)
 	if (pwrdm_read_prev_pwrst(mpu_pwrdm) == PWRDM_POWER_OFF)
 		restore_table_entry();
 
+	/* CORE */
 	if (core_next_state < PWRDM_POWER_ON) {
-		if (per_next_state < PWRDM_POWER_ON)
-			omap_uart_resume_idle(2);
-		omap_uart_resume_idle(1);
-		omap_uart_resume_idle(0);
-
-		/* Disable IO-PAD wakeup */
-		prm_clear_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN);
 		core_prev_state = pwrdm_read_prev_pwrst(core_pwrdm);
 		if (core_prev_state == PWRDM_POWER_OFF) {
 			omap3_core_restore_context();
@@ -407,15 +402,27 @@ static void omap_sram_idle(void)
 			omap3_sram_restore_context();
 			omap2_sms_restore_context();
 		}
-		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();
-		}
+		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);
+		omap_uart_resume_idle(2);
+		if (per_prev_state == PWRDM_POWER_OFF)
+			omap3_per_restore_context();
 		omap2_gpio_resume_after_retention();
 	}
 
+	/* Disable IO-PAD wakeup */
+	if (core_next_state < PWRDM_POWER_ON)
+		prm_clear_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN);
+
 	pwrdm_post_transition();
 
 }
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 29/32] OMAP3: PM: Prevent PER from going OFF when CORE is going INA
  2009-10-22 23:09                                                       ` [PATCH v2 28/32] OMAP3: PM: decouple PER and CORE context save and restore Kevin Hilman
@ 2009-10-22 23:09                                                         ` Kevin Hilman
  2009-10-22 23:09                                                           ` [PATCH v2 30/32] OMAP3: PM: MPU and CORE should stay awake if there is CAM domain ACTIVE Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Tero Kristo <tero.kristo@nokia.com>

OMAP3 can't generate wakeups in this state, thus it is not permitted.

Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/pm34xx.c |   19 ++++++++++++++-----
 1 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index d8a6e10..55567bf 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -308,6 +308,7 @@ static void omap_sram_idle(void)
 	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;
@@ -340,15 +341,21 @@ static void omap_sram_idle(void)
 
 	/* 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) {
-		omap2_gpio_prepare_for_retention();
 		omap_uart_prepare_idle(2);
-		if (per_next_state == PWRDM_POWER_OFF)
-			omap3_per_save_context();
+		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();
+		}
 	}
 
 	/* CORE */
-	core_next_state = pwrdm_read_next_pwrst(core_pwrdm);
 	if (core_next_state < PWRDM_POWER_ON) {
 		omap_uart_prepare_idle(0);
 		omap_uart_prepare_idle(1);
@@ -413,10 +420,12 @@ static void omap_sram_idle(void)
 	/* PER */
 	if (per_next_state < PWRDM_POWER_ON) {
 		per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm);
-		omap_uart_resume_idle(2);
 		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 wakeup */
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 30/32] OMAP3: PM: MPU and CORE should stay awake if there is CAM domain ACTIVE
  2009-10-22 23:09                                                         ` [PATCH v2 29/32] OMAP3: PM: Prevent PER from going OFF when CORE is going INA Kevin Hilman
@ 2009-10-22 23:09                                                           ` Kevin Hilman
  2009-10-22 23:09                                                             ` [PATCH v2 31/32] OMAP3: PM: Enable IO-CHAIN wakeup Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Tero Kristo <tero.kristo@nokia.com>

MPU and CORE should stay awake if there is CAM domain ACTIVE. This is
because that module doesn't have wake-up capability.

This should replace the patch that is currently in the PM branch.

Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/pm34xx.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 55567bf..7623eda 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -80,6 +80,7 @@ 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);
 
@@ -355,6 +356,9 @@ static void omap_sram_idle(void)
 		}
 	}
 
+	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);
@@ -434,6 +438,7 @@ static void omap_sram_idle(void)
 
 	pwrdm_post_transition();
 
+	omap2_clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]);
 }
 
 /*
@@ -1067,6 +1072,7 @@ static int __init omap3_pm_init(void)
 	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
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 31/32] OMAP3: PM: Enable IO-CHAIN wakeup
  2009-10-22 23:09                                                           ` [PATCH v2 30/32] OMAP3: PM: MPU and CORE should stay awake if there is CAM domain ACTIVE Kevin Hilman
@ 2009-10-22 23:09                                                             ` Kevin Hilman
  2009-10-22 23:09                                                               ` [PATCH v2 32/32] OMAP3: PM: Program SDRC to send self refresh on timeout of AUTO_CNT Kevin Hilman
  0 siblings, 1 reply; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Kalle Jokiniemi <kalle.jokiniemi@digia.com>

OMAP 3430 ES3.1 chips have a separate bit for IO daisy-chain
wake up enabling. It needs to be enabled when entering
retention or off state, otherwise waking up might not work
in all situations.

Signed-off-by: Kalle Jokiniemi <kalle.jokiniemi@digia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/pm34xx.c           |   38 +++++++++++++++++++++++++++++--
 arch/arm/mach-omap2/prm-regbits-34xx.h |    2 +
 2 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 7623eda..511a57d 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -94,6 +94,35 @@ 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;
@@ -367,8 +396,9 @@ static void omap_sram_idle(void)
 			omap3_core_save_context();
 			omap3_prcm_save_context();
 		}
-		/* Enable IO-PAD wakeup */
+		/* Enable IO-PAD and IO-CHAIN wakeups */
 		prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN);
+		omap3_enable_io_chain();
 	}
 
 	/*
@@ -432,9 +462,11 @@ static void omap_sram_idle(void)
 			pwrdm_set_next_pwrst(per_pwrdm, PWRDM_POWER_OFF);
 	}
 
-	/* Disable IO-PAD wakeup */
-	if (core_next_state < PWRDM_POWER_ON)
+	/* 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();
 
diff --git a/arch/arm/mach-omap2/prm-regbits-34xx.h b/arch/arm/mach-omap2/prm-regbits-34xx.h
index 9fd03a2..8f21bae 100644
--- a/arch/arm/mach-omap2/prm-regbits-34xx.h
+++ b/arch/arm/mach-omap2/prm-regbits-34xx.h
@@ -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 */
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 32/32] OMAP3: PM: Program SDRC to send self refresh on timeout of AUTO_CNT
  2009-10-22 23:09                                                             ` [PATCH v2 31/32] OMAP3: PM: Enable IO-CHAIN wakeup Kevin Hilman
@ 2009-10-22 23:09                                                               ` Kevin Hilman
  0 siblings, 0 replies; 39+ messages in thread
From: Kevin Hilman @ 2009-10-22 23:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rajendra Nayak <rnayak@ti.com>

Due to an OMAP3 errata (1.142), on HS/EMU devices SDRC should be
programed to issue automatic self refresh on timeout
of AUTO_CNT = 1 prior to any transition to OFF mode.
This is needed only on sil rev's ES3.0 and above.

This patch enables the above needed WA in the SDRC power register
value stored in scratchpad, so that ROM code restores this value
in SDRC POWER on the wakeup path.
The original SDRC POWER register value is stored and restored back
in omap_sram_idle() function.

This fixes some random crashes observed while stressing suspend
on HS/EMU devices.

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Kalle Jokiniemi <kalle.jokiniemi@digia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/control.c          |   16 +++++++++++++++-
 arch/arm/mach-omap2/pm34xx.c           |   24 +++++++-----------------
 arch/arm/plat-omap/include/plat/sdrc.h |    6 ++++++
 3 files changed, 28 insertions(+), 18 deletions(-)

diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index 2ff8d7c..cdd1f35 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -265,7 +265,21 @@ void omap3_save_scratchpad_contents(void)
 			(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;
-	sdrc_block_contents.power = sdrc_read_reg(SDRC_POWER);
+	/*
+	 * 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);
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 511a57d..01b95ea 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -48,12 +48,6 @@
 #include "pm.h"
 #include "sdrc.h"
 
-#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)
-
 /* Scratchpad offsets */
 #define OMAP343X_TABLE_ADDRESS_OFFSET	   0x31
 #define OMAP343X_TABLE_VALUE_OFFSET	   0x30
@@ -402,19 +396,15 @@ static void omap_sram_idle(void)
 	}
 
 	/*
-	 * Force SDRAM controller to self-refresh mode after timeout on
-	 * autocount. This is needed on ES3.0 to avoid SDRAM controller
-	 * hang-ups.
-	 */
+	* 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) {
+	    core_next_state == PWRDM_POWER_OFF)
 		sdrc_pwr = sdrc_read_reg(SDRC_POWER);
-		sdrc_write_reg((sdrc_pwr &
-			~(SDRC_POWER_AUTOCOUNT_MASK|SDRC_POWER_CLKCTRL_MASK)) |
-			(1 << SDRC_POWER_AUTOCOUNT_SHIFT) |
-			SDRC_SELF_REFRESH_ON_AUTOCOUNT, SDRC_POWER);
-	}
 
 	/*
 	 * omap3_arm_context is the location where ARM registers
@@ -424,7 +414,7 @@ static void omap_sram_idle(void)
 	_omap_sram_idle(omap3_arm_context, save_state);
 	cpu_init();
 
-	/* Restore normal SDRAM settings */
+	/* Restore normal SDRC POWER settings */
 	if (omap_rev() >= OMAP3430_REV_ES3_0 &&
 	    omap_type() != OMAP2_DEVICE_TYPE_GP &&
 	    core_next_state == PWRDM_POWER_OFF)
diff --git a/arch/arm/plat-omap/include/plat/sdrc.h b/arch/arm/plat-omap/include/plat/sdrc.h
index 772b71e..f704030 100644
--- a/arch/arm/plat-omap/include/plat/sdrc.h
+++ b/arch/arm/plat-omap/include/plat/sdrc.h
@@ -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
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 12/32] OMAP: PM: DMA context save/restore for off-mode support
  2009-10-22 23:09                       ` [PATCH v2 12/32] OMAP: PM: DMA context save/restore for " Kevin Hilman
  2009-10-22 23:09                         ` [PATCH v2 13/32] OMAP3 PM: off-mode support for HS/EMU devices Kevin Hilman
@ 2009-10-23  8:32                         ` Grazvydas Ignotas
  2009-10-23 17:33                           ` Kevin Hilman
  2009-10-23 13:54                         ` Venkatraman S
  2 siblings, 1 reply; 39+ messages in thread
From: Grazvydas Ignotas @ 2009-10-23  8:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Oct 23, 2009 at 2:09 AM, Kevin Hilman
<khilman@deeprootsystems.com> wrote:
> From: Tero Kristo <tero.kristo@nokia.com>
>
> For HS/EMU devices, these additional features are also used:
>
> - DMA interrupt disable routine added
> - Added DMA controller reset to DMA context restore
>
> Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
> ---
> ?arch/arm/mach-omap2/pm34xx.c ? ? ? ? ?| ? ?3 ++
> ?arch/arm/plat-omap/dma.c ? ? ? ? ? ? ?| ? 41 +++++++++++++++++++++++++++++++++
> ?arch/arm/plat-omap/include/plat/dma.h | ? ?5 ++++
> ?3 files changed, 49 insertions(+), 0 deletions(-)
> ?mode change 100644 => 100755 arch/arm/plat-omap/include/plat/dma.h
>
> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
> index bab9b48..54fea79 100644
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -34,6 +34,7 @@
> ?#include <plat/sdrc.h>
> ?#include <plat/prcm.h>
> ?#include <plat/gpmc.h>
> +#include <plat/dma.h>
>
> ?#include <asm/tlbflush.h>
>
> @@ -95,6 +96,7 @@ static void omap3_core_save_context(void)
> ? ? ? ?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)
> @@ -105,6 +107,7 @@ static void omap3_core_restore_context(void)
> ? ? ? ?omap3_gpmc_restore_context();
> ? ? ? ?/* Restore the interrupt controller context */
> ? ? ? ?omap_intc_restore_context();
> + ? ? ? omap_dma_global_context_restore();
> ?}
>
> ?/*
> diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
> index 3edffde..c0a6060 100644
> --- a/arch/arm/plat-omap/dma.c
> +++ b/arch/arm/plat-omap/dma.c
> @@ -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,41 @@ 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);
> +}
> +EXPORT_SYMBOL(omap_dma_global_context_save);
> +
> +void omap_dma_global_context_restore(void)
> +{
> + ? ? ? dma_write(0x2, OCP_SYSCONFIG);
> + ? ? ? while (!__raw_readl(omap_dma_base + OMAP_DMA4_SYSSTATUS))
> + ? ? ? ? ? ? ? ;
> + ? ? ? 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);
> +}
> +EXPORT_SYMBOL(omap_dma_global_context_restore);
> +
> +void omap_dma_disable_irq(int lch)
> +{
> + ? ? ? u32 val;
> +
> + ? ? ? if (cpu_class_is_omap2()) {
> + ? ? ? ? ? ? ? /* Disable interrupts */
> + ? ? ? ? ? ? ? val = dma_read(IRQENABLE_L0);
> + ? ? ? ? ? ? ? val &= ~(1 << lch);
> + ? ? ? ? ? ? ? dma_write(val, IRQENABLE_L0);
> + ? ? ? }
> +}
> +
> ?/*----------------------------------------------------------------------------*/
>
> ?static int __init omap_init_dma(void)
> diff --git a/arch/arm/plat-omap/include/plat/dma.h b/arch/arm/plat-omap/include/plat/dma.h
> old mode 100644
> new mode 100755

^^ whoops?

> index 72f680b..1c017b2
> --- a/arch/arm/plat-omap/include/plat/dma.h
> +++ b/arch/arm/plat-omap/include/plat/dma.h
> @@ -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,
> --
> 1.6.4.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v2 12/32] OMAP: PM: DMA context save/restore for off-mode support
  2009-10-22 23:09                       ` [PATCH v2 12/32] OMAP: PM: DMA context save/restore for " Kevin Hilman
  2009-10-22 23:09                         ` [PATCH v2 13/32] OMAP3 PM: off-mode support for HS/EMU devices Kevin Hilman
  2009-10-23  8:32                         ` [PATCH v2 12/32] OMAP: PM: DMA context save/restore for off-mode support Grazvydas Ignotas
@ 2009-10-23 13:54                         ` Venkatraman S
  2009-10-23 17:57                           ` Kevin Hilman
  2 siblings, 1 reply; 39+ messages in thread
From: Venkatraman S @ 2009-10-23 13:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Oct 23, 2009 at 4:39 AM, Kevin Hilman
<khilman@deeprootsystems.com> wrote:
> From: Tero Kristo <tero.kristo@nokia.com>
>
> For HS/EMU devices, these additional features are also used:
>
> - DMA interrupt disable routine added
> - Added DMA controller reset to DMA context restore
>
> Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
> ---
> ?arch/arm/mach-omap2/pm34xx.c ? ? ? ? ?| ? ?3 ++
> ?arch/arm/plat-omap/dma.c ? ? ? ? ? ? ?| ? 41 +++++++++++++++++++++++++++++++++
> ?arch/arm/plat-omap/include/plat/dma.h | ? ?5 ++++
> ?3 files changed, 49 insertions(+), 0 deletions(-)
> ?mode change 100644 => 100755 arch/arm/plat-omap/include/plat/dma.h
>
> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
> index bab9b48..54fea79 100644
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -34,6 +34,7 @@
> ?#include <plat/sdrc.h>
> ?#include <plat/prcm.h>
> ?#include <plat/gpmc.h>
> +#include <plat/dma.h>
>
> ?#include <asm/tlbflush.h>
>
> @@ -95,6 +96,7 @@ static void omap3_core_save_context(void)
> ? ? ? ?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)
> @@ -105,6 +107,7 @@ static void omap3_core_restore_context(void)
> ? ? ? ?omap3_gpmc_restore_context();
> ? ? ? ?/* Restore the interrupt controller context */
> ? ? ? ?omap_intc_restore_context();
> + ? ? ? omap_dma_global_context_restore();
> ?}
>
> ?/*
> diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
> index 3edffde..c0a6060 100644
> --- a/arch/arm/plat-omap/dma.c
> +++ b/arch/arm/plat-omap/dma.c
> @@ -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,41 @@ 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);
> +}
> +EXPORT_SYMBOL(omap_dma_global_context_save);
> +
> +void omap_dma_global_context_restore(void)
> +{
> + ? ? ? dma_write(0x2, OCP_SYSCONFIG);
> + ? ? ? while (!__raw_readl(omap_dma_base + OMAP_DMA4_SYSSTATUS))
> + ? ? ? ? ? ? ? ;
> + ? ? ? 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);
> +}
> +EXPORT_SYMBOL(omap_dma_global_context_restore);
> +
> +void omap_dma_disable_irq(int lch)
> +{
> + ? ? ? u32 val;
> +
> + ? ? ? if (cpu_class_is_omap2()) {
> + ? ? ? ? ? ? ? /* Disable interrupts */
> + ? ? ? ? ? ? ? val = dma_read(IRQENABLE_L0);
> + ? ? ? ? ? ? ? val &= ~(1 << lch);
> + ? ? ? ? ? ? ? dma_write(val, IRQENABLE_L0);
> + ? ? ? }
> +}
> +
Just curious - Doesn't it need EXPORT_SYMBOL() ?
Is this used somewhere ? If yes,
would be nice to have omap_dma_enable_irq as well

> ?/*----------------------------------------------------------------------------*/
>
> ?static int __init omap_init_dma(void)
> diff --git a/arch/arm/plat-omap/include/plat/dma.h b/arch/arm/plat-omap/include/plat/dma.h
> old mode 100644
> new mode 100755
> index 72f680b..1c017b2
> --- a/arch/arm/plat-omap/include/plat/dma.h
> +++ b/arch/arm/plat-omap/include/plat/dma.h
> @@ -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,
> --
> 1.6.4.3
>
> --

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v2 12/32] OMAP: PM: DMA context save/restore for off-mode support
  2009-10-23  8:32                         ` [PATCH v2 12/32] OMAP: PM: DMA context save/restore for off-mode support Grazvydas Ignotas
@ 2009-10-23 17:33                           ` Kevin Hilman
  0 siblings, 0 replies; 39+ messages in thread
From: Kevin Hilman @ 2009-10-23 17:33 UTC (permalink / raw)
  To: linux-arm-kernel

Grazvydas Ignotas <notasas@gmail.com> writes:

>> ?static int __init omap_init_dma(void)
>> diff --git a/arch/arm/plat-omap/include/plat/dma.h b/arch/arm/plat-omap/include/plat/dma.h
>> old mode 100644
>> new mode 100755
>
> ^^ whoops?
>

Good catch, I'll fix this up in my pm-off branch.

Kevin

>> index 72f680b..1c017b2
>> --- a/arch/arm/plat-omap/include/plat/dma.h
>> +++ b/arch/arm/plat-omap/include/plat/dma.h
>> @@ -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,
>> --
>> 1.6.4.3
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
>>

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v2 12/32] OMAP: PM: DMA context save/restore for off-mode support
  2009-10-23 13:54                         ` Venkatraman S
@ 2009-10-23 17:57                           ` Kevin Hilman
  0 siblings, 0 replies; 39+ messages in thread
From: Kevin Hilman @ 2009-10-23 17:57 UTC (permalink / raw)
  To: linux-arm-kernel

Venkatraman S <svenkatr@ti.com> writes:

> On Fri, Oct 23, 2009 at 4:39 AM, Kevin Hilman
> <khilman@deeprootsystems.com> wrote:
>> From: Tero Kristo <tero.kristo@nokia.com>
>>
>> For HS/EMU devices, these additional features are also used:
>>
>> - DMA interrupt disable routine added
>> - Added DMA controller reset to DMA context restore
>>
>> Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
>> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>

[...]

>> +void omap_dma_disable_irq(int lch)
>> +{
>> + ? ? ? u32 val;
>> +
>> + ? ? ? if (cpu_class_is_omap2()) {
>> + ? ? ? ? ? ? ? /* Disable interrupts */
>> + ? ? ? ? ? ? ? val = dma_read(IRQENABLE_L0);
>> + ? ? ? ? ? ? ? val &= ~(1 << lch);
>> + ? ? ? ? ? ? ? dma_write(val, IRQENABLE_L0);
>> + ? ? ? }
>> +}
>> +
> Just curious - Doesn't it need EXPORT_SYMBOL() ?

No, was not meant to be used by modules.  In fact, when I update this
patch for the chmod problem, I'm going to drop the EXPORT_SYMBOL() for
the context save/restore as well since that is only meant to be called
from the PM core.

> Is this used somewhere ? If yes,
> would be nice to have omap_dma_enable_irq as well

Looking closer, it looks like the user of this was removed in 
"[PATCH v2 17/32] OMAP3: PM: Fix secure SRAM context save/restore", so I'll
remove this function in that patch as well.

Kevin

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v2 26/32] OMAP3: PM debug: allow runtime toggle of PM features
  2009-10-22 23:09                                                   ` [PATCH v2 26/32] OMAP3: PM debug: allow runtime toggle of PM features Kevin Hilman
  2009-10-22 23:09                                                     ` [PATCH v2 27/32] PM debug: allow configurable wakeup from suspend on OMAP GPtimer Kevin Hilman
@ 2009-11-13 10:05                                                     ` Gopinath, Thara
  2009-11-16 18:31                                                       ` Kevin Hilman
  1 sibling, 1 reply; 39+ messages in thread
From: Gopinath, Thara @ 2009-11-13 10:05 UTC (permalink / raw)
  To: linux-arm-kernel



>>-----Original Message-----
>>From: linux-omap-owner at vger.kernel.org [mailto:linux-omap-owner at vger.kernel.org] On Behalf Of Kevin
>>Hilman
>>Sent: Friday, October 23, 2009 4:40 AM
>>To: linux-omap at vger.kernel.org
>>Cc: linux-arm-kernel at lists.infradead.org
>>Subject: [PATCH v2 26/32] OMAP3: PM debug: allow runtime toggle of PM features
>>
>>Allow enable/disable of low-power states during idle.  To
>>enable low-power idle:
>>
>>   echo 1 > /debug/pm_debug/sleep_while_idle
>>
>> to disable:
>>
>>   echo 0 > /debug/pm_debug/sleep_while_idle
>>
>>Also allow enable/disable of OFF-mode.  To enable:
>>
>>   echo 1 > /debug/pm_debug/enable_off_mode
>>
>> to disable:
>>
>>   echo 0 > /debug/pm_debug/enable_off_mode
>>
>>Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
>>---
>> arch/arm/mach-omap2/pm-debug.c |   27 +++++++++++++++++++++++++++
>> arch/arm/mach-omap2/pm.h       |    4 ++++
>> arch/arm/mach-omap2/pm34xx.c   |   22 ++++++++++++++++++++++
>> arch/arm/mach-omap2/serial.c   |    2 --
>> 4 files changed, 53 insertions(+), 2 deletions(-)
>>
>>diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
>>index 7eb2c12..1725da3 100644
>>--- a/arch/arm/mach-omap2/pm-debug.c
>>+++ b/arch/arm/mach-omap2/pm-debug.c
>>@@ -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,10 @@ 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);
>> 	pm_dbg_init_done = 1;
>>
>> 	return 0;
>>diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
>>index 45cafac..9582793 100644
>>--- a/arch/arm/mach-omap2/pm.h
>>+++ b/arch/arm/mach-omap2/pm.h
>>@@ -13,7 +13,11 @@
>>
>> #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);
>>diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
>>index 90d1dc5..ade2e4a 100644
>>--- a/arch/arm/mach-omap2/pm34xx.c
>>+++ b/arch/arm/mach-omap2/pm34xx.c
>>@@ -25,6 +25,7 @@
>> #include <linux/list.h>
>> #include <linux/err.h>
>> #include <linux/gpio.h>
>>+#include <linux/clk.h>
>>
>> #include <plat/sram.h>
>> #include <plat/clockdomain.h>
>>@@ -57,6 +58,9 @@
>> #define OMAP343X_TABLE_VALUE_OFFSET	   0x30
>> #define OMAP343X_CONTROL_REG_VALUE_OFFSET  0x32
>>
>>+u32 enable_off_mode;
>>+u32 sleep_while_idle;
>>+
>> struct power_state {
>> 	struct powerdomain *pwrdm;
>> 	u32 next_state;
>>@@ -456,6 +460,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())
>>@@ -900,6 +906,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);

Shld the next states of MPU and CORE domain also be changed? It should happen only in idle thread or system suspend path. Not at any arbit point where user sets enable_off_mode.
>>+	}
>>+}
>>+
>> int omap3_pm_get_suspend_state(struct powerdomain *pwrdm)
>> {
>> 	struct power_state *pwrst;
>>diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
>>index dabc089..2e17b57 100644
>>--- a/arch/arm/mach-omap2/serial.c
>>+++ b/arch/arm/mach-omap2/serial.c
>>@@ -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;
>>--
>>1.6.4.3
>>
>>--
>>To unsubscribe from this list: send the line "unsubscribe linux-omap" in
>>the body of a message to majordomo at vger.kernel.org
>>More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v2 26/32] OMAP3: PM debug: allow runtime toggle of PM features
  2009-11-13 10:05                                                     ` [PATCH v2 26/32] OMAP3: PM debug: allow runtime toggle of PM features Gopinath, Thara
@ 2009-11-16 18:31                                                       ` Kevin Hilman
  0 siblings, 0 replies; 39+ messages in thread
From: Kevin Hilman @ 2009-11-16 18:31 UTC (permalink / raw)
  To: linux-arm-kernel

"Gopinath, Thara" <thara@ti.com> writes:

[...]

>>>
>>>+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);
>
> Shld the next states of MPU and CORE domain also be changed? 

No.  MPU & CORE are handled by CPUidle, and there the enable_off_mode
flag is checked.

> It should happen only in idle thread or system suspend path. Not at
> any arbit point where user sets enable_off_mode.

Why not?  

If the domain is idle, it is turned off immediately.  If it's not idle,
it doesn't transition until it is.

Kevin
<

^ permalink raw reply	[flat|nested] 39+ messages in thread

end of thread, other threads:[~2009-11-16 18:31 UTC | newest]

Thread overview: 39+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-10-22 23:09 [PATCH v2 00/32] OMAP3: PM: base off-mode support Kevin Hilman
2009-10-22 23:09 ` [PATCH v2 01/32] OMAP3: PM: GPMC context save/restore Kevin Hilman
2009-10-22 23:09   ` [PATCH v2 02/32] OMAP3: PM: GPIO " Kevin Hilman
2009-10-22 23:09     ` [PATCH v2 03/32] OMAP3: PM: INTC " Kevin Hilman
2009-10-22 23:09       ` [PATCH v2 04/32] OMAP3: PM: PRCM " Kevin Hilman
2009-10-22 23:09         ` [PATCH v2 05/32] OMAP3: PM: Populate scratchpad contents Kevin Hilman
2009-10-22 23:09           ` [PATCH v2 06/32] OMAP3: PM: SCM context save/restore Kevin Hilman
2009-10-22 23:09             ` [PATCH v2 07/32] OMAP3: PM: restore SRAM functions after off-mode Kevin Hilman
2009-10-22 23:09               ` [PATCH v2 08/32] OMAP3: PM: handle PER/NEON/CORE in idle Kevin Hilman
2009-10-22 23:09                 ` [PATCH v2 09/32] OMAP3: PM: Restore MMU table entry Kevin Hilman
2009-10-22 23:09                   ` [PATCH v2 10/32] OMAP3: PM: MPU off-mode support Kevin Hilman
2009-10-22 23:09                     ` [PATCH v2 11/32] OMAP3: PM: CORE domain " Kevin Hilman
2009-10-22 23:09                       ` [PATCH v2 12/32] OMAP: PM: DMA context save/restore for " Kevin Hilman
2009-10-22 23:09                         ` [PATCH v2 13/32] OMAP3 PM: off-mode support for HS/EMU devices Kevin Hilman
2009-10-22 23:09                           ` [PATCH v2 14/32] OMAP3: PM: save secure RAM only during init Kevin Hilman
2009-10-22 23:09                             ` [PATCH v2 15/32] OMAP3: PM: Enable SDRAM auto-refresh during sleep Kevin Hilman
2009-10-22 23:09                               ` [PATCH v2 16/32] OMAP3: PM: Save and restore also CM_CLKSEL1_PLL_IVA2 Kevin Hilman
2009-10-22 23:09                                 ` [PATCH v2 17/32] OMAP3: PM: Fix secure SRAM context save/restore Kevin Hilman
2009-10-22 23:09                                   ` [PATCH v2 18/32] ARM: OMAP: SMS: save/restore of SMS_SYSCONFIG for off-mode Kevin Hilman
2009-10-22 23:09                                     ` [PATCH v2 19/32] OMAP3: PM: Fix PLL_MOD CLKEN offset in scratchpad Kevin Hilman
2009-10-22 23:09                                       ` [PATCH v2 20/32] OMAP: PM: Clear DMA channel state after a wakeup Kevin Hilman
2009-10-22 23:09                                         ` [PATCH v2 21/32] OMAP: Store reboot mode in scratchpad on OMAP34xx Kevin Hilman
2009-10-22 23:09                                           ` [PATCH v2 22/32] OMAP3: PM: SDRC auto-refresh workaround for off-mode Kevin Hilman
2009-10-22 23:09                                             ` [PATCH v2 23/32] OMAP3: PM: Fix INTC context save/restore Kevin Hilman
2009-10-22 23:09                                               ` [PATCH v2 24/32] PM: Disable usb host HW save and restore Kevin Hilman
2009-10-22 23:09                                                 ` [PATCH v2 25/32] OMAP3: PM: Wait for SDRC ready iso a blind delay Kevin Hilman
2009-10-22 23:09                                                   ` [PATCH v2 26/32] OMAP3: PM debug: allow runtime toggle of PM features Kevin Hilman
2009-10-22 23:09                                                     ` [PATCH v2 27/32] PM debug: allow configurable wakeup from suspend on OMAP GPtimer Kevin Hilman
2009-10-22 23:09                                                       ` [PATCH v2 28/32] OMAP3: PM: decouple PER and CORE context save and restore Kevin Hilman
2009-10-22 23:09                                                         ` [PATCH v2 29/32] OMAP3: PM: Prevent PER from going OFF when CORE is going INA Kevin Hilman
2009-10-22 23:09                                                           ` [PATCH v2 30/32] OMAP3: PM: MPU and CORE should stay awake if there is CAM domain ACTIVE Kevin Hilman
2009-10-22 23:09                                                             ` [PATCH v2 31/32] OMAP3: PM: Enable IO-CHAIN wakeup Kevin Hilman
2009-10-22 23:09                                                               ` [PATCH v2 32/32] OMAP3: PM: Program SDRC to send self refresh on timeout of AUTO_CNT Kevin Hilman
2009-11-13 10:05                                                     ` [PATCH v2 26/32] OMAP3: PM debug: allow runtime toggle of PM features Gopinath, Thara
2009-11-16 18:31                                                       ` Kevin Hilman
2009-10-23  8:32                         ` [PATCH v2 12/32] OMAP: PM: DMA context save/restore for off-mode support Grazvydas Ignotas
2009-10-23 17:33                           ` Kevin Hilman
2009-10-23 13:54                         ` Venkatraman S
2009-10-23 17:57                           ` Kevin Hilman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).