All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/19] ARM: OMAP4 device off support
@ 2012-04-20  9:33 ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-omap, khilman, paul; +Cc: linux-arm-kernel

Hi,

First version for this work. Applies on top of mainline + iochain set +
OMAP4 core retention set. Working tree available here:
tree: git://gitorious.org/~kristo/omap-pm/omap-pm-work.git
branch: mainline-3.4-omap4-dev-off

Tested on omap4430 EMU blaze + omap4460 GP panda boards.

Some drivers have issues with device off, most notably MMC, as it breaks
device off on blaze device after 1 entry to device off mode:

[  208.906921] omap_i2c omap_i2c.1: XRDY IRQ while no data to send
[  209.905639] omap_i2c omap_i2c.1: controller timed out
[  209.905792] twl: i2c_read failed to transfer all messages
[  209.905792] omap_hsmmc omap_hsmmc.1: could not set regulator OCR (-110)
[  212.296203] mmc0: error -110 during resume (card was removed?)
[  212.562164] PM: resume of devices complete after 3656.007 msecs
[  212.660125] Restarting tasks ... done.
# 
# echo mem > /sys/power/state 
[  220.376892] PM: Syncing filesystems ... done.
[  220.382476] Freezing user space processes ... (elapsed 0.01 seconds) done.
[  220.408386] Freezing remaining freezable tasks ... (elapsed 0.02 seconds) don
e.
[  220.439605] Suspending console(s) (use no_console_suspend to debug)
[  220.454650] dpm_run_callback(): platform_pm_suspend+0x0/0x54 returns -110
[  220.454711] PM: Device omap_hsmmc.1 failed to suspend: error -110
[  220.454711] PM: Some devices failed to suspend
[  220.718261] PM: resume of devices complete after 263.539 msecs
[  220.743988] Restarting tasks ... done.

Attempting to disable MMC from config prevented boot completely for me,
so this issue is likely to stay until someone fixes the MMC driver.
Panda device works fine though, although the wakeup from device off is
slow due to problems with some other drivers (most likely I2C.)

Off mode is disabled by default, it can be enabled by either calling
omap4_pm_enable_off_mode(1) from board files or alternatively writing
to a debugfs node from userspace:

echo 1 > /debug/pm_debug/enable_off_mode

Device off entry can be tracked through the debugfs also, it increases
the core_pwrdm OFF state counter / timer, as this is an invalid state
for the chip normally (core enters OSWR in device off.) Not sure if this
a good way to do this but comments are welcome.

-Tero


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

* [PATCH 00/19] ARM: OMAP4 device off support
@ 2012-04-20  9:33 ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

First version for this work. Applies on top of mainline + iochain set +
OMAP4 core retention set. Working tree available here:
tree: git://gitorious.org/~kristo/omap-pm/omap-pm-work.git
branch: mainline-3.4-omap4-dev-off

Tested on omap4430 EMU blaze + omap4460 GP panda boards.

Some drivers have issues with device off, most notably MMC, as it breaks
device off on blaze device after 1 entry to device off mode:

[  208.906921] omap_i2c omap_i2c.1: XRDY IRQ while no data to send
[  209.905639] omap_i2c omap_i2c.1: controller timed out
[  209.905792] twl: i2c_read failed to transfer all messages
[  209.905792] omap_hsmmc omap_hsmmc.1: could not set regulator OCR (-110)
[  212.296203] mmc0: error -110 during resume (card was removed?)
[  212.562164] PM: resume of devices complete after 3656.007 msecs
[  212.660125] Restarting tasks ... done.
# 
# echo mem > /sys/power/state 
[  220.376892] PM: Syncing filesystems ... done.
[  220.382476] Freezing user space processes ... (elapsed 0.01 seconds) done.
[  220.408386] Freezing remaining freezable tasks ... (elapsed 0.02 seconds) don
e.
[  220.439605] Suspending console(s) (use no_console_suspend to debug)
[  220.454650] dpm_run_callback(): platform_pm_suspend+0x0/0x54 returns -110
[  220.454711] PM: Device omap_hsmmc.1 failed to suspend: error -110
[  220.454711] PM: Some devices failed to suspend
[  220.718261] PM: resume of devices complete after 263.539 msecs
[  220.743988] Restarting tasks ... done.

Attempting to disable MMC from config prevented boot completely for me,
so this issue is likely to stay until someone fixes the MMC driver.
Panda device works fine though, although the wakeup from device off is
slow due to problems with some other drivers (most likely I2C.)

Off mode is disabled by default, it can be enabled by either calling
omap4_pm_enable_off_mode(1) from board files or alternatively writing
to a debugfs node from userspace:

echo 1 > /debug/pm_debug/enable_off_mode

Device off entry can be tracked through the debugfs also, it increases
the core_pwrdm OFF state counter / timer, as this is an invalid state
for the chip normally (core enters OSWR in device off.) Not sure if this
a good way to do this but comments are welcome.

-Tero

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

* [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
  2012-04-20  9:33 ` Tero Kristo
@ 2012-04-20  9:33   ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-omap, khilman, paul
  Cc: Nishanth Menon, Rajendra Nayak, Santosh Shilimkar, linux-arm-kernel

From: Rajendra Nayak <rnayak@ti.com>

SAR/ROM code restores only CORE DPLL to its original state
post wakeup from OFF mode.
The rest of the DPLL's in OMAP4 platform (MPU/IVA/ABE/USB/PER)
are saved and restored here during an OFF transition.

[nm@ti.com: minor cleanups]
Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/cm44xx.h   |    5 +
 arch/arm/mach-omap2/dpll44xx.c |  271 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 276 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/cm44xx.h b/arch/arm/mach-omap2/cm44xx.h
index 3380bee..5fba0fa 100644
--- a/arch/arm/mach-omap2/cm44xx.h
+++ b/arch/arm/mach-omap2/cm44xx.h
@@ -23,4 +23,9 @@
 #define OMAP4_CM_CLKSTCTRL				0x0000
 #define OMAP4_CM_STATICDEP				0x0004
 
+#ifndef __ASSEMBLER__
+extern void omap4_dpll_prepare_off(void);
+extern void omap4_dpll_resume_off(void);
+#endif
+
 #endif
diff --git a/arch/arm/mach-omap2/dpll44xx.c b/arch/arm/mach-omap2/dpll44xx.c
index 9c6a296..b411d3b 100644
--- a/arch/arm/mach-omap2/dpll44xx.c
+++ b/arch/arm/mach-omap2/dpll44xx.c
@@ -14,6 +14,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/bitops.h>
+#include <linux/delay.h>
 
 #include <plat/cpu.h>
 #include <plat/clock.h>
@@ -21,6 +22,96 @@
 #include "clock.h"
 #include "clock44xx.h"
 #include "cm-regbits-44xx.h"
+#include "cm1_44xx.h"
+#include "cm2_44xx.h"
+#include "prcm44xx.h"
+#include "cminst44xx.h"
+#include "cm44xx.h"
+
+#define MAX_DPLL_WAIT_TRIES	1000000
+
+struct dpll_reg {
+	u16 offset;
+	u32 val;
+};
+
+struct omap4_dpll_regs {
+	char *name;
+	u32 mod_partition;
+	u32 mod_inst;
+	struct dpll_reg clkmode;
+	struct dpll_reg autoidle;
+	struct dpll_reg idlest;
+	struct dpll_reg clksel;
+	struct dpll_reg div_m2;
+	struct dpll_reg div_m3;
+	struct dpll_reg div_m4;
+	struct dpll_reg div_m5;
+	struct dpll_reg div_m6;
+	struct dpll_reg div_m7;
+	struct dpll_reg clkdcoldo;
+};
+
+static struct omap4_dpll_regs dpll_regs[] = {
+	/* MPU DPLL */
+	{ .name		= "mpu",
+	  .mod_partition = OMAP4430_CM1_PARTITION,
+	  .mod_inst	= OMAP4430_CM1_CKGEN_INST,
+	  .clkmode	= {.offset = OMAP4_CM_CLKMODE_DPLL_MPU_OFFSET},
+	  .autoidle	= {.offset = OMAP4_CM_AUTOIDLE_DPLL_MPU_OFFSET},
+	  .idlest	= {.offset = OMAP4_CM_IDLEST_DPLL_MPU_OFFSET},
+	  .clksel	= {.offset = OMAP4_CM_CLKSEL_DPLL_MPU_OFFSET},
+	  .div_m2	= {.offset = OMAP4_CM_DIV_M2_DPLL_MPU_OFFSET},
+	},
+	/* IVA DPLL */
+	{ .name		= "iva",
+	  .mod_partition = OMAP4430_CM1_PARTITION,
+	  .mod_inst	= OMAP4430_CM1_CKGEN_INST,
+	  .clkmode	= {.offset = OMAP4_CM_CLKMODE_DPLL_IVA_OFFSET},
+	  .autoidle	= {.offset = OMAP4_CM_AUTOIDLE_DPLL_IVA_OFFSET},
+	  .idlest	= {.offset = OMAP4_CM_IDLEST_DPLL_IVA_OFFSET},
+	  .clksel	= {.offset = OMAP4_CM_CLKSEL_DPLL_IVA_OFFSET},
+	  .div_m4	= {.offset = OMAP4_CM_DIV_M4_DPLL_IVA_OFFSET},
+	  .div_m5	= {.offset = OMAP4_CM_DIV_M5_DPLL_IVA_OFFSET},
+	},
+	/* ABE DPLL */
+	{ .name		= "abe",
+	  .mod_partition = OMAP4430_CM1_PARTITION,
+	  .mod_inst	= OMAP4430_CM1_CKGEN_INST,
+	  .clkmode	= {.offset = OMAP4_CM_CLKMODE_DPLL_ABE_OFFSET},
+	  .autoidle	= {.offset = OMAP4_CM_AUTOIDLE_DPLL_ABE_OFFSET},
+	  .idlest	= {.offset = OMAP4_CM_IDLEST_DPLL_ABE_OFFSET},
+	  .clksel	= {.offset = OMAP4_CM_CLKSEL_DPLL_ABE_OFFSET},
+	  .div_m2	= {.offset = OMAP4_CM_DIV_M2_DPLL_ABE_OFFSET},
+	  .div_m3	= {.offset = OMAP4_CM_DIV_M3_DPLL_ABE_OFFSET},
+	},
+	/* USB DPLL */
+	{ .name		= "usb",
+	  .mod_partition = OMAP4430_CM2_PARTITION,
+	  .mod_inst	= OMAP4430_CM2_CKGEN_INST,
+	  .clkmode	= {.offset = OMAP4_CM_CLKMODE_DPLL_USB_OFFSET},
+	  .autoidle	= {.offset = OMAP4_CM_AUTOIDLE_DPLL_USB_OFFSET},
+	  .idlest	= {.offset = OMAP4_CM_IDLEST_DPLL_USB_OFFSET},
+	  .clksel	= {.offset = OMAP4_CM_CLKSEL_DPLL_USB_OFFSET},
+	  .div_m2	= {.offset = OMAP4_CM_DIV_M2_DPLL_USB_OFFSET},
+	  .clkdcoldo	= {.offset = OMAP4_CM_CLKDCOLDO_DPLL_USB_OFFSET},
+	 },
+	/* PER DPLL */
+	{ .name		= "per",
+	  .mod_partition = OMAP4430_CM2_PARTITION,
+	  .mod_inst	= OMAP4430_CM2_CKGEN_INST,
+	  .clkmode	= {.offset = OMAP4_CM_CLKMODE_DPLL_PER_OFFSET},
+	  .autoidle	= {.offset = OMAP4_CM_AUTOIDLE_DPLL_PER_OFFSET},
+	  .idlest	= {.offset = OMAP4_CM_IDLEST_DPLL_PER_OFFSET},
+	  .clksel	= {.offset = OMAP4_CM_CLKSEL_DPLL_PER_OFFSET},
+	  .div_m2	= {.offset = OMAP4_CM_DIV_M2_DPLL_PER_OFFSET},
+	  .div_m3	= {.offset = OMAP4_CM_DIV_M3_DPLL_PER_OFFSET},
+	  .div_m4	= {.offset = OMAP4_CM_DIV_M4_DPLL_PER_OFFSET},
+	  .div_m5	= {.offset = OMAP4_CM_DIV_M5_DPLL_PER_OFFSET},
+	  .div_m6	= {.offset = OMAP4_CM_DIV_M6_DPLL_PER_OFFSET},
+	  .div_m7	= {.offset = OMAP4_CM_DIV_M7_DPLL_PER_OFFSET},
+	},
+};
 
 /* Supported only on OMAP4 */
 int omap4_dpllmx_gatectrl_read(struct clk *clk)
@@ -151,3 +242,183 @@ long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate)
 
 	return clk->dpll_data->last_rounded_rate;
 }
+
+/**
+ * omap4_dpll_read_reg - reads DPLL register value
+ * @dpll_reg: DPLL register to read
+ *
+ * Reads the value of a single DPLL register.
+ */
+static inline u32 omap4_dpll_read_reg(struct omap4_dpll_regs *dpll_reg,
+				      struct dpll_reg *tuple)
+{
+	if (tuple->offset)
+		return omap4_cminst_read_inst_reg(dpll_reg->mod_partition,
+						  dpll_reg->mod_inst,
+						  tuple->offset);
+	return 0;
+}
+
+/**
+ * omap4_dpll_store_reg - stores DPLL register value to memory location
+ * @dpll_reg: DPLL register to save
+ * @tuple: save address
+ *
+ * Saves a single DPLL register content to memory location defined by
+ * @tuple before entering device off mode.
+ */
+static inline void omap4_dpll_store_reg(struct omap4_dpll_regs *dpll_reg,
+					struct dpll_reg *tuple)
+{
+	tuple->val = omap4_dpll_read_reg(dpll_reg, tuple);
+}
+
+/**
+ * omap4_dpll_prepare_off - stores DPLL settings before off mode
+ *
+ * Saves all DPLL register settings. This must be called before
+ * entering device off.
+ */
+void omap4_dpll_prepare_off(void)
+{
+	u32 i;
+	struct omap4_dpll_regs *dpll_reg = dpll_regs;
+
+	for (i = 0; i < ARRAY_SIZE(dpll_regs); i++, dpll_reg++) {
+		omap4_dpll_store_reg(dpll_reg, &dpll_reg->clkmode);
+		omap4_dpll_store_reg(dpll_reg, &dpll_reg->autoidle);
+		omap4_dpll_store_reg(dpll_reg, &dpll_reg->clksel);
+		omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m2);
+		omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m3);
+		omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m4);
+		omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m5);
+		omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m6);
+		omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m7);
+		omap4_dpll_store_reg(dpll_reg, &dpll_reg->clkdcoldo);
+		omap4_dpll_store_reg(dpll_reg, &dpll_reg->idlest);
+	}
+}
+
+/**
+ * omap4_dpll_print_reg - dump out a single DPLL register value
+ * @dpll_reg: register to dump
+ * @name: name of the register
+ * @tuple: content of the register
+ *
+ * Helper dump function to print out a DPLL register value in case
+ * of restore failures.
+ */
+static void omap4_dpll_print_reg(struct omap4_dpll_regs *dpll_reg, char *name,
+				 struct dpll_reg *tuple)
+{
+	if (tuple->offset)
+		pr_warn("%s - Address offset = 0x%08x, value=0x%08x\n", name,
+			tuple->offset, tuple->val);
+}
+
+/*
+ * omap4_dpll_dump_regs - dump out DPLL registers
+ * @dpll_reg: DPLL to dump
+ *
+ * Dump out the contents of the registers for a DPLL. Called if a
+ * restore for DPLL fails to lock.
+ */
+static void omap4_dpll_dump_regs(struct omap4_dpll_regs *dpll_reg)
+{
+	pr_warn("%s: Unable to lock dpll %s[part=%x inst=%x]:\n",
+		__func__, dpll_reg->name, dpll_reg->mod_partition,
+		dpll_reg->mod_inst);
+	omap4_dpll_print_reg(dpll_reg, "clksel", &dpll_reg->clksel);
+	omap4_dpll_print_reg(dpll_reg, "div_m2", &dpll_reg->div_m2);
+	omap4_dpll_print_reg(dpll_reg, "div_m3", &dpll_reg->div_m3);
+	omap4_dpll_print_reg(dpll_reg, "div_m4", &dpll_reg->div_m4);
+	omap4_dpll_print_reg(dpll_reg, "div_m5", &dpll_reg->div_m5);
+	omap4_dpll_print_reg(dpll_reg, "div_m6", &dpll_reg->div_m6);
+	omap4_dpll_print_reg(dpll_reg, "div_m7", &dpll_reg->div_m7);
+	omap4_dpll_print_reg(dpll_reg, "clkdcoldo", &dpll_reg->clkdcoldo);
+	omap4_dpll_print_reg(dpll_reg, "clkmode", &dpll_reg->clkmode);
+	omap4_dpll_print_reg(dpll_reg, "autoidle", &dpll_reg->autoidle);
+	if (dpll_reg->idlest.offset)
+		pr_warn("idlest - Address offset = 0x%08x, before val=0x%08x"
+			" after = 0x%08x\n", dpll_reg->idlest.offset,
+			dpll_reg->idlest.val,
+			omap4_dpll_read_reg(dpll_reg, &dpll_reg->idlest));
+}
+
+/**
+ * omap4_wait_dpll_lock - wait for a DPLL lock
+ * @dpll_reg: DPLL to wait for
+ *
+ * Waits for a DPLL lock after restore.
+ */
+static void omap4_wait_dpll_lock(struct omap4_dpll_regs *dpll_reg)
+{
+	int j = 0;
+	u32 status;
+
+	/* Return if we dont need to lock. */
+	if ((dpll_reg->clkmode.val & OMAP4430_DPLL_EN_MASK) !=
+	     DPLL_LOCKED << OMAP4430_DPLL_EN_SHIFT)
+		return;
+
+	while (1) {
+		status = (omap4_dpll_read_reg(dpll_reg, &dpll_reg->idlest)
+			  & OMAP4430_ST_DPLL_CLK_MASK)
+			 >> OMAP4430_ST_DPLL_CLK_SHIFT;
+		if (status == 0x1)
+			break;
+		if (j == MAX_DPLL_WAIT_TRIES) {
+			/* If we are unable to lock, warn and move on.. */
+			omap4_dpll_dump_regs(dpll_reg);
+			break;
+		}
+		j++;
+		udelay(1);
+	}
+}
+
+/**
+ * omap4_dpll_restore_reg - restores a single register for a DPLL
+ * @dpll_reg: DPLL to restore
+ * @tuple: register value to restore
+ *
+ * Restores a single register for a DPLL.
+ */
+static inline void omap4_dpll_restore_reg(struct omap4_dpll_regs *dpll_reg,
+					  struct dpll_reg *tuple)
+{
+	if (tuple->offset)
+		omap4_cminst_write_inst_reg(tuple->val, dpll_reg->mod_partition,
+					    dpll_reg->mod_inst, tuple->offset);
+}
+
+/**
+ * omap4_dpll_resume_off - restore DPLL settings after device off
+ *
+ * Restores all DPLL settings. Must be called after wakeup from device
+ * off.
+ */
+void omap4_dpll_resume_off(void)
+{
+	u32 i;
+	struct omap4_dpll_regs *dpll_reg = dpll_regs;
+
+	for (i = 0; i < ARRAY_SIZE(dpll_regs); i++, dpll_reg++) {
+		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clksel);
+		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m2);
+		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m3);
+		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m4);
+		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m5);
+		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m6);
+		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m7);
+		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkdcoldo);
+
+		/* Restore clkmode after the above registers are restored */
+		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkmode);
+
+		omap4_wait_dpll_lock(dpll_reg);
+
+		/* Restore autoidle settings after the dpll is locked */
+		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->autoidle);
+	}
+}
-- 
1.7.4.1

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

* [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
@ 2012-04-20  9:33   ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rajendra Nayak <rnayak@ti.com>

SAR/ROM code restores only CORE DPLL to its original state
post wakeup from OFF mode.
The rest of the DPLL's in OMAP4 platform (MPU/IVA/ABE/USB/PER)
are saved and restored here during an OFF transition.

[nm at ti.com: minor cleanups]
Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/cm44xx.h   |    5 +
 arch/arm/mach-omap2/dpll44xx.c |  271 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 276 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/cm44xx.h b/arch/arm/mach-omap2/cm44xx.h
index 3380bee..5fba0fa 100644
--- a/arch/arm/mach-omap2/cm44xx.h
+++ b/arch/arm/mach-omap2/cm44xx.h
@@ -23,4 +23,9 @@
 #define OMAP4_CM_CLKSTCTRL				0x0000
 #define OMAP4_CM_STATICDEP				0x0004
 
+#ifndef __ASSEMBLER__
+extern void omap4_dpll_prepare_off(void);
+extern void omap4_dpll_resume_off(void);
+#endif
+
 #endif
diff --git a/arch/arm/mach-omap2/dpll44xx.c b/arch/arm/mach-omap2/dpll44xx.c
index 9c6a296..b411d3b 100644
--- a/arch/arm/mach-omap2/dpll44xx.c
+++ b/arch/arm/mach-omap2/dpll44xx.c
@@ -14,6 +14,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/bitops.h>
+#include <linux/delay.h>
 
 #include <plat/cpu.h>
 #include <plat/clock.h>
@@ -21,6 +22,96 @@
 #include "clock.h"
 #include "clock44xx.h"
 #include "cm-regbits-44xx.h"
+#include "cm1_44xx.h"
+#include "cm2_44xx.h"
+#include "prcm44xx.h"
+#include "cminst44xx.h"
+#include "cm44xx.h"
+
+#define MAX_DPLL_WAIT_TRIES	1000000
+
+struct dpll_reg {
+	u16 offset;
+	u32 val;
+};
+
+struct omap4_dpll_regs {
+	char *name;
+	u32 mod_partition;
+	u32 mod_inst;
+	struct dpll_reg clkmode;
+	struct dpll_reg autoidle;
+	struct dpll_reg idlest;
+	struct dpll_reg clksel;
+	struct dpll_reg div_m2;
+	struct dpll_reg div_m3;
+	struct dpll_reg div_m4;
+	struct dpll_reg div_m5;
+	struct dpll_reg div_m6;
+	struct dpll_reg div_m7;
+	struct dpll_reg clkdcoldo;
+};
+
+static struct omap4_dpll_regs dpll_regs[] = {
+	/* MPU DPLL */
+	{ .name		= "mpu",
+	  .mod_partition = OMAP4430_CM1_PARTITION,
+	  .mod_inst	= OMAP4430_CM1_CKGEN_INST,
+	  .clkmode	= {.offset = OMAP4_CM_CLKMODE_DPLL_MPU_OFFSET},
+	  .autoidle	= {.offset = OMAP4_CM_AUTOIDLE_DPLL_MPU_OFFSET},
+	  .idlest	= {.offset = OMAP4_CM_IDLEST_DPLL_MPU_OFFSET},
+	  .clksel	= {.offset = OMAP4_CM_CLKSEL_DPLL_MPU_OFFSET},
+	  .div_m2	= {.offset = OMAP4_CM_DIV_M2_DPLL_MPU_OFFSET},
+	},
+	/* IVA DPLL */
+	{ .name		= "iva",
+	  .mod_partition = OMAP4430_CM1_PARTITION,
+	  .mod_inst	= OMAP4430_CM1_CKGEN_INST,
+	  .clkmode	= {.offset = OMAP4_CM_CLKMODE_DPLL_IVA_OFFSET},
+	  .autoidle	= {.offset = OMAP4_CM_AUTOIDLE_DPLL_IVA_OFFSET},
+	  .idlest	= {.offset = OMAP4_CM_IDLEST_DPLL_IVA_OFFSET},
+	  .clksel	= {.offset = OMAP4_CM_CLKSEL_DPLL_IVA_OFFSET},
+	  .div_m4	= {.offset = OMAP4_CM_DIV_M4_DPLL_IVA_OFFSET},
+	  .div_m5	= {.offset = OMAP4_CM_DIV_M5_DPLL_IVA_OFFSET},
+	},
+	/* ABE DPLL */
+	{ .name		= "abe",
+	  .mod_partition = OMAP4430_CM1_PARTITION,
+	  .mod_inst	= OMAP4430_CM1_CKGEN_INST,
+	  .clkmode	= {.offset = OMAP4_CM_CLKMODE_DPLL_ABE_OFFSET},
+	  .autoidle	= {.offset = OMAP4_CM_AUTOIDLE_DPLL_ABE_OFFSET},
+	  .idlest	= {.offset = OMAP4_CM_IDLEST_DPLL_ABE_OFFSET},
+	  .clksel	= {.offset = OMAP4_CM_CLKSEL_DPLL_ABE_OFFSET},
+	  .div_m2	= {.offset = OMAP4_CM_DIV_M2_DPLL_ABE_OFFSET},
+	  .div_m3	= {.offset = OMAP4_CM_DIV_M3_DPLL_ABE_OFFSET},
+	},
+	/* USB DPLL */
+	{ .name		= "usb",
+	  .mod_partition = OMAP4430_CM2_PARTITION,
+	  .mod_inst	= OMAP4430_CM2_CKGEN_INST,
+	  .clkmode	= {.offset = OMAP4_CM_CLKMODE_DPLL_USB_OFFSET},
+	  .autoidle	= {.offset = OMAP4_CM_AUTOIDLE_DPLL_USB_OFFSET},
+	  .idlest	= {.offset = OMAP4_CM_IDLEST_DPLL_USB_OFFSET},
+	  .clksel	= {.offset = OMAP4_CM_CLKSEL_DPLL_USB_OFFSET},
+	  .div_m2	= {.offset = OMAP4_CM_DIV_M2_DPLL_USB_OFFSET},
+	  .clkdcoldo	= {.offset = OMAP4_CM_CLKDCOLDO_DPLL_USB_OFFSET},
+	 },
+	/* PER DPLL */
+	{ .name		= "per",
+	  .mod_partition = OMAP4430_CM2_PARTITION,
+	  .mod_inst	= OMAP4430_CM2_CKGEN_INST,
+	  .clkmode	= {.offset = OMAP4_CM_CLKMODE_DPLL_PER_OFFSET},
+	  .autoidle	= {.offset = OMAP4_CM_AUTOIDLE_DPLL_PER_OFFSET},
+	  .idlest	= {.offset = OMAP4_CM_IDLEST_DPLL_PER_OFFSET},
+	  .clksel	= {.offset = OMAP4_CM_CLKSEL_DPLL_PER_OFFSET},
+	  .div_m2	= {.offset = OMAP4_CM_DIV_M2_DPLL_PER_OFFSET},
+	  .div_m3	= {.offset = OMAP4_CM_DIV_M3_DPLL_PER_OFFSET},
+	  .div_m4	= {.offset = OMAP4_CM_DIV_M4_DPLL_PER_OFFSET},
+	  .div_m5	= {.offset = OMAP4_CM_DIV_M5_DPLL_PER_OFFSET},
+	  .div_m6	= {.offset = OMAP4_CM_DIV_M6_DPLL_PER_OFFSET},
+	  .div_m7	= {.offset = OMAP4_CM_DIV_M7_DPLL_PER_OFFSET},
+	},
+};
 
 /* Supported only on OMAP4 */
 int omap4_dpllmx_gatectrl_read(struct clk *clk)
@@ -151,3 +242,183 @@ long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate)
 
 	return clk->dpll_data->last_rounded_rate;
 }
+
+/**
+ * omap4_dpll_read_reg - reads DPLL register value
+ * @dpll_reg: DPLL register to read
+ *
+ * Reads the value of a single DPLL register.
+ */
+static inline u32 omap4_dpll_read_reg(struct omap4_dpll_regs *dpll_reg,
+				      struct dpll_reg *tuple)
+{
+	if (tuple->offset)
+		return omap4_cminst_read_inst_reg(dpll_reg->mod_partition,
+						  dpll_reg->mod_inst,
+						  tuple->offset);
+	return 0;
+}
+
+/**
+ * omap4_dpll_store_reg - stores DPLL register value to memory location
+ * @dpll_reg: DPLL register to save
+ * @tuple: save address
+ *
+ * Saves a single DPLL register content to memory location defined by
+ * @tuple before entering device off mode.
+ */
+static inline void omap4_dpll_store_reg(struct omap4_dpll_regs *dpll_reg,
+					struct dpll_reg *tuple)
+{
+	tuple->val = omap4_dpll_read_reg(dpll_reg, tuple);
+}
+
+/**
+ * omap4_dpll_prepare_off - stores DPLL settings before off mode
+ *
+ * Saves all DPLL register settings. This must be called before
+ * entering device off.
+ */
+void omap4_dpll_prepare_off(void)
+{
+	u32 i;
+	struct omap4_dpll_regs *dpll_reg = dpll_regs;
+
+	for (i = 0; i < ARRAY_SIZE(dpll_regs); i++, dpll_reg++) {
+		omap4_dpll_store_reg(dpll_reg, &dpll_reg->clkmode);
+		omap4_dpll_store_reg(dpll_reg, &dpll_reg->autoidle);
+		omap4_dpll_store_reg(dpll_reg, &dpll_reg->clksel);
+		omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m2);
+		omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m3);
+		omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m4);
+		omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m5);
+		omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m6);
+		omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m7);
+		omap4_dpll_store_reg(dpll_reg, &dpll_reg->clkdcoldo);
+		omap4_dpll_store_reg(dpll_reg, &dpll_reg->idlest);
+	}
+}
+
+/**
+ * omap4_dpll_print_reg - dump out a single DPLL register value
+ * @dpll_reg: register to dump
+ * @name: name of the register
+ * @tuple: content of the register
+ *
+ * Helper dump function to print out a DPLL register value in case
+ * of restore failures.
+ */
+static void omap4_dpll_print_reg(struct omap4_dpll_regs *dpll_reg, char *name,
+				 struct dpll_reg *tuple)
+{
+	if (tuple->offset)
+		pr_warn("%s - Address offset = 0x%08x, value=0x%08x\n", name,
+			tuple->offset, tuple->val);
+}
+
+/*
+ * omap4_dpll_dump_regs - dump out DPLL registers
+ * @dpll_reg: DPLL to dump
+ *
+ * Dump out the contents of the registers for a DPLL. Called if a
+ * restore for DPLL fails to lock.
+ */
+static void omap4_dpll_dump_regs(struct omap4_dpll_regs *dpll_reg)
+{
+	pr_warn("%s: Unable to lock dpll %s[part=%x inst=%x]:\n",
+		__func__, dpll_reg->name, dpll_reg->mod_partition,
+		dpll_reg->mod_inst);
+	omap4_dpll_print_reg(dpll_reg, "clksel", &dpll_reg->clksel);
+	omap4_dpll_print_reg(dpll_reg, "div_m2", &dpll_reg->div_m2);
+	omap4_dpll_print_reg(dpll_reg, "div_m3", &dpll_reg->div_m3);
+	omap4_dpll_print_reg(dpll_reg, "div_m4", &dpll_reg->div_m4);
+	omap4_dpll_print_reg(dpll_reg, "div_m5", &dpll_reg->div_m5);
+	omap4_dpll_print_reg(dpll_reg, "div_m6", &dpll_reg->div_m6);
+	omap4_dpll_print_reg(dpll_reg, "div_m7", &dpll_reg->div_m7);
+	omap4_dpll_print_reg(dpll_reg, "clkdcoldo", &dpll_reg->clkdcoldo);
+	omap4_dpll_print_reg(dpll_reg, "clkmode", &dpll_reg->clkmode);
+	omap4_dpll_print_reg(dpll_reg, "autoidle", &dpll_reg->autoidle);
+	if (dpll_reg->idlest.offset)
+		pr_warn("idlest - Address offset = 0x%08x, before val=0x%08x"
+			" after = 0x%08x\n", dpll_reg->idlest.offset,
+			dpll_reg->idlest.val,
+			omap4_dpll_read_reg(dpll_reg, &dpll_reg->idlest));
+}
+
+/**
+ * omap4_wait_dpll_lock - wait for a DPLL lock
+ * @dpll_reg: DPLL to wait for
+ *
+ * Waits for a DPLL lock after restore.
+ */
+static void omap4_wait_dpll_lock(struct omap4_dpll_regs *dpll_reg)
+{
+	int j = 0;
+	u32 status;
+
+	/* Return if we dont need to lock. */
+	if ((dpll_reg->clkmode.val & OMAP4430_DPLL_EN_MASK) !=
+	     DPLL_LOCKED << OMAP4430_DPLL_EN_SHIFT)
+		return;
+
+	while (1) {
+		status = (omap4_dpll_read_reg(dpll_reg, &dpll_reg->idlest)
+			  & OMAP4430_ST_DPLL_CLK_MASK)
+			 >> OMAP4430_ST_DPLL_CLK_SHIFT;
+		if (status == 0x1)
+			break;
+		if (j == MAX_DPLL_WAIT_TRIES) {
+			/* If we are unable to lock, warn and move on.. */
+			omap4_dpll_dump_regs(dpll_reg);
+			break;
+		}
+		j++;
+		udelay(1);
+	}
+}
+
+/**
+ * omap4_dpll_restore_reg - restores a single register for a DPLL
+ * @dpll_reg: DPLL to restore
+ * @tuple: register value to restore
+ *
+ * Restores a single register for a DPLL.
+ */
+static inline void omap4_dpll_restore_reg(struct omap4_dpll_regs *dpll_reg,
+					  struct dpll_reg *tuple)
+{
+	if (tuple->offset)
+		omap4_cminst_write_inst_reg(tuple->val, dpll_reg->mod_partition,
+					    dpll_reg->mod_inst, tuple->offset);
+}
+
+/**
+ * omap4_dpll_resume_off - restore DPLL settings after device off
+ *
+ * Restores all DPLL settings. Must be called after wakeup from device
+ * off.
+ */
+void omap4_dpll_resume_off(void)
+{
+	u32 i;
+	struct omap4_dpll_regs *dpll_reg = dpll_regs;
+
+	for (i = 0; i < ARRAY_SIZE(dpll_regs); i++, dpll_reg++) {
+		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clksel);
+		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m2);
+		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m3);
+		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m4);
+		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m5);
+		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m6);
+		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m7);
+		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkdcoldo);
+
+		/* Restore clkmode after the above registers are restored */
+		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkmode);
+
+		omap4_wait_dpll_lock(dpll_reg);
+
+		/* Restore autoidle settings after the dpll is locked */
+		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->autoidle);
+	}
+}
-- 
1.7.4.1

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

* [PATCH 02/19] ARM: OMAP4: PM: save/restore all CM1/2 settings in OFF mode
  2012-04-20  9:33 ` Tero Kristo
@ 2012-04-20  9:33   ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-omap, khilman, paul
  Cc: linux-arm-kernel, Rajendra Nayak, Nishanth Menon,
	Santosh Shilimkar, Axel Haslam

From: Rajendra Nayak <rnayak@ti.com>

Restore all CM1/2 module registers as they are lost in OFF mode.

[nm@ti.com: minor clean ups]
Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Signed-off-by: Axel Haslam <axelhaslam@gmail.com>
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/cm44xx.c |  322 ++++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/cm44xx.h |    2 +
 2 files changed, 324 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/cm44xx.c b/arch/arm/mach-omap2/cm44xx.c
index 535d66e..fb5465b 100644
--- a/arch/arm/mach-omap2/cm44xx.c
+++ b/arch/arm/mach-omap2/cm44xx.c
@@ -21,8 +21,11 @@
 #include "iomap.h"
 #include "common.h"
 #include "cm.h"
+#include "cm44xx.h"
 #include "cm1_44xx.h"
 #include "cm2_44xx.h"
+#include "cminst44xx.h"
+#include "prcm44xx.h"
 #include "cm-regbits-44xx.h"
 
 /* CM1 hardware module low-level functions */
@@ -50,3 +53,322 @@ void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 reg)
 {
 	__raw_writel(val, OMAP44XX_CM2_REGADDR(inst, reg));
 }
+
+#define MAX_CM_REGISTERS 51
+
+struct omap4_cm_reg {
+	u16 offset;
+	u32 val;
+};
+
+struct omap4_cm_regs {
+	u32 mod_off;
+	u32 no_reg;
+	struct omap4_cm_reg reg[MAX_CM_REGISTERS];
+};
+
+static struct omap4_cm_regs cm1_regs[] = {
+	/* OMAP4430_CM1_OCP_SOCKET_MOD */
+	{ .mod_off = OMAP4430_CM1_OCP_SOCKET_INST, .no_reg = 1,
+	{{.offset = OMAP4_CM_CM1_PROFILING_CLKCTRL_OFFSET} },
+	},
+	/* OMAP4430_CM1_CKGEN_MOD */
+	{ .mod_off = OMAP4430_CM1_CKGEN_INST, .no_reg = 4,
+	{{.offset = OMAP4_CM_CLKSEL_CORE_OFFSET},
+	 {.offset = OMAP4_CM_CLKSEL_ABE_OFFSET},
+	 {.offset = OMAP4_CM_DLL_CTRL_OFFSET},
+	 {.offset = OMAP4_CM_DYN_DEP_PRESCAL_OFFSET} },
+	},
+	/* OMAP4430_CM1_MPU_MOD */
+	{ .mod_off = OMAP4430_CM1_MPU_INST, .no_reg = 4,
+	{{.offset = OMAP4_CM_MPU_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_MPU_STATICDEP_OFFSET},
+	 {.offset = OMAP4_CM_MPU_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_MPU_MPU_CLKCTRL_OFFSET} },
+	},
+	/* OMAP4430_CM1_TESLA_MOD */
+	{ .mod_off = OMAP4430_CM1_TESLA_INST, .no_reg = 4,
+	{{.offset = OMAP4_CM_TESLA_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_TESLA_STATICDEP_OFFSET},
+	 {.offset = OMAP4_CM_TESLA_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_TESLA_TESLA_CLKCTRL_OFFSET} },
+	},
+	/* OMAP4430_CM1_ABE_MOD */
+	{ .mod_off = OMAP4430_CM1_ABE_INST, .no_reg = 15,
+	{{.offset = OMAP4_CM1_ABE_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_L4ABE_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_AESS_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_PDM_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_DMIC_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_MCASP_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_MCBSP1_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_MCBSP2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_MCBSP3_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_SLIMBUS_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_TIMER5_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_TIMER6_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_TIMER7_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_TIMER8_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_WDT3_CLKCTRL_OFFSET} },
+	},
+};
+
+static struct omap4_cm_regs cm2_regs[] = {
+	/* OMAP4430_CM2_OCP_SOCKET_MOD */
+	{.mod_off = OMAP4430_CM2_OCP_SOCKET_INST, .no_reg = 1,
+	{{.offset = OMAP4_CM_CM2_PROFILING_CLKCTRL_OFFSET} },
+	},
+	/* OMAP4430_CM2_CKGEN_MOD */
+	{.mod_off = OMAP4430_CM2_CKGEN_INST, .no_reg = 12,
+	{{.offset = OMAP4_CM_CLKSEL_DUCATI_ISS_ROOT_OFFSET},
+	 {.offset = OMAP4_CM_CLKSEL_USB_60MHZ_OFFSET},
+	 {.offset = OMAP4_CM_SCALE_FCLK_OFFSET},
+	 {.offset = OMAP4_CM_CORE_DVFS_PERF1_OFFSET},
+	 {.offset = OMAP4_CM_CORE_DVFS_PERF2_OFFSET},
+	 {.offset = OMAP4_CM_CORE_DVFS_PERF3_OFFSET},
+	 {.offset = OMAP4_CM_CORE_DVFS_PERF4_OFFSET},
+	 {.offset = OMAP4_CM_CORE_DVFS_CURRENT_OFFSET},
+	 {.offset = OMAP4_CM_IVA_DVFS_PERF_TESLA_OFFSET},
+	 {.offset = OMAP4_CM_IVA_DVFS_PERF_IVAHD_OFFSET},
+	 {.offset = OMAP4_CM_IVA_DVFS_PERF_ABE_OFFSET},
+	 {.offset = OMAP4_CM_IVA_DVFS_CURRENT_OFFSET} },
+	},
+	/* OMAP4430_CM2_ALWAYS_ON_MOD */
+	{.mod_off = OMAP4430_CM2_ALWAYS_ON_INST, .no_reg = 6,
+	{{.offset = OMAP4_CM_ALWON_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_ALWON_MDMINTC_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_ALWON_SR_MPU_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_ALWON_SR_IVA_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_ALWON_SR_CORE_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_ALWON_USBPHY_CLKCTRL_OFFSET} },
+	},
+	/* OMAP4430_CM2_CORE_MOD */
+	{.mod_off = OMAP4430_CM2_CORE_INST, .no_reg = 41,
+	{{.offset = OMAP4_CM_L3_1_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3_1_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_L3_1_L3_1_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3_2_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3_2_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_L3_2_L3_2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3_2_GPMC_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3_2_OCMC_RAM_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_DUCATI_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_DUCATI_STATICDEP_OFFSET},
+	 {.offset = OMAP4_CM_DUCATI_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_SDMA_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_SDMA_STATICDEP_OFFSET},
+	 {.offset = OMAP4_CM_SDMA_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_SDMA_SDMA_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_MEMIF_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_MEMIF_DMM_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_MEMIF_EMIF_FW_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_MEMIF_EMIF_1_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_MEMIF_EMIF_2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_MEMIF_DLL_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_MEMIF_EMIF_H1_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_MEMIF_EMIF_H2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_MEMIF_DLL_H_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_D2D_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_D2D_STATICDEP_OFFSET},
+	 {.offset = OMAP4_CM_D2D_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_D2D_SAD2D_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_D2D_MODEM_ICR_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_D2D_SAD2D_FW_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4CFG_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4CFG_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4CFG_HW_SEM_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4CFG_MAILBOX_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4CFG_SAR_ROM_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INSTR_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INSTR_L3_3_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INSTR_OCP_WP1_CLKCTRL_OFFSET} },
+	},
+	/* OMAP4430_CM2_IVAHD_MOD */
+	{.mod_off = OMAP4430_CM2_IVAHD_INST, .no_reg = 5,
+	{{.offset = OMAP4_CM_IVAHD_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_IVAHD_STATICDEP_OFFSET},
+	 {.offset = OMAP4_CM_IVAHD_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_IVAHD_IVAHD_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_IVAHD_SL2_CLKCTRL_OFFSET} },
+	},
+	/* OMAP4430_CM2_CAM_MOD */
+	{.mod_off = OMAP4430_CM2_CAM_INST, .no_reg = 5,
+	{{.offset = OMAP4_CM_CAM_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_CAM_STATICDEP_OFFSET},
+	 {.offset = OMAP4_CM_CAM_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_CAM_ISS_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_CAM_FDIF_CLKCTRL_OFFSET} },
+	},
+	/* OMAP4430_CM2_DSS_MOD */
+	{.mod_off = OMAP4430_CM2_DSS_INST, .no_reg = 5,
+	{{.offset = OMAP4_CM_DSS_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_DSS_STATICDEP_OFFSET},
+	 {.offset = OMAP4_CM_DSS_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_DSS_DEISS_CLKCTRL_OFFSET} },
+	},
+	/* OMAP4430_CM2_GFX_MOD */
+	{.mod_off = OMAP4430_CM2_GFX_INST, .no_reg = 4,
+	{{.offset = OMAP4_CM_GFX_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_GFX_STATICDEP_OFFSET},
+	 {.offset = OMAP4_CM_GFX_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_GFX_GFX_CLKCTRL_OFFSET} },
+	},
+	/* OMAP4430_CM2_L3INIT_MOD */
+	{.mod_off = OMAP4430_CM2_L3INIT_INST, .no_reg = 20,
+	{{.offset = OMAP4_CM_L3INIT_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_STATICDEP_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_MMC1_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_MMC2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_HSI_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_UNIPRO1_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_USB_OTG_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_P1500_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_EMAC_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_SATA_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_TPPSS_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_PCIESS_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_CCPTX_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_XHPI_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_MMC6_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_USB_HOST_FS_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL_OFFSET} },
+	},
+	/* OMAP4430_CM2_L4PER_MOD */
+	{.mod_off = OMAP4430_CM2_L4PER_INST, .no_reg = 51,
+	{{.offset = OMAP4_CM_L4PER_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_ADC_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_DMTIMER10_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_DMTIMER11_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_DMTIMER2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_DMTIMER3_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_DMTIMER4_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_DMTIMER9_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_ELM_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_GPIO2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_GPIO3_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_GPIO4_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_GPIO5_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_GPIO6_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_HDQ1W_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_HECC1_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_HECC2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_I2C1_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_I2C2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_I2C3_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_I2C4_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_L4PER_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_MCASP2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_MCASP3_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_MCBSP4_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_MGATE_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_MCSPI1_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_MCSPI2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_MCSPI3_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_MCSPI4_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_MMCSD3_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_MMCSD4_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_MSPROHG_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_SLIMBUS2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_UART1_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_UART2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_UART3_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_UART4_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_MMCSD5_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_I2C5_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4SEC_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4SEC_STATICDEP_OFFSET},
+	 {.offset = OMAP4_CM_L4SEC_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_L4SEC_AES1_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4SEC_AES2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4SEC_DES3DES_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4SEC_PKAEIP29_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4SEC_RNG_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4SEC_SHA2MD51_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4SEC_CRYPTODMA_CLKCTRL_OFFSET} },
+	},
+	/* OMAP4430_CM2_CEFUSE_MOD */
+	{.mod_off = OMAP4430_CM2_CEFUSE_INST, .no_reg = 2,
+	{{.offset = OMAP4_CM_CEFUSE_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_CEFUSE_CEFUSE_CLKCTRL_OFFSET} },
+	},
+};
+
+static void omap4_cm1_prepare_off(void)
+{
+	u32 i, j;
+	struct omap4_cm_regs *cm_reg = cm1_regs;
+
+	for (i = 0; i < ARRAY_SIZE(cm1_regs); i++, cm_reg++) {
+		for (j = 0; j < cm_reg->no_reg; j++) {
+			cm_reg->reg[j].val =
+			    omap4_cminst_read_inst_reg(OMAP4430_CM1_PARTITION,
+						       cm_reg->mod_off,
+						       cm_reg->reg[j].offset);
+		}
+	}
+}
+
+static void omap4_cm2_prepare_off(void)
+{
+	u32 i, j;
+	struct omap4_cm_regs *cm_reg = cm2_regs;
+
+	for (i = 0; i < ARRAY_SIZE(cm2_regs); i++, cm_reg++) {
+		for (j = 0; j < cm_reg->no_reg; j++) {
+			cm_reg->reg[j].val =
+			    omap4_cminst_read_inst_reg(OMAP4430_CM2_PARTITION,
+						       cm_reg->mod_off,
+						       cm_reg->reg[j].offset);
+		}
+	}
+}
+
+static void omap4_cm1_resume_off(void)
+{
+	u32 i, j;
+	struct omap4_cm_regs *cm_reg = cm1_regs;
+
+	for (i = 0; i < ARRAY_SIZE(cm1_regs); i++, cm_reg++) {
+		for (j = 0; j < cm_reg->no_reg; j++) {
+			omap4_cminst_write_inst_reg(cm_reg->reg[j].val,
+						    OMAP4430_CM1_PARTITION,
+						    cm_reg->mod_off,
+						    cm_reg->reg[j].offset);
+		}
+	}
+}
+
+static void omap4_cm2_resume_off(void)
+{
+	u32 i, j;
+	struct omap4_cm_regs *cm_reg = cm2_regs;
+
+	for (i = 0; i < ARRAY_SIZE(cm2_regs); i++, cm_reg++) {
+		for (j = 0; j < cm_reg->no_reg; j++) {
+			omap4_cminst_write_inst_reg(cm_reg->reg[j].val,
+						    OMAP4430_CM2_PARTITION,
+						    cm_reg->mod_off,
+						    cm_reg->reg[j].offset);
+		}
+	}
+}
+
+void omap4_cm_prepare_off(void)
+{
+	omap4_cm1_prepare_off();
+	omap4_cm2_prepare_off();
+}
+
+void omap4_cm_resume_off(void)
+{
+	omap4_cm1_resume_off();
+	omap4_cm2_resume_off();
+}
diff --git a/arch/arm/mach-omap2/cm44xx.h b/arch/arm/mach-omap2/cm44xx.h
index 5fba0fa..b3b0f21 100644
--- a/arch/arm/mach-omap2/cm44xx.h
+++ b/arch/arm/mach-omap2/cm44xx.h
@@ -24,6 +24,8 @@
 #define OMAP4_CM_STATICDEP				0x0004
 
 #ifndef __ASSEMBLER__
+extern void omap4_cm_prepare_off(void);
+extern void omap4_cm_resume_off(void);
 extern void omap4_dpll_prepare_off(void);
 extern void omap4_dpll_resume_off(void);
 #endif
-- 
1.7.4.1


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

* [PATCH 02/19] ARM: OMAP4: PM: save/restore all CM1/2 settings in OFF mode
@ 2012-04-20  9:33   ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rajendra Nayak <rnayak@ti.com>

Restore all CM1/2 module registers as they are lost in OFF mode.

[nm at ti.com: minor clean ups]
Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Signed-off-by: Axel Haslam <axelhaslam@gmail.com>
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/cm44xx.c |  322 ++++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/cm44xx.h |    2 +
 2 files changed, 324 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/cm44xx.c b/arch/arm/mach-omap2/cm44xx.c
index 535d66e..fb5465b 100644
--- a/arch/arm/mach-omap2/cm44xx.c
+++ b/arch/arm/mach-omap2/cm44xx.c
@@ -21,8 +21,11 @@
 #include "iomap.h"
 #include "common.h"
 #include "cm.h"
+#include "cm44xx.h"
 #include "cm1_44xx.h"
 #include "cm2_44xx.h"
+#include "cminst44xx.h"
+#include "prcm44xx.h"
 #include "cm-regbits-44xx.h"
 
 /* CM1 hardware module low-level functions */
@@ -50,3 +53,322 @@ void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 reg)
 {
 	__raw_writel(val, OMAP44XX_CM2_REGADDR(inst, reg));
 }
+
+#define MAX_CM_REGISTERS 51
+
+struct omap4_cm_reg {
+	u16 offset;
+	u32 val;
+};
+
+struct omap4_cm_regs {
+	u32 mod_off;
+	u32 no_reg;
+	struct omap4_cm_reg reg[MAX_CM_REGISTERS];
+};
+
+static struct omap4_cm_regs cm1_regs[] = {
+	/* OMAP4430_CM1_OCP_SOCKET_MOD */
+	{ .mod_off = OMAP4430_CM1_OCP_SOCKET_INST, .no_reg = 1,
+	{{.offset = OMAP4_CM_CM1_PROFILING_CLKCTRL_OFFSET} },
+	},
+	/* OMAP4430_CM1_CKGEN_MOD */
+	{ .mod_off = OMAP4430_CM1_CKGEN_INST, .no_reg = 4,
+	{{.offset = OMAP4_CM_CLKSEL_CORE_OFFSET},
+	 {.offset = OMAP4_CM_CLKSEL_ABE_OFFSET},
+	 {.offset = OMAP4_CM_DLL_CTRL_OFFSET},
+	 {.offset = OMAP4_CM_DYN_DEP_PRESCAL_OFFSET} },
+	},
+	/* OMAP4430_CM1_MPU_MOD */
+	{ .mod_off = OMAP4430_CM1_MPU_INST, .no_reg = 4,
+	{{.offset = OMAP4_CM_MPU_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_MPU_STATICDEP_OFFSET},
+	 {.offset = OMAP4_CM_MPU_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_MPU_MPU_CLKCTRL_OFFSET} },
+	},
+	/* OMAP4430_CM1_TESLA_MOD */
+	{ .mod_off = OMAP4430_CM1_TESLA_INST, .no_reg = 4,
+	{{.offset = OMAP4_CM_TESLA_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_TESLA_STATICDEP_OFFSET},
+	 {.offset = OMAP4_CM_TESLA_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_TESLA_TESLA_CLKCTRL_OFFSET} },
+	},
+	/* OMAP4430_CM1_ABE_MOD */
+	{ .mod_off = OMAP4430_CM1_ABE_INST, .no_reg = 15,
+	{{.offset = OMAP4_CM1_ABE_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_L4ABE_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_AESS_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_PDM_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_DMIC_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_MCASP_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_MCBSP1_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_MCBSP2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_MCBSP3_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_SLIMBUS_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_TIMER5_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_TIMER6_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_TIMER7_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_TIMER8_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM1_ABE_WDT3_CLKCTRL_OFFSET} },
+	},
+};
+
+static struct omap4_cm_regs cm2_regs[] = {
+	/* OMAP4430_CM2_OCP_SOCKET_MOD */
+	{.mod_off = OMAP4430_CM2_OCP_SOCKET_INST, .no_reg = 1,
+	{{.offset = OMAP4_CM_CM2_PROFILING_CLKCTRL_OFFSET} },
+	},
+	/* OMAP4430_CM2_CKGEN_MOD */
+	{.mod_off = OMAP4430_CM2_CKGEN_INST, .no_reg = 12,
+	{{.offset = OMAP4_CM_CLKSEL_DUCATI_ISS_ROOT_OFFSET},
+	 {.offset = OMAP4_CM_CLKSEL_USB_60MHZ_OFFSET},
+	 {.offset = OMAP4_CM_SCALE_FCLK_OFFSET},
+	 {.offset = OMAP4_CM_CORE_DVFS_PERF1_OFFSET},
+	 {.offset = OMAP4_CM_CORE_DVFS_PERF2_OFFSET},
+	 {.offset = OMAP4_CM_CORE_DVFS_PERF3_OFFSET},
+	 {.offset = OMAP4_CM_CORE_DVFS_PERF4_OFFSET},
+	 {.offset = OMAP4_CM_CORE_DVFS_CURRENT_OFFSET},
+	 {.offset = OMAP4_CM_IVA_DVFS_PERF_TESLA_OFFSET},
+	 {.offset = OMAP4_CM_IVA_DVFS_PERF_IVAHD_OFFSET},
+	 {.offset = OMAP4_CM_IVA_DVFS_PERF_ABE_OFFSET},
+	 {.offset = OMAP4_CM_IVA_DVFS_CURRENT_OFFSET} },
+	},
+	/* OMAP4430_CM2_ALWAYS_ON_MOD */
+	{.mod_off = OMAP4430_CM2_ALWAYS_ON_INST, .no_reg = 6,
+	{{.offset = OMAP4_CM_ALWON_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_ALWON_MDMINTC_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_ALWON_SR_MPU_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_ALWON_SR_IVA_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_ALWON_SR_CORE_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_ALWON_USBPHY_CLKCTRL_OFFSET} },
+	},
+	/* OMAP4430_CM2_CORE_MOD */
+	{.mod_off = OMAP4430_CM2_CORE_INST, .no_reg = 41,
+	{{.offset = OMAP4_CM_L3_1_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3_1_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_L3_1_L3_1_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3_2_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3_2_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_L3_2_L3_2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3_2_GPMC_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3_2_OCMC_RAM_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_DUCATI_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_DUCATI_STATICDEP_OFFSET},
+	 {.offset = OMAP4_CM_DUCATI_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_SDMA_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_SDMA_STATICDEP_OFFSET},
+	 {.offset = OMAP4_CM_SDMA_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_SDMA_SDMA_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_MEMIF_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_MEMIF_DMM_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_MEMIF_EMIF_FW_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_MEMIF_EMIF_1_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_MEMIF_EMIF_2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_MEMIF_DLL_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_MEMIF_EMIF_H1_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_MEMIF_EMIF_H2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_MEMIF_DLL_H_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_D2D_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_D2D_STATICDEP_OFFSET},
+	 {.offset = OMAP4_CM_D2D_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_D2D_SAD2D_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_D2D_MODEM_ICR_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_D2D_SAD2D_FW_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4CFG_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4CFG_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4CFG_HW_SEM_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4CFG_MAILBOX_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4CFG_SAR_ROM_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INSTR_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INSTR_L3_3_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INSTR_OCP_WP1_CLKCTRL_OFFSET} },
+	},
+	/* OMAP4430_CM2_IVAHD_MOD */
+	{.mod_off = OMAP4430_CM2_IVAHD_INST, .no_reg = 5,
+	{{.offset = OMAP4_CM_IVAHD_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_IVAHD_STATICDEP_OFFSET},
+	 {.offset = OMAP4_CM_IVAHD_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_IVAHD_IVAHD_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_IVAHD_SL2_CLKCTRL_OFFSET} },
+	},
+	/* OMAP4430_CM2_CAM_MOD */
+	{.mod_off = OMAP4430_CM2_CAM_INST, .no_reg = 5,
+	{{.offset = OMAP4_CM_CAM_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_CAM_STATICDEP_OFFSET},
+	 {.offset = OMAP4_CM_CAM_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_CAM_ISS_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_CAM_FDIF_CLKCTRL_OFFSET} },
+	},
+	/* OMAP4430_CM2_DSS_MOD */
+	{.mod_off = OMAP4430_CM2_DSS_INST, .no_reg = 5,
+	{{.offset = OMAP4_CM_DSS_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_DSS_STATICDEP_OFFSET},
+	 {.offset = OMAP4_CM_DSS_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_DSS_DEISS_CLKCTRL_OFFSET} },
+	},
+	/* OMAP4430_CM2_GFX_MOD */
+	{.mod_off = OMAP4430_CM2_GFX_INST, .no_reg = 4,
+	{{.offset = OMAP4_CM_GFX_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_GFX_STATICDEP_OFFSET},
+	 {.offset = OMAP4_CM_GFX_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_GFX_GFX_CLKCTRL_OFFSET} },
+	},
+	/* OMAP4430_CM2_L3INIT_MOD */
+	{.mod_off = OMAP4430_CM2_L3INIT_INST, .no_reg = 20,
+	{{.offset = OMAP4_CM_L3INIT_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_STATICDEP_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_MMC1_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_MMC2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_HSI_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_UNIPRO1_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_USB_OTG_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_P1500_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_EMAC_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_SATA_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_TPPSS_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_PCIESS_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_CCPTX_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_XHPI_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_MMC6_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_USB_HOST_FS_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL_OFFSET} },
+	},
+	/* OMAP4430_CM2_L4PER_MOD */
+	{.mod_off = OMAP4430_CM2_L4PER_INST, .no_reg = 51,
+	{{.offset = OMAP4_CM_L4PER_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_ADC_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_DMTIMER10_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_DMTIMER11_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_DMTIMER2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_DMTIMER3_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_DMTIMER4_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_DMTIMER9_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_ELM_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_GPIO2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_GPIO3_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_GPIO4_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_GPIO5_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_GPIO6_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_HDQ1W_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_HECC1_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_HECC2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_I2C1_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_I2C2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_I2C3_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_I2C4_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_L4PER_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_MCASP2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_MCASP3_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_MCBSP4_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_MGATE_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_MCSPI1_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_MCSPI2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_MCSPI3_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_MCSPI4_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_MMCSD3_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_MMCSD4_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_MSPROHG_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_SLIMBUS2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_UART1_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_UART2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_UART3_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_UART4_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_MMCSD5_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4PER_I2C5_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4SEC_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4SEC_STATICDEP_OFFSET},
+	 {.offset = OMAP4_CM_L4SEC_DYNAMICDEP_OFFSET},
+	 {.offset = OMAP4_CM_L4SEC_AES1_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4SEC_AES2_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4SEC_DES3DES_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4SEC_PKAEIP29_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4SEC_RNG_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4SEC_SHA2MD51_CLKCTRL_OFFSET},
+	 {.offset = OMAP4_CM_L4SEC_CRYPTODMA_CLKCTRL_OFFSET} },
+	},
+	/* OMAP4430_CM2_CEFUSE_MOD */
+	{.mod_off = OMAP4430_CM2_CEFUSE_INST, .no_reg = 2,
+	{{.offset = OMAP4_CM_CEFUSE_CLKSTCTRL_OFFSET},
+	 {.offset = OMAP4_CM_CEFUSE_CEFUSE_CLKCTRL_OFFSET} },
+	},
+};
+
+static void omap4_cm1_prepare_off(void)
+{
+	u32 i, j;
+	struct omap4_cm_regs *cm_reg = cm1_regs;
+
+	for (i = 0; i < ARRAY_SIZE(cm1_regs); i++, cm_reg++) {
+		for (j = 0; j < cm_reg->no_reg; j++) {
+			cm_reg->reg[j].val =
+			    omap4_cminst_read_inst_reg(OMAP4430_CM1_PARTITION,
+						       cm_reg->mod_off,
+						       cm_reg->reg[j].offset);
+		}
+	}
+}
+
+static void omap4_cm2_prepare_off(void)
+{
+	u32 i, j;
+	struct omap4_cm_regs *cm_reg = cm2_regs;
+
+	for (i = 0; i < ARRAY_SIZE(cm2_regs); i++, cm_reg++) {
+		for (j = 0; j < cm_reg->no_reg; j++) {
+			cm_reg->reg[j].val =
+			    omap4_cminst_read_inst_reg(OMAP4430_CM2_PARTITION,
+						       cm_reg->mod_off,
+						       cm_reg->reg[j].offset);
+		}
+	}
+}
+
+static void omap4_cm1_resume_off(void)
+{
+	u32 i, j;
+	struct omap4_cm_regs *cm_reg = cm1_regs;
+
+	for (i = 0; i < ARRAY_SIZE(cm1_regs); i++, cm_reg++) {
+		for (j = 0; j < cm_reg->no_reg; j++) {
+			omap4_cminst_write_inst_reg(cm_reg->reg[j].val,
+						    OMAP4430_CM1_PARTITION,
+						    cm_reg->mod_off,
+						    cm_reg->reg[j].offset);
+		}
+	}
+}
+
+static void omap4_cm2_resume_off(void)
+{
+	u32 i, j;
+	struct omap4_cm_regs *cm_reg = cm2_regs;
+
+	for (i = 0; i < ARRAY_SIZE(cm2_regs); i++, cm_reg++) {
+		for (j = 0; j < cm_reg->no_reg; j++) {
+			omap4_cminst_write_inst_reg(cm_reg->reg[j].val,
+						    OMAP4430_CM2_PARTITION,
+						    cm_reg->mod_off,
+						    cm_reg->reg[j].offset);
+		}
+	}
+}
+
+void omap4_cm_prepare_off(void)
+{
+	omap4_cm1_prepare_off();
+	omap4_cm2_prepare_off();
+}
+
+void omap4_cm_resume_off(void)
+{
+	omap4_cm1_resume_off();
+	omap4_cm2_resume_off();
+}
diff --git a/arch/arm/mach-omap2/cm44xx.h b/arch/arm/mach-omap2/cm44xx.h
index 5fba0fa..b3b0f21 100644
--- a/arch/arm/mach-omap2/cm44xx.h
+++ b/arch/arm/mach-omap2/cm44xx.h
@@ -24,6 +24,8 @@
 #define OMAP4_CM_STATICDEP				0x0004
 
 #ifndef __ASSEMBLER__
+extern void omap4_cm_prepare_off(void);
+extern void omap4_cm_resume_off(void);
 extern void omap4_dpll_prepare_off(void);
 extern void omap4_dpll_resume_off(void);
 #endif
-- 
1.7.4.1

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

* [PATCH 03/19] ARM: OMAP4: PM: powerdomain: Add HWSAR flag to L3INIT
  2012-04-20  9:33 ` Tero Kristo
@ 2012-04-20  9:33   ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-omap, khilman, paul; +Cc: linux-arm-kernel, Santosh Shilimkar

From: Santosh Shilimkar <santosh.shilimkar@ti.com>

L3INIT powerdomain has USB HOST and USB TLL modules which support
hardware save-and-restore (HW SAR) mechanism.
This patch updates the L3INIT power domain to mark them as capable
of doing H/w save and restore and provides functions to do them
explicitly.

Note: Eventually, these custom function implementation will be
abstracted and might be done in hwmod or in other layer.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/powerdomain44xx.c       |   41 +++++++++++++++++++++++++++
 arch/arm/mach-omap2/powerdomains44xx_data.c |    2 +-
 2 files changed, 42 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomain44xx.c b/arch/arm/mach-omap2/powerdomain44xx.c
index 601325b..9bfb8a0 100644
--- a/arch/arm/mach-omap2/powerdomain44xx.c
+++ b/arch/arm/mach-omap2/powerdomain44xx.c
@@ -23,6 +23,10 @@
 #include "prm44xx.h"
 #include "prminst44xx.h"
 #include "prm-regbits-44xx.h"
+#include "cm-regbits-44xx.h"
+#include "prcm44xx.h"
+#include "cm2_44xx.h"
+#include "cminst44xx.h"
 
 static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
 {
@@ -208,6 +212,41 @@ static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm)
 	return 0;
 }
 
+static int omap4_pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
+{
+	/*
+	 * FIXME: This should be fixed right way by moving it into HWMOD
+	 * or clock framework since sar control is moved to module level
+	 */
+	omap4_cminst_rmw_inst_reg_bits(OMAP4430_SAR_MODE_MASK,
+		1 << OMAP4430_SAR_MODE_SHIFT, OMAP4430_CM2_PARTITION,
+		OMAP4430_CM2_L3INIT_INST,
+		OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET);
+	omap4_cminst_rmw_inst_reg_bits(OMAP4430_SAR_MODE_MASK,
+		1 << OMAP4430_SAR_MODE_SHIFT, OMAP4430_CM2_PARTITION,
+		OMAP4430_CM2_L3INIT_INST,
+		OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET);
+	return 0;
+}
+
+static int omap4_pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
+{
+	/*
+	 * FIXME: This should be fixed right way by moving it into HWMOD
+	 * or clock framework since sar control is moved to module level
+	 */
+	omap4_cminst_rmw_inst_reg_bits(OMAP4430_SAR_MODE_MASK,
+		0 << OMAP4430_SAR_MODE_SHIFT, OMAP4430_CM2_PARTITION,
+		OMAP4430_CM2_L3INIT_INST,
+		OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET);
+	omap4_cminst_rmw_inst_reg_bits(OMAP4430_SAR_MODE_MASK,
+		0 << OMAP4430_SAR_MODE_SHIFT, OMAP4430_CM2_PARTITION,
+		OMAP4430_CM2_L3INIT_INST,
+		OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET);
+
+	return 0;
+}
+
 struct pwrdm_ops omap4_pwrdm_operations = {
 	.pwrdm_set_next_pwrst	= omap4_pwrdm_set_next_pwrst,
 	.pwrdm_read_next_pwrst	= omap4_pwrdm_read_next_pwrst,
@@ -223,4 +262,6 @@ struct pwrdm_ops omap4_pwrdm_operations = {
 	.pwrdm_set_mem_onst	= omap4_pwrdm_set_mem_onst,
 	.pwrdm_set_mem_retst	= omap4_pwrdm_set_mem_retst,
 	.pwrdm_wait_transition	= omap4_pwrdm_wait_transition,
+	.pwrdm_enable_hdwr_sar	= omap4_pwrdm_enable_hdwr_sar,
+	.pwrdm_disable_hdwr_sar	= omap4_pwrdm_disable_hdwr_sar,
 };
diff --git a/arch/arm/mach-omap2/powerdomains44xx_data.c b/arch/arm/mach-omap2/powerdomains44xx_data.c
index 704664c..d8701ce 100644
--- a/arch/arm/mach-omap2/powerdomains44xx_data.c
+++ b/arch/arm/mach-omap2/powerdomains44xx_data.c
@@ -276,7 +276,7 @@ static struct powerdomain l3init_44xx_pwrdm = {
 	.pwrsts_mem_on	= {
 		[0] = PWRSTS_ON,	/* l3init_bank1 */
 	},
-	.flags		  = PWRDM_HAS_LOWPOWERSTATECHANGE,
+	.flags		  = PWRDM_HAS_LOWPOWERSTATECHANGE | PWRDM_HAS_HDWR_SAR,
 };
 
 /* l4per_44xx_pwrdm: Target peripherals power domain */
-- 
1.7.4.1


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

* [PATCH 03/19] ARM: OMAP4: PM: powerdomain: Add HWSAR flag to L3INIT
@ 2012-04-20  9:33   ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-arm-kernel

From: Santosh Shilimkar <santosh.shilimkar@ti.com>

L3INIT powerdomain has USB HOST and USB TLL modules which support
hardware save-and-restore (HW SAR) mechanism.
This patch updates the L3INIT power domain to mark them as capable
of doing H/w save and restore and provides functions to do them
explicitly.

Note: Eventually, these custom function implementation will be
abstracted and might be done in hwmod or in other layer.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/powerdomain44xx.c       |   41 +++++++++++++++++++++++++++
 arch/arm/mach-omap2/powerdomains44xx_data.c |    2 +-
 2 files changed, 42 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomain44xx.c b/arch/arm/mach-omap2/powerdomain44xx.c
index 601325b..9bfb8a0 100644
--- a/arch/arm/mach-omap2/powerdomain44xx.c
+++ b/arch/arm/mach-omap2/powerdomain44xx.c
@@ -23,6 +23,10 @@
 #include "prm44xx.h"
 #include "prminst44xx.h"
 #include "prm-regbits-44xx.h"
+#include "cm-regbits-44xx.h"
+#include "prcm44xx.h"
+#include "cm2_44xx.h"
+#include "cminst44xx.h"
 
 static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
 {
@@ -208,6 +212,41 @@ static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm)
 	return 0;
 }
 
+static int omap4_pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
+{
+	/*
+	 * FIXME: This should be fixed right way by moving it into HWMOD
+	 * or clock framework since sar control is moved to module level
+	 */
+	omap4_cminst_rmw_inst_reg_bits(OMAP4430_SAR_MODE_MASK,
+		1 << OMAP4430_SAR_MODE_SHIFT, OMAP4430_CM2_PARTITION,
+		OMAP4430_CM2_L3INIT_INST,
+		OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET);
+	omap4_cminst_rmw_inst_reg_bits(OMAP4430_SAR_MODE_MASK,
+		1 << OMAP4430_SAR_MODE_SHIFT, OMAP4430_CM2_PARTITION,
+		OMAP4430_CM2_L3INIT_INST,
+		OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET);
+	return 0;
+}
+
+static int omap4_pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
+{
+	/*
+	 * FIXME: This should be fixed right way by moving it into HWMOD
+	 * or clock framework since sar control is moved to module level
+	 */
+	omap4_cminst_rmw_inst_reg_bits(OMAP4430_SAR_MODE_MASK,
+		0 << OMAP4430_SAR_MODE_SHIFT, OMAP4430_CM2_PARTITION,
+		OMAP4430_CM2_L3INIT_INST,
+		OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET);
+	omap4_cminst_rmw_inst_reg_bits(OMAP4430_SAR_MODE_MASK,
+		0 << OMAP4430_SAR_MODE_SHIFT, OMAP4430_CM2_PARTITION,
+		OMAP4430_CM2_L3INIT_INST,
+		OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET);
+
+	return 0;
+}
+
 struct pwrdm_ops omap4_pwrdm_operations = {
 	.pwrdm_set_next_pwrst	= omap4_pwrdm_set_next_pwrst,
 	.pwrdm_read_next_pwrst	= omap4_pwrdm_read_next_pwrst,
@@ -223,4 +262,6 @@ struct pwrdm_ops omap4_pwrdm_operations = {
 	.pwrdm_set_mem_onst	= omap4_pwrdm_set_mem_onst,
 	.pwrdm_set_mem_retst	= omap4_pwrdm_set_mem_retst,
 	.pwrdm_wait_transition	= omap4_pwrdm_wait_transition,
+	.pwrdm_enable_hdwr_sar	= omap4_pwrdm_enable_hdwr_sar,
+	.pwrdm_disable_hdwr_sar	= omap4_pwrdm_disable_hdwr_sar,
 };
diff --git a/arch/arm/mach-omap2/powerdomains44xx_data.c b/arch/arm/mach-omap2/powerdomains44xx_data.c
index 704664c..d8701ce 100644
--- a/arch/arm/mach-omap2/powerdomains44xx_data.c
+++ b/arch/arm/mach-omap2/powerdomains44xx_data.c
@@ -276,7 +276,7 @@ static struct powerdomain l3init_44xx_pwrdm = {
 	.pwrsts_mem_on	= {
 		[0] = PWRSTS_ON,	/* l3init_bank1 */
 	},
-	.flags		  = PWRDM_HAS_LOWPOWERSTATECHANGE,
+	.flags		  = PWRDM_HAS_LOWPOWERSTATECHANGE | PWRDM_HAS_HDWR_SAR,
 };
 
 /* l4per_44xx_pwrdm: Target peripherals power domain */
-- 
1.7.4.1

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

* [PATCH 04/19] ARM: OMAP4: Add SAR ROM base address
  2012-04-20  9:33 ` Tero Kristo
@ 2012-04-20  9:33   ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-omap, khilman, paul; +Cc: linux-arm-kernel

Added in preparation for device off mode. SAR ROM contains the mapping
from SAR RAM to IO registers, and this will eventually be parsed during
init time to do the reverse before device off.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/plat-omap/include/plat/omap44xx.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/omap44xx.h b/arch/arm/plat-omap/include/plat/omap44xx.h
index c0d478e..1a45700 100644
--- a/arch/arm/plat-omap/include/plat/omap44xx.h
+++ b/arch/arm/plat-omap/include/plat/omap44xx.h
@@ -46,6 +46,7 @@
 #define OMAP44XX_MCPDM_BASE		0x40132000
 #define OMAP44XX_MCPDM_L3_BASE		0x49032000
 #define OMAP44XX_SAR_RAM_BASE		0x4a326000
+#define OMAP44XX_SAR_ROM_BASE		0x4a05e000
 
 #define OMAP44XX_MAILBOX_BASE		(L4_44XX_BASE + 0xF4000)
 #define OMAP44XX_HSUSB_OTG_BASE		(L4_44XX_BASE + 0xAB000)
-- 
1.7.4.1


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

* [PATCH 04/19] ARM: OMAP4: Add SAR ROM base address
@ 2012-04-20  9:33   ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-arm-kernel

Added in preparation for device off mode. SAR ROM contains the mapping
from SAR RAM to IO registers, and this will eventually be parsed during
init time to do the reverse before device off.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/plat-omap/include/plat/omap44xx.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/omap44xx.h b/arch/arm/plat-omap/include/plat/omap44xx.h
index c0d478e..1a45700 100644
--- a/arch/arm/plat-omap/include/plat/omap44xx.h
+++ b/arch/arm/plat-omap/include/plat/omap44xx.h
@@ -46,6 +46,7 @@
 #define OMAP44XX_MCPDM_BASE		0x40132000
 #define OMAP44XX_MCPDM_L3_BASE		0x49032000
 #define OMAP44XX_SAR_RAM_BASE		0x4a326000
+#define OMAP44XX_SAR_ROM_BASE		0x4a05e000
 
 #define OMAP44XX_MAILBOX_BASE		(L4_44XX_BASE + 0xF4000)
 #define OMAP44XX_HSUSB_OTG_BASE		(L4_44XX_BASE + 0xAB000)
-- 
1.7.4.1

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

* [PATCH 05/19] ARM: OMAP4: PM: Add SAR backup support towards device OFF
  2012-04-20  9:33 ` Tero Kristo
@ 2012-04-20  9:33   ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-omap, khilman, paul; +Cc: linux-arm-kernel, Santosh Shilimkar

From: Santosh Shilimkar <santosh.shilimkar@ti.com>

The SAR RAM is maintained during Device OFF mode. The register layout
is fixed in SAR ROM. SAR is split into 4 banks with different
privilege accesses based on device type

 ---------------------------------------------------------------
 Access mode		Bank	Address Range
 ---------------------------------------------------------------
 HS/GP : Public		1	0x4A32_6000 - 0x4A32_6FFF (4kB)
 HS/GP : Public		2	0x4A32_7000 - 0x4A32_73FF (1kB)

 HS/EMU : Secured
 GP : Public		3	0x4A32_8000 - 0x4A32_87FF (2kB)

 HS/GP :Secure
 write once.		4	0x4A32_9000 - 0x4A32_93FF (1kB)
 ---------------------------------------------------------------

The save process is done entirely by software and restore is done by
hardware using the auto-restore feature. The restore feature is enabled
by default and cannot be disabled. The software must save the data
to be restored in a dedicated location in SAR RAM.

[with contributions for 4460, cleanups from:
Rajeev Kulkarni <rajeevk@ti.com>
Nishanth Menon <nm@ti.com>
Axel Haslam <axelhaslam@gmail.com>
Avinash.H.M <avinashhm@ti.com>]
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
[t-kristo@ti.com: dropped huge data tables as they are no longer needed
 with subsequent patches that generate the layouts based on SAR ROM
 contents, also dropped unnecessary dmm-44xx.h header file.]
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/Makefile               |    2 +-
 arch/arm/mach-omap2/cm1_44xx.h             |    2 +
 arch/arm/mach-omap2/cm2_44xx.h             |    2 +
 arch/arm/mach-omap2/omap-sar.c             |  341 ++++++++++++++++++++++++++++
 arch/arm/mach-omap2/omap4-common.c         |   28 ---
 arch/arm/mach-omap2/omap4-sar-layout.h     |   50 ++++
 arch/arm/mach-omap2/pm.h                   |   12 +
 arch/arm/plat-omap/include/plat/omap44xx.h |    5 +
 8 files changed, 413 insertions(+), 29 deletions(-)
 create mode 100644 arch/arm/mach-omap2/omap-sar.c

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 49f92bc..a978679 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -27,7 +27,7 @@ obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
 obj-$(CONFIG_SMP)			+= omap-smp.o omap-headsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)		+= omap-hotplug.o
 obj-$(CONFIG_ARCH_OMAP4)		+= omap4-common.o omap-wakeupgen.o \
-					   sleep44xx.o
+					   sleep44xx.o omap-sar.o
 
 plus_sec := $(call as-instr,.arch_extension sec,+sec)
 AFLAGS_omap-headsmp.o			:=-Wa,-march=armv7-a$(plus_sec)
diff --git a/arch/arm/mach-omap2/cm1_44xx.h b/arch/arm/mach-omap2/cm1_44xx.h
index 1bc00dc..c21b660 100644
--- a/arch/arm/mach-omap2/cm1_44xx.h
+++ b/arch/arm/mach-omap2/cm1_44xx.h
@@ -218,8 +218,10 @@
 #define OMAP4430_CM1_ABE_WDT3_CLKCTRL			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0088)
 
 /* Function prototypes */
+#ifndef __ASSEMBLER__
 extern u32 omap4_cm1_read_inst_reg(s16 inst, u16 idx);
 extern void omap4_cm1_write_inst_reg(u32 val, s16 inst, u16 idx);
 extern u32 omap4_cm1_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
+#endif
 
 #endif
diff --git a/arch/arm/mach-omap2/cm2_44xx.h b/arch/arm/mach-omap2/cm2_44xx.h
index b9de72d..3e8871e 100644
--- a/arch/arm/mach-omap2/cm2_44xx.h
+++ b/arch/arm/mach-omap2/cm2_44xx.h
@@ -450,8 +450,10 @@
 #define OMAP4430_CM_CEFUSE_CEFUSE_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CEFUSE_INST, 0x0020)
 
 /* Function prototypes */
+#ifndef __ASSEMBLER__
 extern u32 omap4_cm2_read_inst_reg(s16 inst, u16 idx);
 extern void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 idx);
 extern u32 omap4_cm2_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
+#endif
 
 #endif
diff --git a/arch/arm/mach-omap2/omap-sar.c b/arch/arm/mach-omap2/omap-sar.c
new file mode 100644
index 0000000..74e0207
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-sar.c
@@ -0,0 +1,341 @@
+/*
+ * OMAP4 Save Restore source file
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Written by Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+
+#include "iomap.h"
+#include "pm.h"
+#include "clockdomain.h"
+
+#include "omap4-sar-layout.h"
+#include "cm-regbits-44xx.h"
+#include "prcm44xx.h"
+#include "cminst44xx.h"
+
+static void __iomem *sar_ram_base;
+static void __iomem *omap4_sar_modules[MAX_SAR_MODULES];
+static struct powerdomain *l3init_pwrdm;
+	static struct clockdomain *l3init_clkdm;
+static struct clk *usb_host_ck, *usb_tll_ck;
+
+/*
+ * SAR_RAM1 register layout consist of EMIF1, EMIF2, CM1, CM2,
+ * CONTROL_CORE efuse, DMM and USB TLL registers.
+ * The layout is arranged is a two dimentional array like
+ * below,
+ * const u32 sar_ramX_layout[nb_regs_sets][4] = {
+ *	{module_index, reg_offset, size, sar_ram_offset},
+ * }
+ */
+static const u32 omap443x_sar_ram1_layout[][4] = {
+};
+
+/*
+ * SAR_RAM2 register layout consist of SYSCTRL_PADCONF_CORE regsiters
+ */
+static const u32 omap443x_sar_ram2_layout[][4] = {
+};
+
+/*
+ * SAR_RAM3 and  SAR_RAM4 layout is not listed since moslty it's handle by
+ * secure software.
+ */
+static const u32 omap443x_sar_ram3_layout[][4] = {
+};
+
+/*
+ * omap_sar_save :
+ * common routine to save the registers to  SAR RAM with the
+ * given parameters
+ * @nb_regs - Number of registers to saved
+ * @sar_bank_offset - where to backup
+ * @sar_layout - constant table containing the backup info
+ */
+static void sar_save(u32 nb_regs, u32 sar_bank, const u32 sar_layout_table[][4])
+{
+	u32 reg_val, size, i, j;
+	void __iomem *reg_read_addr, *sar_wr_addr;
+
+	for (i = 0; i < nb_regs; i++) {
+		if (omap4_sar_modules[(sar_layout_table[i][MODULE_ADDR_IDX])]) {
+			size = sar_layout_table[i][MODULE_NB_REGS_IDX];
+			reg_read_addr =
+			    omap4_sar_modules[sar_layout_table[i]
+					      [MODULE_ADDR_IDX]]
+			    + sar_layout_table[i][MODULE_OFFSET_IDX];
+			sar_wr_addr = sar_ram_base + sar_bank +
+			    sar_layout_table[i][SAR_RAM_OFFSET_IDX];
+			for (j = 0; j < size; j++) {
+				reg_val = __raw_readl(reg_read_addr + j * 4);
+				__raw_writel(reg_val, sar_wr_addr + j * 4);
+			}
+		}
+	}
+}
+
+static void save_sar_bank3(void)
+{
+	struct clockdomain *l4_secure_clkdm;
+
+	/*
+	 * Not supported on ES1.0 silicon
+	 */
+	if (omap_rev() == OMAP4430_REV_ES1_0) {
+		WARN_ONCE(1, "omap4: SAR backup not supported on ES1.0 ..\n");
+		return;
+	}
+
+	l4_secure_clkdm = clkdm_lookup("l4_secure_clkdm");
+	clkdm_wakeup(l4_secure_clkdm);
+
+	sar_save(ARRAY_SIZE(omap443x_sar_ram3_layout), SAR_BANK3_OFFSET,
+		 omap443x_sar_ram3_layout);
+
+	clkdm_allow_idle(l4_secure_clkdm);
+}
+
+static int omap4_sar_not_accessible(void)
+{
+	u32 usbhost_state, usbtll_state;
+
+	/*
+	 * Make sure that USB host and TLL modules are not
+	 * enabled before attempting to save the context
+	 * registers, otherwise this will trigger an exception.
+	 */
+	usbhost_state = omap4_cminst_read_inst_reg(OMAP4430_CM2_PARTITION,
+						   OMAP4430_CM2_L3INIT_INST,
+						   OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET)
+	    & (OMAP4430_STBYST_MASK | OMAP4430_IDLEST_MASK);
+
+	usbtll_state = omap4_cminst_read_inst_reg(OMAP4430_CM2_PARTITION,
+						  OMAP4430_CM2_L3INIT_INST,
+						  OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET)
+	    & OMAP4430_IDLEST_MASK;
+
+	if ((usbhost_state == (OMAP4430_STBYST_MASK | OMAP4430_IDLEST_MASK)) &&
+	    (usbtll_state == (OMAP4430_IDLEST_MASK)))
+		return 0;
+	else
+		return -EBUSY;
+}
+
+ /*
+  * omap4_sar_save -
+  * Save the context to SAR_RAM1 and SAR_RAM2 as per
+  * omap4xxx_sar_ram1_layout and omap4xxx_sar_ram2_layout for the device OFF
+  * mode
+  */
+int omap4_sar_save(void)
+{
+	/*
+	 * Not supported on ES1.0 silicon
+	 */
+	if (omap_rev() == OMAP4430_REV_ES1_0) {
+		WARN_ONCE(1, "omap4: SAR backup not supported on ES1.0 ..\n");
+		return -ENODEV;
+	}
+
+	if (omap4_sar_not_accessible()) {
+		pr_debug("%s: USB SAR CNTX registers are not accessible!\n",
+			 __func__);
+		return -EBUSY;
+	}
+
+	/*
+	 * SAR bits and clocks needs to be enabled
+	 */
+	clkdm_wakeup(l3init_clkdm);
+	pwrdm_enable_hdwr_sar(l3init_pwrdm);
+	clk_enable(usb_host_ck);
+	clk_enable(usb_tll_ck);
+
+	/* Save SAR BANK1 */
+	sar_save(ARRAY_SIZE(omap443x_sar_ram1_layout), SAR_BANK1_OFFSET,
+		 omap443x_sar_ram1_layout);
+
+	clk_disable(usb_host_ck);
+	clk_disable(usb_tll_ck);
+	pwrdm_disable_hdwr_sar(l3init_pwrdm);
+	clkdm_allow_idle(l3init_clkdm);
+
+	/* Save SAR BANK2 */
+	sar_save(ARRAY_SIZE(omap443x_sar_ram2_layout), SAR_BANK2_OFFSET,
+		 omap443x_sar_ram2_layout);
+
+	return 0;
+}
+
+/**
+ * omap4_sar_overwrite :
+ * This API overwrite some of the SAR locations as a special cases
+ * The register content to be saved can be the register value before
+ * going into OFF-mode or a value that is required on wake up. This means
+ * that the restored register value can be different from the last value
+ * of the register before going into OFF-mode
+ *	- CM1 and CM2 configuration
+ *		Bits 0 of the CM_SHADOW_FREQ_CONFIG1 regiser and the
+ *		CM_SHADOW_FREQ_CONFIG2 register are self-clearing and must
+ *		 be set at restore time. Thus, these data must always be
+ *		overwritten in the SAR RAM.
+ *	- Because USBHOSTHS and USBTLL restore needs a particular
+ *		sequencing, the software must overwrite data read from
+ *		the following registers implied in phase2a and phase 2b
+ */
+void omap4_sar_overwrite(void)
+{
+	u32 val = 0;
+	u32 offset = 0;
+
+	if (cpu_is_omap446x())
+		offset = 0x04;
+
+	/* Overwriting Phase1 data to be restored */
+	/* CM2 MEMIF_CLKTRCTRL = SW_WKUP, before FREQ UPDATE */
+	__raw_writel(0x2, sar_ram_base + SAR_BANK1_OFFSET + 0xd0);
+	/* CM1 CM_SHADOW_FREQ_CONFIG2, Enable FREQ UPDATE */
+	val = __raw_readl(OMAP4430_CM_SHADOW_FREQ_CONFIG2);
+	/*
+	 * FIXME: Implement FREQ UPDATE for L#/M5 before enabling this
+	 * val |= 1 << OMAP4430_FREQ_UPDATE_SHIFT;
+	 */
+	__raw_writel(val, sar_ram_base + SAR_BANK1_OFFSET + 0x100);
+	/* CM1 CM_SHADOW_FREQ_CONFIG1, Enable FREQ UPDATE */
+	val = __raw_readl(OMAP4430_CM_SHADOW_FREQ_CONFIG1);
+	val |= 1 << OMAP4430_FREQ_UPDATE_SHIFT;
+	val &= ~OMAP4430_DLL_OVERRIDE_MASK;
+	__raw_writel(val, sar_ram_base + SAR_BANK1_OFFSET + 0x104);
+	/* CM2 MEMIF_CLKTRCTRL = HW_AUTO, after FREQ UPDATE */
+	__raw_writel(0x3, sar_ram_base + SAR_BANK1_OFFSET + 0x124);
+
+	/* Overwriting Phase2a data to be restored */
+	/* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 1, MODULEMODE = 2 */
+	__raw_writel(0x00000012,
+		     sar_ram_base + SAR_BANK1_OFFSET + 0x2ec + offset);
+	/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 1, MODULEMODE = 1 */
+	__raw_writel(0x00000011,
+		     sar_ram_base + SAR_BANK1_OFFSET + 0x2f0 + offset);
+	/* CM2 CM_SDMA_STATICDEP : Enable static depedency for SAR modules */
+	__raw_writel(0x000090e8,
+		     sar_ram_base + SAR_BANK1_OFFSET + 0x2f4 + offset);
+
+	/* Overwriting Phase2b data to be restored */
+	/* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */
+	val = __raw_readl(OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL);
+	val &= (OMAP4430_CLKSEL_UTMI_P1_MASK | OMAP4430_CLKSEL_UTMI_P2_MASK);
+	__raw_writel(val, sar_ram_base + SAR_BANK1_OFFSET + 0x91c + offset);
+	/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */
+	__raw_writel(0x0000000,
+		     sar_ram_base + SAR_BANK1_OFFSET + 0x920 + offset);
+	/* CM2 CM_SDMA_STATICDEP : Clear the static depedency */
+	__raw_writel(0x00000040,
+		     sar_ram_base + SAR_BANK1_OFFSET + 0x924 + offset);
+
+	/* readback to ensure data reaches to SAR RAM */
+	barrier();
+	val = __raw_readl(sar_ram_base + SAR_BANK1_OFFSET + 0x924 + offset);
+}
+
+void __iomem *omap4_get_sar_ram_base(void)
+{
+	return sar_ram_base;
+}
+
+/*
+ * SAR RAM used to save and restore the HW
+ * context in low power modes
+ */
+static int __init omap4_sar_ram_init(void)
+{
+	/*
+	 * To avoid code running on other OMAPs in
+	 * multi-omap builds
+	 */
+	if (!cpu_is_omap44xx())
+		return -ENODEV;
+
+	/*
+	 * Static mapping, never released Actual SAR area used is 8K it's
+	 * spaced over 16K address with some part is reserved.
+	 */
+	sar_ram_base = ioremap(OMAP44XX_SAR_RAM_BASE, SZ_16K);
+	BUG_ON(!sar_ram_base);
+
+	/*
+	 * All these are static mappings so ioremap() will
+	 * just return with mapped VA
+	 */
+	omap4_sar_modules[EMIF1_INDEX] = ioremap(OMAP44XX_EMIF1_BASE, SZ_1M);
+	BUG_ON(!omap4_sar_modules[EMIF1_INDEX]);
+	omap4_sar_modules[EMIF2_INDEX] = ioremap(OMAP44XX_EMIF2_BASE, SZ_1M);
+	BUG_ON(!omap4_sar_modules[EMIF2_INDEX]);
+	omap4_sar_modules[DMM_INDEX] = ioremap(OMAP44XX_DMM_BASE, SZ_1M);
+	BUG_ON(!omap4_sar_modules[DMM_INDEX]);
+	omap4_sar_modules[CM1_INDEX] = ioremap(OMAP4430_CM1_BASE, SZ_8K);
+	BUG_ON(!omap4_sar_modules[CM1_INDEX]);
+	omap4_sar_modules[CM2_INDEX] = ioremap(OMAP4430_CM2_BASE, SZ_8K);
+	BUG_ON(!omap4_sar_modules[CM2_INDEX]);
+	omap4_sar_modules[C2C_INDEX] = ioremap(OMAP44XX_C2C_BASE, SZ_1M);
+	BUG_ON(!omap4_sar_modules[C2C_INDEX]);
+	omap4_sar_modules[CTRL_MODULE_PAD_CORE_INDEX] =
+	    ioremap(OMAP443X_CTRL_BASE, SZ_4K);
+	BUG_ON(!omap4_sar_modules[CTRL_MODULE_PAD_CORE_INDEX]);
+	omap4_sar_modules[L3_CLK1_INDEX] = ioremap(L3_44XX_BASE_CLK1, SZ_1M);
+	BUG_ON(!omap4_sar_modules[L3_CLK1_INDEX]);
+	omap4_sar_modules[L3_CLK2_INDEX] = ioremap(L3_44XX_BASE_CLK2, SZ_1M);
+	BUG_ON(!omap4_sar_modules[L3_CLK2_INDEX]);
+	omap4_sar_modules[L3_CLK3_INDEX] = ioremap(L3_44XX_BASE_CLK3, SZ_1M);
+	BUG_ON(!omap4_sar_modules[L3_CLK3_INDEX]);
+	omap4_sar_modules[USBTLL_INDEX] = ioremap(OMAP44XX_USBTLL_BASE, SZ_1M);
+	BUG_ON(!omap4_sar_modules[USBTLL_INDEX]);
+	omap4_sar_modules[UHH_INDEX] = ioremap(OMAP44XX_UHH_CONFIG_BASE, SZ_1M);
+	BUG_ON(!omap4_sar_modules[UHH_INDEX]);
+	omap4_sar_modules[L4CORE_INDEX] = ioremap(L4_44XX_PHYS, SZ_4M);
+	BUG_ON(!omap4_sar_modules[L4CORE_INDEX]);
+	omap4_sar_modules[L4PER_INDEX] = ioremap(L4_PER_44XX_PHYS, SZ_4M);
+	BUG_ON(!omap4_sar_modules[L4PER_INDEX]);
+
+	/*
+	 * SAR BANK3 contains all firewall settings and it's saved through
+	 * secure API on HS device. On GP device these registers are
+	 * meaningless but still needs to be saved. Otherwise Auto-restore
+	 * phase DMA takes an abort. Hence save these conents only once
+	 * in init to avoid the issue while waking up from device OFF
+	 */
+	if (omap_type() == OMAP2_DEVICE_TYPE_GP)
+		save_sar_bank3();
+
+	/*
+	 * L3INIT PD and clocks are needed for SAR save phase
+	 */
+	l3init_pwrdm = pwrdm_lookup("l3init_pwrdm");
+	if (!l3init_pwrdm)
+		pr_err("Failed to get l3init_pwrdm\n");
+
+	l3init_clkdm = clkdm_lookup("l3_init_clkdm");
+	if (!l3init_clkdm)
+		pr_err("Failed to get l3_init_clkdm\n");
+
+	usb_host_ck = clk_get_sys("usbhs_omap", "hs_fck");
+	if (IS_ERR(usb_host_ck))
+		pr_err("Could not get usb_host_ck\n");
+
+	usb_tll_ck = clk_get_sys("usbhs_omap", "usbtll_ick");
+	if (IS_ERR(usb_tll_ck))
+		pr_err("Could not get usb_tll_ck\n");
+
+	return 0;
+}
+early_initcall(omap4_sar_ram_init);
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c
index cc6a915..7ea4652 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -37,7 +37,6 @@
 static void __iomem *l2cache_base;
 #endif
 
-static void __iomem *sar_ram_base;
 static void __iomem *gic_dist_base_addr;
 
 #ifdef CONFIG_OMAP4_ERRATA_I688
@@ -186,30 +185,3 @@ static int __init omap_l2_cache_init(void)
 }
 early_initcall(omap_l2_cache_init);
 #endif
-
-void __iomem *omap4_get_sar_ram_base(void)
-{
-	return sar_ram_base;
-}
-
-/*
- * SAR RAM used to save and restore the HW
- * context in low power modes
- */
-static int __init omap4_sar_ram_init(void)
-{
-	/*
-	 * To avoid code running on other OMAPs in
-	 * multi-omap builds
-	 */
-	if (!cpu_is_omap44xx())
-		return -ENOMEM;
-
-	/* Static mapping, never released */
-	sar_ram_base = ioremap(OMAP44XX_SAR_RAM_BASE, SZ_16K);
-	if (WARN_ON(!sar_ram_base))
-		return -ENOMEM;
-
-	return 0;
-}
-early_initcall(omap4_sar_ram_init);
diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h
index fe5b545..eef2839 100644
--- a/arch/arm/mach-omap2/omap4-sar-layout.h
+++ b/arch/arm/mach-omap2/omap4-sar-layout.h
@@ -11,6 +11,56 @@
 #ifndef OMAP_ARCH_OMAP4_SAR_LAYOUT_H
 #define OMAP_ARCH_OMAP4_SAR_LAYOUT_H
 
+#include <mach/hardware.h>
+#include <mach/ctrl_module_pad_core_44xx.h>
+
+#include "cm1_44xx.h"
+#include "cm2_44xx.h"
+#include "prcm-common.h"
+
+/*
+ * The SAR RAM is maintained during Device OFF mode.
+ * It is split into 4 banks with different privilege accesses
+ *
+ * ---------------------------------------------------------------------
+ * Access mode			Bank	Address Range
+ * ---------------------------------------------------------------------
+ * HS/GP : Public		1	0x4A32_6000 - 0x4A32_6FFF (4kB)
+ * HS/GP : Public, Secured
+ * if padconfaccdisable=1	2	0x4A32_7000 - 0x4A32_73FF (1kB)
+ * HS/EMU : Secured
+ * GP : Public			3	0x4A32_8000 - 0x4A32_87FF (2kB)
+ * HS/GP :
+ * Secure Priviledge,
+ * write once.			4	0x4A32_9000 - 0x4A32_93FF (1kB)
+ * ---------------------------------------------------------------------
+ * The SAR RAM save regiter layout is fixed since restore is done by hardware.
+ */
+
+#define MODULE_ADDR_IDX				0
+#define MODULE_OFFSET_IDX			1
+#define MODULE_NB_REGS_IDX			2
+#define SAR_RAM_OFFSET_IDX			3
+
+/*
+ * Module Index used to lookup VA using index
+ */
+#define MAX_SAR_MODULES				14
+#define EMIF1_INDEX				0
+#define EMIF2_INDEX				1
+#define DMM_INDEX				2
+#define CM1_INDEX				3
+#define CM2_INDEX				4
+#define C2C_INDEX				5
+#define CTRL_MODULE_PAD_CORE_INDEX		6
+#define L3_CLK1_INDEX				7
+#define L3_CLK2_INDEX				8
+#define L3_CLK3_INDEX				9
+#define USBTLL_INDEX				10
+#define UHH_INDEX				11
+#define L4CORE_INDEX				12
+#define L4PER_INDEX				13
+
 /*
  * SAR BANK offsets from base address OMAP44XX_SAR_RAM_BASE
  */
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 07ad800..c13e3c1 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -138,4 +138,16 @@ static inline int omap4_twl_init(void)
 }
 #endif
 
+#ifdef CONFIG_PM
+extern int omap4_sar_save(void);
+extern void omap4_sar_overwrite(void);
+#else
+static inline void omap4_sar_save(void)
+{
+}
+static inline void omap4_sar_overwrite(void)
+{
+}
+#endif
+
 #endif
diff --git a/arch/arm/plat-omap/include/plat/omap44xx.h b/arch/arm/plat-omap/include/plat/omap44xx.h
index 1a45700..8e83e16 100644
--- a/arch/arm/plat-omap/include/plat/omap44xx.h
+++ b/arch/arm/plat-omap/include/plat/omap44xx.h
@@ -22,6 +22,9 @@
 #define L4_PER_44XX_BASE		0x48000000
 #define L4_EMU_44XX_BASE		0x54000000
 #define L3_44XX_BASE			0x44000000
+#define L3_44XX_BASE_CLK1		L3_44XX_BASE
+#define L3_44XX_BASE_CLK2		0x44800000
+#define L3_44XX_BASE_CLK3		0x45000000
 #define OMAP44XX_EMIF1_BASE		0x4c000000
 #define OMAP44XX_EMIF2_BASE		0x4d000000
 #define OMAP44XX_DMM_BASE		0x4e000000
@@ -59,5 +62,7 @@
 #define OMAP44XX_HSUSB_OHCI_BASE	(L4_44XX_BASE + 0x64800)
 #define OMAP44XX_HSUSB_EHCI_BASE	(L4_44XX_BASE + 0x64C00)
 
+#define OMAP44XX_C2C_BASE		0x5c000000
+
 #endif /* __ASM_ARCH_OMAP44XX_H */
 
-- 
1.7.4.1


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

* [PATCH 05/19] ARM: OMAP4: PM: Add SAR backup support towards device OFF
@ 2012-04-20  9:33   ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-arm-kernel

From: Santosh Shilimkar <santosh.shilimkar@ti.com>

The SAR RAM is maintained during Device OFF mode. The register layout
is fixed in SAR ROM. SAR is split into 4 banks with different
privilege accesses based on device type

 ---------------------------------------------------------------
 Access mode		Bank	Address Range
 ---------------------------------------------------------------
 HS/GP : Public		1	0x4A32_6000 - 0x4A32_6FFF (4kB)
 HS/GP : Public		2	0x4A32_7000 - 0x4A32_73FF (1kB)

 HS/EMU : Secured
 GP : Public		3	0x4A32_8000 - 0x4A32_87FF (2kB)

 HS/GP :Secure
 write once.		4	0x4A32_9000 - 0x4A32_93FF (1kB)
 ---------------------------------------------------------------

The save process is done entirely by software and restore is done by
hardware using the auto-restore feature. The restore feature is enabled
by default and cannot be disabled. The software must save the data
to be restored in a dedicated location in SAR RAM.

[with contributions for 4460, cleanups from:
Rajeev Kulkarni <rajeevk@ti.com>
Nishanth Menon <nm@ti.com>
Axel Haslam <axelhaslam@gmail.com>
Avinash.H.M <avinashhm@ti.com>]
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
[t-kristo at ti.com: dropped huge data tables as they are no longer needed
 with subsequent patches that generate the layouts based on SAR ROM
 contents, also dropped unnecessary dmm-44xx.h header file.]
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/Makefile               |    2 +-
 arch/arm/mach-omap2/cm1_44xx.h             |    2 +
 arch/arm/mach-omap2/cm2_44xx.h             |    2 +
 arch/arm/mach-omap2/omap-sar.c             |  341 ++++++++++++++++++++++++++++
 arch/arm/mach-omap2/omap4-common.c         |   28 ---
 arch/arm/mach-omap2/omap4-sar-layout.h     |   50 ++++
 arch/arm/mach-omap2/pm.h                   |   12 +
 arch/arm/plat-omap/include/plat/omap44xx.h |    5 +
 8 files changed, 413 insertions(+), 29 deletions(-)
 create mode 100644 arch/arm/mach-omap2/omap-sar.c

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 49f92bc..a978679 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -27,7 +27,7 @@ obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
 obj-$(CONFIG_SMP)			+= omap-smp.o omap-headsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)		+= omap-hotplug.o
 obj-$(CONFIG_ARCH_OMAP4)		+= omap4-common.o omap-wakeupgen.o \
-					   sleep44xx.o
+					   sleep44xx.o omap-sar.o
 
 plus_sec := $(call as-instr,.arch_extension sec,+sec)
 AFLAGS_omap-headsmp.o			:=-Wa,-march=armv7-a$(plus_sec)
diff --git a/arch/arm/mach-omap2/cm1_44xx.h b/arch/arm/mach-omap2/cm1_44xx.h
index 1bc00dc..c21b660 100644
--- a/arch/arm/mach-omap2/cm1_44xx.h
+++ b/arch/arm/mach-omap2/cm1_44xx.h
@@ -218,8 +218,10 @@
 #define OMAP4430_CM1_ABE_WDT3_CLKCTRL			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0088)
 
 /* Function prototypes */
+#ifndef __ASSEMBLER__
 extern u32 omap4_cm1_read_inst_reg(s16 inst, u16 idx);
 extern void omap4_cm1_write_inst_reg(u32 val, s16 inst, u16 idx);
 extern u32 omap4_cm1_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
+#endif
 
 #endif
diff --git a/arch/arm/mach-omap2/cm2_44xx.h b/arch/arm/mach-omap2/cm2_44xx.h
index b9de72d..3e8871e 100644
--- a/arch/arm/mach-omap2/cm2_44xx.h
+++ b/arch/arm/mach-omap2/cm2_44xx.h
@@ -450,8 +450,10 @@
 #define OMAP4430_CM_CEFUSE_CEFUSE_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CEFUSE_INST, 0x0020)
 
 /* Function prototypes */
+#ifndef __ASSEMBLER__
 extern u32 omap4_cm2_read_inst_reg(s16 inst, u16 idx);
 extern void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 idx);
 extern u32 omap4_cm2_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
+#endif
 
 #endif
diff --git a/arch/arm/mach-omap2/omap-sar.c b/arch/arm/mach-omap2/omap-sar.c
new file mode 100644
index 0000000..74e0207
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-sar.c
@@ -0,0 +1,341 @@
+/*
+ * OMAP4 Save Restore source file
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Written by Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+
+#include "iomap.h"
+#include "pm.h"
+#include "clockdomain.h"
+
+#include "omap4-sar-layout.h"
+#include "cm-regbits-44xx.h"
+#include "prcm44xx.h"
+#include "cminst44xx.h"
+
+static void __iomem *sar_ram_base;
+static void __iomem *omap4_sar_modules[MAX_SAR_MODULES];
+static struct powerdomain *l3init_pwrdm;
+	static struct clockdomain *l3init_clkdm;
+static struct clk *usb_host_ck, *usb_tll_ck;
+
+/*
+ * SAR_RAM1 register layout consist of EMIF1, EMIF2, CM1, CM2,
+ * CONTROL_CORE efuse, DMM and USB TLL registers.
+ * The layout is arranged is a two dimentional array like
+ * below,
+ * const u32 sar_ramX_layout[nb_regs_sets][4] = {
+ *	{module_index, reg_offset, size, sar_ram_offset},
+ * }
+ */
+static const u32 omap443x_sar_ram1_layout[][4] = {
+};
+
+/*
+ * SAR_RAM2 register layout consist of SYSCTRL_PADCONF_CORE regsiters
+ */
+static const u32 omap443x_sar_ram2_layout[][4] = {
+};
+
+/*
+ * SAR_RAM3 and  SAR_RAM4 layout is not listed since moslty it's handle by
+ * secure software.
+ */
+static const u32 omap443x_sar_ram3_layout[][4] = {
+};
+
+/*
+ * omap_sar_save :
+ * common routine to save the registers to  SAR RAM with the
+ * given parameters
+ * @nb_regs - Number of registers to saved
+ * @sar_bank_offset - where to backup
+ * @sar_layout - constant table containing the backup info
+ */
+static void sar_save(u32 nb_regs, u32 sar_bank, const u32 sar_layout_table[][4])
+{
+	u32 reg_val, size, i, j;
+	void __iomem *reg_read_addr, *sar_wr_addr;
+
+	for (i = 0; i < nb_regs; i++) {
+		if (omap4_sar_modules[(sar_layout_table[i][MODULE_ADDR_IDX])]) {
+			size = sar_layout_table[i][MODULE_NB_REGS_IDX];
+			reg_read_addr =
+			    omap4_sar_modules[sar_layout_table[i]
+					      [MODULE_ADDR_IDX]]
+			    + sar_layout_table[i][MODULE_OFFSET_IDX];
+			sar_wr_addr = sar_ram_base + sar_bank +
+			    sar_layout_table[i][SAR_RAM_OFFSET_IDX];
+			for (j = 0; j < size; j++) {
+				reg_val = __raw_readl(reg_read_addr + j * 4);
+				__raw_writel(reg_val, sar_wr_addr + j * 4);
+			}
+		}
+	}
+}
+
+static void save_sar_bank3(void)
+{
+	struct clockdomain *l4_secure_clkdm;
+
+	/*
+	 * Not supported on ES1.0 silicon
+	 */
+	if (omap_rev() == OMAP4430_REV_ES1_0) {
+		WARN_ONCE(1, "omap4: SAR backup not supported on ES1.0 ..\n");
+		return;
+	}
+
+	l4_secure_clkdm = clkdm_lookup("l4_secure_clkdm");
+	clkdm_wakeup(l4_secure_clkdm);
+
+	sar_save(ARRAY_SIZE(omap443x_sar_ram3_layout), SAR_BANK3_OFFSET,
+		 omap443x_sar_ram3_layout);
+
+	clkdm_allow_idle(l4_secure_clkdm);
+}
+
+static int omap4_sar_not_accessible(void)
+{
+	u32 usbhost_state, usbtll_state;
+
+	/*
+	 * Make sure that USB host and TLL modules are not
+	 * enabled before attempting to save the context
+	 * registers, otherwise this will trigger an exception.
+	 */
+	usbhost_state = omap4_cminst_read_inst_reg(OMAP4430_CM2_PARTITION,
+						   OMAP4430_CM2_L3INIT_INST,
+						   OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET)
+	    & (OMAP4430_STBYST_MASK | OMAP4430_IDLEST_MASK);
+
+	usbtll_state = omap4_cminst_read_inst_reg(OMAP4430_CM2_PARTITION,
+						  OMAP4430_CM2_L3INIT_INST,
+						  OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET)
+	    & OMAP4430_IDLEST_MASK;
+
+	if ((usbhost_state == (OMAP4430_STBYST_MASK | OMAP4430_IDLEST_MASK)) &&
+	    (usbtll_state == (OMAP4430_IDLEST_MASK)))
+		return 0;
+	else
+		return -EBUSY;
+}
+
+ /*
+  * omap4_sar_save -
+  * Save the context to SAR_RAM1 and SAR_RAM2 as per
+  * omap4xxx_sar_ram1_layout and omap4xxx_sar_ram2_layout for the device OFF
+  * mode
+  */
+int omap4_sar_save(void)
+{
+	/*
+	 * Not supported on ES1.0 silicon
+	 */
+	if (omap_rev() == OMAP4430_REV_ES1_0) {
+		WARN_ONCE(1, "omap4: SAR backup not supported on ES1.0 ..\n");
+		return -ENODEV;
+	}
+
+	if (omap4_sar_not_accessible()) {
+		pr_debug("%s: USB SAR CNTX registers are not accessible!\n",
+			 __func__);
+		return -EBUSY;
+	}
+
+	/*
+	 * SAR bits and clocks needs to be enabled
+	 */
+	clkdm_wakeup(l3init_clkdm);
+	pwrdm_enable_hdwr_sar(l3init_pwrdm);
+	clk_enable(usb_host_ck);
+	clk_enable(usb_tll_ck);
+
+	/* Save SAR BANK1 */
+	sar_save(ARRAY_SIZE(omap443x_sar_ram1_layout), SAR_BANK1_OFFSET,
+		 omap443x_sar_ram1_layout);
+
+	clk_disable(usb_host_ck);
+	clk_disable(usb_tll_ck);
+	pwrdm_disable_hdwr_sar(l3init_pwrdm);
+	clkdm_allow_idle(l3init_clkdm);
+
+	/* Save SAR BANK2 */
+	sar_save(ARRAY_SIZE(omap443x_sar_ram2_layout), SAR_BANK2_OFFSET,
+		 omap443x_sar_ram2_layout);
+
+	return 0;
+}
+
+/**
+ * omap4_sar_overwrite :
+ * This API overwrite some of the SAR locations as a special cases
+ * The register content to be saved can be the register value before
+ * going into OFF-mode or a value that is required on wake up. This means
+ * that the restored register value can be different from the last value
+ * of the register before going into OFF-mode
+ *	- CM1 and CM2 configuration
+ *		Bits 0 of the CM_SHADOW_FREQ_CONFIG1 regiser and the
+ *		CM_SHADOW_FREQ_CONFIG2 register are self-clearing and must
+ *		 be set@restore time. Thus, these data must always be
+ *		overwritten in the SAR RAM.
+ *	- Because USBHOSTHS and USBTLL restore needs a particular
+ *		sequencing, the software must overwrite data read from
+ *		the following registers implied in phase2a and phase 2b
+ */
+void omap4_sar_overwrite(void)
+{
+	u32 val = 0;
+	u32 offset = 0;
+
+	if (cpu_is_omap446x())
+		offset = 0x04;
+
+	/* Overwriting Phase1 data to be restored */
+	/* CM2 MEMIF_CLKTRCTRL = SW_WKUP, before FREQ UPDATE */
+	__raw_writel(0x2, sar_ram_base + SAR_BANK1_OFFSET + 0xd0);
+	/* CM1 CM_SHADOW_FREQ_CONFIG2, Enable FREQ UPDATE */
+	val = __raw_readl(OMAP4430_CM_SHADOW_FREQ_CONFIG2);
+	/*
+	 * FIXME: Implement FREQ UPDATE for L#/M5 before enabling this
+	 * val |= 1 << OMAP4430_FREQ_UPDATE_SHIFT;
+	 */
+	__raw_writel(val, sar_ram_base + SAR_BANK1_OFFSET + 0x100);
+	/* CM1 CM_SHADOW_FREQ_CONFIG1, Enable FREQ UPDATE */
+	val = __raw_readl(OMAP4430_CM_SHADOW_FREQ_CONFIG1);
+	val |= 1 << OMAP4430_FREQ_UPDATE_SHIFT;
+	val &= ~OMAP4430_DLL_OVERRIDE_MASK;
+	__raw_writel(val, sar_ram_base + SAR_BANK1_OFFSET + 0x104);
+	/* CM2 MEMIF_CLKTRCTRL = HW_AUTO, after FREQ UPDATE */
+	__raw_writel(0x3, sar_ram_base + SAR_BANK1_OFFSET + 0x124);
+
+	/* Overwriting Phase2a data to be restored */
+	/* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 1, MODULEMODE = 2 */
+	__raw_writel(0x00000012,
+		     sar_ram_base + SAR_BANK1_OFFSET + 0x2ec + offset);
+	/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 1, MODULEMODE = 1 */
+	__raw_writel(0x00000011,
+		     sar_ram_base + SAR_BANK1_OFFSET + 0x2f0 + offset);
+	/* CM2 CM_SDMA_STATICDEP : Enable static depedency for SAR modules */
+	__raw_writel(0x000090e8,
+		     sar_ram_base + SAR_BANK1_OFFSET + 0x2f4 + offset);
+
+	/* Overwriting Phase2b data to be restored */
+	/* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */
+	val = __raw_readl(OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL);
+	val &= (OMAP4430_CLKSEL_UTMI_P1_MASK | OMAP4430_CLKSEL_UTMI_P2_MASK);
+	__raw_writel(val, sar_ram_base + SAR_BANK1_OFFSET + 0x91c + offset);
+	/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */
+	__raw_writel(0x0000000,
+		     sar_ram_base + SAR_BANK1_OFFSET + 0x920 + offset);
+	/* CM2 CM_SDMA_STATICDEP : Clear the static depedency */
+	__raw_writel(0x00000040,
+		     sar_ram_base + SAR_BANK1_OFFSET + 0x924 + offset);
+
+	/* readback to ensure data reaches to SAR RAM */
+	barrier();
+	val = __raw_readl(sar_ram_base + SAR_BANK1_OFFSET + 0x924 + offset);
+}
+
+void __iomem *omap4_get_sar_ram_base(void)
+{
+	return sar_ram_base;
+}
+
+/*
+ * SAR RAM used to save and restore the HW
+ * context in low power modes
+ */
+static int __init omap4_sar_ram_init(void)
+{
+	/*
+	 * To avoid code running on other OMAPs in
+	 * multi-omap builds
+	 */
+	if (!cpu_is_omap44xx())
+		return -ENODEV;
+
+	/*
+	 * Static mapping, never released Actual SAR area used is 8K it's
+	 * spaced over 16K address with some part is reserved.
+	 */
+	sar_ram_base = ioremap(OMAP44XX_SAR_RAM_BASE, SZ_16K);
+	BUG_ON(!sar_ram_base);
+
+	/*
+	 * All these are static mappings so ioremap() will
+	 * just return with mapped VA
+	 */
+	omap4_sar_modules[EMIF1_INDEX] = ioremap(OMAP44XX_EMIF1_BASE, SZ_1M);
+	BUG_ON(!omap4_sar_modules[EMIF1_INDEX]);
+	omap4_sar_modules[EMIF2_INDEX] = ioremap(OMAP44XX_EMIF2_BASE, SZ_1M);
+	BUG_ON(!omap4_sar_modules[EMIF2_INDEX]);
+	omap4_sar_modules[DMM_INDEX] = ioremap(OMAP44XX_DMM_BASE, SZ_1M);
+	BUG_ON(!omap4_sar_modules[DMM_INDEX]);
+	omap4_sar_modules[CM1_INDEX] = ioremap(OMAP4430_CM1_BASE, SZ_8K);
+	BUG_ON(!omap4_sar_modules[CM1_INDEX]);
+	omap4_sar_modules[CM2_INDEX] = ioremap(OMAP4430_CM2_BASE, SZ_8K);
+	BUG_ON(!omap4_sar_modules[CM2_INDEX]);
+	omap4_sar_modules[C2C_INDEX] = ioremap(OMAP44XX_C2C_BASE, SZ_1M);
+	BUG_ON(!omap4_sar_modules[C2C_INDEX]);
+	omap4_sar_modules[CTRL_MODULE_PAD_CORE_INDEX] =
+	    ioremap(OMAP443X_CTRL_BASE, SZ_4K);
+	BUG_ON(!omap4_sar_modules[CTRL_MODULE_PAD_CORE_INDEX]);
+	omap4_sar_modules[L3_CLK1_INDEX] = ioremap(L3_44XX_BASE_CLK1, SZ_1M);
+	BUG_ON(!omap4_sar_modules[L3_CLK1_INDEX]);
+	omap4_sar_modules[L3_CLK2_INDEX] = ioremap(L3_44XX_BASE_CLK2, SZ_1M);
+	BUG_ON(!omap4_sar_modules[L3_CLK2_INDEX]);
+	omap4_sar_modules[L3_CLK3_INDEX] = ioremap(L3_44XX_BASE_CLK3, SZ_1M);
+	BUG_ON(!omap4_sar_modules[L3_CLK3_INDEX]);
+	omap4_sar_modules[USBTLL_INDEX] = ioremap(OMAP44XX_USBTLL_BASE, SZ_1M);
+	BUG_ON(!omap4_sar_modules[USBTLL_INDEX]);
+	omap4_sar_modules[UHH_INDEX] = ioremap(OMAP44XX_UHH_CONFIG_BASE, SZ_1M);
+	BUG_ON(!omap4_sar_modules[UHH_INDEX]);
+	omap4_sar_modules[L4CORE_INDEX] = ioremap(L4_44XX_PHYS, SZ_4M);
+	BUG_ON(!omap4_sar_modules[L4CORE_INDEX]);
+	omap4_sar_modules[L4PER_INDEX] = ioremap(L4_PER_44XX_PHYS, SZ_4M);
+	BUG_ON(!omap4_sar_modules[L4PER_INDEX]);
+
+	/*
+	 * SAR BANK3 contains all firewall settings and it's saved through
+	 * secure API on HS device. On GP device these registers are
+	 * meaningless but still needs to be saved. Otherwise Auto-restore
+	 * phase DMA takes an abort. Hence save these conents only once
+	 * in init to avoid the issue while waking up from device OFF
+	 */
+	if (omap_type() == OMAP2_DEVICE_TYPE_GP)
+		save_sar_bank3();
+
+	/*
+	 * L3INIT PD and clocks are needed for SAR save phase
+	 */
+	l3init_pwrdm = pwrdm_lookup("l3init_pwrdm");
+	if (!l3init_pwrdm)
+		pr_err("Failed to get l3init_pwrdm\n");
+
+	l3init_clkdm = clkdm_lookup("l3_init_clkdm");
+	if (!l3init_clkdm)
+		pr_err("Failed to get l3_init_clkdm\n");
+
+	usb_host_ck = clk_get_sys("usbhs_omap", "hs_fck");
+	if (IS_ERR(usb_host_ck))
+		pr_err("Could not get usb_host_ck\n");
+
+	usb_tll_ck = clk_get_sys("usbhs_omap", "usbtll_ick");
+	if (IS_ERR(usb_tll_ck))
+		pr_err("Could not get usb_tll_ck\n");
+
+	return 0;
+}
+early_initcall(omap4_sar_ram_init);
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c
index cc6a915..7ea4652 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -37,7 +37,6 @@
 static void __iomem *l2cache_base;
 #endif
 
-static void __iomem *sar_ram_base;
 static void __iomem *gic_dist_base_addr;
 
 #ifdef CONFIG_OMAP4_ERRATA_I688
@@ -186,30 +185,3 @@ static int __init omap_l2_cache_init(void)
 }
 early_initcall(omap_l2_cache_init);
 #endif
-
-void __iomem *omap4_get_sar_ram_base(void)
-{
-	return sar_ram_base;
-}
-
-/*
- * SAR RAM used to save and restore the HW
- * context in low power modes
- */
-static int __init omap4_sar_ram_init(void)
-{
-	/*
-	 * To avoid code running on other OMAPs in
-	 * multi-omap builds
-	 */
-	if (!cpu_is_omap44xx())
-		return -ENOMEM;
-
-	/* Static mapping, never released */
-	sar_ram_base = ioremap(OMAP44XX_SAR_RAM_BASE, SZ_16K);
-	if (WARN_ON(!sar_ram_base))
-		return -ENOMEM;
-
-	return 0;
-}
-early_initcall(omap4_sar_ram_init);
diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h
index fe5b545..eef2839 100644
--- a/arch/arm/mach-omap2/omap4-sar-layout.h
+++ b/arch/arm/mach-omap2/omap4-sar-layout.h
@@ -11,6 +11,56 @@
 #ifndef OMAP_ARCH_OMAP4_SAR_LAYOUT_H
 #define OMAP_ARCH_OMAP4_SAR_LAYOUT_H
 
+#include <mach/hardware.h>
+#include <mach/ctrl_module_pad_core_44xx.h>
+
+#include "cm1_44xx.h"
+#include "cm2_44xx.h"
+#include "prcm-common.h"
+
+/*
+ * The SAR RAM is maintained during Device OFF mode.
+ * It is split into 4 banks with different privilege accesses
+ *
+ * ---------------------------------------------------------------------
+ * Access mode			Bank	Address Range
+ * ---------------------------------------------------------------------
+ * HS/GP : Public		1	0x4A32_6000 - 0x4A32_6FFF (4kB)
+ * HS/GP : Public, Secured
+ * if padconfaccdisable=1	2	0x4A32_7000 - 0x4A32_73FF (1kB)
+ * HS/EMU : Secured
+ * GP : Public			3	0x4A32_8000 - 0x4A32_87FF (2kB)
+ * HS/GP :
+ * Secure Priviledge,
+ * write once.			4	0x4A32_9000 - 0x4A32_93FF (1kB)
+ * ---------------------------------------------------------------------
+ * The SAR RAM save regiter layout is fixed since restore is done by hardware.
+ */
+
+#define MODULE_ADDR_IDX				0
+#define MODULE_OFFSET_IDX			1
+#define MODULE_NB_REGS_IDX			2
+#define SAR_RAM_OFFSET_IDX			3
+
+/*
+ * Module Index used to lookup VA using index
+ */
+#define MAX_SAR_MODULES				14
+#define EMIF1_INDEX				0
+#define EMIF2_INDEX				1
+#define DMM_INDEX				2
+#define CM1_INDEX				3
+#define CM2_INDEX				4
+#define C2C_INDEX				5
+#define CTRL_MODULE_PAD_CORE_INDEX		6
+#define L3_CLK1_INDEX				7
+#define L3_CLK2_INDEX				8
+#define L3_CLK3_INDEX				9
+#define USBTLL_INDEX				10
+#define UHH_INDEX				11
+#define L4CORE_INDEX				12
+#define L4PER_INDEX				13
+
 /*
  * SAR BANK offsets from base address OMAP44XX_SAR_RAM_BASE
  */
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 07ad800..c13e3c1 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -138,4 +138,16 @@ static inline int omap4_twl_init(void)
 }
 #endif
 
+#ifdef CONFIG_PM
+extern int omap4_sar_save(void);
+extern void omap4_sar_overwrite(void);
+#else
+static inline void omap4_sar_save(void)
+{
+}
+static inline void omap4_sar_overwrite(void)
+{
+}
+#endif
+
 #endif
diff --git a/arch/arm/plat-omap/include/plat/omap44xx.h b/arch/arm/plat-omap/include/plat/omap44xx.h
index 1a45700..8e83e16 100644
--- a/arch/arm/plat-omap/include/plat/omap44xx.h
+++ b/arch/arm/plat-omap/include/plat/omap44xx.h
@@ -22,6 +22,9 @@
 #define L4_PER_44XX_BASE		0x48000000
 #define L4_EMU_44XX_BASE		0x54000000
 #define L3_44XX_BASE			0x44000000
+#define L3_44XX_BASE_CLK1		L3_44XX_BASE
+#define L3_44XX_BASE_CLK2		0x44800000
+#define L3_44XX_BASE_CLK3		0x45000000
 #define OMAP44XX_EMIF1_BASE		0x4c000000
 #define OMAP44XX_EMIF2_BASE		0x4d000000
 #define OMAP44XX_DMM_BASE		0x4e000000
@@ -59,5 +62,7 @@
 #define OMAP44XX_HSUSB_OHCI_BASE	(L4_44XX_BASE + 0x64800)
 #define OMAP44XX_HSUSB_EHCI_BASE	(L4_44XX_BASE + 0x64C00)
 
+#define OMAP44XX_C2C_BASE		0x5c000000
+
 #endif /* __ASM_ARCH_OMAP44XX_H */
 
-- 
1.7.4.1

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

* [PATCH 06/19] ARM: OMAP4: Auto generate SAR layout contents
  2012-04-20  9:33 ` Tero Kristo
@ 2012-04-20  9:33   ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-omap, khilman, paul; +Cc: linux-arm-kernel

SAR layout contents are now generated automatically based on SAR ROM
contents during boot.

u32 offset	description
----------	-------------------------
0		pointer to next entry
1		size of DMA transfer in bytes
2		SAR RAM address for save / restore
3		IO address for save / restore

sar_layout_generate() parses this info and stores the resulting data to
a list of sar_ram_entry structs, which in turn will be used by sar_save.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap-sar.c |  290 +++++++++++++++++++++++++++-------------
 1 files changed, 194 insertions(+), 96 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-sar.c b/arch/arm/mach-omap2/omap-sar.c
index 74e0207..da4696a 100644
--- a/arch/arm/mach-omap2/omap-sar.c
+++ b/arch/arm/mach-omap2/omap-sar.c
@@ -2,7 +2,8 @@
  * OMAP4 Save Restore source file
  *
  * Copyright (C) 2010 Texas Instruments, Inc.
- * Written by Santosh Shilimkar <santosh.shilimkar@ti.com>
+ * Santosh Shilimkar <santosh.shilimkar@ti.com>
+ * Tero Kristo <t-kristo@ti.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -14,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/slab.h>
 
 #include "iomap.h"
 #include "pm.h"
@@ -25,35 +27,18 @@
 #include "cminst44xx.h"
 
 static void __iomem *sar_ram_base;
-static void __iomem *omap4_sar_modules[MAX_SAR_MODULES];
 static struct powerdomain *l3init_pwrdm;
 	static struct clockdomain *l3init_clkdm;
 static struct clk *usb_host_ck, *usb_tll_ck;
 
-/*
- * SAR_RAM1 register layout consist of EMIF1, EMIF2, CM1, CM2,
- * CONTROL_CORE efuse, DMM and USB TLL registers.
- * The layout is arranged is a two dimentional array like
- * below,
- * const u32 sar_ramX_layout[nb_regs_sets][4] = {
- *	{module_index, reg_offset, size, sar_ram_offset},
- * }
- */
-static const u32 omap443x_sar_ram1_layout[][4] = {
-};
-
-/*
- * SAR_RAM2 register layout consist of SYSCTRL_PADCONF_CORE regsiters
- */
-static const u32 omap443x_sar_ram2_layout[][4] = {
+struct sar_ram_entry {
+	void __iomem *io_base;
+	u32 offset;
+	u32 size;
+	u32 ram_addr;
 };
 
-/*
- * SAR_RAM3 and  SAR_RAM4 layout is not listed since moslty it's handle by
- * secure software.
- */
-static const u32 omap443x_sar_ram3_layout[][4] = {
-};
+static struct sar_ram_entry *sar_ram_layout[3];
 
 /*
  * omap_sar_save :
@@ -63,25 +48,20 @@ static const u32 omap443x_sar_ram3_layout[][4] = {
  * @sar_bank_offset - where to backup
  * @sar_layout - constant table containing the backup info
  */
-static void sar_save(u32 nb_regs, u32 sar_bank, const u32 sar_layout_table[][4])
+static void sar_save(struct sar_ram_entry *entry)
 {
-	u32 reg_val, size, i, j;
+	u32 reg_val, size, i;
 	void __iomem *reg_read_addr, *sar_wr_addr;
 
-	for (i = 0; i < nb_regs; i++) {
-		if (omap4_sar_modules[(sar_layout_table[i][MODULE_ADDR_IDX])]) {
-			size = sar_layout_table[i][MODULE_NB_REGS_IDX];
-			reg_read_addr =
-			    omap4_sar_modules[sar_layout_table[i]
-					      [MODULE_ADDR_IDX]]
-			    + sar_layout_table[i][MODULE_OFFSET_IDX];
-			sar_wr_addr = sar_ram_base + sar_bank +
-			    sar_layout_table[i][SAR_RAM_OFFSET_IDX];
-			for (j = 0; j < size; j++) {
-				reg_val = __raw_readl(reg_read_addr + j * 4);
-				__raw_writel(reg_val, sar_wr_addr + j * 4);
-			}
+	while (entry->size) {
+		size = entry->size;
+		reg_read_addr = entry->io_base + entry->offset;
+		sar_wr_addr = sar_ram_base + entry->ram_addr;
+		for (i = 0; i < size; i++) {
+			reg_val = __raw_readl(reg_read_addr + i * 4);
+			__raw_writel(reg_val, sar_wr_addr + i * 4);
 		}
+		entry++;
 	}
 }
 
@@ -100,8 +80,7 @@ static void save_sar_bank3(void)
 	l4_secure_clkdm = clkdm_lookup("l4_secure_clkdm");
 	clkdm_wakeup(l4_secure_clkdm);
 
-	sar_save(ARRAY_SIZE(omap443x_sar_ram3_layout), SAR_BANK3_OFFSET,
-		 omap443x_sar_ram3_layout);
+	sar_save(sar_ram_layout[2]);
 
 	clkdm_allow_idle(l4_secure_clkdm);
 }
@@ -116,13 +95,13 @@ static int omap4_sar_not_accessible(void)
 	 * registers, otherwise this will trigger an exception.
 	 */
 	usbhost_state = omap4_cminst_read_inst_reg(OMAP4430_CM2_PARTITION,
-						   OMAP4430_CM2_L3INIT_INST,
-						   OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET)
+				OMAP4430_CM2_L3INIT_INST,
+				OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET)
 	    & (OMAP4430_STBYST_MASK | OMAP4430_IDLEST_MASK);
 
 	usbtll_state = omap4_cminst_read_inst_reg(OMAP4430_CM2_PARTITION,
-						  OMAP4430_CM2_L3INIT_INST,
-						  OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET)
+				OMAP4430_CM2_L3INIT_INST,
+				OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET)
 	    & OMAP4430_IDLEST_MASK;
 
 	if ((usbhost_state == (OMAP4430_STBYST_MASK | OMAP4430_IDLEST_MASK)) &&
@@ -133,12 +112,12 @@ static int omap4_sar_not_accessible(void)
 }
 
  /*
-  * omap4_sar_save -
+  * omap_sar_save -
   * Save the context to SAR_RAM1 and SAR_RAM2 as per
   * omap4xxx_sar_ram1_layout and omap4xxx_sar_ram2_layout for the device OFF
   * mode
   */
-int omap4_sar_save(void)
+int omap_sar_save(void)
 {
 	/*
 	 * Not supported on ES1.0 silicon
@@ -163,8 +142,7 @@ int omap4_sar_save(void)
 	clk_enable(usb_tll_ck);
 
 	/* Save SAR BANK1 */
-	sar_save(ARRAY_SIZE(omap443x_sar_ram1_layout), SAR_BANK1_OFFSET,
-		 omap443x_sar_ram1_layout);
+	sar_save(sar_ram_layout[0]);
 
 	clk_disable(usb_host_ck);
 	clk_disable(usb_tll_ck);
@@ -172,8 +150,7 @@ int omap4_sar_save(void)
 	clkdm_allow_idle(l3init_clkdm);
 
 	/* Save SAR BANK2 */
-	sar_save(ARRAY_SIZE(omap443x_sar_ram2_layout), SAR_BANK2_OFFSET,
-		 omap443x_sar_ram2_layout);
+	sar_save(sar_ram_layout[1]);
 
 	return 0;
 }
@@ -194,13 +171,16 @@ int omap4_sar_save(void)
  *		sequencing, the software must overwrite data read from
  *		the following registers implied in phase2a and phase 2b
  */
-void omap4_sar_overwrite(void)
+void omap_sar_overwrite(void)
 {
 	u32 val = 0;
-	u32 offset = 0;
+	u32 usb_offset = 0x2ec;
+	u32 usb_offset2 = 0x91c;
 
-	if (cpu_is_omap446x())
-		offset = 0x04;
+	if (cpu_is_omap446x()) {
+		usb_offset = 0x2f4;
+		usb_offset2 = 0x920;
+	}
 
 	/* Overwriting Phase1 data to be restored */
 	/* CM2 MEMIF_CLKTRCTRL = SW_WKUP, before FREQ UPDATE */
@@ -215,7 +195,7 @@ void omap4_sar_overwrite(void)
 	/* CM1 CM_SHADOW_FREQ_CONFIG1, Enable FREQ UPDATE */
 	val = __raw_readl(OMAP4430_CM_SHADOW_FREQ_CONFIG1);
 	val |= 1 << OMAP4430_FREQ_UPDATE_SHIFT;
-	val &= ~OMAP4430_DLL_OVERRIDE_MASK;
+	val &= ~OMAP4430_DLL_OVERRIDE_2_2_MASK;
 	__raw_writel(val, sar_ram_base + SAR_BANK1_OFFSET + 0x104);
 	/* CM2 MEMIF_CLKTRCTRL = HW_AUTO, after FREQ UPDATE */
 	__raw_writel(0x3, sar_ram_base + SAR_BANK1_OFFSET + 0x124);
@@ -223,29 +203,29 @@ void omap4_sar_overwrite(void)
 	/* Overwriting Phase2a data to be restored */
 	/* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 1, MODULEMODE = 2 */
 	__raw_writel(0x00000012,
-		     sar_ram_base + SAR_BANK1_OFFSET + 0x2ec + offset);
+		     sar_ram_base + SAR_BANK1_OFFSET + usb_offset);
 	/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 1, MODULEMODE = 1 */
 	__raw_writel(0x00000011,
-		     sar_ram_base + SAR_BANK1_OFFSET + 0x2f0 + offset);
+		     sar_ram_base + SAR_BANK1_OFFSET + usb_offset + 4);
 	/* CM2 CM_SDMA_STATICDEP : Enable static depedency for SAR modules */
 	__raw_writel(0x000090e8,
-		     sar_ram_base + SAR_BANK1_OFFSET + 0x2f4 + offset);
+		     sar_ram_base + SAR_BANK1_OFFSET + usb_offset + 8);
 
 	/* Overwriting Phase2b data to be restored */
 	/* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */
 	val = __raw_readl(OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL);
 	val &= (OMAP4430_CLKSEL_UTMI_P1_MASK | OMAP4430_CLKSEL_UTMI_P2_MASK);
-	__raw_writel(val, sar_ram_base + SAR_BANK1_OFFSET + 0x91c + offset);
+	__raw_writel(val, sar_ram_base + SAR_BANK1_OFFSET + usb_offset2);
 	/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */
 	__raw_writel(0x0000000,
-		     sar_ram_base + SAR_BANK1_OFFSET + 0x920 + offset);
+		     sar_ram_base + SAR_BANK1_OFFSET + usb_offset2 + 4);
 	/* CM2 CM_SDMA_STATICDEP : Clear the static depedency */
 	__raw_writel(0x00000040,
-		     sar_ram_base + SAR_BANK1_OFFSET + 0x924 + offset);
+		     sar_ram_base + SAR_BANK1_OFFSET + usb_offset2 + 8);
 
 	/* readback to ensure data reaches to SAR RAM */
 	barrier();
-	val = __raw_readl(sar_ram_base + SAR_BANK1_OFFSET + 0x924 + offset);
+	val = __raw_readl(sar_ram_base + SAR_BANK1_OFFSET + usb_offset2 + 8);
 }
 
 void __iomem *omap4_get_sar_ram_base(void)
@@ -253,6 +233,152 @@ void __iomem *omap4_get_sar_ram_base(void)
 	return sar_ram_base;
 }
 
+static const u32 sar_rom_phases[] = {
+	0, 0x30, 0x60
+};
+
+struct sar_module {
+	void __iomem *io_base;
+	u32 base;
+	u32 size;
+	bool invalid;
+};
+
+static struct sar_module *sar_modules;
+
+static void sar_ioremap_modules(void)
+{
+	struct sar_module *mod;
+
+	mod = sar_modules;
+
+	while (mod->base) {
+		if (!mod->invalid) {
+			mod->io_base = ioremap(mod->base, mod->size);
+			if (!mod->io_base)
+				pr_err("%s: ioremap failed for %08x[%08x]\n",
+					__func__, mod->base, mod->size);
+			BUG_ON(!mod->io_base);
+		}
+		mod++;
+	}
+}
+
+static int set_sar_io_addr(struct sar_ram_entry *entry, u32 addr)
+{
+	struct sar_module *mod;
+
+	mod = sar_modules;
+
+	while (mod->base) {
+		if (addr >= mod->base && addr <= mod->base + mod->size) {
+			if (mod->invalid)
+				break;
+			entry->io_base = mod->io_base;
+			entry->offset = addr - mod->base;
+			return 0;
+		}
+		mod++;
+	}
+	pr_warn("%s: no matching sar_module for %08x\n", __func__, addr);
+	return -EINVAL;
+}
+
+static int sar_layout_generate(void)
+{
+	int phase;
+	void __iomem *sarrom;
+	u32 rombase, romend, rambase, ramend;
+	u32 offset, next;
+	u16 size;
+	u32 ram_addr, io_addr;
+	void *sarram;
+	struct sar_ram_entry *entry[3];
+	int bank;
+	int ret = 0;
+
+	pr_info("generating sar_ram layout...\n");
+
+	rombase = OMAP44XX_SAR_ROM_BASE;
+	romend = rombase + SZ_8K;
+	rambase = OMAP44XX_SAR_RAM_BASE;
+	ramend = rambase + SAR_BANK4_OFFSET - 1;
+
+	sarrom = ioremap(rombase, SZ_8K);
+
+	/* Allocate temporary memory for sar ram layout */
+	sarram = kmalloc(SAR_BANK4_OFFSET, GFP_KERNEL);
+	for (bank = 0; bank < 3; bank++)
+		entry[bank] = sarram + SAR_BANK2_OFFSET * bank;
+
+	for (phase = 0; phase < ARRAY_SIZE(sar_rom_phases); phase++) {
+		offset = sar_rom_phases[phase];
+
+		while (1) {
+			next = __raw_readl(sarrom + offset);
+			size = __raw_readl(sarrom + offset + 4) & 0xffff;
+			ram_addr = __raw_readl(sarrom + offset + 8);
+			io_addr = __raw_readl(sarrom + offset + 12);
+
+			if (ram_addr >= rambase && ram_addr <= ramend) {
+				/* Valid ram address, add entry */
+				ram_addr -= rambase;
+				bank = ram_addr / SAR_BANK2_OFFSET;
+				if (!set_sar_io_addr(entry[bank], io_addr)) {
+					entry[bank]->size = size;
+					entry[bank]->ram_addr = ram_addr;
+					entry[bank]++;
+				}
+			}
+
+			if (next < rombase || next > romend)
+				break;
+
+			offset = next - rombase;
+		}
+	}
+
+	for (bank = 0; bank < 3; bank++) {
+		size = (u32)entry[bank] -
+			(u32)(sarram + SAR_BANK2_OFFSET * bank);
+		sar_ram_layout[bank] = kmalloc(size +
+			sizeof(struct sar_ram_entry), GFP_KERNEL);
+		if (!sar_ram_layout[bank]) {
+			pr_err("%s: kmalloc failed\n", __func__);
+			goto cleanup;
+		}
+		memcpy(sar_ram_layout[bank], sarram + SAR_BANK2_OFFSET * bank,
+			size);
+		memset((void *)sar_ram_layout[bank] + size, 0,
+			sizeof(struct sar_ram_entry));
+		entry[bank] = sar_ram_layout[bank];
+	}
+
+cleanup:
+	kfree(sarram);
+	iounmap(sarrom);
+	pr_info("sar ram layout created\n");
+	return ret;
+}
+
+static struct sar_module omap44xx_sar_modules[] = {
+	{ .base = OMAP44XX_EMIF1_BASE, .size = SZ_1M },
+	{ .base = OMAP44XX_EMIF2_BASE, .size = SZ_1M },
+	{ .base = OMAP44XX_DMM_BASE, .size = SZ_1M },
+	{ .base = OMAP4430_CM1_BASE, .size = SZ_8K },
+	{ .base = OMAP4430_CM2_BASE, .size = SZ_8K },
+	{ .base = OMAP44XX_C2C_BASE, .size = SZ_1M },
+	{ .base = OMAP443X_CTRL_BASE, .size = SZ_4K },
+	{ .base = L3_44XX_BASE_CLK1, .size = SZ_1M },
+	{ .base = L3_44XX_BASE_CLK2, .size = SZ_1M },
+	{ .base = L3_44XX_BASE_CLK3, .size = SZ_1M },
+	{ .base = OMAP44XX_USBTLL_BASE, .size = SZ_1M },
+	{ .base = OMAP44XX_UHH_CONFIG_BASE, .size = SZ_1M },
+	{ .base = L4_44XX_PHYS, .size = SZ_4M },
+	{ .base = L4_PER_44XX_PHYS, .size = SZ_4M },
+	{ .base = 0 },
+};
+
 /*
  * SAR RAM used to save and restore the HW
  * context in low power modes
@@ -273,39 +399,11 @@ static int __init omap4_sar_ram_init(void)
 	sar_ram_base = ioremap(OMAP44XX_SAR_RAM_BASE, SZ_16K);
 	BUG_ON(!sar_ram_base);
 
-	/*
-	 * All these are static mappings so ioremap() will
-	 * just return with mapped VA
-	 */
-	omap4_sar_modules[EMIF1_INDEX] = ioremap(OMAP44XX_EMIF1_BASE, SZ_1M);
-	BUG_ON(!omap4_sar_modules[EMIF1_INDEX]);
-	omap4_sar_modules[EMIF2_INDEX] = ioremap(OMAP44XX_EMIF2_BASE, SZ_1M);
-	BUG_ON(!omap4_sar_modules[EMIF2_INDEX]);
-	omap4_sar_modules[DMM_INDEX] = ioremap(OMAP44XX_DMM_BASE, SZ_1M);
-	BUG_ON(!omap4_sar_modules[DMM_INDEX]);
-	omap4_sar_modules[CM1_INDEX] = ioremap(OMAP4430_CM1_BASE, SZ_8K);
-	BUG_ON(!omap4_sar_modules[CM1_INDEX]);
-	omap4_sar_modules[CM2_INDEX] = ioremap(OMAP4430_CM2_BASE, SZ_8K);
-	BUG_ON(!omap4_sar_modules[CM2_INDEX]);
-	omap4_sar_modules[C2C_INDEX] = ioremap(OMAP44XX_C2C_BASE, SZ_1M);
-	BUG_ON(!omap4_sar_modules[C2C_INDEX]);
-	omap4_sar_modules[CTRL_MODULE_PAD_CORE_INDEX] =
-	    ioremap(OMAP443X_CTRL_BASE, SZ_4K);
-	BUG_ON(!omap4_sar_modules[CTRL_MODULE_PAD_CORE_INDEX]);
-	omap4_sar_modules[L3_CLK1_INDEX] = ioremap(L3_44XX_BASE_CLK1, SZ_1M);
-	BUG_ON(!omap4_sar_modules[L3_CLK1_INDEX]);
-	omap4_sar_modules[L3_CLK2_INDEX] = ioremap(L3_44XX_BASE_CLK2, SZ_1M);
-	BUG_ON(!omap4_sar_modules[L3_CLK2_INDEX]);
-	omap4_sar_modules[L3_CLK3_INDEX] = ioremap(L3_44XX_BASE_CLK3, SZ_1M);
-	BUG_ON(!omap4_sar_modules[L3_CLK3_INDEX]);
-	omap4_sar_modules[USBTLL_INDEX] = ioremap(OMAP44XX_USBTLL_BASE, SZ_1M);
-	BUG_ON(!omap4_sar_modules[USBTLL_INDEX]);
-	omap4_sar_modules[UHH_INDEX] = ioremap(OMAP44XX_UHH_CONFIG_BASE, SZ_1M);
-	BUG_ON(!omap4_sar_modules[UHH_INDEX]);
-	omap4_sar_modules[L4CORE_INDEX] = ioremap(L4_44XX_PHYS, SZ_4M);
-	BUG_ON(!omap4_sar_modules[L4CORE_INDEX]);
-	omap4_sar_modules[L4PER_INDEX] = ioremap(L4_PER_44XX_PHYS, SZ_4M);
-	BUG_ON(!omap4_sar_modules[L4PER_INDEX]);
+	sar_modules = omap44xx_sar_modules;
+
+	sar_ioremap_modules();
+
+	sar_layout_generate();
 
 	/*
 	 * SAR BANK3 contains all firewall settings and it's saved through
-- 
1.7.4.1


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

* [PATCH 06/19] ARM: OMAP4: Auto generate SAR layout contents
@ 2012-04-20  9:33   ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-arm-kernel

SAR layout contents are now generated automatically based on SAR ROM
contents during boot.

u32 offset	description
----------	-------------------------
0		pointer to next entry
1		size of DMA transfer in bytes
2		SAR RAM address for save / restore
3		IO address for save / restore

sar_layout_generate() parses this info and stores the resulting data to
a list of sar_ram_entry structs, which in turn will be used by sar_save.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap-sar.c |  290 +++++++++++++++++++++++++++-------------
 1 files changed, 194 insertions(+), 96 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-sar.c b/arch/arm/mach-omap2/omap-sar.c
index 74e0207..da4696a 100644
--- a/arch/arm/mach-omap2/omap-sar.c
+++ b/arch/arm/mach-omap2/omap-sar.c
@@ -2,7 +2,8 @@
  * OMAP4 Save Restore source file
  *
  * Copyright (C) 2010 Texas Instruments, Inc.
- * Written by Santosh Shilimkar <santosh.shilimkar@ti.com>
+ * Santosh Shilimkar <santosh.shilimkar@ti.com>
+ * Tero Kristo <t-kristo@ti.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -14,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/slab.h>
 
 #include "iomap.h"
 #include "pm.h"
@@ -25,35 +27,18 @@
 #include "cminst44xx.h"
 
 static void __iomem *sar_ram_base;
-static void __iomem *omap4_sar_modules[MAX_SAR_MODULES];
 static struct powerdomain *l3init_pwrdm;
 	static struct clockdomain *l3init_clkdm;
 static struct clk *usb_host_ck, *usb_tll_ck;
 
-/*
- * SAR_RAM1 register layout consist of EMIF1, EMIF2, CM1, CM2,
- * CONTROL_CORE efuse, DMM and USB TLL registers.
- * The layout is arranged is a two dimentional array like
- * below,
- * const u32 sar_ramX_layout[nb_regs_sets][4] = {
- *	{module_index, reg_offset, size, sar_ram_offset},
- * }
- */
-static const u32 omap443x_sar_ram1_layout[][4] = {
-};
-
-/*
- * SAR_RAM2 register layout consist of SYSCTRL_PADCONF_CORE regsiters
- */
-static const u32 omap443x_sar_ram2_layout[][4] = {
+struct sar_ram_entry {
+	void __iomem *io_base;
+	u32 offset;
+	u32 size;
+	u32 ram_addr;
 };
 
-/*
- * SAR_RAM3 and  SAR_RAM4 layout is not listed since moslty it's handle by
- * secure software.
- */
-static const u32 omap443x_sar_ram3_layout[][4] = {
-};
+static struct sar_ram_entry *sar_ram_layout[3];
 
 /*
  * omap_sar_save :
@@ -63,25 +48,20 @@ static const u32 omap443x_sar_ram3_layout[][4] = {
  * @sar_bank_offset - where to backup
  * @sar_layout - constant table containing the backup info
  */
-static void sar_save(u32 nb_regs, u32 sar_bank, const u32 sar_layout_table[][4])
+static void sar_save(struct sar_ram_entry *entry)
 {
-	u32 reg_val, size, i, j;
+	u32 reg_val, size, i;
 	void __iomem *reg_read_addr, *sar_wr_addr;
 
-	for (i = 0; i < nb_regs; i++) {
-		if (omap4_sar_modules[(sar_layout_table[i][MODULE_ADDR_IDX])]) {
-			size = sar_layout_table[i][MODULE_NB_REGS_IDX];
-			reg_read_addr =
-			    omap4_sar_modules[sar_layout_table[i]
-					      [MODULE_ADDR_IDX]]
-			    + sar_layout_table[i][MODULE_OFFSET_IDX];
-			sar_wr_addr = sar_ram_base + sar_bank +
-			    sar_layout_table[i][SAR_RAM_OFFSET_IDX];
-			for (j = 0; j < size; j++) {
-				reg_val = __raw_readl(reg_read_addr + j * 4);
-				__raw_writel(reg_val, sar_wr_addr + j * 4);
-			}
+	while (entry->size) {
+		size = entry->size;
+		reg_read_addr = entry->io_base + entry->offset;
+		sar_wr_addr = sar_ram_base + entry->ram_addr;
+		for (i = 0; i < size; i++) {
+			reg_val = __raw_readl(reg_read_addr + i * 4);
+			__raw_writel(reg_val, sar_wr_addr + i * 4);
 		}
+		entry++;
 	}
 }
 
@@ -100,8 +80,7 @@ static void save_sar_bank3(void)
 	l4_secure_clkdm = clkdm_lookup("l4_secure_clkdm");
 	clkdm_wakeup(l4_secure_clkdm);
 
-	sar_save(ARRAY_SIZE(omap443x_sar_ram3_layout), SAR_BANK3_OFFSET,
-		 omap443x_sar_ram3_layout);
+	sar_save(sar_ram_layout[2]);
 
 	clkdm_allow_idle(l4_secure_clkdm);
 }
@@ -116,13 +95,13 @@ static int omap4_sar_not_accessible(void)
 	 * registers, otherwise this will trigger an exception.
 	 */
 	usbhost_state = omap4_cminst_read_inst_reg(OMAP4430_CM2_PARTITION,
-						   OMAP4430_CM2_L3INIT_INST,
-						   OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET)
+				OMAP4430_CM2_L3INIT_INST,
+				OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET)
 	    & (OMAP4430_STBYST_MASK | OMAP4430_IDLEST_MASK);
 
 	usbtll_state = omap4_cminst_read_inst_reg(OMAP4430_CM2_PARTITION,
-						  OMAP4430_CM2_L3INIT_INST,
-						  OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET)
+				OMAP4430_CM2_L3INIT_INST,
+				OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET)
 	    & OMAP4430_IDLEST_MASK;
 
 	if ((usbhost_state == (OMAP4430_STBYST_MASK | OMAP4430_IDLEST_MASK)) &&
@@ -133,12 +112,12 @@ static int omap4_sar_not_accessible(void)
 }
 
  /*
-  * omap4_sar_save -
+  * omap_sar_save -
   * Save the context to SAR_RAM1 and SAR_RAM2 as per
   * omap4xxx_sar_ram1_layout and omap4xxx_sar_ram2_layout for the device OFF
   * mode
   */
-int omap4_sar_save(void)
+int omap_sar_save(void)
 {
 	/*
 	 * Not supported on ES1.0 silicon
@@ -163,8 +142,7 @@ int omap4_sar_save(void)
 	clk_enable(usb_tll_ck);
 
 	/* Save SAR BANK1 */
-	sar_save(ARRAY_SIZE(omap443x_sar_ram1_layout), SAR_BANK1_OFFSET,
-		 omap443x_sar_ram1_layout);
+	sar_save(sar_ram_layout[0]);
 
 	clk_disable(usb_host_ck);
 	clk_disable(usb_tll_ck);
@@ -172,8 +150,7 @@ int omap4_sar_save(void)
 	clkdm_allow_idle(l3init_clkdm);
 
 	/* Save SAR BANK2 */
-	sar_save(ARRAY_SIZE(omap443x_sar_ram2_layout), SAR_BANK2_OFFSET,
-		 omap443x_sar_ram2_layout);
+	sar_save(sar_ram_layout[1]);
 
 	return 0;
 }
@@ -194,13 +171,16 @@ int omap4_sar_save(void)
  *		sequencing, the software must overwrite data read from
  *		the following registers implied in phase2a and phase 2b
  */
-void omap4_sar_overwrite(void)
+void omap_sar_overwrite(void)
 {
 	u32 val = 0;
-	u32 offset = 0;
+	u32 usb_offset = 0x2ec;
+	u32 usb_offset2 = 0x91c;
 
-	if (cpu_is_omap446x())
-		offset = 0x04;
+	if (cpu_is_omap446x()) {
+		usb_offset = 0x2f4;
+		usb_offset2 = 0x920;
+	}
 
 	/* Overwriting Phase1 data to be restored */
 	/* CM2 MEMIF_CLKTRCTRL = SW_WKUP, before FREQ UPDATE */
@@ -215,7 +195,7 @@ void omap4_sar_overwrite(void)
 	/* CM1 CM_SHADOW_FREQ_CONFIG1, Enable FREQ UPDATE */
 	val = __raw_readl(OMAP4430_CM_SHADOW_FREQ_CONFIG1);
 	val |= 1 << OMAP4430_FREQ_UPDATE_SHIFT;
-	val &= ~OMAP4430_DLL_OVERRIDE_MASK;
+	val &= ~OMAP4430_DLL_OVERRIDE_2_2_MASK;
 	__raw_writel(val, sar_ram_base + SAR_BANK1_OFFSET + 0x104);
 	/* CM2 MEMIF_CLKTRCTRL = HW_AUTO, after FREQ UPDATE */
 	__raw_writel(0x3, sar_ram_base + SAR_BANK1_OFFSET + 0x124);
@@ -223,29 +203,29 @@ void omap4_sar_overwrite(void)
 	/* Overwriting Phase2a data to be restored */
 	/* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 1, MODULEMODE = 2 */
 	__raw_writel(0x00000012,
-		     sar_ram_base + SAR_BANK1_OFFSET + 0x2ec + offset);
+		     sar_ram_base + SAR_BANK1_OFFSET + usb_offset);
 	/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 1, MODULEMODE = 1 */
 	__raw_writel(0x00000011,
-		     sar_ram_base + SAR_BANK1_OFFSET + 0x2f0 + offset);
+		     sar_ram_base + SAR_BANK1_OFFSET + usb_offset + 4);
 	/* CM2 CM_SDMA_STATICDEP : Enable static depedency for SAR modules */
 	__raw_writel(0x000090e8,
-		     sar_ram_base + SAR_BANK1_OFFSET + 0x2f4 + offset);
+		     sar_ram_base + SAR_BANK1_OFFSET + usb_offset + 8);
 
 	/* Overwriting Phase2b data to be restored */
 	/* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */
 	val = __raw_readl(OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL);
 	val &= (OMAP4430_CLKSEL_UTMI_P1_MASK | OMAP4430_CLKSEL_UTMI_P2_MASK);
-	__raw_writel(val, sar_ram_base + SAR_BANK1_OFFSET + 0x91c + offset);
+	__raw_writel(val, sar_ram_base + SAR_BANK1_OFFSET + usb_offset2);
 	/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */
 	__raw_writel(0x0000000,
-		     sar_ram_base + SAR_BANK1_OFFSET + 0x920 + offset);
+		     sar_ram_base + SAR_BANK1_OFFSET + usb_offset2 + 4);
 	/* CM2 CM_SDMA_STATICDEP : Clear the static depedency */
 	__raw_writel(0x00000040,
-		     sar_ram_base + SAR_BANK1_OFFSET + 0x924 + offset);
+		     sar_ram_base + SAR_BANK1_OFFSET + usb_offset2 + 8);
 
 	/* readback to ensure data reaches to SAR RAM */
 	barrier();
-	val = __raw_readl(sar_ram_base + SAR_BANK1_OFFSET + 0x924 + offset);
+	val = __raw_readl(sar_ram_base + SAR_BANK1_OFFSET + usb_offset2 + 8);
 }
 
 void __iomem *omap4_get_sar_ram_base(void)
@@ -253,6 +233,152 @@ void __iomem *omap4_get_sar_ram_base(void)
 	return sar_ram_base;
 }
 
+static const u32 sar_rom_phases[] = {
+	0, 0x30, 0x60
+};
+
+struct sar_module {
+	void __iomem *io_base;
+	u32 base;
+	u32 size;
+	bool invalid;
+};
+
+static struct sar_module *sar_modules;
+
+static void sar_ioremap_modules(void)
+{
+	struct sar_module *mod;
+
+	mod = sar_modules;
+
+	while (mod->base) {
+		if (!mod->invalid) {
+			mod->io_base = ioremap(mod->base, mod->size);
+			if (!mod->io_base)
+				pr_err("%s: ioremap failed for %08x[%08x]\n",
+					__func__, mod->base, mod->size);
+			BUG_ON(!mod->io_base);
+		}
+		mod++;
+	}
+}
+
+static int set_sar_io_addr(struct sar_ram_entry *entry, u32 addr)
+{
+	struct sar_module *mod;
+
+	mod = sar_modules;
+
+	while (mod->base) {
+		if (addr >= mod->base && addr <= mod->base + mod->size) {
+			if (mod->invalid)
+				break;
+			entry->io_base = mod->io_base;
+			entry->offset = addr - mod->base;
+			return 0;
+		}
+		mod++;
+	}
+	pr_warn("%s: no matching sar_module for %08x\n", __func__, addr);
+	return -EINVAL;
+}
+
+static int sar_layout_generate(void)
+{
+	int phase;
+	void __iomem *sarrom;
+	u32 rombase, romend, rambase, ramend;
+	u32 offset, next;
+	u16 size;
+	u32 ram_addr, io_addr;
+	void *sarram;
+	struct sar_ram_entry *entry[3];
+	int bank;
+	int ret = 0;
+
+	pr_info("generating sar_ram layout...\n");
+
+	rombase = OMAP44XX_SAR_ROM_BASE;
+	romend = rombase + SZ_8K;
+	rambase = OMAP44XX_SAR_RAM_BASE;
+	ramend = rambase + SAR_BANK4_OFFSET - 1;
+
+	sarrom = ioremap(rombase, SZ_8K);
+
+	/* Allocate temporary memory for sar ram layout */
+	sarram = kmalloc(SAR_BANK4_OFFSET, GFP_KERNEL);
+	for (bank = 0; bank < 3; bank++)
+		entry[bank] = sarram + SAR_BANK2_OFFSET * bank;
+
+	for (phase = 0; phase < ARRAY_SIZE(sar_rom_phases); phase++) {
+		offset = sar_rom_phases[phase];
+
+		while (1) {
+			next = __raw_readl(sarrom + offset);
+			size = __raw_readl(sarrom + offset + 4) & 0xffff;
+			ram_addr = __raw_readl(sarrom + offset + 8);
+			io_addr = __raw_readl(sarrom + offset + 12);
+
+			if (ram_addr >= rambase && ram_addr <= ramend) {
+				/* Valid ram address, add entry */
+				ram_addr -= rambase;
+				bank = ram_addr / SAR_BANK2_OFFSET;
+				if (!set_sar_io_addr(entry[bank], io_addr)) {
+					entry[bank]->size = size;
+					entry[bank]->ram_addr = ram_addr;
+					entry[bank]++;
+				}
+			}
+
+			if (next < rombase || next > romend)
+				break;
+
+			offset = next - rombase;
+		}
+	}
+
+	for (bank = 0; bank < 3; bank++) {
+		size = (u32)entry[bank] -
+			(u32)(sarram + SAR_BANK2_OFFSET * bank);
+		sar_ram_layout[bank] = kmalloc(size +
+			sizeof(struct sar_ram_entry), GFP_KERNEL);
+		if (!sar_ram_layout[bank]) {
+			pr_err("%s: kmalloc failed\n", __func__);
+			goto cleanup;
+		}
+		memcpy(sar_ram_layout[bank], sarram + SAR_BANK2_OFFSET * bank,
+			size);
+		memset((void *)sar_ram_layout[bank] + size, 0,
+			sizeof(struct sar_ram_entry));
+		entry[bank] = sar_ram_layout[bank];
+	}
+
+cleanup:
+	kfree(sarram);
+	iounmap(sarrom);
+	pr_info("sar ram layout created\n");
+	return ret;
+}
+
+static struct sar_module omap44xx_sar_modules[] = {
+	{ .base = OMAP44XX_EMIF1_BASE, .size = SZ_1M },
+	{ .base = OMAP44XX_EMIF2_BASE, .size = SZ_1M },
+	{ .base = OMAP44XX_DMM_BASE, .size = SZ_1M },
+	{ .base = OMAP4430_CM1_BASE, .size = SZ_8K },
+	{ .base = OMAP4430_CM2_BASE, .size = SZ_8K },
+	{ .base = OMAP44XX_C2C_BASE, .size = SZ_1M },
+	{ .base = OMAP443X_CTRL_BASE, .size = SZ_4K },
+	{ .base = L3_44XX_BASE_CLK1, .size = SZ_1M },
+	{ .base = L3_44XX_BASE_CLK2, .size = SZ_1M },
+	{ .base = L3_44XX_BASE_CLK3, .size = SZ_1M },
+	{ .base = OMAP44XX_USBTLL_BASE, .size = SZ_1M },
+	{ .base = OMAP44XX_UHH_CONFIG_BASE, .size = SZ_1M },
+	{ .base = L4_44XX_PHYS, .size = SZ_4M },
+	{ .base = L4_PER_44XX_PHYS, .size = SZ_4M },
+	{ .base = 0 },
+};
+
 /*
  * SAR RAM used to save and restore the HW
  * context in low power modes
@@ -273,39 +399,11 @@ static int __init omap4_sar_ram_init(void)
 	sar_ram_base = ioremap(OMAP44XX_SAR_RAM_BASE, SZ_16K);
 	BUG_ON(!sar_ram_base);
 
-	/*
-	 * All these are static mappings so ioremap() will
-	 * just return with mapped VA
-	 */
-	omap4_sar_modules[EMIF1_INDEX] = ioremap(OMAP44XX_EMIF1_BASE, SZ_1M);
-	BUG_ON(!omap4_sar_modules[EMIF1_INDEX]);
-	omap4_sar_modules[EMIF2_INDEX] = ioremap(OMAP44XX_EMIF2_BASE, SZ_1M);
-	BUG_ON(!omap4_sar_modules[EMIF2_INDEX]);
-	omap4_sar_modules[DMM_INDEX] = ioremap(OMAP44XX_DMM_BASE, SZ_1M);
-	BUG_ON(!omap4_sar_modules[DMM_INDEX]);
-	omap4_sar_modules[CM1_INDEX] = ioremap(OMAP4430_CM1_BASE, SZ_8K);
-	BUG_ON(!omap4_sar_modules[CM1_INDEX]);
-	omap4_sar_modules[CM2_INDEX] = ioremap(OMAP4430_CM2_BASE, SZ_8K);
-	BUG_ON(!omap4_sar_modules[CM2_INDEX]);
-	omap4_sar_modules[C2C_INDEX] = ioremap(OMAP44XX_C2C_BASE, SZ_1M);
-	BUG_ON(!omap4_sar_modules[C2C_INDEX]);
-	omap4_sar_modules[CTRL_MODULE_PAD_CORE_INDEX] =
-	    ioremap(OMAP443X_CTRL_BASE, SZ_4K);
-	BUG_ON(!omap4_sar_modules[CTRL_MODULE_PAD_CORE_INDEX]);
-	omap4_sar_modules[L3_CLK1_INDEX] = ioremap(L3_44XX_BASE_CLK1, SZ_1M);
-	BUG_ON(!omap4_sar_modules[L3_CLK1_INDEX]);
-	omap4_sar_modules[L3_CLK2_INDEX] = ioremap(L3_44XX_BASE_CLK2, SZ_1M);
-	BUG_ON(!omap4_sar_modules[L3_CLK2_INDEX]);
-	omap4_sar_modules[L3_CLK3_INDEX] = ioremap(L3_44XX_BASE_CLK3, SZ_1M);
-	BUG_ON(!omap4_sar_modules[L3_CLK3_INDEX]);
-	omap4_sar_modules[USBTLL_INDEX] = ioremap(OMAP44XX_USBTLL_BASE, SZ_1M);
-	BUG_ON(!omap4_sar_modules[USBTLL_INDEX]);
-	omap4_sar_modules[UHH_INDEX] = ioremap(OMAP44XX_UHH_CONFIG_BASE, SZ_1M);
-	BUG_ON(!omap4_sar_modules[UHH_INDEX]);
-	omap4_sar_modules[L4CORE_INDEX] = ioremap(L4_44XX_PHYS, SZ_4M);
-	BUG_ON(!omap4_sar_modules[L4CORE_INDEX]);
-	omap4_sar_modules[L4PER_INDEX] = ioremap(L4_PER_44XX_PHYS, SZ_4M);
-	BUG_ON(!omap4_sar_modules[L4PER_INDEX]);
+	sar_modules = omap44xx_sar_modules;
+
+	sar_ioremap_modules();
+
+	sar_layout_generate();
 
 	/*
 	 * SAR BANK3 contains all firewall settings and it's saved through
-- 
1.7.4.1

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

* [PATCH 07/19] ARM: OMAP4: SAR: generate overwrite data based on SAR ROM contents
  2012-04-20  9:33 ` Tero Kristo
@ 2012-04-20  9:33   ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-omap, khilman, paul; +Cc: linux-arm-kernel

omap_sar_overwrite() now uses offsets detected during init time from
the SAR ROM contents.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap-sar.c |  158 ++++++++++++++++++++++++++++------------
 1 files changed, 112 insertions(+), 46 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-sar.c b/arch/arm/mach-omap2/omap-sar.c
index da4696a..0572e7b 100644
--- a/arch/arm/mach-omap2/omap-sar.c
+++ b/arch/arm/mach-omap2/omap-sar.c
@@ -38,7 +38,52 @@ struct sar_ram_entry {
 	u32 ram_addr;
 };
 
+struct sar_overwrite_entry {
+	u32 reg_addr;
+	u32 sar_offset;
+	bool valid;
+};
+
+enum {
+	MEMIF_CLKSTCTRL_IDX,
+	SHADOW_FREQ_CFG2_IDX,
+	SHADOW_FREQ_CFG1_IDX,
+	MEMIF_CLKSTCTRL_2_IDX,
+	HSUSBHOST_CLKCTRL_IDX,
+	HSUSBHOST_CLKCTRL_2_IDX,
+	OW_IDX_SIZE
+};
+
 static struct sar_ram_entry *sar_ram_layout[3];
+static struct sar_overwrite_entry *sar_overwrite_data;
+
+static struct sar_overwrite_entry omap4_sar_overwrite_data[OW_IDX_SIZE] = {
+	[MEMIF_CLKSTCTRL_IDX] = { .reg_addr = 0x4a009e0c },
+	[SHADOW_FREQ_CFG2_IDX] = { .reg_addr = 0x4a004e2c },
+	[SHADOW_FREQ_CFG1_IDX] = { .reg_addr = 0x4a004e30 },
+	[MEMIF_CLKSTCTRL_2_IDX] = { .reg_addr = 0x4a009e0c },
+	[HSUSBHOST_CLKCTRL_IDX] = { .reg_addr = 0x4a009e54 },
+	[HSUSBHOST_CLKCTRL_2_IDX] = { .reg_addr = 0x4a009e54 },
+};
+
+static void check_overwrite_data(u32 io_addr, u32 ram_addr, int size)
+{
+	int i;
+
+	while (size) {
+		for (i = 0; i < OW_IDX_SIZE; i++) {
+			if (sar_overwrite_data[i].reg_addr == io_addr &&
+			    !sar_overwrite_data[i].valid) {
+				sar_overwrite_data[i].sar_offset = ram_addr;
+				sar_overwrite_data[i].valid = true;
+				break;
+			}
+		}
+		size--;
+		io_addr += 4;
+		ram_addr += 4;
+	}
+}
 
 /*
  * omap_sar_save :
@@ -174,58 +219,76 @@ int omap_sar_save(void)
 void omap_sar_overwrite(void)
 {
 	u32 val = 0;
-	u32 usb_offset = 0x2ec;
-	u32 usb_offset2 = 0x91c;
+	u32 offset = 0;
+
+	if (sar_overwrite_data[MEMIF_CLKSTCTRL_IDX].valid)
+		__raw_writel(0x2, sar_ram_base +
+			sar_overwrite_data[MEMIF_CLKSTCTRL_IDX].sar_offset);
+
+	if (sar_overwrite_data[SHADOW_FREQ_CFG1_IDX].valid) {
+		offset = sar_overwrite_data[SHADOW_FREQ_CFG1_IDX].sar_offset;
+		val = __raw_readl(sar_ram_base + offset);
+		val |= 1 << OMAP4430_FREQ_UPDATE_SHIFT;
+		val &= ~OMAP4430_DLL_OVERRIDE_2_2_MASK;
+		__raw_writel(val, sar_ram_base + offset);
+	}
 
-	if (cpu_is_omap446x()) {
-		usb_offset = 0x2f4;
-		usb_offset2 = 0x920;
+	if (sar_overwrite_data[SHADOW_FREQ_CFG2_IDX].valid) {
+		offset = sar_overwrite_data[SHADOW_FREQ_CFG2_IDX].sar_offset;
+		val = __raw_readl(sar_ram_base + offset);
+		/*
+		 * FIXME: Implement FREQ UPDATE for L#/M5 before enabling
+		 * val |= 1 << OMAP4430_FREQ_UPDATE_SHIFT;
+		 */
+		__raw_writel(val, sar_ram_base + offset);
 	}
 
-	/* Overwriting Phase1 data to be restored */
-	/* CM2 MEMIF_CLKTRCTRL = SW_WKUP, before FREQ UPDATE */
-	__raw_writel(0x2, sar_ram_base + SAR_BANK1_OFFSET + 0xd0);
-	/* CM1 CM_SHADOW_FREQ_CONFIG2, Enable FREQ UPDATE */
-	val = __raw_readl(OMAP4430_CM_SHADOW_FREQ_CONFIG2);
-	/*
-	 * FIXME: Implement FREQ UPDATE for L#/M5 before enabling this
-	 * val |= 1 << OMAP4430_FREQ_UPDATE_SHIFT;
-	 */
-	__raw_writel(val, sar_ram_base + SAR_BANK1_OFFSET + 0x100);
-	/* CM1 CM_SHADOW_FREQ_CONFIG1, Enable FREQ UPDATE */
-	val = __raw_readl(OMAP4430_CM_SHADOW_FREQ_CONFIG1);
-	val |= 1 << OMAP4430_FREQ_UPDATE_SHIFT;
-	val &= ~OMAP4430_DLL_OVERRIDE_2_2_MASK;
-	__raw_writel(val, sar_ram_base + SAR_BANK1_OFFSET + 0x104);
-	/* CM2 MEMIF_CLKTRCTRL = HW_AUTO, after FREQ UPDATE */
-	__raw_writel(0x3, sar_ram_base + SAR_BANK1_OFFSET + 0x124);
-
-	/* Overwriting Phase2a data to be restored */
-	/* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 1, MODULEMODE = 2 */
-	__raw_writel(0x00000012,
-		     sar_ram_base + SAR_BANK1_OFFSET + usb_offset);
-	/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 1, MODULEMODE = 1 */
-	__raw_writel(0x00000011,
-		     sar_ram_base + SAR_BANK1_OFFSET + usb_offset + 4);
-	/* CM2 CM_SDMA_STATICDEP : Enable static depedency for SAR modules */
-	__raw_writel(0x000090e8,
-		     sar_ram_base + SAR_BANK1_OFFSET + usb_offset + 8);
-
-	/* Overwriting Phase2b data to be restored */
-	/* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */
-	val = __raw_readl(OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL);
-	val &= (OMAP4430_CLKSEL_UTMI_P1_MASK | OMAP4430_CLKSEL_UTMI_P2_MASK);
-	__raw_writel(val, sar_ram_base + SAR_BANK1_OFFSET + usb_offset2);
-	/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */
-	__raw_writel(0x0000000,
-		     sar_ram_base + SAR_BANK1_OFFSET + usb_offset2 + 4);
-	/* CM2 CM_SDMA_STATICDEP : Clear the static depedency */
-	__raw_writel(0x00000040,
-		     sar_ram_base + SAR_BANK1_OFFSET + usb_offset2 + 8);
+	if (sar_overwrite_data[MEMIF_CLKSTCTRL_2_IDX].valid)
+		__raw_writel(0x3, sar_ram_base +
+			sar_overwrite_data[MEMIF_CLKSTCTRL_2_IDX].sar_offset);
+
+	if (sar_overwrite_data[HSUSBHOST_CLKCTRL_IDX].valid) {
+		offset = sar_overwrite_data[HSUSBHOST_CLKCTRL_IDX].sar_offset;
+
+		/* Overwriting Phase2a data to be restored */
+		/* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 1, MODULEMODE = 2 */
+		__raw_writel(OMAP4430_SAR_MODE_MASK | 0x2,
+			sar_ram_base + offset);
+		/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 1, MODULEMODE = 1 */
+		__raw_writel(OMAP4430_SAR_MODE_MASK | 0x1,
+			sar_ram_base + offset + 4);
+		/*
+		 * CM2 CM_SDMA_STATICDEP : Enable static depedency for
+		 * SAR modules
+		 */
+		__raw_writel(OMAP4430_L4WKUP_STATDEP_MASK |
+			     OMAP4430_L4CFG_STATDEP_MASK |
+			     OMAP4430_L3INIT_STATDEP_MASK |
+			     OMAP4430_L3_1_STATDEP_MASK |
+			     OMAP4430_L3_2_STATDEP_MASK |
+			     OMAP4430_ABE_STATDEP_MASK,
+			     sar_ram_base + offset + 8);
+	}
+
+	if (sar_overwrite_data[HSUSBHOST_CLKCTRL_2_IDX].valid) {
+		offset = sar_overwrite_data[HSUSBHOST_CLKCTRL_2_IDX].sar_offset;
+
+		/* Overwriting Phase2b data to be restored */
+		/* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */
+		val = __raw_readl(OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL);
+		val &= (OMAP4430_CLKSEL_UTMI_P1_MASK |
+			OMAP4430_CLKSEL_UTMI_P2_MASK);
+		__raw_writel(val, sar_ram_base + offset);
+		/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */
+		__raw_writel(0, sar_ram_base + offset + 4);
+		/* CM2 CM_SDMA_STATICDEP : Clear the static depedency */
+		__raw_writel(OMAP4430_L3_2_STATDEP_MASK,
+			     sar_ram_base + offset + 8);
+	}
 
 	/* readback to ensure data reaches to SAR RAM */
 	barrier();
-	val = __raw_readl(sar_ram_base + SAR_BANK1_OFFSET + usb_offset2 + 8);
+	val = __raw_readl(sar_ram_base + offset + 8);
 }
 
 void __iomem *omap4_get_sar_ram_base(void)
@@ -327,6 +390,8 @@ static int sar_layout_generate(void)
 				if (!set_sar_io_addr(entry[bank], io_addr)) {
 					entry[bank]->size = size;
 					entry[bank]->ram_addr = ram_addr;
+					check_overwrite_data(io_addr, ram_addr,
+						size);
 					entry[bank]++;
 				}
 			}
@@ -400,6 +465,7 @@ static int __init omap4_sar_ram_init(void)
 	BUG_ON(!sar_ram_base);
 
 	sar_modules = omap44xx_sar_modules;
+	sar_overwrite_data = omap4_sar_overwrite_data;
 
 	sar_ioremap_modules();
 
-- 
1.7.4.1


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

* [PATCH 07/19] ARM: OMAP4: SAR: generate overwrite data based on SAR ROM contents
@ 2012-04-20  9:33   ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-arm-kernel

omap_sar_overwrite() now uses offsets detected during init time from
the SAR ROM contents.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap-sar.c |  158 ++++++++++++++++++++++++++++------------
 1 files changed, 112 insertions(+), 46 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-sar.c b/arch/arm/mach-omap2/omap-sar.c
index da4696a..0572e7b 100644
--- a/arch/arm/mach-omap2/omap-sar.c
+++ b/arch/arm/mach-omap2/omap-sar.c
@@ -38,7 +38,52 @@ struct sar_ram_entry {
 	u32 ram_addr;
 };
 
+struct sar_overwrite_entry {
+	u32 reg_addr;
+	u32 sar_offset;
+	bool valid;
+};
+
+enum {
+	MEMIF_CLKSTCTRL_IDX,
+	SHADOW_FREQ_CFG2_IDX,
+	SHADOW_FREQ_CFG1_IDX,
+	MEMIF_CLKSTCTRL_2_IDX,
+	HSUSBHOST_CLKCTRL_IDX,
+	HSUSBHOST_CLKCTRL_2_IDX,
+	OW_IDX_SIZE
+};
+
 static struct sar_ram_entry *sar_ram_layout[3];
+static struct sar_overwrite_entry *sar_overwrite_data;
+
+static struct sar_overwrite_entry omap4_sar_overwrite_data[OW_IDX_SIZE] = {
+	[MEMIF_CLKSTCTRL_IDX] = { .reg_addr = 0x4a009e0c },
+	[SHADOW_FREQ_CFG2_IDX] = { .reg_addr = 0x4a004e2c },
+	[SHADOW_FREQ_CFG1_IDX] = { .reg_addr = 0x4a004e30 },
+	[MEMIF_CLKSTCTRL_2_IDX] = { .reg_addr = 0x4a009e0c },
+	[HSUSBHOST_CLKCTRL_IDX] = { .reg_addr = 0x4a009e54 },
+	[HSUSBHOST_CLKCTRL_2_IDX] = { .reg_addr = 0x4a009e54 },
+};
+
+static void check_overwrite_data(u32 io_addr, u32 ram_addr, int size)
+{
+	int i;
+
+	while (size) {
+		for (i = 0; i < OW_IDX_SIZE; i++) {
+			if (sar_overwrite_data[i].reg_addr == io_addr &&
+			    !sar_overwrite_data[i].valid) {
+				sar_overwrite_data[i].sar_offset = ram_addr;
+				sar_overwrite_data[i].valid = true;
+				break;
+			}
+		}
+		size--;
+		io_addr += 4;
+		ram_addr += 4;
+	}
+}
 
 /*
  * omap_sar_save :
@@ -174,58 +219,76 @@ int omap_sar_save(void)
 void omap_sar_overwrite(void)
 {
 	u32 val = 0;
-	u32 usb_offset = 0x2ec;
-	u32 usb_offset2 = 0x91c;
+	u32 offset = 0;
+
+	if (sar_overwrite_data[MEMIF_CLKSTCTRL_IDX].valid)
+		__raw_writel(0x2, sar_ram_base +
+			sar_overwrite_data[MEMIF_CLKSTCTRL_IDX].sar_offset);
+
+	if (sar_overwrite_data[SHADOW_FREQ_CFG1_IDX].valid) {
+		offset = sar_overwrite_data[SHADOW_FREQ_CFG1_IDX].sar_offset;
+		val = __raw_readl(sar_ram_base + offset);
+		val |= 1 << OMAP4430_FREQ_UPDATE_SHIFT;
+		val &= ~OMAP4430_DLL_OVERRIDE_2_2_MASK;
+		__raw_writel(val, sar_ram_base + offset);
+	}
 
-	if (cpu_is_omap446x()) {
-		usb_offset = 0x2f4;
-		usb_offset2 = 0x920;
+	if (sar_overwrite_data[SHADOW_FREQ_CFG2_IDX].valid) {
+		offset = sar_overwrite_data[SHADOW_FREQ_CFG2_IDX].sar_offset;
+		val = __raw_readl(sar_ram_base + offset);
+		/*
+		 * FIXME: Implement FREQ UPDATE for L#/M5 before enabling
+		 * val |= 1 << OMAP4430_FREQ_UPDATE_SHIFT;
+		 */
+		__raw_writel(val, sar_ram_base + offset);
 	}
 
-	/* Overwriting Phase1 data to be restored */
-	/* CM2 MEMIF_CLKTRCTRL = SW_WKUP, before FREQ UPDATE */
-	__raw_writel(0x2, sar_ram_base + SAR_BANK1_OFFSET + 0xd0);
-	/* CM1 CM_SHADOW_FREQ_CONFIG2, Enable FREQ UPDATE */
-	val = __raw_readl(OMAP4430_CM_SHADOW_FREQ_CONFIG2);
-	/*
-	 * FIXME: Implement FREQ UPDATE for L#/M5 before enabling this
-	 * val |= 1 << OMAP4430_FREQ_UPDATE_SHIFT;
-	 */
-	__raw_writel(val, sar_ram_base + SAR_BANK1_OFFSET + 0x100);
-	/* CM1 CM_SHADOW_FREQ_CONFIG1, Enable FREQ UPDATE */
-	val = __raw_readl(OMAP4430_CM_SHADOW_FREQ_CONFIG1);
-	val |= 1 << OMAP4430_FREQ_UPDATE_SHIFT;
-	val &= ~OMAP4430_DLL_OVERRIDE_2_2_MASK;
-	__raw_writel(val, sar_ram_base + SAR_BANK1_OFFSET + 0x104);
-	/* CM2 MEMIF_CLKTRCTRL = HW_AUTO, after FREQ UPDATE */
-	__raw_writel(0x3, sar_ram_base + SAR_BANK1_OFFSET + 0x124);
-
-	/* Overwriting Phase2a data to be restored */
-	/* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 1, MODULEMODE = 2 */
-	__raw_writel(0x00000012,
-		     sar_ram_base + SAR_BANK1_OFFSET + usb_offset);
-	/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 1, MODULEMODE = 1 */
-	__raw_writel(0x00000011,
-		     sar_ram_base + SAR_BANK1_OFFSET + usb_offset + 4);
-	/* CM2 CM_SDMA_STATICDEP : Enable static depedency for SAR modules */
-	__raw_writel(0x000090e8,
-		     sar_ram_base + SAR_BANK1_OFFSET + usb_offset + 8);
-
-	/* Overwriting Phase2b data to be restored */
-	/* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */
-	val = __raw_readl(OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL);
-	val &= (OMAP4430_CLKSEL_UTMI_P1_MASK | OMAP4430_CLKSEL_UTMI_P2_MASK);
-	__raw_writel(val, sar_ram_base + SAR_BANK1_OFFSET + usb_offset2);
-	/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */
-	__raw_writel(0x0000000,
-		     sar_ram_base + SAR_BANK1_OFFSET + usb_offset2 + 4);
-	/* CM2 CM_SDMA_STATICDEP : Clear the static depedency */
-	__raw_writel(0x00000040,
-		     sar_ram_base + SAR_BANK1_OFFSET + usb_offset2 + 8);
+	if (sar_overwrite_data[MEMIF_CLKSTCTRL_2_IDX].valid)
+		__raw_writel(0x3, sar_ram_base +
+			sar_overwrite_data[MEMIF_CLKSTCTRL_2_IDX].sar_offset);
+
+	if (sar_overwrite_data[HSUSBHOST_CLKCTRL_IDX].valid) {
+		offset = sar_overwrite_data[HSUSBHOST_CLKCTRL_IDX].sar_offset;
+
+		/* Overwriting Phase2a data to be restored */
+		/* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 1, MODULEMODE = 2 */
+		__raw_writel(OMAP4430_SAR_MODE_MASK | 0x2,
+			sar_ram_base + offset);
+		/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 1, MODULEMODE = 1 */
+		__raw_writel(OMAP4430_SAR_MODE_MASK | 0x1,
+			sar_ram_base + offset + 4);
+		/*
+		 * CM2 CM_SDMA_STATICDEP : Enable static depedency for
+		 * SAR modules
+		 */
+		__raw_writel(OMAP4430_L4WKUP_STATDEP_MASK |
+			     OMAP4430_L4CFG_STATDEP_MASK |
+			     OMAP4430_L3INIT_STATDEP_MASK |
+			     OMAP4430_L3_1_STATDEP_MASK |
+			     OMAP4430_L3_2_STATDEP_MASK |
+			     OMAP4430_ABE_STATDEP_MASK,
+			     sar_ram_base + offset + 8);
+	}
+
+	if (sar_overwrite_data[HSUSBHOST_CLKCTRL_2_IDX].valid) {
+		offset = sar_overwrite_data[HSUSBHOST_CLKCTRL_2_IDX].sar_offset;
+
+		/* Overwriting Phase2b data to be restored */
+		/* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */
+		val = __raw_readl(OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL);
+		val &= (OMAP4430_CLKSEL_UTMI_P1_MASK |
+			OMAP4430_CLKSEL_UTMI_P2_MASK);
+		__raw_writel(val, sar_ram_base + offset);
+		/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */
+		__raw_writel(0, sar_ram_base + offset + 4);
+		/* CM2 CM_SDMA_STATICDEP : Clear the static depedency */
+		__raw_writel(OMAP4430_L3_2_STATDEP_MASK,
+			     sar_ram_base + offset + 8);
+	}
 
 	/* readback to ensure data reaches to SAR RAM */
 	barrier();
-	val = __raw_readl(sar_ram_base + SAR_BANK1_OFFSET + usb_offset2 + 8);
+	val = __raw_readl(sar_ram_base + offset + 8);
 }
 
 void __iomem *omap4_get_sar_ram_base(void)
@@ -327,6 +390,8 @@ static int sar_layout_generate(void)
 				if (!set_sar_io_addr(entry[bank], io_addr)) {
 					entry[bank]->size = size;
 					entry[bank]->ram_addr = ram_addr;
+					check_overwrite_data(io_addr, ram_addr,
+						size);
 					entry[bank]++;
 				}
 			}
@@ -400,6 +465,7 @@ static int __init omap4_sar_ram_init(void)
 	BUG_ON(!sar_ram_base);
 
 	sar_modules = omap44xx_sar_modules;
+	sar_overwrite_data = omap4_sar_overwrite_data;
 
 	sar_ioremap_modules();
 
-- 
1.7.4.1

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

* [PATCH 08/19] ARM: OMAP4: PM: Add device-off support
  2012-04-20  9:33 ` Tero Kristo
@ 2012-04-20  9:33   ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-omap, khilman, paul; +Cc: linux-arm-kernel, Santosh Shilimkar

This patch adds device off support to OMAP4 device type.

OFF mode is disabled by default, however, there are two ways to enable
OFF mode:
a) In the board file, call omap4_pm_off_mode_enable(1)
b) Enable OFF mode using the debugfs entry
echo "1">/sys/kernel/debug/pm_debug/enable_off_mode
(conversely echo '0' will disable it as well).

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
[t-kristo@ti.com: largely re-structured the code]
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap-mpuss-lowpower.c |   24 ++++++++++-
 arch/arm/mach-omap2/omap-wakeupgen.c      |   47 +++++++++++++++++++-
 arch/arm/mach-omap2/pm-debug.c            |   17 +++++--
 arch/arm/mach-omap2/pm.h                  |   28 ++++++++++--
 arch/arm/mach-omap2/pm44xx.c              |   45 +++++++++++++++++++
 arch/arm/mach-omap2/prm44xx.c             |   66 +++++++++++++++++++++++++++++
 6 files changed, 214 insertions(+), 13 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index e02c082..b9a2cc7 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -60,6 +60,7 @@
 #include "prcm44xx.h"
 #include "prm44xx.h"
 #include "prm-regbits-44xx.h"
+#include "cm44xx.h"
 
 #ifdef CONFIG_SMP
 
@@ -232,6 +233,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 {
 	unsigned int save_state = 0;
 	unsigned int wakeup_cpu;
+	int ret;
 
 	if (omap_rev() == OMAP4430_REV_ES1_0)
 		return -ENXIO;
@@ -263,9 +265,21 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 	 * In MPUSS OSWR or device OFF, interrupt controller  contest is lost.
 	 */
 	mpuss_clear_prev_logic_pwrst();
-	if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) &&
-		(pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF))
+	if (omap4_device_next_state_off()) {
+		/* Save the device context to SAR RAM */
+		ret = omap_sar_save();
+		if (ret)
+			return ret;
+		omap_sar_overwrite();
+		omap4_cm_prepare_off();
+		omap4_dpll_prepare_off();
+		save_state = 3;
+	} else if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) &&
+		(pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF)) {
 		save_state = 2;
+	} else if (pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_OFF) {
+		save_state = 3;
+	}
 
 	cpu_clear_prev_logic_pwrst(cpu);
 	set_cpu_next_pwrst(cpu, power_state);
@@ -288,6 +302,12 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 	wakeup_cpu = smp_processor_id();
 	set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON);
 
+	if (omap4_device_prev_state_off()) {
+		omap4_dpll_resume_off();
+		omap4_cm_resume_off();
+		omap4_device_clear_prev_off_state();
+	}
+
 	pwrdm_post_transition();
 
 	return 0;
diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
index 42cd7fb..805d08d 100644
--- a/arch/arm/mach-omap2/omap-wakeupgen.c
+++ b/arch/arm/mach-omap2/omap-wakeupgen.c
@@ -32,6 +32,7 @@
 
 #include "omap4-sar-layout.h"
 #include "common.h"
+#include "pm.h"
 
 #define NR_REG_BANKS		4
 #define MAX_IRQS		128
@@ -46,6 +47,8 @@ static void __iomem *sar_base;
 static DEFINE_SPINLOCK(wakeupgen_lock);
 static unsigned int irq_target_cpu[NR_IRQS];
 
+static struct powerdomain *mpuss_pd;
+
 /*
  * Static helper functions.
  */
@@ -259,7 +262,7 @@ static void irq_save_context(void)
 /*
  * Clear WakeupGen SAR backup status.
  */
-void irq_sar_clear(void)
+static void irq_sar_clear(void)
 {
 	u32 val;
 	val = __raw_readl(sar_base + SAR_BACKUP_STATUS_OFFSET);
@@ -271,7 +274,7 @@ void irq_sar_clear(void)
  * Save GIC and Wakeupgen interrupt context using secure API
  * for HS/EMU devices.
  */
-static void irq_save_secure_context(void)
+static void irq_save_secure_gic(void)
 {
 	u32 ret;
 	ret = omap_secure_dispatcher(OMAP4_HAL_SAVEGIC_INDEX,
@@ -282,6 +285,40 @@ static void irq_save_secure_context(void)
 }
 #endif
 
+static void save_secure_ram(void)
+{
+	u32 ret;
+	ret = omap_secure_dispatcher(OMAP4_HAL_SAVESECURERAM_INDEX,
+				FLAG_START_CRITICAL,
+				1, omap_secure_ram_mempool_base(),
+				0, 0, 0);
+	if (ret != API_HAL_RET_VALUE_OK)
+		pr_err("Secure ram context save failed\n");
+}
+
+static void save_secure_all(void)
+{
+	u32 ret;
+	ret = omap_secure_dispatcher(OMAP4_HAL_SAVEALL_INDEX,
+				FLAG_START_CRITICAL,
+				1, omap_secure_ram_mempool_base(),
+				0, 0, 0);
+	if (ret != API_HAL_RET_VALUE_OK)
+		pr_err("Secure all context save failed\n");
+}
+
+static void irq_save_secure_context(void)
+{
+	if (omap4_device_next_state_off()) {
+		save_secure_all();
+	} else if (pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_OFF) {
+		irq_save_secure_gic();
+		save_secure_ram();
+	} else {
+		irq_save_secure_gic();
+	}
+}
+
 #ifdef CONFIG_HOTPLUG_CPU
 static int __cpuinit irq_cpu_hotplug_notify(struct notifier_block *self,
 					 unsigned long action, void *hcpu)
@@ -388,5 +425,11 @@ int __init omap_wakeupgen_init(void)
 	irq_hotplug_init();
 	irq_pm_init();
 
+	mpuss_pd = pwrdm_lookup("mpu_pwrdm");
+	if (!mpuss_pd) {
+		pr_err("wakeupgen: unable to get mpu_pwrdm\n");
+		return -EINVAL;
+	}
+
 	return 0;
 }
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index d9a8e42..d8cf5e5 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -40,6 +40,7 @@
 
 u32 enable_off_mode;
 static u32 enable_oswr_mode;
+static void (*off_mode_enable_func) (int);
 
 #ifdef CONFIG_DEBUG_FS
 #include <linux/debugfs.h>
@@ -249,7 +250,8 @@ static int option_set(void *data, u64 val)
 		else
 			omap_pm_disable_off_mode();
 
-		omap3_pm_off_mode_enable(val);
+		if (off_mode_enable_func)
+			off_mode_enable_func(val);
 	}
 
 	if (option == &enable_oswr_mode)
@@ -278,16 +280,21 @@ static int __init pm_dbg_init(void)
 
 	pwrdm_for_each(pwrdms_setup, (void *)d);
 
-	if (cpu_is_omap34xx())
-		(void) debugfs_create_file("enable_off_mode",
-			S_IRUGO | S_IWUSR, d, &enable_off_mode,
-			&pm_dbg_option_fops);
+	(void) debugfs_create_file("enable_off_mode",
+		S_IRUGO | S_IWUSR, d, &enable_off_mode,
+		&pm_dbg_option_fops);
 
 	if (cpu_is_omap44xx())
 		(void) debugfs_create_file("enable_oswr_mode",
 			S_IRUGO | S_IWUSR, d, &enable_oswr_mode,
 			&pm_dbg_option_fops);
 
+	if (cpu_is_omap34xx())
+		off_mode_enable_func = omap3_pm_off_mode_enable;
+
+	if (cpu_is_omap44xx())
+		off_mode_enable_func = omap4_pm_off_mode_enable;
+
 	pm_dbg_init_done = 1;
 
 	return 0;
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index c13e3c1..f65da57 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -18,6 +18,7 @@
 extern void *omap3_secure_ram_storage;
 extern void omap3_pm_off_mode_enable(int);
 extern void omap4_pm_oswr_mode_enable(int);
+extern void omap4_pm_off_mode_enable(int);
 extern void omap_sram_idle(void);
 extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
 extern int omap3_idle_init(void);
@@ -26,6 +27,25 @@ extern int omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused);
 extern int (*omap_pm_suspend)(void);
 extern void omap_trigger_io_chain(void);
 
+#ifdef CONFIG_PM
+extern void omap4_device_set_state_off(u8 enable);
+extern bool omap4_device_prev_state_off(void);
+extern bool omap4_device_next_state_off(void);
+extern void omap4_device_clear_prev_off_state(void);
+#else
+static inline void omap4_device_set_state_off(u8 enable)
+{
+}
+static inline bool omap4_device_prev_state_off(void)
+{
+	return false;
+}
+static inline bool omap4_device_next_state_off(void)
+{
+	return false;
+}
+#endif
+
 #if defined(CONFIG_PM_OPP)
 extern int omap3_opp_init(void);
 extern int omap4_opp_init(void);
@@ -139,13 +159,13 @@ static inline int omap4_twl_init(void)
 #endif
 
 #ifdef CONFIG_PM
-extern int omap4_sar_save(void);
-extern void omap4_sar_overwrite(void);
+extern int omap_sar_save(void);
+extern void omap_sar_overwrite(void);
 #else
-static inline void omap4_sar_save(void)
+static inline void omap_sar_save(void)
 {
 }
-static inline void omap4_sar_overwrite(void)
+static inline void omap_sar_overwrite(void)
 {
 }
 #endif
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 07ac0d3..8f0ec56 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -87,6 +87,27 @@ static int omap4_pm_suspend(void)
 }
 #endif /* CONFIG_SUSPEND */
 
+/**
+ * get_achievable_state() - Provide achievable state
+ * @available_states:	what states are available
+ * @req_min_state:	what state is the minimum we'd like to hit
+ *
+ * Power domains have varied capabilities. When attempting a low power
+ * state such as OFF/RET, a specific min requested state may not be
+ * supported on the power domain, in which case, the next higher power
+ * state which is supported is returned. This is because a combination
+ * of system power states where the parent PD's state is not in line
+ * with expectation can result in system instabilities.
+ */
+static inline u8 get_achievable_state(u8 available_states, u8 req_min_state)
+{
+	u16 mask = 0xFF << req_min_state;
+
+	if (available_states & mask)
+		return __ffs(available_states & mask);
+	return PWRDM_POWER_ON;
+}
+
 static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
 {
 	struct power_state *pwrst;
@@ -115,6 +136,30 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
 	return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
 }
 
+void omap4_pm_off_mode_enable(int enable)
+{
+	u32 next_state = PWRDM_POWER_RET;
+	u32 next_logic_state = PWRDM_POWER_ON;
+	struct power_state *pwrst;
+
+	if (enable) {
+		next_state = PWRDM_POWER_OFF;
+		next_logic_state = PWRDM_POWER_OFF;
+	}
+
+	omap4_device_set_state_off(enable);
+
+	list_for_each_entry(pwrst, &pwrst_list, node) {
+		pwrst->next_state =
+			get_achievable_state(pwrst->pwrdm->pwrsts, next_state);
+		pwrst->next_logic_state =
+			get_achievable_state(pwrst->pwrdm->pwrsts_logic_ret,
+				next_logic_state);
+		omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
+		pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->next_logic_state);
+	}
+}
+
 void omap4_pm_oswr_mode_enable(int enable)
 {
 	u32 next_logic_state;
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index f6dab07..ab810cd 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -274,6 +274,72 @@ static void __init omap4_enable_io_wakeup(void)
 			OMAP4_PRM_IO_PMCTRL_OFFSET);
 }
 
+/**
+ * omap4_device_set_state_off() - setup device off state
+ * @enable:	set to off or not.
+ *
+ * When Device OFF is enabled, Device is allowed to perform
+ * transition to off mode as soon as all power domains in MPU, IVA
+ * and CORE voltage are in OFF or OSWR state (open switch retention)
+ */
+void omap4_device_set_state_off(u8 enable)
+{
+	if (enable)
+		omap4_prminst_write_inst_reg(0x1 <<
+				OMAP4430_DEVICE_OFF_ENABLE_SHIFT,
+				OMAP4430_PRM_PARTITION,
+				OMAP4430_PRM_DEVICE_INST,
+				OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET);
+	else
+		omap4_prminst_write_inst_reg(0x0 <<
+				OMAP4430_DEVICE_OFF_ENABLE_SHIFT,
+				OMAP4430_PRM_PARTITION,
+				OMAP4430_PRM_DEVICE_INST,
+				OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET);
+}
+
+/**
+ * omap4_device_prev_state_off:
+ * returns true if the device hit OFF mode
+ * This is API to check whether OMAP is waking up from device OFF mode.
+ * There is no other status bit available for SW to read whether last state
+ * entered was device OFF. To work around this, CORE PD, RFF context state
+ * is used which is lost only when we hit device OFF state
+ */
+bool omap4_device_prev_state_off(void)
+{
+	u32 reg;
+
+	reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
+				OMAP4430_PRM_CORE_INST,
+				OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET)
+		& OMAP4430_LOSTCONTEXT_RFF_MASK;
+
+	return reg ? true : false;
+}
+
+void omap4_device_clear_prev_off_state(void)
+{
+	omap4_prminst_write_inst_reg(OMAP4430_LOSTCONTEXT_RFF_MASK |
+				OMAP4430_LOSTCONTEXT_DFF_MASK,
+				OMAP4430_PRM_PARTITION,
+				OMAP4430_PRM_CORE_INST,
+				OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET);
+}
+
+/**
+ * omap4_device_next_state_off:
+ * returns true if the device next state is OFF
+ * This is API to check whether OMAP is programmed for device OFF
+ */
+bool omap4_device_next_state_off(void)
+{
+	return omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
+			OMAP4430_PRM_DEVICE_INST,
+			OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET)
+			& OMAP4430_DEVICE_OFF_ENABLE_MASK ? true : false;
+}
+
 static int __init omap4xxx_prcm_init(void)
 {
 	if (cpu_is_omap44xx()) {
-- 
1.7.4.1


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

* [PATCH 08/19] ARM: OMAP4: PM: Add device-off support
@ 2012-04-20  9:33   ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds device off support to OMAP4 device type.

OFF mode is disabled by default, however, there are two ways to enable
OFF mode:
a) In the board file, call omap4_pm_off_mode_enable(1)
b) Enable OFF mode using the debugfs entry
echo "1">/sys/kernel/debug/pm_debug/enable_off_mode
(conversely echo '0' will disable it as well).

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
[t-kristo at ti.com: largely re-structured the code]
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap-mpuss-lowpower.c |   24 ++++++++++-
 arch/arm/mach-omap2/omap-wakeupgen.c      |   47 +++++++++++++++++++-
 arch/arm/mach-omap2/pm-debug.c            |   17 +++++--
 arch/arm/mach-omap2/pm.h                  |   28 ++++++++++--
 arch/arm/mach-omap2/pm44xx.c              |   45 +++++++++++++++++++
 arch/arm/mach-omap2/prm44xx.c             |   66 +++++++++++++++++++++++++++++
 6 files changed, 214 insertions(+), 13 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index e02c082..b9a2cc7 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -60,6 +60,7 @@
 #include "prcm44xx.h"
 #include "prm44xx.h"
 #include "prm-regbits-44xx.h"
+#include "cm44xx.h"
 
 #ifdef CONFIG_SMP
 
@@ -232,6 +233,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 {
 	unsigned int save_state = 0;
 	unsigned int wakeup_cpu;
+	int ret;
 
 	if (omap_rev() == OMAP4430_REV_ES1_0)
 		return -ENXIO;
@@ -263,9 +265,21 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 	 * In MPUSS OSWR or device OFF, interrupt controller  contest is lost.
 	 */
 	mpuss_clear_prev_logic_pwrst();
-	if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) &&
-		(pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF))
+	if (omap4_device_next_state_off()) {
+		/* Save the device context to SAR RAM */
+		ret = omap_sar_save();
+		if (ret)
+			return ret;
+		omap_sar_overwrite();
+		omap4_cm_prepare_off();
+		omap4_dpll_prepare_off();
+		save_state = 3;
+	} else if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) &&
+		(pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF)) {
 		save_state = 2;
+	} else if (pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_OFF) {
+		save_state = 3;
+	}
 
 	cpu_clear_prev_logic_pwrst(cpu);
 	set_cpu_next_pwrst(cpu, power_state);
@@ -288,6 +302,12 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 	wakeup_cpu = smp_processor_id();
 	set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON);
 
+	if (omap4_device_prev_state_off()) {
+		omap4_dpll_resume_off();
+		omap4_cm_resume_off();
+		omap4_device_clear_prev_off_state();
+	}
+
 	pwrdm_post_transition();
 
 	return 0;
diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
index 42cd7fb..805d08d 100644
--- a/arch/arm/mach-omap2/omap-wakeupgen.c
+++ b/arch/arm/mach-omap2/omap-wakeupgen.c
@@ -32,6 +32,7 @@
 
 #include "omap4-sar-layout.h"
 #include "common.h"
+#include "pm.h"
 
 #define NR_REG_BANKS		4
 #define MAX_IRQS		128
@@ -46,6 +47,8 @@ static void __iomem *sar_base;
 static DEFINE_SPINLOCK(wakeupgen_lock);
 static unsigned int irq_target_cpu[NR_IRQS];
 
+static struct powerdomain *mpuss_pd;
+
 /*
  * Static helper functions.
  */
@@ -259,7 +262,7 @@ static void irq_save_context(void)
 /*
  * Clear WakeupGen SAR backup status.
  */
-void irq_sar_clear(void)
+static void irq_sar_clear(void)
 {
 	u32 val;
 	val = __raw_readl(sar_base + SAR_BACKUP_STATUS_OFFSET);
@@ -271,7 +274,7 @@ void irq_sar_clear(void)
  * Save GIC and Wakeupgen interrupt context using secure API
  * for HS/EMU devices.
  */
-static void irq_save_secure_context(void)
+static void irq_save_secure_gic(void)
 {
 	u32 ret;
 	ret = omap_secure_dispatcher(OMAP4_HAL_SAVEGIC_INDEX,
@@ -282,6 +285,40 @@ static void irq_save_secure_context(void)
 }
 #endif
 
+static void save_secure_ram(void)
+{
+	u32 ret;
+	ret = omap_secure_dispatcher(OMAP4_HAL_SAVESECURERAM_INDEX,
+				FLAG_START_CRITICAL,
+				1, omap_secure_ram_mempool_base(),
+				0, 0, 0);
+	if (ret != API_HAL_RET_VALUE_OK)
+		pr_err("Secure ram context save failed\n");
+}
+
+static void save_secure_all(void)
+{
+	u32 ret;
+	ret = omap_secure_dispatcher(OMAP4_HAL_SAVEALL_INDEX,
+				FLAG_START_CRITICAL,
+				1, omap_secure_ram_mempool_base(),
+				0, 0, 0);
+	if (ret != API_HAL_RET_VALUE_OK)
+		pr_err("Secure all context save failed\n");
+}
+
+static void irq_save_secure_context(void)
+{
+	if (omap4_device_next_state_off()) {
+		save_secure_all();
+	} else if (pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_OFF) {
+		irq_save_secure_gic();
+		save_secure_ram();
+	} else {
+		irq_save_secure_gic();
+	}
+}
+
 #ifdef CONFIG_HOTPLUG_CPU
 static int __cpuinit irq_cpu_hotplug_notify(struct notifier_block *self,
 					 unsigned long action, void *hcpu)
@@ -388,5 +425,11 @@ int __init omap_wakeupgen_init(void)
 	irq_hotplug_init();
 	irq_pm_init();
 
+	mpuss_pd = pwrdm_lookup("mpu_pwrdm");
+	if (!mpuss_pd) {
+		pr_err("wakeupgen: unable to get mpu_pwrdm\n");
+		return -EINVAL;
+	}
+
 	return 0;
 }
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index d9a8e42..d8cf5e5 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -40,6 +40,7 @@
 
 u32 enable_off_mode;
 static u32 enable_oswr_mode;
+static void (*off_mode_enable_func) (int);
 
 #ifdef CONFIG_DEBUG_FS
 #include <linux/debugfs.h>
@@ -249,7 +250,8 @@ static int option_set(void *data, u64 val)
 		else
 			omap_pm_disable_off_mode();
 
-		omap3_pm_off_mode_enable(val);
+		if (off_mode_enable_func)
+			off_mode_enable_func(val);
 	}
 
 	if (option == &enable_oswr_mode)
@@ -278,16 +280,21 @@ static int __init pm_dbg_init(void)
 
 	pwrdm_for_each(pwrdms_setup, (void *)d);
 
-	if (cpu_is_omap34xx())
-		(void) debugfs_create_file("enable_off_mode",
-			S_IRUGO | S_IWUSR, d, &enable_off_mode,
-			&pm_dbg_option_fops);
+	(void) debugfs_create_file("enable_off_mode",
+		S_IRUGO | S_IWUSR, d, &enable_off_mode,
+		&pm_dbg_option_fops);
 
 	if (cpu_is_omap44xx())
 		(void) debugfs_create_file("enable_oswr_mode",
 			S_IRUGO | S_IWUSR, d, &enable_oswr_mode,
 			&pm_dbg_option_fops);
 
+	if (cpu_is_omap34xx())
+		off_mode_enable_func = omap3_pm_off_mode_enable;
+
+	if (cpu_is_omap44xx())
+		off_mode_enable_func = omap4_pm_off_mode_enable;
+
 	pm_dbg_init_done = 1;
 
 	return 0;
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index c13e3c1..f65da57 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -18,6 +18,7 @@
 extern void *omap3_secure_ram_storage;
 extern void omap3_pm_off_mode_enable(int);
 extern void omap4_pm_oswr_mode_enable(int);
+extern void omap4_pm_off_mode_enable(int);
 extern void omap_sram_idle(void);
 extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
 extern int omap3_idle_init(void);
@@ -26,6 +27,25 @@ extern int omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused);
 extern int (*omap_pm_suspend)(void);
 extern void omap_trigger_io_chain(void);
 
+#ifdef CONFIG_PM
+extern void omap4_device_set_state_off(u8 enable);
+extern bool omap4_device_prev_state_off(void);
+extern bool omap4_device_next_state_off(void);
+extern void omap4_device_clear_prev_off_state(void);
+#else
+static inline void omap4_device_set_state_off(u8 enable)
+{
+}
+static inline bool omap4_device_prev_state_off(void)
+{
+	return false;
+}
+static inline bool omap4_device_next_state_off(void)
+{
+	return false;
+}
+#endif
+
 #if defined(CONFIG_PM_OPP)
 extern int omap3_opp_init(void);
 extern int omap4_opp_init(void);
@@ -139,13 +159,13 @@ static inline int omap4_twl_init(void)
 #endif
 
 #ifdef CONFIG_PM
-extern int omap4_sar_save(void);
-extern void omap4_sar_overwrite(void);
+extern int omap_sar_save(void);
+extern void omap_sar_overwrite(void);
 #else
-static inline void omap4_sar_save(void)
+static inline void omap_sar_save(void)
 {
 }
-static inline void omap4_sar_overwrite(void)
+static inline void omap_sar_overwrite(void)
 {
 }
 #endif
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 07ac0d3..8f0ec56 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -87,6 +87,27 @@ static int omap4_pm_suspend(void)
 }
 #endif /* CONFIG_SUSPEND */
 
+/**
+ * get_achievable_state() - Provide achievable state
+ * @available_states:	what states are available
+ * @req_min_state:	what state is the minimum we'd like to hit
+ *
+ * Power domains have varied capabilities. When attempting a low power
+ * state such as OFF/RET, a specific min requested state may not be
+ * supported on the power domain, in which case, the next higher power
+ * state which is supported is returned. This is because a combination
+ * of system power states where the parent PD's state is not in line
+ * with expectation can result in system instabilities.
+ */
+static inline u8 get_achievable_state(u8 available_states, u8 req_min_state)
+{
+	u16 mask = 0xFF << req_min_state;
+
+	if (available_states & mask)
+		return __ffs(available_states & mask);
+	return PWRDM_POWER_ON;
+}
+
 static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
 {
 	struct power_state *pwrst;
@@ -115,6 +136,30 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
 	return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
 }
 
+void omap4_pm_off_mode_enable(int enable)
+{
+	u32 next_state = PWRDM_POWER_RET;
+	u32 next_logic_state = PWRDM_POWER_ON;
+	struct power_state *pwrst;
+
+	if (enable) {
+		next_state = PWRDM_POWER_OFF;
+		next_logic_state = PWRDM_POWER_OFF;
+	}
+
+	omap4_device_set_state_off(enable);
+
+	list_for_each_entry(pwrst, &pwrst_list, node) {
+		pwrst->next_state =
+			get_achievable_state(pwrst->pwrdm->pwrsts, next_state);
+		pwrst->next_logic_state =
+			get_achievable_state(pwrst->pwrdm->pwrsts_logic_ret,
+				next_logic_state);
+		omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
+		pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->next_logic_state);
+	}
+}
+
 void omap4_pm_oswr_mode_enable(int enable)
 {
 	u32 next_logic_state;
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index f6dab07..ab810cd 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -274,6 +274,72 @@ static void __init omap4_enable_io_wakeup(void)
 			OMAP4_PRM_IO_PMCTRL_OFFSET);
 }
 
+/**
+ * omap4_device_set_state_off() - setup device off state
+ * @enable:	set to off or not.
+ *
+ * When Device OFF is enabled, Device is allowed to perform
+ * transition to off mode as soon as all power domains in MPU, IVA
+ * and CORE voltage are in OFF or OSWR state (open switch retention)
+ */
+void omap4_device_set_state_off(u8 enable)
+{
+	if (enable)
+		omap4_prminst_write_inst_reg(0x1 <<
+				OMAP4430_DEVICE_OFF_ENABLE_SHIFT,
+				OMAP4430_PRM_PARTITION,
+				OMAP4430_PRM_DEVICE_INST,
+				OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET);
+	else
+		omap4_prminst_write_inst_reg(0x0 <<
+				OMAP4430_DEVICE_OFF_ENABLE_SHIFT,
+				OMAP4430_PRM_PARTITION,
+				OMAP4430_PRM_DEVICE_INST,
+				OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET);
+}
+
+/**
+ * omap4_device_prev_state_off:
+ * returns true if the device hit OFF mode
+ * This is API to check whether OMAP is waking up from device OFF mode.
+ * There is no other status bit available for SW to read whether last state
+ * entered was device OFF. To work around this, CORE PD, RFF context state
+ * is used which is lost only when we hit device OFF state
+ */
+bool omap4_device_prev_state_off(void)
+{
+	u32 reg;
+
+	reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
+				OMAP4430_PRM_CORE_INST,
+				OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET)
+		& OMAP4430_LOSTCONTEXT_RFF_MASK;
+
+	return reg ? true : false;
+}
+
+void omap4_device_clear_prev_off_state(void)
+{
+	omap4_prminst_write_inst_reg(OMAP4430_LOSTCONTEXT_RFF_MASK |
+				OMAP4430_LOSTCONTEXT_DFF_MASK,
+				OMAP4430_PRM_PARTITION,
+				OMAP4430_PRM_CORE_INST,
+				OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET);
+}
+
+/**
+ * omap4_device_next_state_off:
+ * returns true if the device next state is OFF
+ * This is API to check whether OMAP is programmed for device OFF
+ */
+bool omap4_device_next_state_off(void)
+{
+	return omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
+			OMAP4430_PRM_DEVICE_INST,
+			OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET)
+			& OMAP4430_DEVICE_OFF_ENABLE_MASK ? true : false;
+}
+
 static int __init omap4xxx_prcm_init(void)
 {
 	if (cpu_is_omap44xx()) {
-- 
1.7.4.1

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

* [PATCH 09/19] ARM: OMAP4: PM: add errata support
  2012-04-20  9:33 ` Tero Kristo
@ 2012-04-20  9:33   ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-omap, khilman, paul; +Cc: linux-arm-kernel

Added similar PM errata flag support as omap3 has. A few errata flags
will be added in subsequent patches.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/pm.h     |    7 +++++++
 arch/arm/mach-omap2/pm44xx.c |    1 +
 2 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index f65da57..e78ec63 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -131,6 +131,13 @@ extern void enable_omap3630_toggle_l2_on_restore(void);
 static inline void enable_omap3630_toggle_l2_on_restore(void) { }
 #endif		/* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */
 
+#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
+extern u16 pm44xx_errata;
+#define IS_PM44XX_ERRATUM(id)		(pm44xx_errata & (id))
+#else
+#define IS_PM44XX_ERRATUM(id)		0
+#endif
+
 #ifdef CONFIG_OMAP_SMARTREFLEX
 extern int omap_devinit_smartreflex(void);
 extern void omap_enable_smartreflex_on_init(void);
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 8f0ec56..8238097 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -35,6 +35,7 @@ struct power_state {
 };
 
 static LIST_HEAD(pwrst_list);
+u16 pm44xx_errata;
 
 #ifdef CONFIG_SUSPEND
 static int omap4_pm_suspend(void)
-- 
1.7.4.1


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

* [PATCH 09/19] ARM: OMAP4: PM: add errata support
@ 2012-04-20  9:33   ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-arm-kernel

Added similar PM errata flag support as omap3 has. A few errata flags
will be added in subsequent patches.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/pm.h     |    7 +++++++
 arch/arm/mach-omap2/pm44xx.c |    1 +
 2 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index f65da57..e78ec63 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -131,6 +131,13 @@ extern void enable_omap3630_toggle_l2_on_restore(void);
 static inline void enable_omap3630_toggle_l2_on_restore(void) { }
 #endif		/* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */
 
+#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
+extern u16 pm44xx_errata;
+#define IS_PM44XX_ERRATUM(id)		(pm44xx_errata & (id))
+#else
+#define IS_PM44XX_ERRATUM(id)		0
+#endif
+
 #ifdef CONFIG_OMAP_SMARTREFLEX
 extern int omap_devinit_smartreflex(void);
 extern void omap_enable_smartreflex_on_init(void);
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 8f0ec56..8238097 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -35,6 +35,7 @@ struct power_state {
 };
 
 static LIST_HEAD(pwrst_list);
+u16 pm44xx_errata;
 
 #ifdef CONFIG_SUSPEND
 static int omap4_pm_suspend(void)
-- 
1.7.4.1

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

* [PATCH 10/19] ARM: OMAP4: PM: Work-around for ROM code BUG of IVAHD/TESLA
  2012-04-20  9:33 ` Tero Kristo
@ 2012-04-20  9:33   ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-omap, khilman, paul
  Cc: linux-arm-kernel, Santosh Shilimkar, Rajendra Nayak

From: Santosh Shilimkar <santosh.shilimkar@ti.com>

The ROM BUG is when MPU Domain OFF wake up sequence that can compromise
IVA and Tesla execution.

At wakeup from MPU OFF on HS device only (not GP device), when
restoring the Secure RAM, the ROM Code reconfigures the clocks the
same way it is done at Cold Reset.
The IVAHD Clocks and Power Domain settings are:
	IVAHD_CM2 IVAHD_CLKCTRL_MODULE_MODE = DISABLE
	IVAHD_CM2 SL2_CLKCTRL_MODULE_MODE = DISABLE
	IVAHD_CM2 SL2_CLKSTCTRL_CLKTRCTRL = HW_AUTO
	IVAHD_PRM IVAHD_PWRSTCTRL_POWERSTATE = OFF
The TESLA Clocks and Power Domain settings are:
	TESLA_CM1 TESLA_CLKCTRL_MODULE_MODE = DISABLE
	TESLA_CM1 TESLA_CLKSTCTRL_CLKTRCTRL = HW_AUTO
	TESLA_PRM TESLA_PWRSTCTRL_POWERSTATE = OFF

This patch fixes the low power OFF mode code so that the these
registers are saved and restore across MPU OFF state.

Also because of this limitation, MPU OFF alone is not targeted without
device OFF to avoid IVAHD and TESLA execution impact

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
[t-kristo@ti.com: added omap4 pm errata support]
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap-mpuss-lowpower.c |   53 +++++++++++++++++++++++++++++
 arch/arm/mach-omap2/pm.h                  |    2 +
 arch/arm/mach-omap2/pm44xx.c              |    9 +++++
 3 files changed, 64 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index b9a2cc7..208d4a4 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -52,6 +52,7 @@
 
 #include <plat/omap44xx.h>
 
+#include "iomap.h"
 #include "common.h"
 #include "omap4-sar-layout.h"
 #include "pm.h"
@@ -76,6 +77,24 @@ static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
 static struct powerdomain *mpuss_pd;
 static void __iomem *sar_base;
 
+struct reg_tuple {
+	void __iomem *addr;
+	u32 val;
+};
+
+static struct reg_tuple tesla_reg[] = {
+	{.addr = OMAP4430_CM_TESLA_CLKSTCTRL},
+	{.addr = OMAP4430_CM_TESLA_TESLA_CLKCTRL},
+	{.addr = OMAP4430_PM_TESLA_PWRSTCTRL},
+};
+
+static struct reg_tuple ivahd_reg[] = {
+	{.addr = OMAP4430_CM_IVAHD_CLKSTCTRL},
+	{.addr = OMAP4430_CM_IVAHD_IVAHD_CLKCTRL},
+	{.addr = OMAP4430_CM_IVAHD_SL2_CLKCTRL},
+	{.addr = OMAP4430_PM_IVAHD_PWRSTCTRL}
+};
+
 /*
  * Program the wakeup routine address for the CPU0 and CPU1
  * used for OFF or DORMANT wakeup.
@@ -215,6 +234,34 @@ static void save_l2x0_context(void)
 {}
 #endif
 
+static inline void save_ivahd_tesla_regs(void)
+{
+	int i;
+
+	if (!IS_PM44XX_ERRATUM(PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM))
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(tesla_reg); i++)
+		tesla_reg[i].val = __raw_readl(tesla_reg[i].addr);
+
+	for (i = 0; i < ARRAY_SIZE(ivahd_reg); i++)
+		ivahd_reg[i].val = __raw_readl(ivahd_reg[i].addr);
+}
+
+static inline void restore_ivahd_tesla_regs(void)
+{
+	int i;
+
+	if (!IS_PM44XX_ERRATUM(PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM))
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(tesla_reg); i++)
+		__raw_writel(tesla_reg[i].val, tesla_reg[i].addr);
+
+	for (i = 0; i < ARRAY_SIZE(ivahd_reg); i++)
+		__raw_writel(ivahd_reg[i].val, ivahd_reg[i].addr);
+}
+
 /**
  * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function
  * The purpose of this function is to manage low power programming
@@ -273,11 +320,14 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 		omap_sar_overwrite();
 		omap4_cm_prepare_off();
 		omap4_dpll_prepare_off();
+		save_ivahd_tesla_regs();
 		save_state = 3;
 	} else if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) &&
 		(pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF)) {
+		save_ivahd_tesla_regs();
 		save_state = 2;
 	} else if (pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_OFF) {
+		save_ivahd_tesla_regs();
 		save_state = 3;
 	}
 
@@ -302,6 +352,9 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 	wakeup_cpu = smp_processor_id();
 	set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON);
 
+	if (omap4_mpuss_read_prev_context_state())
+		restore_ivahd_tesla_regs();
+
 	if (omap4_device_prev_state_off()) {
 		omap4_dpll_resume_off();
 		omap4_cm_resume_off();
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index e78ec63..051aeb9 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -131,6 +131,8 @@ extern void enable_omap3630_toggle_l2_on_restore(void);
 static inline void enable_omap3630_toggle_l2_on_restore(void) { }
 #endif		/* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */
 
+#define PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM	(1 << 0)
+
 #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
 extern u16 pm44xx_errata;
 #define IS_PM44XX_ERRATUM(id)		(pm44xx_errata & (id))
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 8238097..67cb799 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -263,6 +263,15 @@ static int __init omap4_pm_init(void)
 
 	(void) clkdm_for_each(omap_pm_clkdms_setup, NULL);
 
+	/*
+	 * ROM code initializes IVAHD and TESLA clock registers during
+	 * secure RAM restore phase on omap4430 EMU/HS devices, thus
+	 * IVAHD / TESLA clock registers must be saved / restored
+	 * during MPU OSWR / device off.
+	 */
+	if (cpu_is_omap443x() && omap_type() != OMAP2_DEVICE_TYPE_GP)
+		pm44xx_errata |= PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM;
+
 #ifdef CONFIG_SUSPEND
 	omap_pm_suspend = omap4_pm_suspend;
 #endif
-- 
1.7.4.1


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

* [PATCH 10/19] ARM: OMAP4: PM: Work-around for ROM code BUG of IVAHD/TESLA
@ 2012-04-20  9:33   ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-arm-kernel

From: Santosh Shilimkar <santosh.shilimkar@ti.com>

The ROM BUG is when MPU Domain OFF wake up sequence that can compromise
IVA and Tesla execution.

At wakeup from MPU OFF on HS device only (not GP device), when
restoring the Secure RAM, the ROM Code reconfigures the clocks the
same way it is done at Cold Reset.
The IVAHD Clocks and Power Domain settings are:
	IVAHD_CM2 IVAHD_CLKCTRL_MODULE_MODE = DISABLE
	IVAHD_CM2 SL2_CLKCTRL_MODULE_MODE = DISABLE
	IVAHD_CM2 SL2_CLKSTCTRL_CLKTRCTRL = HW_AUTO
	IVAHD_PRM IVAHD_PWRSTCTRL_POWERSTATE = OFF
The TESLA Clocks and Power Domain settings are:
	TESLA_CM1 TESLA_CLKCTRL_MODULE_MODE = DISABLE
	TESLA_CM1 TESLA_CLKSTCTRL_CLKTRCTRL = HW_AUTO
	TESLA_PRM TESLA_PWRSTCTRL_POWERSTATE = OFF

This patch fixes the low power OFF mode code so that the these
registers are saved and restore across MPU OFF state.

Also because of this limitation, MPU OFF alone is not targeted without
device OFF to avoid IVAHD and TESLA execution impact

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
[t-kristo at ti.com: added omap4 pm errata support]
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap-mpuss-lowpower.c |   53 +++++++++++++++++++++++++++++
 arch/arm/mach-omap2/pm.h                  |    2 +
 arch/arm/mach-omap2/pm44xx.c              |    9 +++++
 3 files changed, 64 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index b9a2cc7..208d4a4 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -52,6 +52,7 @@
 
 #include <plat/omap44xx.h>
 
+#include "iomap.h"
 #include "common.h"
 #include "omap4-sar-layout.h"
 #include "pm.h"
@@ -76,6 +77,24 @@ static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
 static struct powerdomain *mpuss_pd;
 static void __iomem *sar_base;
 
+struct reg_tuple {
+	void __iomem *addr;
+	u32 val;
+};
+
+static struct reg_tuple tesla_reg[] = {
+	{.addr = OMAP4430_CM_TESLA_CLKSTCTRL},
+	{.addr = OMAP4430_CM_TESLA_TESLA_CLKCTRL},
+	{.addr = OMAP4430_PM_TESLA_PWRSTCTRL},
+};
+
+static struct reg_tuple ivahd_reg[] = {
+	{.addr = OMAP4430_CM_IVAHD_CLKSTCTRL},
+	{.addr = OMAP4430_CM_IVAHD_IVAHD_CLKCTRL},
+	{.addr = OMAP4430_CM_IVAHD_SL2_CLKCTRL},
+	{.addr = OMAP4430_PM_IVAHD_PWRSTCTRL}
+};
+
 /*
  * Program the wakeup routine address for the CPU0 and CPU1
  * used for OFF or DORMANT wakeup.
@@ -215,6 +234,34 @@ static void save_l2x0_context(void)
 {}
 #endif
 
+static inline void save_ivahd_tesla_regs(void)
+{
+	int i;
+
+	if (!IS_PM44XX_ERRATUM(PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM))
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(tesla_reg); i++)
+		tesla_reg[i].val = __raw_readl(tesla_reg[i].addr);
+
+	for (i = 0; i < ARRAY_SIZE(ivahd_reg); i++)
+		ivahd_reg[i].val = __raw_readl(ivahd_reg[i].addr);
+}
+
+static inline void restore_ivahd_tesla_regs(void)
+{
+	int i;
+
+	if (!IS_PM44XX_ERRATUM(PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM))
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(tesla_reg); i++)
+		__raw_writel(tesla_reg[i].val, tesla_reg[i].addr);
+
+	for (i = 0; i < ARRAY_SIZE(ivahd_reg); i++)
+		__raw_writel(ivahd_reg[i].val, ivahd_reg[i].addr);
+}
+
 /**
  * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function
  * The purpose of this function is to manage low power programming
@@ -273,11 +320,14 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 		omap_sar_overwrite();
 		omap4_cm_prepare_off();
 		omap4_dpll_prepare_off();
+		save_ivahd_tesla_regs();
 		save_state = 3;
 	} else if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) &&
 		(pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF)) {
+		save_ivahd_tesla_regs();
 		save_state = 2;
 	} else if (pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_OFF) {
+		save_ivahd_tesla_regs();
 		save_state = 3;
 	}
 
@@ -302,6 +352,9 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 	wakeup_cpu = smp_processor_id();
 	set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON);
 
+	if (omap4_mpuss_read_prev_context_state())
+		restore_ivahd_tesla_regs();
+
 	if (omap4_device_prev_state_off()) {
 		omap4_dpll_resume_off();
 		omap4_cm_resume_off();
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index e78ec63..051aeb9 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -131,6 +131,8 @@ extern void enable_omap3630_toggle_l2_on_restore(void);
 static inline void enable_omap3630_toggle_l2_on_restore(void) { }
 #endif		/* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */
 
+#define PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM	(1 << 0)
+
 #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
 extern u16 pm44xx_errata;
 #define IS_PM44XX_ERRATUM(id)		(pm44xx_errata & (id))
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 8238097..67cb799 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -263,6 +263,15 @@ static int __init omap4_pm_init(void)
 
 	(void) clkdm_for_each(omap_pm_clkdms_setup, NULL);
 
+	/*
+	 * ROM code initializes IVAHD and TESLA clock registers during
+	 * secure RAM restore phase on omap4430 EMU/HS devices, thus
+	 * IVAHD / TESLA clock registers must be saved / restored
+	 * during MPU OSWR / device off.
+	 */
+	if (cpu_is_omap443x() && omap_type() != OMAP2_DEVICE_TYPE_GP)
+		pm44xx_errata |= PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM;
+
 #ifdef CONFIG_SUSPEND
 	omap_pm_suspend = omap4_pm_suspend;
 #endif
-- 
1.7.4.1

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

* [PATCH 11/19] ARM: OMAP4: PM: save/restore CM L3INSTR registers when MPU hits OSWR/OFF mode
  2012-04-20  9:33 ` Tero Kristo
@ 2012-04-20  9:33   ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-omap, khilman, paul
  Cc: linux-arm-kernel, Rajendra Nayak, Santosh Shilimkar

From: Rajendra Nayak <rnayak@ti.com>

On HS devices on the way out of MPU OSWR and OFF ROM code wrongly
overwrites the CM L3INSTR registers. So to avoid this, save them and
restore on the way out from MPU OSWR/OFF.

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
[t-kristo@ti.com: added omap4 pm errata support]
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap-mpuss-lowpower.c |   35 ++++++++++++++++++++++++++++-
 arch/arm/mach-omap2/pm.h                  |    1 +
 arch/arm/mach-omap2/pm44xx.c              |    8 ++++++
 3 files changed, 43 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index 208d4a4..2ae5e2c 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -95,6 +95,12 @@ static struct reg_tuple ivahd_reg[] = {
 	{.addr = OMAP4430_PM_IVAHD_PWRSTCTRL}
 };
 
+static struct reg_tuple l3instr_reg[] = {
+	{.addr = OMAP4430_CM_L3INSTR_L3_3_CLKCTRL},
+	{.addr = OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL},
+	{.addr = OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL},
+};
+
 /*
  * Program the wakeup routine address for the CPU0 and CPU1
  * used for OFF or DORMANT wakeup.
@@ -262,6 +268,28 @@ static inline void restore_ivahd_tesla_regs(void)
 		__raw_writel(ivahd_reg[i].val, ivahd_reg[i].addr);
 }
 
+static inline void save_l3instr_regs(void)
+{
+	int i;
+
+	if (!IS_PM44XX_ERRATUM(PM_OMAP4_ROM_L3INSTR_ERRATUM))
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(l3instr_reg); i++)
+		l3instr_reg[i].val = __raw_readl(l3instr_reg[i].addr);
+}
+
+static inline void restore_l3instr_regs(void)
+{
+	int i;
+
+	if (!IS_PM44XX_ERRATUM(PM_OMAP4_ROM_L3INSTR_ERRATUM))
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(l3instr_reg); i++)
+		__raw_writel(l3instr_reg[i].val, l3instr_reg[i].addr);
+}
+
 /**
  * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function
  * The purpose of this function is to manage low power programming
@@ -321,13 +349,16 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 		omap4_cm_prepare_off();
 		omap4_dpll_prepare_off();
 		save_ivahd_tesla_regs();
+		save_l3instr_regs();
 		save_state = 3;
 	} else if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) &&
 		(pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF)) {
 		save_ivahd_tesla_regs();
+		save_l3instr_regs();
 		save_state = 2;
 	} else if (pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_OFF) {
 		save_ivahd_tesla_regs();
+		save_l3instr_regs();
 		save_state = 3;
 	}
 
@@ -352,8 +383,10 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 	wakeup_cpu = smp_processor_id();
 	set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON);
 
-	if (omap4_mpuss_read_prev_context_state())
+	if (omap4_mpuss_read_prev_context_state()) {
 		restore_ivahd_tesla_regs();
+		restore_l3instr_regs();
+	}
 
 	if (omap4_device_prev_state_off()) {
 		omap4_dpll_resume_off();
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 051aeb9..c312d57 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -132,6 +132,7 @@ static inline void enable_omap3630_toggle_l2_on_restore(void) { }
 #endif		/* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */
 
 #define PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM	(1 << 0)
+#define PM_OMAP4_ROM_L3INSTR_ERRATUM		(1 << 1)
 
 #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
 extern u16 pm44xx_errata;
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 67cb799..0472921 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -272,6 +272,14 @@ static int __init omap4_pm_init(void)
 	if (cpu_is_omap443x() && omap_type() != OMAP2_DEVICE_TYPE_GP)
 		pm44xx_errata |= PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM;
 
+	/*
+	 * Similar to above errata, ROM code modifies L3INSTR clock
+	 * registers also and these must be saved / restored during
+	 * MPU OSWR / device off.
+	 */
+	if (omap_type() != OMAP2_DEVICE_TYPE_GP)
+		pm44xx_errata |= PM_OMAP4_ROM_L3INSTR_ERRATUM;
+
 #ifdef CONFIG_SUSPEND
 	omap_pm_suspend = omap4_pm_suspend;
 #endif
-- 
1.7.4.1


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

* [PATCH 11/19] ARM: OMAP4: PM: save/restore CM L3INSTR registers when MPU hits OSWR/OFF mode
@ 2012-04-20  9:33   ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rajendra Nayak <rnayak@ti.com>

On HS devices on the way out of MPU OSWR and OFF ROM code wrongly
overwrites the CM L3INSTR registers. So to avoid this, save them and
restore on the way out from MPU OSWR/OFF.

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
[t-kristo at ti.com: added omap4 pm errata support]
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap-mpuss-lowpower.c |   35 ++++++++++++++++++++++++++++-
 arch/arm/mach-omap2/pm.h                  |    1 +
 arch/arm/mach-omap2/pm44xx.c              |    8 ++++++
 3 files changed, 43 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index 208d4a4..2ae5e2c 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -95,6 +95,12 @@ static struct reg_tuple ivahd_reg[] = {
 	{.addr = OMAP4430_PM_IVAHD_PWRSTCTRL}
 };
 
+static struct reg_tuple l3instr_reg[] = {
+	{.addr = OMAP4430_CM_L3INSTR_L3_3_CLKCTRL},
+	{.addr = OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL},
+	{.addr = OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL},
+};
+
 /*
  * Program the wakeup routine address for the CPU0 and CPU1
  * used for OFF or DORMANT wakeup.
@@ -262,6 +268,28 @@ static inline void restore_ivahd_tesla_regs(void)
 		__raw_writel(ivahd_reg[i].val, ivahd_reg[i].addr);
 }
 
+static inline void save_l3instr_regs(void)
+{
+	int i;
+
+	if (!IS_PM44XX_ERRATUM(PM_OMAP4_ROM_L3INSTR_ERRATUM))
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(l3instr_reg); i++)
+		l3instr_reg[i].val = __raw_readl(l3instr_reg[i].addr);
+}
+
+static inline void restore_l3instr_regs(void)
+{
+	int i;
+
+	if (!IS_PM44XX_ERRATUM(PM_OMAP4_ROM_L3INSTR_ERRATUM))
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(l3instr_reg); i++)
+		__raw_writel(l3instr_reg[i].val, l3instr_reg[i].addr);
+}
+
 /**
  * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function
  * The purpose of this function is to manage low power programming
@@ -321,13 +349,16 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 		omap4_cm_prepare_off();
 		omap4_dpll_prepare_off();
 		save_ivahd_tesla_regs();
+		save_l3instr_regs();
 		save_state = 3;
 	} else if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) &&
 		(pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF)) {
 		save_ivahd_tesla_regs();
+		save_l3instr_regs();
 		save_state = 2;
 	} else if (pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_OFF) {
 		save_ivahd_tesla_regs();
+		save_l3instr_regs();
 		save_state = 3;
 	}
 
@@ -352,8 +383,10 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 	wakeup_cpu = smp_processor_id();
 	set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON);
 
-	if (omap4_mpuss_read_prev_context_state())
+	if (omap4_mpuss_read_prev_context_state()) {
 		restore_ivahd_tesla_regs();
+		restore_l3instr_regs();
+	}
 
 	if (omap4_device_prev_state_off()) {
 		omap4_dpll_resume_off();
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 051aeb9..c312d57 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -132,6 +132,7 @@ static inline void enable_omap3630_toggle_l2_on_restore(void) { }
 #endif		/* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */
 
 #define PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM	(1 << 0)
+#define PM_OMAP4_ROM_L3INSTR_ERRATUM		(1 << 1)
 
 #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
 extern u16 pm44xx_errata;
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 67cb799..0472921 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -272,6 +272,14 @@ static int __init omap4_pm_init(void)
 	if (cpu_is_omap443x() && omap_type() != OMAP2_DEVICE_TYPE_GP)
 		pm44xx_errata |= PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM;
 
+	/*
+	 * Similar to above errata, ROM code modifies L3INSTR clock
+	 * registers also and these must be saved / restored during
+	 * MPU OSWR / device off.
+	 */
+	if (omap_type() != OMAP2_DEVICE_TYPE_GP)
+		pm44xx_errata |= PM_OMAP4_ROM_L3INSTR_ERRATUM;
+
 #ifdef CONFIG_SUSPEND
 	omap_pm_suspend = omap4_pm_suspend;
 #endif
-- 
1.7.4.1

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

* [PATCH 12/19] ARM: OMAP4: PM: update ROM return address for OSWR and OFF
  2012-04-20  9:33 ` Tero Kristo
@ 2012-04-20  9:33   ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-omap, khilman, paul
  Cc: linux-arm-kernel, Carlos Leija, Praneeth Bajjuri, Bryan Buckley

From: Carlos Leija <cileija@ti.com>

At wakeup from OFF/OSWR CPU1 will call secure HAL service through a local
secure dispatcher with MMU off, thus ROM will save a PA return address.
Later in the wakeup, when SMC driver calls an RPC through
omap4_secure_dispatcher (MMU is on now), ROM code won't log the new return
address as RPCs are handled different. Thus ROM will attempt to return to
a PA address when the MMU is on and the system will hang.

We need to do this for OSWR state and OFF state of mpu power domain,
not just for device off(mpu pd OFF).

Signed-off-by: Carlos Leija <cileija@ti.com>
Signed-off-by: Praneeth Bajjuri <praneeth@ti.com>
Signed-off-by: Bryan Buckley <bryan.buckley@ti.com>
[t-kristo@ti.com: merged the two patches into one]
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/include/mach/omap-secure.h |    1 +
 arch/arm/mach-omap2/omap-mpuss-lowpower.c      |   13 +++++++++++++
 2 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/include/mach/omap-secure.h b/arch/arm/mach-omap2/include/mach/omap-secure.h
index c90a435..d9bde61 100644
--- a/arch/arm/mach-omap2/include/mach/omap-secure.h
+++ b/arch/arm/mach-omap2/include/mach/omap-secure.h
@@ -43,6 +43,7 @@
 #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
 
 /* Secure PPA(Primary Protected Application) APIs */
+#define OMAP4_PPA_SERVICE_0		0x21
 #define OMAP4_PPA_L2_POR_INDEX		0x23
 #define OMAP4_PPA_CPU_ACTRL_SMP_INDEX	0x25
 
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index 2ae5e2c..b4ca6f3 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -52,6 +52,8 @@
 
 #include <plat/omap44xx.h>
 
+#include <mach/omap-secure.h>
+
 #include "iomap.h"
 #include "common.h"
 #include "omap4-sar-layout.h"
@@ -384,6 +386,17 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 	set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON);
 
 	if (omap4_mpuss_read_prev_context_state()) {
+		/*
+		 * Dummy dispatcher call after OSWR and OFF
+		 * Restore the right return Kernel address (with MMU on) for
+		 * subsequent calls to secure ROM. Otherwise the return address
+		 * will be to a PA return address and the system will hang.
+		 */
+		if (omap_type() != OMAP2_DEVICE_TYPE_GP)
+			omap_secure_dispatcher(OMAP4_PPA_SERVICE_0,
+					       FLAG_START_CRITICAL,
+					       0, 0, 0, 0, 0);
+
 		restore_ivahd_tesla_regs();
 		restore_l3instr_regs();
 	}
-- 
1.7.4.1


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

* [PATCH 12/19] ARM: OMAP4: PM: update ROM return address for OSWR and OFF
@ 2012-04-20  9:33   ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-arm-kernel

From: Carlos Leija <cileija@ti.com>

At wakeup from OFF/OSWR CPU1 will call secure HAL service through a local
secure dispatcher with MMU off, thus ROM will save a PA return address.
Later in the wakeup, when SMC driver calls an RPC through
omap4_secure_dispatcher (MMU is on now), ROM code won't log the new return
address as RPCs are handled different. Thus ROM will attempt to return to
a PA address when the MMU is on and the system will hang.

We need to do this for OSWR state and OFF state of mpu power domain,
not just for device off(mpu pd OFF).

Signed-off-by: Carlos Leija <cileija@ti.com>
Signed-off-by: Praneeth Bajjuri <praneeth@ti.com>
Signed-off-by: Bryan Buckley <bryan.buckley@ti.com>
[t-kristo at ti.com: merged the two patches into one]
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/include/mach/omap-secure.h |    1 +
 arch/arm/mach-omap2/omap-mpuss-lowpower.c      |   13 +++++++++++++
 2 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/include/mach/omap-secure.h b/arch/arm/mach-omap2/include/mach/omap-secure.h
index c90a435..d9bde61 100644
--- a/arch/arm/mach-omap2/include/mach/omap-secure.h
+++ b/arch/arm/mach-omap2/include/mach/omap-secure.h
@@ -43,6 +43,7 @@
 #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
 
 /* Secure PPA(Primary Protected Application) APIs */
+#define OMAP4_PPA_SERVICE_0		0x21
 #define OMAP4_PPA_L2_POR_INDEX		0x23
 #define OMAP4_PPA_CPU_ACTRL_SMP_INDEX	0x25
 
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index 2ae5e2c..b4ca6f3 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -52,6 +52,8 @@
 
 #include <plat/omap44xx.h>
 
+#include <mach/omap-secure.h>
+
 #include "iomap.h"
 #include "common.h"
 #include "omap4-sar-layout.h"
@@ -384,6 +386,17 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 	set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON);
 
 	if (omap4_mpuss_read_prev_context_state()) {
+		/*
+		 * Dummy dispatcher call after OSWR and OFF
+		 * Restore the right return Kernel address (with MMU on) for
+		 * subsequent calls to secure ROM. Otherwise the return address
+		 * will be to a PA return address and the system will hang.
+		 */
+		if (omap_type() != OMAP2_DEVICE_TYPE_GP)
+			omap_secure_dispatcher(OMAP4_PPA_SERVICE_0,
+					       FLAG_START_CRITICAL,
+					       0, 0, 0, 0, 0);
+
 		restore_ivahd_tesla_regs();
 		restore_l3instr_regs();
 	}
-- 
1.7.4.1

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

* [PATCH 13/19] ARM: OMAP4: PM: Mark the PPI and SPI interrupts as non-secure for GP
  2012-04-20  9:33 ` Tero Kristo
@ 2012-04-20  9:33   ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-omap, khilman, paul; +Cc: linux-arm-kernel, Axel Haslam

From: Axel Haslam <axelhaslam@gmail.com>

ROM code restores part of the GIC context during wakeup from device
off mode from the SAR RAM. If the PPI and SPI interrupts are not
marked as non-secure on GP chips, this crashes the device during
wakeup, thus mark them as non-secure.

Signed-off-by: Axel Haslam <axelhaslam@gmail.com>
[t-kristo@ti.com: fixed commit message, merged multiple patches to one]
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/common.h           |    1 +
 arch/arm/mach-omap2/omap-wakeupgen.c   |   21 +++++++++++++++++++++
 arch/arm/mach-omap2/omap4-common.c     |    5 +++++
 arch/arm/mach-omap2/omap4-sar-layout.h |    3 +++
 4 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index 48d1ebe..0fbb4e2 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -200,6 +200,7 @@ static inline void __iomem *omap4_get_scu_base(void)
 
 extern void __init gic_init_irq(void);
 extern void gic_dist_disable(void);
+extern u32 gic_readl(u32 offset, u8 idx);
 extern void omap_smc1(u32 fn, u32 arg);
 extern void __iomem *omap4_get_sar_ram_base(void);
 extern void omap_do_wfi(void);
diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
index 805d08d..b2165e4 100644
--- a/arch/arm/mach-omap2/omap-wakeupgen.c
+++ b/arch/arm/mach-omap2/omap-wakeupgen.c
@@ -41,6 +41,7 @@
 #define CPU_ENA_OFFSET		0x400
 #define CPU0_ID			0x0
 #define CPU1_ID			0x1
+#define GIC_ISR_NON_SECURE	0xffffffff
 
 static void __iomem *wakeupgen_base;
 static void __iomem *sar_base;
@@ -387,6 +388,7 @@ int __init omap_wakeupgen_init(void)
 {
 	int i;
 	unsigned int boot_cpu = smp_processor_id();
+	int max_spi_reg;
 
 	/* Not supported on OMAP4 ES1.0 silicon */
 	if (omap_rev() == OMAP4430_REV_ES1_0) {
@@ -422,6 +424,25 @@ int __init omap_wakeupgen_init(void)
 	for (i = 0; i < NR_IRQS; i++)
 		irq_target_cpu[i] = boot_cpu;
 
+	/*
+	 * Find out how many interrupts are supported.
+	 * OMAP4 supports max of 128 SPIs where as GIC can support
+	 * up to 1020 interrupt sources. On OMAP4, maximum SPIs are
+	 * fused in DIST_CTR bit-fields as 128. Hence the code is safe
+	 * from reserved register writes since its well within 1020.
+	 */
+	max_spi_reg = gic_readl(GIC_DIST_CTR, 0) & 0x1f;
+
+	if (omap_type() == OMAP2_DEVICE_TYPE_GP) {
+		sar_base = ioremap(OMAP44XX_SAR_RAM_BASE, SZ_16K);
+		sar_writel(GIC_ISR_NON_SECURE, ICDISR_CPU0_OFFSET, 0);
+		sar_writel(GIC_ISR_NON_SECURE, ICDISR_CPU1_OFFSET, 0);
+		for (i = 0; i < max_spi_reg; i++)
+			sar_writel(GIC_ISR_NON_SECURE, ICDISR_SPI_OFFSET, i);
+		iounmap(sar_base);
+		sar_base = NULL;
+	}
+
 	irq_hotplug_init();
 	irq_pm_init();
 
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c
index 7ea4652..f6019f6 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -112,6 +112,11 @@ void gic_dist_disable(void)
 		__raw_writel(0x0, gic_dist_base_addr + GIC_DIST_CTRL);
 }
 
+u32 gic_readl(u32 offset, u8 idx)
+{
+	return __raw_readl(gic_dist_base_addr + offset + 4 * idx);
+}
+
 #ifdef CONFIG_CACHE_L2X0
 
 void __iomem *omap4_get_l2cache_base(void)
diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h
index eef2839..0056667 100644
--- a/arch/arm/mach-omap2/omap4-sar-layout.h
+++ b/arch/arm/mach-omap2/omap4-sar-layout.h
@@ -85,6 +85,9 @@
 #define SAR_BACKUP_STATUS_OFFSET		(SAR_BANK3_OFFSET + 0x500)
 #define SAR_SECURE_RAM_SIZE_OFFSET		(SAR_BANK3_OFFSET + 0x504)
 #define SAR_SECRAM_SAVED_AT_OFFSET		(SAR_BANK3_OFFSET + 0x508)
+#define ICDISR_CPU0_OFFSET			(SAR_BANK3_OFFSET + 0x50c)
+#define ICDISR_CPU1_OFFSET			(SAR_BANK3_OFFSET + 0x510)
+#define ICDISR_SPI_OFFSET			(SAR_BANK3_OFFSET + 0x514)
 
 /* WakeUpGen save restore offset from OMAP44XX_SAR_RAM_BASE */
 #define WAKEUPGENENB_OFFSET_CPU0		(SAR_BANK3_OFFSET + 0x684)
-- 
1.7.4.1


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

* [PATCH 13/19] ARM: OMAP4: PM: Mark the PPI and SPI interrupts as non-secure for GP
@ 2012-04-20  9:33   ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-arm-kernel

From: Axel Haslam <axelhaslam@gmail.com>

ROM code restores part of the GIC context during wakeup from device
off mode from the SAR RAM. If the PPI and SPI interrupts are not
marked as non-secure on GP chips, this crashes the device during
wakeup, thus mark them as non-secure.

Signed-off-by: Axel Haslam <axelhaslam@gmail.com>
[t-kristo at ti.com: fixed commit message, merged multiple patches to one]
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/common.h           |    1 +
 arch/arm/mach-omap2/omap-wakeupgen.c   |   21 +++++++++++++++++++++
 arch/arm/mach-omap2/omap4-common.c     |    5 +++++
 arch/arm/mach-omap2/omap4-sar-layout.h |    3 +++
 4 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index 48d1ebe..0fbb4e2 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -200,6 +200,7 @@ static inline void __iomem *omap4_get_scu_base(void)
 
 extern void __init gic_init_irq(void);
 extern void gic_dist_disable(void);
+extern u32 gic_readl(u32 offset, u8 idx);
 extern void omap_smc1(u32 fn, u32 arg);
 extern void __iomem *omap4_get_sar_ram_base(void);
 extern void omap_do_wfi(void);
diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
index 805d08d..b2165e4 100644
--- a/arch/arm/mach-omap2/omap-wakeupgen.c
+++ b/arch/arm/mach-omap2/omap-wakeupgen.c
@@ -41,6 +41,7 @@
 #define CPU_ENA_OFFSET		0x400
 #define CPU0_ID			0x0
 #define CPU1_ID			0x1
+#define GIC_ISR_NON_SECURE	0xffffffff
 
 static void __iomem *wakeupgen_base;
 static void __iomem *sar_base;
@@ -387,6 +388,7 @@ int __init omap_wakeupgen_init(void)
 {
 	int i;
 	unsigned int boot_cpu = smp_processor_id();
+	int max_spi_reg;
 
 	/* Not supported on OMAP4 ES1.0 silicon */
 	if (omap_rev() == OMAP4430_REV_ES1_0) {
@@ -422,6 +424,25 @@ int __init omap_wakeupgen_init(void)
 	for (i = 0; i < NR_IRQS; i++)
 		irq_target_cpu[i] = boot_cpu;
 
+	/*
+	 * Find out how many interrupts are supported.
+	 * OMAP4 supports max of 128 SPIs where as GIC can support
+	 * up to 1020 interrupt sources. On OMAP4, maximum SPIs are
+	 * fused in DIST_CTR bit-fields as 128. Hence the code is safe
+	 * from reserved register writes since its well within 1020.
+	 */
+	max_spi_reg = gic_readl(GIC_DIST_CTR, 0) & 0x1f;
+
+	if (omap_type() == OMAP2_DEVICE_TYPE_GP) {
+		sar_base = ioremap(OMAP44XX_SAR_RAM_BASE, SZ_16K);
+		sar_writel(GIC_ISR_NON_SECURE, ICDISR_CPU0_OFFSET, 0);
+		sar_writel(GIC_ISR_NON_SECURE, ICDISR_CPU1_OFFSET, 0);
+		for (i = 0; i < max_spi_reg; i++)
+			sar_writel(GIC_ISR_NON_SECURE, ICDISR_SPI_OFFSET, i);
+		iounmap(sar_base);
+		sar_base = NULL;
+	}
+
 	irq_hotplug_init();
 	irq_pm_init();
 
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c
index 7ea4652..f6019f6 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -112,6 +112,11 @@ void gic_dist_disable(void)
 		__raw_writel(0x0, gic_dist_base_addr + GIC_DIST_CTRL);
 }
 
+u32 gic_readl(u32 offset, u8 idx)
+{
+	return __raw_readl(gic_dist_base_addr + offset + 4 * idx);
+}
+
 #ifdef CONFIG_CACHE_L2X0
 
 void __iomem *omap4_get_l2cache_base(void)
diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h
index eef2839..0056667 100644
--- a/arch/arm/mach-omap2/omap4-sar-layout.h
+++ b/arch/arm/mach-omap2/omap4-sar-layout.h
@@ -85,6 +85,9 @@
 #define SAR_BACKUP_STATUS_OFFSET		(SAR_BANK3_OFFSET + 0x500)
 #define SAR_SECURE_RAM_SIZE_OFFSET		(SAR_BANK3_OFFSET + 0x504)
 #define SAR_SECRAM_SAVED_AT_OFFSET		(SAR_BANK3_OFFSET + 0x508)
+#define ICDISR_CPU0_OFFSET			(SAR_BANK3_OFFSET + 0x50c)
+#define ICDISR_CPU1_OFFSET			(SAR_BANK3_OFFSET + 0x510)
+#define ICDISR_SPI_OFFSET			(SAR_BANK3_OFFSET + 0x514)
 
 /* WakeUpGen save restore offset from OMAP44XX_SAR_RAM_BASE */
 #define WAKEUPGENENB_OFFSET_CPU0		(SAR_BANK3_OFFSET + 0x684)
-- 
1.7.4.1

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

* [PATCH 14/19] ARM: OMAP4: wakeupgen: enable clocks for save_secure_all
  2012-04-20  9:33 ` Tero Kristo
@ 2012-04-20  9:33   ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-omap, khilman, paul; +Cc: linux-arm-kernel

save_secure_all needs l3_main_3_ick and l4_secure_clkdm enabled,
otherwise the secure ROM code will crash.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap-wakeupgen.c |   20 ++++++++++++++++++++
 1 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
index b2165e4..c7c4db4 100644
--- a/arch/arm/mach-omap2/omap-wakeupgen.c
+++ b/arch/arm/mach-omap2/omap-wakeupgen.c
@@ -29,10 +29,12 @@
 
 #include <mach/omap-wakeupgen.h>
 #include <mach/omap-secure.h>
+#include <plat/omap_hwmod.h>
 
 #include "omap4-sar-layout.h"
 #include "common.h"
 #include "pm.h"
+#include "clockdomain.h"
 
 #define NR_REG_BANKS		4
 #define MAX_IRQS		128
@@ -49,6 +51,8 @@ static DEFINE_SPINLOCK(wakeupgen_lock);
 static unsigned int irq_target_cpu[NR_IRQS];
 
 static struct powerdomain *mpuss_pd;
+static struct clockdomain *l4_secure_clkdm;
+static struct omap_hwmod *l3_main_3_oh;
 
 /*
  * Static helper functions.
@@ -300,10 +304,18 @@ static void save_secure_ram(void)
 static void save_secure_all(void)
 {
 	u32 ret;
+
+	omap_hwmod_enable(l3_main_3_oh);
+	clkdm_wakeup(l4_secure_clkdm);
+
 	ret = omap_secure_dispatcher(OMAP4_HAL_SAVEALL_INDEX,
 				FLAG_START_CRITICAL,
 				1, omap_secure_ram_mempool_base(),
 				0, 0, 0);
+
+	clkdm_allow_idle(l4_secure_clkdm);
+	omap_hwmod_idle(l3_main_3_oh);
+
 	if (ret != API_HAL_RET_VALUE_OK)
 		pr_err("Secure all context save failed\n");
 }
@@ -441,6 +453,14 @@ int __init omap_wakeupgen_init(void)
 			sar_writel(GIC_ISR_NON_SECURE, ICDISR_SPI_OFFSET, i);
 		iounmap(sar_base);
 		sar_base = NULL;
+	} else {
+		l3_main_3_oh = omap_hwmod_lookup("l3_main_3");
+		if (!l3_main_3_oh)
+			pr_err("%s: failed to get l3_main_3_oh\n", __func__);
+
+		l4_secure_clkdm = clkdm_lookup("l4_secure_clkdm");
+		if (!l4_secure_clkdm)
+			pr_err("%s: failed to get l4_secure_clkdm\n", __func__);
 	}
 
 	irq_hotplug_init();
-- 
1.7.4.1


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

* [PATCH 14/19] ARM: OMAP4: wakeupgen: enable clocks for save_secure_all
@ 2012-04-20  9:33   ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-arm-kernel

save_secure_all needs l3_main_3_ick and l4_secure_clkdm enabled,
otherwise the secure ROM code will crash.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap-wakeupgen.c |   20 ++++++++++++++++++++
 1 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
index b2165e4..c7c4db4 100644
--- a/arch/arm/mach-omap2/omap-wakeupgen.c
+++ b/arch/arm/mach-omap2/omap-wakeupgen.c
@@ -29,10 +29,12 @@
 
 #include <mach/omap-wakeupgen.h>
 #include <mach/omap-secure.h>
+#include <plat/omap_hwmod.h>
 
 #include "omap4-sar-layout.h"
 #include "common.h"
 #include "pm.h"
+#include "clockdomain.h"
 
 #define NR_REG_BANKS		4
 #define MAX_IRQS		128
@@ -49,6 +51,8 @@ static DEFINE_SPINLOCK(wakeupgen_lock);
 static unsigned int irq_target_cpu[NR_IRQS];
 
 static struct powerdomain *mpuss_pd;
+static struct clockdomain *l4_secure_clkdm;
+static struct omap_hwmod *l3_main_3_oh;
 
 /*
  * Static helper functions.
@@ -300,10 +304,18 @@ static void save_secure_ram(void)
 static void save_secure_all(void)
 {
 	u32 ret;
+
+	omap_hwmod_enable(l3_main_3_oh);
+	clkdm_wakeup(l4_secure_clkdm);
+
 	ret = omap_secure_dispatcher(OMAP4_HAL_SAVEALL_INDEX,
 				FLAG_START_CRITICAL,
 				1, omap_secure_ram_mempool_base(),
 				0, 0, 0);
+
+	clkdm_allow_idle(l4_secure_clkdm);
+	omap_hwmod_idle(l3_main_3_oh);
+
 	if (ret != API_HAL_RET_VALUE_OK)
 		pr_err("Secure all context save failed\n");
 }
@@ -441,6 +453,14 @@ int __init omap_wakeupgen_init(void)
 			sar_writel(GIC_ISR_NON_SECURE, ICDISR_SPI_OFFSET, i);
 		iounmap(sar_base);
 		sar_base = NULL;
+	} else {
+		l3_main_3_oh = omap_hwmod_lookup("l3_main_3");
+		if (!l3_main_3_oh)
+			pr_err("%s: failed to get l3_main_3_oh\n", __func__);
+
+		l4_secure_clkdm = clkdm_lookup("l4_secure_clkdm");
+		if (!l4_secure_clkdm)
+			pr_err("%s: failed to get l4_secure_clkdm\n", __func__);
 	}
 
 	irq_hotplug_init();
-- 
1.7.4.1

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

* [PATCH 15/19] ARM: OMAP4430: PM: workaround for DDR corruption on second CS
  2012-04-20  9:33 ` Tero Kristo
@ 2012-04-20  9:33   ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-omap, khilman, paul; +Cc: linux-arm-kernel, Santosh Shilimkar

From: Santosh Shilimkar <santosh.shilimkar@ti.com>

Work around for Errata ID: i632 "LPDDR2 Corruption After OFF Mode
Transition When CS1 Is Used On EMIF" which impacts OMAP443x silicon
The issue occurs when EMIF_SDRAM_CONFIG is restored first before
EMIF_SDRAM_CONFIG_2 is not yet restored, the register configuration
is not set properly, we apply the required workaround allowing
the restore sequence to work properly.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
[t-kristo@ti.com: moved workaround from omap-sar.c to pm44xx.c]
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 .../include/mach/ctrl_module_wkup_44xx.h           |    2 +
 arch/arm/mach-omap2/pm44xx.c                       |   24 ++++++++++++++++++++
 2 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
index a0af9ba..b763a79 100644
--- a/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
+++ b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
@@ -28,6 +28,8 @@
 #define OMAP4_CTRL_MODULE_WKUP_IP_REVISION		0x0000
 #define OMAP4_CTRL_MODULE_WKUP_IP_HWINFO		0x0004
 #define OMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG		0x0010
+#define OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG	0x0114
+#define OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG	0x011c
 #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0	0x0460
 #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1	0x0464
 #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2	0x0468
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 0472921..d4d18d9 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -17,6 +17,9 @@
 #include <linux/err.h>
 #include <linux/slab.h>
 #include <asm/system_misc.h>
+#include <linux/io.h>
+
+#include <mach/ctrl_module_wkup_44xx.h>
 
 #include "common.h"
 #include "clockdomain.h"
@@ -215,6 +218,27 @@ static int __init omap4_pm_init(void)
 
 	pr_err("Power Management for TI OMAP4.\n");
 
+	/*
+	 * Work around for OMAP443x Errata i632: "LPDDR2 Corruption After OFF
+	 * Mode Transition When CS1 Is Used On EMIF":
+	 * Overwrite EMIF1/EMIF2
+	 * SECURE_EMIF1_SDRAM_CONFIG2_REG
+	 * SECURE_EMIF2_SDRAM_CONFIG2_REG
+	 */
+	if (cpu_is_omap443x()) {
+		void __iomem *secure_ctrl_mod;
+
+		secure_ctrl_mod = ioremap(OMAP4_CTRL_MODULE_WKUP, SZ_4K);
+		BUG_ON(!secure_ctrl_mod);
+
+		__raw_writel(0x10, secure_ctrl_mod +
+			     OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG);
+		__raw_writel(0x10, secure_ctrl_mod +
+			     OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG);
+		wmb();
+		iounmap(secure_ctrl_mod);
+	}
+
 	ret = pwrdm_for_each(pwrdms_setup, NULL);
 	if (ret) {
 		pr_err("Failed to setup powerdomains\n");
-- 
1.7.4.1


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

* [PATCH 15/19] ARM: OMAP4430: PM: workaround for DDR corruption on second CS
@ 2012-04-20  9:33   ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-arm-kernel

From: Santosh Shilimkar <santosh.shilimkar@ti.com>

Work around for Errata ID: i632 "LPDDR2 Corruption After OFF Mode
Transition When CS1 Is Used On EMIF" which impacts OMAP443x silicon
The issue occurs when EMIF_SDRAM_CONFIG is restored first before
EMIF_SDRAM_CONFIG_2 is not yet restored, the register configuration
is not set properly, we apply the required workaround allowing
the restore sequence to work properly.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
[t-kristo at ti.com: moved workaround from omap-sar.c to pm44xx.c]
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 .../include/mach/ctrl_module_wkup_44xx.h           |    2 +
 arch/arm/mach-omap2/pm44xx.c                       |   24 ++++++++++++++++++++
 2 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
index a0af9ba..b763a79 100644
--- a/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
+++ b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
@@ -28,6 +28,8 @@
 #define OMAP4_CTRL_MODULE_WKUP_IP_REVISION		0x0000
 #define OMAP4_CTRL_MODULE_WKUP_IP_HWINFO		0x0004
 #define OMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG		0x0010
+#define OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG	0x0114
+#define OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG	0x011c
 #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0	0x0460
 #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1	0x0464
 #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2	0x0468
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 0472921..d4d18d9 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -17,6 +17,9 @@
 #include <linux/err.h>
 #include <linux/slab.h>
 #include <asm/system_misc.h>
+#include <linux/io.h>
+
+#include <mach/ctrl_module_wkup_44xx.h>
 
 #include "common.h"
 #include "clockdomain.h"
@@ -215,6 +218,27 @@ static int __init omap4_pm_init(void)
 
 	pr_err("Power Management for TI OMAP4.\n");
 
+	/*
+	 * Work around for OMAP443x Errata i632: "LPDDR2 Corruption After OFF
+	 * Mode Transition When CS1 Is Used On EMIF":
+	 * Overwrite EMIF1/EMIF2
+	 * SECURE_EMIF1_SDRAM_CONFIG2_REG
+	 * SECURE_EMIF2_SDRAM_CONFIG2_REG
+	 */
+	if (cpu_is_omap443x()) {
+		void __iomem *secure_ctrl_mod;
+
+		secure_ctrl_mod = ioremap(OMAP4_CTRL_MODULE_WKUP, SZ_4K);
+		BUG_ON(!secure_ctrl_mod);
+
+		__raw_writel(0x10, secure_ctrl_mod +
+			     OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG);
+		__raw_writel(0x10, secure_ctrl_mod +
+			     OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG);
+		wmb();
+		iounmap(secure_ctrl_mod);
+	}
+
 	ret = pwrdm_for_each(pwrdms_setup, NULL);
 	if (ret) {
 		pr_err("Failed to setup powerdomains\n");
-- 
1.7.4.1

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

* [PATCH 16/19] TEMP: ARM: OMAP4: prevent voltage transitions
  2012-04-20  9:33 ` Tero Kristo
@ 2012-04-20  9:33   ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-omap, khilman, paul; +Cc: linux-arm-kernel

During device off, the off-mode voltage transitions are enabled on reset.
Because the voltage control logic is not still completely functional for
OMAP4, we must disable the voltage transitions for device off for now.
This can only be done by disabling the I2C channel it seems.

This patch does not prevent voltage scaling done by voltdm->scale / DVFS.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/pm44xx.c |   22 ++++++++++++++++++++++
 1 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index d4d18d9..e678962 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -25,6 +25,9 @@
 #include "clockdomain.h"
 #include "powerdomain.h"
 #include "pm.h"
+#include "voltage.h"
+#include "prm44xx.h"
+#include "prm-regbits-44xx.h"
 
 struct power_state {
 	struct powerdomain *pwrdm;
@@ -207,6 +210,7 @@ static int __init omap4_pm_init(void)
 	int ret;
 	struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm, *l4wkup;
 	struct clockdomain *ducati_clkdm, *l3_2_clkdm, *l4_per_clkdm;
+	struct voltagedomain *mpu_voltdm;
 
 	if (!cpu_is_omap44xx())
 		return -ENODEV;
@@ -279,6 +283,24 @@ static int __init omap4_pm_init(void)
 		goto err2;
 	}
 
+	/*
+	 * XXX: voltage config is not still completely valid for
+	 * OMAP4, and this causes crashes on some platform during
+	 * device off because voltage transitions for device off
+	 * are enabled on reset. Thus, we have to disable the I2C
+	 * channel completely in the VOLTCTRL register to avoid
+	 * trouble. Remove this once voltconfigs are valid.
+	 */
+	mpu_voltdm = voltdm_lookup("mpu");
+	if (!mpu_voltdm) {
+		pr_err("Failed to get MPU voltdm\n");
+		goto err2;
+	}
+	mpu_voltdm->write(OMAP4430_VDD_MPU_I2C_DISABLE_MASK |
+			  OMAP4430_VDD_CORE_I2C_DISABLE_MASK |
+			  OMAP4430_VDD_IVA_I2C_DISABLE_MASK,
+			  OMAP4_PRM_VOLTCTRL_OFFSET);
+
 	ret = omap4_mpuss_init();
 	if (ret) {
 		pr_err("Failed to initialise OMAP4 MPUSS\n");
-- 
1.7.4.1


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

* [PATCH 16/19] TEMP: ARM: OMAP4: prevent voltage transitions
@ 2012-04-20  9:33   ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-arm-kernel

During device off, the off-mode voltage transitions are enabled on reset.
Because the voltage control logic is not still completely functional for
OMAP4, we must disable the voltage transitions for device off for now.
This can only be done by disabling the I2C channel it seems.

This patch does not prevent voltage scaling done by voltdm->scale / DVFS.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/pm44xx.c |   22 ++++++++++++++++++++++
 1 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index d4d18d9..e678962 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -25,6 +25,9 @@
 #include "clockdomain.h"
 #include "powerdomain.h"
 #include "pm.h"
+#include "voltage.h"
+#include "prm44xx.h"
+#include "prm-regbits-44xx.h"
 
 struct power_state {
 	struct powerdomain *pwrdm;
@@ -207,6 +210,7 @@ static int __init omap4_pm_init(void)
 	int ret;
 	struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm, *l4wkup;
 	struct clockdomain *ducati_clkdm, *l3_2_clkdm, *l4_per_clkdm;
+	struct voltagedomain *mpu_voltdm;
 
 	if (!cpu_is_omap44xx())
 		return -ENODEV;
@@ -279,6 +283,24 @@ static int __init omap4_pm_init(void)
 		goto err2;
 	}
 
+	/*
+	 * XXX: voltage config is not still completely valid for
+	 * OMAP4, and this causes crashes on some platform during
+	 * device off because voltage transitions for device off
+	 * are enabled on reset. Thus, we have to disable the I2C
+	 * channel completely in the VOLTCTRL register to avoid
+	 * trouble. Remove this once voltconfigs are valid.
+	 */
+	mpu_voltdm = voltdm_lookup("mpu");
+	if (!mpu_voltdm) {
+		pr_err("Failed to get MPU voltdm\n");
+		goto err2;
+	}
+	mpu_voltdm->write(OMAP4430_VDD_MPU_I2C_DISABLE_MASK |
+			  OMAP4430_VDD_CORE_I2C_DISABLE_MASK |
+			  OMAP4430_VDD_IVA_I2C_DISABLE_MASK,
+			  OMAP4_PRM_VOLTCTRL_OFFSET);
+
 	ret = omap4_mpuss_init();
 	if (ret) {
 		pr_err("Failed to initialise OMAP4 MPUSS\n");
-- 
1.7.4.1

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

* [PATCH 17/19] ARM: OMAP4: put cpu1 back to sleep if no wake request
  2012-04-20  9:33 ` Tero Kristo
@ 2012-04-20  9:33   ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-omap, khilman, paul; +Cc: linux-arm-kernel

If AUX_CORE_BOOT0 does not indicate wakeup request for cpu1, put it back
to off. This is needed during wakeup from device off to prevent cpu1
from being stuck indefinitely in the wakeup loop and also to prevent
wakeup problem on GP chips with device off mode.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap-headsmp.S |   45 ++++++++++++++++++++++++++++++++---
 1 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S
index d602555..59c6578 100644
--- a/arch/arm/mach-omap2/omap-headsmp.S
+++ b/arch/arm/mach-omap2/omap-headsmp.S
@@ -17,8 +17,37 @@
 
 #include <linux/linkage.h>
 #include <linux/init.h>
+#include <mach/omap-secure.h>
+#include "prcm_mpu44xx.h"
+
+#define CPU1_PWRSTCTRL (OMAP4430_PRCM_MPU_BASE + OMAP4430_PRCM_MPU_CPU1_INST + \
+			OMAP4_PM_CPU1_PWRSTCTRL_OFFSET)
 
 	__CPUINIT
+
+ENTRY(omap_cpu1_off)
+	ldr	r12, =CPU1_PWRSTCTRL
+	ldr	r0, [r12]
+	and	r0, #3
+	cmp	r0, #2
+	beq	exit_cpu1_off
+
+	mov	r0, #0x3
+	mov	r1, #0x0
+	ldr	r12, =OMAP4_MON_SCU_PWR_INDEX
+	dsb
+	smc     #0
+
+	isb
+	dsb
+	dmb
+	wfi
+	nop
+	nop
+exit_cpu1_off:
+	mov	pc, lr
+ENDPROC(omap_cpu1_off)
+
 /*
  * OMAP4 specific entry point for secondary CPU to jump from ROM
  * code.  This routine also provides a holding flag into which
@@ -27,32 +56,40 @@
  * register AuxCoreBoot0.
  */
 ENTRY(omap_secondary_startup)
-hold:	ldr	r12,=0x103
+	ldr	r12,=0x103
 	dsb
 	smc	#0			@ read from AuxCoreBoot0
 	mov	r0, r0, lsr #9
 	mrc	p15, 0, r4, c0, c0, 5
 	and	r4, r4, #0x0f
 	cmp	r0, r4
-	bne	hold
+	beq	omap_cont_boot
+
+	bl	omap_cpu1_off
+	b	omap_secondary_startup
 
 	/*
 	 * we've been released from the wait loop,secondary_stack
 	 * should now contain the SVC stack for this core
 	 */
+omap_cont_boot:
 	b	secondary_startup
 ENDPROC(omap_secondary_startup)
 
 ENTRY(omap_secondary_startup_4460)
-hold_2:	ldr	r12,=0x103
+	ldr	r12,=0x103
 	dsb
 	smc	#0			@ read from AuxCoreBoot0
 	mov	r0, r0, lsr #9
 	mrc	p15, 0, r4, c0, c0, 5
 	and	r4, r4, #0x0f
 	cmp	r0, r4
-	bne	hold_2
+	beq	omap4460_cont_boot
+
+	bl	omap_cpu1_off
+	b	omap_secondary_startup_4460
 
+omap4460_cont_boot:
 	/*
 	 * GIC distributor control register has changed between
 	 * CortexA9 r1pX and r2pX. The Control Register secure
-- 
1.7.4.1


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

* [PATCH 17/19] ARM: OMAP4: put cpu1 back to sleep if no wake request
@ 2012-04-20  9:33   ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-arm-kernel

If AUX_CORE_BOOT0 does not indicate wakeup request for cpu1, put it back
to off. This is needed during wakeup from device off to prevent cpu1
from being stuck indefinitely in the wakeup loop and also to prevent
wakeup problem on GP chips with device off mode.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap-headsmp.S |   45 ++++++++++++++++++++++++++++++++---
 1 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S
index d602555..59c6578 100644
--- a/arch/arm/mach-omap2/omap-headsmp.S
+++ b/arch/arm/mach-omap2/omap-headsmp.S
@@ -17,8 +17,37 @@
 
 #include <linux/linkage.h>
 #include <linux/init.h>
+#include <mach/omap-secure.h>
+#include "prcm_mpu44xx.h"
+
+#define CPU1_PWRSTCTRL (OMAP4430_PRCM_MPU_BASE + OMAP4430_PRCM_MPU_CPU1_INST + \
+			OMAP4_PM_CPU1_PWRSTCTRL_OFFSET)
 
 	__CPUINIT
+
+ENTRY(omap_cpu1_off)
+	ldr	r12, =CPU1_PWRSTCTRL
+	ldr	r0, [r12]
+	and	r0, #3
+	cmp	r0, #2
+	beq	exit_cpu1_off
+
+	mov	r0, #0x3
+	mov	r1, #0x0
+	ldr	r12, =OMAP4_MON_SCU_PWR_INDEX
+	dsb
+	smc     #0
+
+	isb
+	dsb
+	dmb
+	wfi
+	nop
+	nop
+exit_cpu1_off:
+	mov	pc, lr
+ENDPROC(omap_cpu1_off)
+
 /*
  * OMAP4 specific entry point for secondary CPU to jump from ROM
  * code.  This routine also provides a holding flag into which
@@ -27,32 +56,40 @@
  * register AuxCoreBoot0.
  */
 ENTRY(omap_secondary_startup)
-hold:	ldr	r12,=0x103
+	ldr	r12,=0x103
 	dsb
 	smc	#0			@ read from AuxCoreBoot0
 	mov	r0, r0, lsr #9
 	mrc	p15, 0, r4, c0, c0, 5
 	and	r4, r4, #0x0f
 	cmp	r0, r4
-	bne	hold
+	beq	omap_cont_boot
+
+	bl	omap_cpu1_off
+	b	omap_secondary_startup
 
 	/*
 	 * we've been released from the wait loop,secondary_stack
 	 * should now contain the SVC stack for this core
 	 */
+omap_cont_boot:
 	b	secondary_startup
 ENDPROC(omap_secondary_startup)
 
 ENTRY(omap_secondary_startup_4460)
-hold_2:	ldr	r12,=0x103
+	ldr	r12,=0x103
 	dsb
 	smc	#0			@ read from AuxCoreBoot0
 	mov	r0, r0, lsr #9
 	mrc	p15, 0, r4, c0, c0, 5
 	and	r4, r4, #0x0f
 	cmp	r0, r4
-	bne	hold_2
+	beq	omap4460_cont_boot
+
+	bl	omap_cpu1_off
+	b	omap_secondary_startup_4460
 
+omap4460_cont_boot:
 	/*
 	 * GIC distributor control register has changed between
 	 * CortexA9 r1pX and r2pX. The Control Register secure
-- 
1.7.4.1

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

* [PATCH 18/19] ARM: OMAP4460: wakeupgen: set GIC_CPU0 backup status flag always
  2012-04-20  9:33 ` Tero Kristo
@ 2012-04-20  9:33   ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-omap, khilman, paul; +Cc: linux-arm-kernel

Without this, CPU0 will crash in the ROM code during wakeup from
device off. This patch also clears the GIC save area, to prevent
ROM code from writing garbage to the GIC registers during wakeup.
The actual GIC restore is done by kernel.

This bug fix applies only to OMAP4460, it is fixed on OMAP4470.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap-wakeupgen.c   |   14 ++++++++++++++
 arch/arm/mach-omap2/omap4-sar-layout.h |    1 +
 2 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
index c7c4db4..30da299 100644
--- a/arch/arm/mach-omap2/omap-wakeupgen.c
+++ b/arch/arm/mach-omap2/omap-wakeupgen.c
@@ -447,10 +447,24 @@ int __init omap_wakeupgen_init(void)
 
 	if (omap_type() == OMAP2_DEVICE_TYPE_GP) {
 		sar_base = ioremap(OMAP44XX_SAR_RAM_BASE, SZ_16K);
+		/* Clean GIC SAR area */
+		for (i = SAR_BACKUP_STATUS_OFFSET; i < WAKEUPGENENB_OFFSET_CPU0;
+			i += 4)
+			sar_writel(0, i, 0);
+
 		sar_writel(GIC_ISR_NON_SECURE, ICDISR_CPU0_OFFSET, 0);
 		sar_writel(GIC_ISR_NON_SECURE, ICDISR_CPU1_OFFSET, 0);
 		for (i = 0; i < max_spi_reg; i++)
 			sar_writel(GIC_ISR_NON_SECURE, ICDISR_SPI_OFFSET, i);
+
+		/*
+		 * Set CPU0 GIC backup flag permanently for omap4460,
+		 * this is needed because of the ROM code bug that breaks
+		 * GIC during wakeup from device off
+		 */
+		if (cpu_is_omap446x())
+			__raw_writel(SAR_BACKUP_STATUS_GIC_CPU0,
+				     sar_base + SAR_BACKUP_STATUS_OFFSET);
 		iounmap(sar_base);
 		sar_base = NULL;
 	} else {
diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h
index 0056667..e621c51 100644
--- a/arch/arm/mach-omap2/omap4-sar-layout.h
+++ b/arch/arm/mach-omap2/omap4-sar-layout.h
@@ -88,6 +88,7 @@
 #define ICDISR_CPU0_OFFSET			(SAR_BANK3_OFFSET + 0x50c)
 #define ICDISR_CPU1_OFFSET			(SAR_BANK3_OFFSET + 0x510)
 #define ICDISR_SPI_OFFSET			(SAR_BANK3_OFFSET + 0x514)
+#define SAR_BACKUP_STATUS_GIC_CPU0		0x1
 
 /* WakeUpGen save restore offset from OMAP44XX_SAR_RAM_BASE */
 #define WAKEUPGENENB_OFFSET_CPU0		(SAR_BANK3_OFFSET + 0x684)
-- 
1.7.4.1


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

* [PATCH 18/19] ARM: OMAP4460: wakeupgen: set GIC_CPU0 backup status flag always
@ 2012-04-20  9:33   ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-arm-kernel

Without this, CPU0 will crash in the ROM code during wakeup from
device off. This patch also clears the GIC save area, to prevent
ROM code from writing garbage to the GIC registers during wakeup.
The actual GIC restore is done by kernel.

This bug fix applies only to OMAP4460, it is fixed on OMAP4470.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap-wakeupgen.c   |   14 ++++++++++++++
 arch/arm/mach-omap2/omap4-sar-layout.h |    1 +
 2 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
index c7c4db4..30da299 100644
--- a/arch/arm/mach-omap2/omap-wakeupgen.c
+++ b/arch/arm/mach-omap2/omap-wakeupgen.c
@@ -447,10 +447,24 @@ int __init omap_wakeupgen_init(void)
 
 	if (omap_type() == OMAP2_DEVICE_TYPE_GP) {
 		sar_base = ioremap(OMAP44XX_SAR_RAM_BASE, SZ_16K);
+		/* Clean GIC SAR area */
+		for (i = SAR_BACKUP_STATUS_OFFSET; i < WAKEUPGENENB_OFFSET_CPU0;
+			i += 4)
+			sar_writel(0, i, 0);
+
 		sar_writel(GIC_ISR_NON_SECURE, ICDISR_CPU0_OFFSET, 0);
 		sar_writel(GIC_ISR_NON_SECURE, ICDISR_CPU1_OFFSET, 0);
 		for (i = 0; i < max_spi_reg; i++)
 			sar_writel(GIC_ISR_NON_SECURE, ICDISR_SPI_OFFSET, i);
+
+		/*
+		 * Set CPU0 GIC backup flag permanently for omap4460,
+		 * this is needed because of the ROM code bug that breaks
+		 * GIC during wakeup from device off
+		 */
+		if (cpu_is_omap446x())
+			__raw_writel(SAR_BACKUP_STATUS_GIC_CPU0,
+				     sar_base + SAR_BACKUP_STATUS_OFFSET);
 		iounmap(sar_base);
 		sar_base = NULL;
 	} else {
diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h
index 0056667..e621c51 100644
--- a/arch/arm/mach-omap2/omap4-sar-layout.h
+++ b/arch/arm/mach-omap2/omap4-sar-layout.h
@@ -88,6 +88,7 @@
 #define ICDISR_CPU0_OFFSET			(SAR_BANK3_OFFSET + 0x50c)
 #define ICDISR_CPU1_OFFSET			(SAR_BANK3_OFFSET + 0x510)
 #define ICDISR_SPI_OFFSET			(SAR_BANK3_OFFSET + 0x514)
+#define SAR_BACKUP_STATUS_GIC_CPU0		0x1
 
 /* WakeUpGen save restore offset from OMAP44XX_SAR_RAM_BASE */
 #define WAKEUPGENENB_OFFSET_CPU0		(SAR_BANK3_OFFSET + 0x684)
-- 
1.7.4.1

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

* [PATCH 19/19] ARM: OMAP4: powerdomain: update mpu / core off counters during device off
  2012-04-20  9:33 ` Tero Kristo
@ 2012-04-20  9:33   ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-omap, khilman, paul; +Cc: linux-arm-kernel

Currently device off does not have any counters / timers of its own
and it is impossible to track the time spent in this state. In device
off, MPU / CORE powerdomains enter OSWR, so normally the RETENTION
state times / counts are increased during device off.

This patch adds a new field to the powerdomain struct for context loss
register, which is checked during pwrdm_post_transition to see if
a device off type context loss has happened. If this is the case,
the counters + timers for OFF state are touched instead of RETENTION.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap-mpuss-lowpower.c   |    1 -
 arch/arm/mach-omap2/powerdomain.c           |    9 +++++++++
 arch/arm/mach-omap2/powerdomain.h           |    2 ++
 arch/arm/mach-omap2/powerdomains44xx_data.c |    2 ++
 arch/arm/mach-omap2/prm44xx.c               |   15 +++++++++++++++
 arch/arm/mach-omap2/prm44xx.h               |    2 ++
 6 files changed, 30 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index b4ca6f3..b7d139a 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -404,7 +404,6 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 	if (omap4_device_prev_state_off()) {
 		omap4_dpll_resume_off();
 		omap4_cm_resume_off();
-		omap4_device_clear_prev_off_state();
 	}
 
 	pwrdm_post_transition();
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 068f06b..cb3eab2 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -160,6 +160,15 @@ static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
 		break;
 	case PWRDM_STATE_PREV:
 		prev = pwrdm_read_prev_pwrst(pwrdm);
+
+		/*
+		 * If powerdomain has context offset defined, check if
+		 * the domain has lost context (i.e. entered off)
+		 */
+		if (pwrdm->context_offs)
+			if (omap4_pwrdm_lost_context_rff(pwrdm->prcm_offs,
+							 pwrdm->context_offs))
+				prev = PWRDM_POWER_OFF;
 		if (pwrdm->state != prev)
 			pwrdm->state_counter[prev]++;
 		if (prev == PWRDM_POWER_RET)
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index 0d72a8a..a427645 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -82,6 +82,7 @@ struct powerdomain;
  * @name: Powerdomain name
  * @voltdm: voltagedomain containing this powerdomain
  * @prcm_offs: the address offset from CM_BASE/PRM_BASE
+ * @context_offs: the address offset for the CONTEXT register
  * @prcm_partition: (OMAP4 only) the PRCM partition ID containing @prcm_offs
  * @pwrsts: Possible powerdomain power states
  * @pwrsts_logic_ret: Possible logic power states when pwrdm in RETENTION
@@ -106,6 +107,7 @@ struct powerdomain {
 		struct voltagedomain *ptr;
 	} voltdm;
 	const s16 prcm_offs;
+	const s16 context_offs;
 	const u8 pwrsts;
 	const u8 pwrsts_logic_ret;
 	const u8 flags;
diff --git a/arch/arm/mach-omap2/powerdomains44xx_data.c b/arch/arm/mach-omap2/powerdomains44xx_data.c
index d8701ce..c4de02f 100644
--- a/arch/arm/mach-omap2/powerdomains44xx_data.c
+++ b/arch/arm/mach-omap2/powerdomains44xx_data.c
@@ -36,6 +36,7 @@ static struct powerdomain core_44xx_pwrdm = {
 	.voltdm		  = { .name = "core" },
 	.prcm_offs	  = OMAP4430_PRM_CORE_INST,
 	.prcm_partition	  = OMAP4430_PRM_PARTITION,
+	.context_offs	  = OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET,
 	.pwrsts		  = PWRSTS_RET_ON,
 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
 	.banks		  = 5,
@@ -205,6 +206,7 @@ static struct powerdomain mpu_44xx_pwrdm = {
 	.voltdm		  = { .name = "mpu" },
 	.prcm_offs	  = OMAP4430_PRM_MPU_INST,
 	.prcm_partition	  = OMAP4430_PRM_PARTITION,
+	.context_offs	  = OMAP4_RM_MPU_MPU_CONTEXT_OFFSET,
 	.pwrsts		  = PWRSTS_RET_ON,
 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
 	.banks		  = 3,
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index ab810cd..cf996a6 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -274,6 +274,21 @@ static void __init omap4_enable_io_wakeup(void)
 			OMAP4_PRM_IO_PMCTRL_OFFSET);
 }
 
+bool omap4_pwrdm_lost_context_rff(s16 inst, s16 offset)
+{
+	u32 val;
+
+	val = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, inst, offset);
+
+	if (val & OMAP4430_LOSTCONTEXT_RFF_MASK) {
+		omap4_prminst_write_inst_reg(val, OMAP4430_PRM_PARTITION, inst,
+					     offset);
+		return true;
+	}
+
+	return false;
+}
+
 /**
  * omap4_device_set_state_off() - setup device off state
  * @enable:	set to off or not.
diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h
index 54a057e..517851b 100644
--- a/arch/arm/mach-omap2/prm44xx.h
+++ b/arch/arm/mach-omap2/prm44xx.h
@@ -770,6 +770,8 @@ extern void omap44xx_prm_ocp_barrier(void);
 extern void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask);
 extern void omap44xx_prm_restore_irqen(u32 *saved_mask);
 
+extern bool omap4_pwrdm_lost_context_rff(s16 inst, s16 offset);
+
 # endif
 
 #endif
-- 
1.7.4.1


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

* [PATCH 19/19] ARM: OMAP4: powerdomain: update mpu / core off counters during device off
@ 2012-04-20  9:33   ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20  9:33 UTC (permalink / raw)
  To: linux-arm-kernel

Currently device off does not have any counters / timers of its own
and it is impossible to track the time spent in this state. In device
off, MPU / CORE powerdomains enter OSWR, so normally the RETENTION
state times / counts are increased during device off.

This patch adds a new field to the powerdomain struct for context loss
register, which is checked during pwrdm_post_transition to see if
a device off type context loss has happened. If this is the case,
the counters + timers for OFF state are touched instead of RETENTION.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap-mpuss-lowpower.c   |    1 -
 arch/arm/mach-omap2/powerdomain.c           |    9 +++++++++
 arch/arm/mach-omap2/powerdomain.h           |    2 ++
 arch/arm/mach-omap2/powerdomains44xx_data.c |    2 ++
 arch/arm/mach-omap2/prm44xx.c               |   15 +++++++++++++++
 arch/arm/mach-omap2/prm44xx.h               |    2 ++
 6 files changed, 30 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index b4ca6f3..b7d139a 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -404,7 +404,6 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 	if (omap4_device_prev_state_off()) {
 		omap4_dpll_resume_off();
 		omap4_cm_resume_off();
-		omap4_device_clear_prev_off_state();
 	}
 
 	pwrdm_post_transition();
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 068f06b..cb3eab2 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -160,6 +160,15 @@ static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
 		break;
 	case PWRDM_STATE_PREV:
 		prev = pwrdm_read_prev_pwrst(pwrdm);
+
+		/*
+		 * If powerdomain has context offset defined, check if
+		 * the domain has lost context (i.e. entered off)
+		 */
+		if (pwrdm->context_offs)
+			if (omap4_pwrdm_lost_context_rff(pwrdm->prcm_offs,
+							 pwrdm->context_offs))
+				prev = PWRDM_POWER_OFF;
 		if (pwrdm->state != prev)
 			pwrdm->state_counter[prev]++;
 		if (prev == PWRDM_POWER_RET)
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index 0d72a8a..a427645 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -82,6 +82,7 @@ struct powerdomain;
  * @name: Powerdomain name
  * @voltdm: voltagedomain containing this powerdomain
  * @prcm_offs: the address offset from CM_BASE/PRM_BASE
+ * @context_offs: the address offset for the CONTEXT register
  * @prcm_partition: (OMAP4 only) the PRCM partition ID containing @prcm_offs
  * @pwrsts: Possible powerdomain power states
  * @pwrsts_logic_ret: Possible logic power states when pwrdm in RETENTION
@@ -106,6 +107,7 @@ struct powerdomain {
 		struct voltagedomain *ptr;
 	} voltdm;
 	const s16 prcm_offs;
+	const s16 context_offs;
 	const u8 pwrsts;
 	const u8 pwrsts_logic_ret;
 	const u8 flags;
diff --git a/arch/arm/mach-omap2/powerdomains44xx_data.c b/arch/arm/mach-omap2/powerdomains44xx_data.c
index d8701ce..c4de02f 100644
--- a/arch/arm/mach-omap2/powerdomains44xx_data.c
+++ b/arch/arm/mach-omap2/powerdomains44xx_data.c
@@ -36,6 +36,7 @@ static struct powerdomain core_44xx_pwrdm = {
 	.voltdm		  = { .name = "core" },
 	.prcm_offs	  = OMAP4430_PRM_CORE_INST,
 	.prcm_partition	  = OMAP4430_PRM_PARTITION,
+	.context_offs	  = OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET,
 	.pwrsts		  = PWRSTS_RET_ON,
 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
 	.banks		  = 5,
@@ -205,6 +206,7 @@ static struct powerdomain mpu_44xx_pwrdm = {
 	.voltdm		  = { .name = "mpu" },
 	.prcm_offs	  = OMAP4430_PRM_MPU_INST,
 	.prcm_partition	  = OMAP4430_PRM_PARTITION,
+	.context_offs	  = OMAP4_RM_MPU_MPU_CONTEXT_OFFSET,
 	.pwrsts		  = PWRSTS_RET_ON,
 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
 	.banks		  = 3,
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index ab810cd..cf996a6 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -274,6 +274,21 @@ static void __init omap4_enable_io_wakeup(void)
 			OMAP4_PRM_IO_PMCTRL_OFFSET);
 }
 
+bool omap4_pwrdm_lost_context_rff(s16 inst, s16 offset)
+{
+	u32 val;
+
+	val = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, inst, offset);
+
+	if (val & OMAP4430_LOSTCONTEXT_RFF_MASK) {
+		omap4_prminst_write_inst_reg(val, OMAP4430_PRM_PARTITION, inst,
+					     offset);
+		return true;
+	}
+
+	return false;
+}
+
 /**
  * omap4_device_set_state_off() - setup device off state
  * @enable:	set to off or not.
diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h
index 54a057e..517851b 100644
--- a/arch/arm/mach-omap2/prm44xx.h
+++ b/arch/arm/mach-omap2/prm44xx.h
@@ -770,6 +770,8 @@ extern void omap44xx_prm_ocp_barrier(void);
 extern void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask);
 extern void omap44xx_prm_restore_irqen(u32 *saved_mask);
 
+extern bool omap4_pwrdm_lost_context_rff(s16 inst, s16 offset);
+
 # endif
 
 #endif
-- 
1.7.4.1

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

* Re: [PATCH 00/19] ARM: OMAP4 device off support
  2012-04-20  9:33 ` Tero Kristo
@ 2012-04-20 12:20   ` T Krishnamoorthy, Balaji
  -1 siblings, 0 replies; 126+ messages in thread
From: T Krishnamoorthy, Balaji @ 2012-04-20 12:20 UTC (permalink / raw)
  To: Tero Kristo; +Cc: khilman, paul, linux-omap, linux-arm-kernel

On Fri, Apr 20, 2012 at 3:03 PM, Tero Kristo <t-kristo@ti.com> wrote:
> Hi,
>
> First version for this work. Applies on top of mainline + iochain set +
> OMAP4 core retention set. Working tree available here:
> tree: git://gitorious.org/~kristo/omap-pm/omap-pm-work.git
> branch: mainline-3.4-omap4-dev-off
>
> Tested on omap4430 EMU blaze + omap4460 GP panda boards.
>
> Some drivers have issues with device off, most notably MMC, as it breaks
> device off on blaze device after 1 entry to device off mode:
>
> [  208.906921] omap_i2c omap_i2c.1: XRDY IRQ while no data to send
> [  209.905639] omap_i2c omap_i2c.1: controller timed out
> [  209.905792] twl: i2c_read failed to transfer all messages
> [  209.905792] omap_hsmmc omap_hsmmc.1: could not set regulator OCR (-110)
> [  212.296203] mmc0: error -110 during resume (card was removed?)
Hi Tero,

I tried your branch on gp/emu devices but could not reproduce this issue.
My observation is that while resuming, omap_hsmmc.1 eMMC is
trying to turn on phoenix vaux1 regulator via i2c which fails due
to controller timeout.
Note: eMMC is present only on sdp/blaze

> [  212.562164] PM: resume of devices complete after 3656.007 msecs
> [  212.660125] Restarting tasks ... done.
> #
> # echo mem > /sys/power/state
> [  220.376892] PM: Syncing filesystems ... done.
> [  220.382476] Freezing user space processes ... (elapsed 0.01 seconds) done.
> [  220.408386] Freezing remaining freezable tasks ... (elapsed 0.02 seconds) don
> e.
> [  220.439605] Suspending console(s) (use no_console_suspend to debug)
> [  220.454650] dpm_run_callback(): platform_pm_suspend+0x0/0x54 returns -110
> [  220.454711] PM: Device omap_hsmmc.1 failed to suspend: error -110
> [  220.454711] PM: Some devices failed to suspend
> [  220.718261] PM: resume of devices complete after 263.539 msecs
> [  220.743988] Restarting tasks ... done.
>
> Attempting to disable MMC from config prevented boot completely for me,
> so this issue is likely to stay until someone fixes the MMC driver.
> Panda device works fine though, although the wakeup from device off is
> slow due to problems with some other drivers (most likely I2C.)
>

can you try this patch if you want to disable MMC
http://permalink.gmane.org/gmane.linux.ports.arm.omap/74540
or
http://www.spinics.net/lists/linux-omap/msg67879.html
and build omap_hsmmc as module.

> Off mode is disabled by default, it can be enabled by either calling
> omap4_pm_enable_off_mode(1) from board files or alternatively writing
> to a debugfs node from userspace:
>
> echo 1 > /debug/pm_debug/enable_off_mode
>
> Device off entry can be tracked through the debugfs also, it increases
> the core_pwrdm OFF state counter / timer, as this is an invalid state
> for the chip normally (core enters OSWR in device off.) Not sure if this
> a good way to do this but comments are welcome.
>
> -Tero
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 00/19] ARM: OMAP4 device off support
@ 2012-04-20 12:20   ` T Krishnamoorthy, Balaji
  0 siblings, 0 replies; 126+ messages in thread
From: T Krishnamoorthy, Balaji @ 2012-04-20 12:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Apr 20, 2012 at 3:03 PM, Tero Kristo <t-kristo@ti.com> wrote:
> Hi,
>
> First version for this work. Applies on top of mainline + iochain set +
> OMAP4 core retention set. Working tree available here:
> tree: git://gitorious.org/~kristo/omap-pm/omap-pm-work.git
> branch: mainline-3.4-omap4-dev-off
>
> Tested on omap4430 EMU blaze + omap4460 GP panda boards.
>
> Some drivers have issues with device off, most notably MMC, as it breaks
> device off on blaze device after 1 entry to device off mode:
>
> [ ?208.906921] omap_i2c omap_i2c.1: XRDY IRQ while no data to send
> [ ?209.905639] omap_i2c omap_i2c.1: controller timed out
> [ ?209.905792] twl: i2c_read failed to transfer all messages
> [ ?209.905792] omap_hsmmc omap_hsmmc.1: could not set regulator OCR (-110)
> [ ?212.296203] mmc0: error -110 during resume (card was removed?)
Hi Tero,

I tried your branch on gp/emu devices but could not reproduce this issue.
My observation is that while resuming, omap_hsmmc.1 eMMC is
trying to turn on phoenix vaux1 regulator via i2c which fails due
to controller timeout.
Note: eMMC is present only on sdp/blaze

> [ ?212.562164] PM: resume of devices complete after 3656.007 msecs
> [ ?212.660125] Restarting tasks ... done.
> #
> # echo mem > /sys/power/state
> [ ?220.376892] PM: Syncing filesystems ... done.
> [ ?220.382476] Freezing user space processes ... (elapsed 0.01 seconds) done.
> [ ?220.408386] Freezing remaining freezable tasks ... (elapsed 0.02 seconds) don
> e.
> [ ?220.439605] Suspending console(s) (use no_console_suspend to debug)
> [ ?220.454650] dpm_run_callback(): platform_pm_suspend+0x0/0x54 returns -110
> [ ?220.454711] PM: Device omap_hsmmc.1 failed to suspend: error -110
> [ ?220.454711] PM: Some devices failed to suspend
> [ ?220.718261] PM: resume of devices complete after 263.539 msecs
> [ ?220.743988] Restarting tasks ... done.
>
> Attempting to disable MMC from config prevented boot completely for me,
> so this issue is likely to stay until someone fixes the MMC driver.
> Panda device works fine though, although the wakeup from device off is
> slow due to problems with some other drivers (most likely I2C.)
>

can you try this patch if you want to disable MMC
http://permalink.gmane.org/gmane.linux.ports.arm.omap/74540
or
http://www.spinics.net/lists/linux-omap/msg67879.html
and build omap_hsmmc as module.

> Off mode is disabled by default, it can be enabled by either calling
> omap4_pm_enable_off_mode(1) from board files or alternatively writing
> to a debugfs node from userspace:
>
> echo 1 > /debug/pm_debug/enable_off_mode
>
> Device off entry can be tracked through the debugfs also, it increases
> the core_pwrdm OFF state counter / timer, as this is an invalid state
> for the chip normally (core enters OSWR in device off.) Not sure if this
> a good way to do this but comments are welcome.
>
> -Tero
>
> --
> 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] 126+ messages in thread

* Re: [PATCH 00/19] ARM: OMAP4 device off support
  2012-04-20 12:20   ` T Krishnamoorthy, Balaji
@ 2012-04-20 12:58     ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20 12:58 UTC (permalink / raw)
  To: T Krishnamoorthy, Balaji; +Cc: linux-omap, khilman, paul, linux-arm-kernel

On Fri, 2012-04-20 at 17:50 +0530, T Krishnamoorthy, Balaji wrote:
> On Fri, Apr 20, 2012 at 3:03 PM, Tero Kristo <t-kristo@ti.com> wrote:
> > Hi,
> >
> > First version for this work. Applies on top of mainline + iochain set +
> > OMAP4 core retention set. Working tree available here:
> > tree: git://gitorious.org/~kristo/omap-pm/omap-pm-work.git
> > branch: mainline-3.4-omap4-dev-off
> >
> > Tested on omap4430 EMU blaze + omap4460 GP panda boards.
> >
> > Some drivers have issues with device off, most notably MMC, as it breaks
> > device off on blaze device after 1 entry to device off mode:
> >
> > [  208.906921] omap_i2c omap_i2c.1: XRDY IRQ while no data to send
> > [  209.905639] omap_i2c omap_i2c.1: controller timed out
> > [  209.905792] twl: i2c_read failed to transfer all messages
> > [  209.905792] omap_hsmmc omap_hsmmc.1: could not set regulator OCR (-110)
> > [  212.296203] mmc0: error -110 during resume (card was removed?)
> Hi Tero,
> 
> I tried your branch on gp/emu devices but could not reproduce this issue.
> My observation is that while resuming, omap_hsmmc.1 eMMC is
> trying to turn on phoenix vaux1 regulator via i2c which fails due
> to controller timeout.
> Note: eMMC is present only on sdp/blaze

Did you try this with off-mode enabled and did you check the device
actually goes to off? (see pm_debug/count and verify core off count is
increasing.) And as said, I was only able to see this problem on a blaze
device, panda works fine. But yes, you are probably right and it is not
an MMC driver issue but I2C.

> 
> > [  212.562164] PM: resume of devices complete after 3656.007 msecs
> > [  212.660125] Restarting tasks ... done.
> > #
> > # echo mem > /sys/power/state
> > [  220.376892] PM: Syncing filesystems ... done.
> > [  220.382476] Freezing user space processes ... (elapsed 0.01 seconds) done.
> > [  220.408386] Freezing remaining freezable tasks ... (elapsed 0.02 seconds) don
> > e.
> > [  220.439605] Suspending console(s) (use no_console_suspend to debug)
> > [  220.454650] dpm_run_callback(): platform_pm_suspend+0x0/0x54 returns -110
> > [  220.454711] PM: Device omap_hsmmc.1 failed to suspend: error -110
> > [  220.454711] PM: Some devices failed to suspend
> > [  220.718261] PM: resume of devices complete after 263.539 msecs
> > [  220.743988] Restarting tasks ... done.
> >
> > Attempting to disable MMC from config prevented boot completely for me,
> > so this issue is likely to stay until someone fixes the MMC driver.
> > Panda device works fine though, although the wakeup from device off is
> > slow due to problems with some other drivers (most likely I2C.)
> >
> 
> can you try this patch if you want to disable MMC
> http://permalink.gmane.org/gmane.linux.ports.arm.omap/74540

Tried this patch and disabled MMC completely. Device off now works with
blaze board also multiple times.

-Tero

> or
> http://www.spinics.net/lists/linux-omap/msg67879.html
> and build omap_hsmmc as module.
> 
> > Off mode is disabled by default, it can be enabled by either calling
> > omap4_pm_enable_off_mode(1) from board files or alternatively writing
> > to a debugfs node from userspace:
> >
> > echo 1 > /debug/pm_debug/enable_off_mode
> >
> > Device off entry can be tracked through the debugfs also, it increases
> > the core_pwrdm OFF state counter / timer, as this is an invalid state
> > for the chip normally (core enters OSWR in device off.) Not sure if this
> > a good way to do this but comments are welcome.
> >
> > -Tero
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html



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

* [PATCH 00/19] ARM: OMAP4 device off support
@ 2012-04-20 12:58     ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20 12:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 2012-04-20 at 17:50 +0530, T Krishnamoorthy, Balaji wrote:
> On Fri, Apr 20, 2012 at 3:03 PM, Tero Kristo <t-kristo@ti.com> wrote:
> > Hi,
> >
> > First version for this work. Applies on top of mainline + iochain set +
> > OMAP4 core retention set. Working tree available here:
> > tree: git://gitorious.org/~kristo/omap-pm/omap-pm-work.git
> > branch: mainline-3.4-omap4-dev-off
> >
> > Tested on omap4430 EMU blaze + omap4460 GP panda boards.
> >
> > Some drivers have issues with device off, most notably MMC, as it breaks
> > device off on blaze device after 1 entry to device off mode:
> >
> > [  208.906921] omap_i2c omap_i2c.1: XRDY IRQ while no data to send
> > [  209.905639] omap_i2c omap_i2c.1: controller timed out
> > [  209.905792] twl: i2c_read failed to transfer all messages
> > [  209.905792] omap_hsmmc omap_hsmmc.1: could not set regulator OCR (-110)
> > [  212.296203] mmc0: error -110 during resume (card was removed?)
> Hi Tero,
> 
> I tried your branch on gp/emu devices but could not reproduce this issue.
> My observation is that while resuming, omap_hsmmc.1 eMMC is
> trying to turn on phoenix vaux1 regulator via i2c which fails due
> to controller timeout.
> Note: eMMC is present only on sdp/blaze

Did you try this with off-mode enabled and did you check the device
actually goes to off? (see pm_debug/count and verify core off count is
increasing.) And as said, I was only able to see this problem on a blaze
device, panda works fine. But yes, you are probably right and it is not
an MMC driver issue but I2C.

> 
> > [  212.562164] PM: resume of devices complete after 3656.007 msecs
> > [  212.660125] Restarting tasks ... done.
> > #
> > # echo mem > /sys/power/state
> > [  220.376892] PM: Syncing filesystems ... done.
> > [  220.382476] Freezing user space processes ... (elapsed 0.01 seconds) done.
> > [  220.408386] Freezing remaining freezable tasks ... (elapsed 0.02 seconds) don
> > e.
> > [  220.439605] Suspending console(s) (use no_console_suspend to debug)
> > [  220.454650] dpm_run_callback(): platform_pm_suspend+0x0/0x54 returns -110
> > [  220.454711] PM: Device omap_hsmmc.1 failed to suspend: error -110
> > [  220.454711] PM: Some devices failed to suspend
> > [  220.718261] PM: resume of devices complete after 263.539 msecs
> > [  220.743988] Restarting tasks ... done.
> >
> > Attempting to disable MMC from config prevented boot completely for me,
> > so this issue is likely to stay until someone fixes the MMC driver.
> > Panda device works fine though, although the wakeup from device off is
> > slow due to problems with some other drivers (most likely I2C.)
> >
> 
> can you try this patch if you want to disable MMC
> http://permalink.gmane.org/gmane.linux.ports.arm.omap/74540

Tried this patch and disabled MMC completely. Device off now works with
blaze board also multiple times.

-Tero

> or
> http://www.spinics.net/lists/linux-omap/msg67879.html
> and build omap_hsmmc as module.
> 
> > Off mode is disabled by default, it can be enabled by either calling
> > omap4_pm_enable_off_mode(1) from board files or alternatively writing
> > to a debugfs node from userspace:
> >
> > echo 1 > /debug/pm_debug/enable_off_mode
> >
> > Device off entry can be tracked through the debugfs also, it increases
> > the core_pwrdm OFF state counter / timer, as this is an invalid state
> > for the chip normally (core enters OSWR in device off.) Not sure if this
> > a good way to do this but comments are welcome.
> >
> > -Tero
> >
> > --
> > 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] 126+ messages in thread

* Re: [PATCH 00/19] ARM: OMAP4 device off support
  2012-04-20 12:58     ` Tero Kristo
@ 2012-04-20 13:55       ` Kevin Hilman
  -1 siblings, 0 replies; 126+ messages in thread
From: Kevin Hilman @ 2012-04-20 13:55 UTC (permalink / raw)
  To: t-kristo; +Cc: T Krishnamoorthy, Balaji, linux-omap, paul, linux-arm-kernel

Tero Kristo <t-kristo@ti.com> writes:

[...]

>> I tried your branch on gp/emu devices but could not reproduce this issue.
>> My observation is that while resuming, omap_hsmmc.1 eMMC is
>> trying to turn on phoenix vaux1 regulator via i2c which fails due
>> to controller timeout.
>> Note: eMMC is present only on sdp/blaze
>
> Did you try this with off-mode enabled and did you check the device
> actually goes to off? (see pm_debug/count and verify core off count is
> increasing.) And as said, I was only able to see this problem on a blaze
> device, panda works fine. But yes, you are probably right and it is not
> an MMC driver issue but I2C.

Can you try the patch below?  It sounds like the same problem.

Kevin


>From 999f34629140f436099050eb7aac514bfd2a2235 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Fri, 30 Dec 2011 12:40:30 +1100
Subject: [PATCH] OMAP/I2C - Fix timeout problem during suspend.

On a board with OMAP3 processor and TWL4030 Power management,
we need to talk to the TWL4030 during late suspend but cannot
because the I2C interrupt is disabled (as late suspend disables
interrupt).

e.g. I get messages like:

[   62.161102] musb-omap2430 musb-omap2430: LATE power domain suspend
[   63.167205] omap_i2c omap_i2c.1: controller timed out
[   63.183044] twl: i2c_read failed to transfer all messages
[   64.182861] omap_i2c omap_i2c.1: controller timed out
[   64.198455] twl: i2c_write failed to transfer all messages
[   65.198455] omap_i2c omap_i2c.1: controller timed out
[   65.203765] twl: i2c_write failed to transfer all messages

The stack shows omap2430_runtime_suspend calling twl4030_set_suspend
which tries to power-down the USB PHY (twl4030_phy_suspend ->
twl4030_phy_power -> __twl4030_phy_power which as a nice WARN_ON
that helps).

Then we get the same in resume:

[   69.603912] musb-omap2430 musb-omap2430: EARLY power domain resume
[   70.610473] omap_i2c omap_i2c.1: controller timed out
[   70.626129] twl: i2c_write failed to transfer all messages
etc.

So don't disable interrupts for I2C.

Signed-off-by: NeilBrown <neilb@suse.de>
---
 drivers/i2c/busses/i2c-omap.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 801df60..e024c50 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1092,7 +1092,7 @@ omap_i2c_probe(struct platform_device *pdev)
 
 	isr = (dev->rev < OMAP_I2C_OMAP1_REV_2) ? omap_i2c_omap1_isr :
 								   omap_i2c_isr;
-	r = request_irq(dev->irq, isr, 0, pdev->name, dev);
+	r = request_irq(dev->irq, isr, IRQF_NO_SUSPEND, pdev->name, dev);
 
 	if (r) {
 		dev_err(dev->dev, "failure requesting irq %i\n", dev->irq);
-- 
1.7.9.2


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

* [PATCH 00/19] ARM: OMAP4 device off support
@ 2012-04-20 13:55       ` Kevin Hilman
  0 siblings, 0 replies; 126+ messages in thread
From: Kevin Hilman @ 2012-04-20 13:55 UTC (permalink / raw)
  To: linux-arm-kernel

Tero Kristo <t-kristo@ti.com> writes:

[...]

>> I tried your branch on gp/emu devices but could not reproduce this issue.
>> My observation is that while resuming, omap_hsmmc.1 eMMC is
>> trying to turn on phoenix vaux1 regulator via i2c which fails due
>> to controller timeout.
>> Note: eMMC is present only on sdp/blaze
>
> Did you try this with off-mode enabled and did you check the device
> actually goes to off? (see pm_debug/count and verify core off count is
> increasing.) And as said, I was only able to see this problem on a blaze
> device, panda works fine. But yes, you are probably right and it is not
> an MMC driver issue but I2C.

Can you try the patch below?  It sounds like the same problem.

Kevin


>From 999f34629140f436099050eb7aac514bfd2a2235 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Fri, 30 Dec 2011 12:40:30 +1100
Subject: [PATCH] OMAP/I2C - Fix timeout problem during suspend.

On a board with OMAP3 processor and TWL4030 Power management,
we need to talk to the TWL4030 during late suspend but cannot
because the I2C interrupt is disabled (as late suspend disables
interrupt).

e.g. I get messages like:

[   62.161102] musb-omap2430 musb-omap2430: LATE power domain suspend
[   63.167205] omap_i2c omap_i2c.1: controller timed out
[   63.183044] twl: i2c_read failed to transfer all messages
[   64.182861] omap_i2c omap_i2c.1: controller timed out
[   64.198455] twl: i2c_write failed to transfer all messages
[   65.198455] omap_i2c omap_i2c.1: controller timed out
[   65.203765] twl: i2c_write failed to transfer all messages

The stack shows omap2430_runtime_suspend calling twl4030_set_suspend
which tries to power-down the USB PHY (twl4030_phy_suspend ->
twl4030_phy_power -> __twl4030_phy_power which as a nice WARN_ON
that helps).

Then we get the same in resume:

[   69.603912] musb-omap2430 musb-omap2430: EARLY power domain resume
[   70.610473] omap_i2c omap_i2c.1: controller timed out
[   70.626129] twl: i2c_write failed to transfer all messages
etc.

So don't disable interrupts for I2C.

Signed-off-by: NeilBrown <neilb@suse.de>
---
 drivers/i2c/busses/i2c-omap.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 801df60..e024c50 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1092,7 +1092,7 @@ omap_i2c_probe(struct platform_device *pdev)
 
 	isr = (dev->rev < OMAP_I2C_OMAP1_REV_2) ? omap_i2c_omap1_isr :
 								   omap_i2c_isr;
-	r = request_irq(dev->irq, isr, 0, pdev->name, dev);
+	r = request_irq(dev->irq, isr, IRQF_NO_SUSPEND, pdev->name, dev);
 
 	if (r) {
 		dev_err(dev->dev, "failure requesting irq %i\n", dev->irq);
-- 
1.7.9.2

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

* Re: [PATCH 00/19] ARM: OMAP4 device off support
  2012-04-20 13:55       ` Kevin Hilman
@ 2012-04-20 14:43         ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20 14:43 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: T Krishnamoorthy, Balaji, linux-omap, paul, linux-arm-kernel

On Fri, 2012-04-20 at 06:55 -0700, Kevin Hilman wrote:
> Tero Kristo <t-kristo@ti.com> writes:
> 
> [...]
> 
> >> I tried your branch on gp/emu devices but could not reproduce this issue.
> >> My observation is that while resuming, omap_hsmmc.1 eMMC is
> >> trying to turn on phoenix vaux1 regulator via i2c which fails due
> >> to controller timeout.
> >> Note: eMMC is present only on sdp/blaze
> >
> > Did you try this with off-mode enabled and did you check the device
> > actually goes to off? (see pm_debug/count and verify core off count is
> > increasing.) And as said, I was only able to see this problem on a blaze
> > device, panda works fine. But yes, you are probably right and it is not
> > an MMC driver issue but I2C.
> 
> Can you try the patch below?  It sounds like the same problem.

Doesn't help with this one. I guess I2C loses context during device off
and it is not restored properly.

-Tero

> 
> Kevin
> 
> 
> From 999f34629140f436099050eb7aac514bfd2a2235 Mon Sep 17 00:00:00 2001
> From: NeilBrown <neilb@suse.de>
> Date: Fri, 30 Dec 2011 12:40:30 +1100
> Subject: [PATCH] OMAP/I2C - Fix timeout problem during suspend.
> 
> On a board with OMAP3 processor and TWL4030 Power management,
> we need to talk to the TWL4030 during late suspend but cannot
> because the I2C interrupt is disabled (as late suspend disables
> interrupt).
> 
> e.g. I get messages like:
> 
> [   62.161102] musb-omap2430 musb-omap2430: LATE power domain suspend
> [   63.167205] omap_i2c omap_i2c.1: controller timed out
> [   63.183044] twl: i2c_read failed to transfer all messages
> [   64.182861] omap_i2c omap_i2c.1: controller timed out
> [   64.198455] twl: i2c_write failed to transfer all messages
> [   65.198455] omap_i2c omap_i2c.1: controller timed out
> [   65.203765] twl: i2c_write failed to transfer all messages
> 
> The stack shows omap2430_runtime_suspend calling twl4030_set_suspend
> which tries to power-down the USB PHY (twl4030_phy_suspend ->
> twl4030_phy_power -> __twl4030_phy_power which as a nice WARN_ON
> that helps).
> 
> Then we get the same in resume:
> 
> [   69.603912] musb-omap2430 musb-omap2430: EARLY power domain resume
> [   70.610473] omap_i2c omap_i2c.1: controller timed out
> [   70.626129] twl: i2c_write failed to transfer all messages
> etc.
> 
> So don't disable interrupts for I2C.
> 
> Signed-off-by: NeilBrown <neilb@suse.de>
> ---
>  drivers/i2c/busses/i2c-omap.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> index 801df60..e024c50 100644
> --- a/drivers/i2c/busses/i2c-omap.c
> +++ b/drivers/i2c/busses/i2c-omap.c
> @@ -1092,7 +1092,7 @@ omap_i2c_probe(struct platform_device *pdev)
>  
>  	isr = (dev->rev < OMAP_I2C_OMAP1_REV_2) ? omap_i2c_omap1_isr :
>  								   omap_i2c_isr;
> -	r = request_irq(dev->irq, isr, 0, pdev->name, dev);
> +	r = request_irq(dev->irq, isr, IRQF_NO_SUSPEND, pdev->name, dev);
>  
>  	if (r) {
>  		dev_err(dev->dev, "failure requesting irq %i\n", dev->irq);



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

* [PATCH 00/19] ARM: OMAP4 device off support
@ 2012-04-20 14:43         ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20 14:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 2012-04-20 at 06:55 -0700, Kevin Hilman wrote:
> Tero Kristo <t-kristo@ti.com> writes:
> 
> [...]
> 
> >> I tried your branch on gp/emu devices but could not reproduce this issue.
> >> My observation is that while resuming, omap_hsmmc.1 eMMC is
> >> trying to turn on phoenix vaux1 regulator via i2c which fails due
> >> to controller timeout.
> >> Note: eMMC is present only on sdp/blaze
> >
> > Did you try this with off-mode enabled and did you check the device
> > actually goes to off? (see pm_debug/count and verify core off count is
> > increasing.) And as said, I was only able to see this problem on a blaze
> > device, panda works fine. But yes, you are probably right and it is not
> > an MMC driver issue but I2C.
> 
> Can you try the patch below?  It sounds like the same problem.

Doesn't help with this one. I guess I2C loses context during device off
and it is not restored properly.

-Tero

> 
> Kevin
> 
> 
> From 999f34629140f436099050eb7aac514bfd2a2235 Mon Sep 17 00:00:00 2001
> From: NeilBrown <neilb@suse.de>
> Date: Fri, 30 Dec 2011 12:40:30 +1100
> Subject: [PATCH] OMAP/I2C - Fix timeout problem during suspend.
> 
> On a board with OMAP3 processor and TWL4030 Power management,
> we need to talk to the TWL4030 during late suspend but cannot
> because the I2C interrupt is disabled (as late suspend disables
> interrupt).
> 
> e.g. I get messages like:
> 
> [   62.161102] musb-omap2430 musb-omap2430: LATE power domain suspend
> [   63.167205] omap_i2c omap_i2c.1: controller timed out
> [   63.183044] twl: i2c_read failed to transfer all messages
> [   64.182861] omap_i2c omap_i2c.1: controller timed out
> [   64.198455] twl: i2c_write failed to transfer all messages
> [   65.198455] omap_i2c omap_i2c.1: controller timed out
> [   65.203765] twl: i2c_write failed to transfer all messages
> 
> The stack shows omap2430_runtime_suspend calling twl4030_set_suspend
> which tries to power-down the USB PHY (twl4030_phy_suspend ->
> twl4030_phy_power -> __twl4030_phy_power which as a nice WARN_ON
> that helps).
> 
> Then we get the same in resume:
> 
> [   69.603912] musb-omap2430 musb-omap2430: EARLY power domain resume
> [   70.610473] omap_i2c omap_i2c.1: controller timed out
> [   70.626129] twl: i2c_write failed to transfer all messages
> etc.
> 
> So don't disable interrupts for I2C.
> 
> Signed-off-by: NeilBrown <neilb@suse.de>
> ---
>  drivers/i2c/busses/i2c-omap.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> index 801df60..e024c50 100644
> --- a/drivers/i2c/busses/i2c-omap.c
> +++ b/drivers/i2c/busses/i2c-omap.c
> @@ -1092,7 +1092,7 @@ omap_i2c_probe(struct platform_device *pdev)
>  
>  	isr = (dev->rev < OMAP_I2C_OMAP1_REV_2) ? omap_i2c_omap1_isr :
>  								   omap_i2c_isr;
> -	r = request_irq(dev->irq, isr, 0, pdev->name, dev);
> +	r = request_irq(dev->irq, isr, IRQF_NO_SUSPEND, pdev->name, dev);
>  
>  	if (r) {
>  		dev_err(dev->dev, "failure requesting irq %i\n", dev->irq);

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

* Re: [PATCH 00/19] ARM: OMAP4 device off support
  2012-04-20 14:43         ` Tero Kristo
@ 2012-04-20 14:51           ` Datta, Shubhrajyoti
  -1 siblings, 0 replies; 126+ messages in thread
From: Datta, Shubhrajyoti @ 2012-04-20 14:51 UTC (permalink / raw)
  To: t-kristo
  Cc: Kevin Hilman, T Krishnamoorthy, Balaji, linux-omap, paul,
	linux-arm-kernel

On Fri, Apr 20, 2012 at 8:13 PM, Tero Kristo <t-kristo@ti.com> wrote:
> On Fri, 2012-04-20 at 06:55 -0700, Kevin Hilman wrote:
>> Tero Kristo <t-kristo@ti.com> writes:
>>
>> [...]
>>
>> >> I tried your branch on gp/emu devices but could not reproduce this issue.
>> >> My observation is that while resuming, omap_hsmmc.1 eMMC is
>> >> trying to turn on phoenix vaux1 regulator via i2c which fails due
>> >> to controller timeout.
>> >> Note: eMMC is present only on sdp/blaze
>> >
>> > Did you try this with off-mode enabled and did you check the device
>> > actually goes to off? (see pm_debug/count and verify core off count is
>> > increasing.) And as said, I was only able to see this problem on a blaze
>> > device, panda works fine. But yes, you are probably right and it is not
>> > an MMC driver issue but I2C.
>>
>> Can you try the patch below?  It sounds like the same problem.
>
> Doesn't help with this one. I guess I2C loses context during device off
> and it is not restored properly.
>
> -Tero
Could you try the following patch

https://lkml.org/lkml/2012/3/30/345
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 00/19] ARM: OMAP4 device off support
@ 2012-04-20 14:51           ` Datta, Shubhrajyoti
  0 siblings, 0 replies; 126+ messages in thread
From: Datta, Shubhrajyoti @ 2012-04-20 14:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Apr 20, 2012 at 8:13 PM, Tero Kristo <t-kristo@ti.com> wrote:
> On Fri, 2012-04-20 at 06:55 -0700, Kevin Hilman wrote:
>> Tero Kristo <t-kristo@ti.com> writes:
>>
>> [...]
>>
>> >> I tried your branch on gp/emu devices but could not reproduce this issue.
>> >> My observation is that while resuming, omap_hsmmc.1 eMMC is
>> >> trying to turn on phoenix vaux1 regulator via i2c which fails due
>> >> to controller timeout.
>> >> Note: eMMC is present only on sdp/blaze
>> >
>> > Did you try this with off-mode enabled and did you check the device
>> > actually goes to off? (see pm_debug/count and verify core off count is
>> > increasing.) And as said, I was only able to see this problem on a blaze
>> > device, panda works fine. But yes, you are probably right and it is not
>> > an MMC driver issue but I2C.
>>
>> Can you try the patch below? ?It sounds like the same problem.
>
> Doesn't help with this one. I guess I2C loses context during device off
> and it is not restored properly.
>
> -Tero
Could you try the following patch

https://lkml.org/lkml/2012/3/30/345

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

* Re: [PATCH 00/19] ARM: OMAP4 device off support
  2012-04-20 14:51           ` Datta, Shubhrajyoti
@ 2012-04-20 15:07             ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20 15:07 UTC (permalink / raw)
  To: Datta, Shubhrajyoti
  Cc: Kevin Hilman, paul, linux-omap, T Krishnamoorthy, Balaji,
	linux-arm-kernel

On Fri, 2012-04-20 at 20:21 +0530, Datta, Shubhrajyoti wrote:
> On Fri, Apr 20, 2012 at 8:13 PM, Tero Kristo <t-kristo@ti.com> wrote:
> > On Fri, 2012-04-20 at 06:55 -0700, Kevin Hilman wrote:
> >> Tero Kristo <t-kristo@ti.com> writes:
> >>
> >> [...]
> >>
> >> >> I tried your branch on gp/emu devices but could not reproduce this issue.
> >> >> My observation is that while resuming, omap_hsmmc.1 eMMC is
> >> >> trying to turn on phoenix vaux1 regulator via i2c which fails due
> >> >> to controller timeout.
> >> >> Note: eMMC is present only on sdp/blaze
> >> >
> >> > Did you try this with off-mode enabled and did you check the device
> >> > actually goes to off? (see pm_debug/count and verify core off count is
> >> > increasing.) And as said, I was only able to see this problem on a blaze
> >> > device, panda works fine. But yes, you are probably right and it is not
> >> > an MMC driver issue but I2C.
> >>
> >> Can you try the patch below?  It sounds like the same problem.
> >
> > Doesn't help with this one. I guess I2C loses context during device off
> > and it is not restored properly.
> >
> > -Tero
> Could you try the following patch
> 
> https://lkml.org/lkml/2012/3/30/345

That does the trick, after this it is working fine on blaze, and this
also fixes the timeout issues seen on panda board (meaning wake-up from
device off is much faster.)

-Tero

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

* [PATCH 00/19] ARM: OMAP4 device off support
@ 2012-04-20 15:07             ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-20 15:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 2012-04-20 at 20:21 +0530, Datta, Shubhrajyoti wrote:
> On Fri, Apr 20, 2012 at 8:13 PM, Tero Kristo <t-kristo@ti.com> wrote:
> > On Fri, 2012-04-20 at 06:55 -0700, Kevin Hilman wrote:
> >> Tero Kristo <t-kristo@ti.com> writes:
> >>
> >> [...]
> >>
> >> >> I tried your branch on gp/emu devices but could not reproduce this issue.
> >> >> My observation is that while resuming, omap_hsmmc.1 eMMC is
> >> >> trying to turn on phoenix vaux1 regulator via i2c which fails due
> >> >> to controller timeout.
> >> >> Note: eMMC is present only on sdp/blaze
> >> >
> >> > Did you try this with off-mode enabled and did you check the device
> >> > actually goes to off? (see pm_debug/count and verify core off count is
> >> > increasing.) And as said, I was only able to see this problem on a blaze
> >> > device, panda works fine. But yes, you are probably right and it is not
> >> > an MMC driver issue but I2C.
> >>
> >> Can you try the patch below?  It sounds like the same problem.
> >
> > Doesn't help with this one. I guess I2C loses context during device off
> > and it is not restored properly.
> >
> > -Tero
> Could you try the following patch
> 
> https://lkml.org/lkml/2012/3/30/345

That does the trick, after this it is working fine on blaze, and this
also fixes the timeout issues seen on panda board (meaning wake-up from
device off is much faster.)

-Tero

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

* Re: [PATCH 00/19] ARM: OMAP4 device off support
  2012-04-20 15:07             ` Tero Kristo
@ 2012-04-23  6:28               ` Shubhrajyoti Datta
  -1 siblings, 0 replies; 126+ messages in thread
From: Shubhrajyoti Datta @ 2012-04-23  6:28 UTC (permalink / raw)
  To: shubhrajyoti
  Cc: Kevin Hilman, T Krishnamoorthy, Balaji, linux-omap, paul,
	linux-arm-kernel

On Fri, Apr 20, 2012 at 8:37 PM, Tero Kristo <t-kristo@ti.com> wrote:
> On Fri, 2012-04-20 at 20:21 +0530, Datta, Shubhrajyoti wrote:
>> On Fri, Apr 20, 2012 at 8:13 PM, Tero Kristo <t-kristo@ti.com> wrote:
>> > On Fri, 2012-04-20 at 06:55 -0700, Kevin Hilman wrote:
>> >> Tero Kristo <t-kristo@ti.com> writes:
>> >>
>> >> [...]
>> >>
>> >> >> I tried your branch on gp/emu devices but could not reproduce this issue.
>> >> >> My observation is that while resuming, omap_hsmmc.1 eMMC is
>> >> >> trying to turn on phoenix vaux1 regulator via i2c which fails due
>> >> >> to controller timeout.
>> >> >> Note: eMMC is present only on sdp/blaze
>> >> >
>> >> > Did you try this with off-mode enabled and did you check the device
>> >> > actually goes to off? (see pm_debug/count and verify core off count is
>> >> > increasing.) And as said, I was only able to see this problem on a blaze
>> >> > device, panda works fine. But yes, you are probably right and it is not
>> >> > an MMC driver issue but I2C.
>> >>
>> >> Can you try the patch below?  It sounds like the same problem.
>> >
>> > Doesn't help with this one. I guess I2C loses context during device off
>> > and it is not restored properly.
>> >
>> > -Tero
>> Could you try the following patch
>>
>> https://lkml.org/lkml/2012/3/30/345
>
> That does the trick, after this it is working fine on blaze, and this
> also fixes the timeout issues seen on panda board (meaning wake-up from
> device off is much faster.)

Thats great.
Feel free to try the following.
I2C conditional restore"
http://www.mail-archive.com/linux-omap@vger.kernel.org/msg66859.html

Also cooked a below rfc/untested patch for mmc restore.



From c28ec76f8a20c3ce59b72245ab9f3bc293b1ac43 Mon Sep 17 00:00:00 2001
From: Shubhrajyoti D <shubhrajyoti@ti.com>
Date: Mon, 23 Apr 2012 11:52:54 +0530
Subject: [RFC PATCH] hsmmc: omap: Support for device off

Attempt to have device off support. Current the function hsmmc_get_context_loss
is made NULL for OMAP4. Remove it as post Terro's patches context may be lost.
Also it is good to have no assumptions of the context loss in the
driver.

Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
---
 arch/arm/mach-omap2/hsmmc.c |    6 ------
 1 files changed, 0 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index b0268ea..2361f24 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -32,17 +32,11 @@ static u16 control_mmc1;

 #define HSMMC_NAME_LEN 9

-#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
-
 static int hsmmc_get_context_loss(struct device *dev)
 {
        return omap_pm_get_dev_context_loss_count(dev);
 }

-#else
-#define hsmmc_get_context_loss NULL
-#endif
-
 static void omap_hsmmc1_before_set_reg(struct device *dev, int slot,
                                  int power_on, int vdd)
 {
--
1.7.0.4
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 00/19] ARM: OMAP4 device off support
@ 2012-04-23  6:28               ` Shubhrajyoti Datta
  0 siblings, 0 replies; 126+ messages in thread
From: Shubhrajyoti Datta @ 2012-04-23  6:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Apr 20, 2012 at 8:37 PM, Tero Kristo <t-kristo@ti.com> wrote:
> On Fri, 2012-04-20 at 20:21 +0530, Datta, Shubhrajyoti wrote:
>> On Fri, Apr 20, 2012 at 8:13 PM, Tero Kristo <t-kristo@ti.com> wrote:
>> > On Fri, 2012-04-20 at 06:55 -0700, Kevin Hilman wrote:
>> >> Tero Kristo <t-kristo@ti.com> writes:
>> >>
>> >> [...]
>> >>
>> >> >> I tried your branch on gp/emu devices but could not reproduce this issue.
>> >> >> My observation is that while resuming, omap_hsmmc.1 eMMC is
>> >> >> trying to turn on phoenix vaux1 regulator via i2c which fails due
>> >> >> to controller timeout.
>> >> >> Note: eMMC is present only on sdp/blaze
>> >> >
>> >> > Did you try this with off-mode enabled and did you check the device
>> >> > actually goes to off? (see pm_debug/count and verify core off count is
>> >> > increasing.) And as said, I was only able to see this problem on a blaze
>> >> > device, panda works fine. But yes, you are probably right and it is not
>> >> > an MMC driver issue but I2C.
>> >>
>> >> Can you try the patch below? ?It sounds like the same problem.
>> >
>> > Doesn't help with this one. I guess I2C loses context during device off
>> > and it is not restored properly.
>> >
>> > -Tero
>> Could you try the following patch
>>
>> https://lkml.org/lkml/2012/3/30/345
>
> That does the trick, after this it is working fine on blaze, and this
> also fixes the timeout issues seen on panda board (meaning wake-up from
> device off is much faster.)

Thats great.
Feel free to try the following.
I2C conditional restore"
http://www.mail-archive.com/linux-omap at vger.kernel.org/msg66859.html

Also cooked a below rfc/untested patch for mmc restore.



>From c28ec76f8a20c3ce59b72245ab9f3bc293b1ac43 Mon Sep 17 00:00:00 2001
From: Shubhrajyoti D <shubhrajyoti@ti.com>
Date: Mon, 23 Apr 2012 11:52:54 +0530
Subject: [RFC PATCH] hsmmc: omap: Support for device off

Attempt to have device off support. Current the function hsmmc_get_context_loss
is made NULL for OMAP4. Remove it as post Terro's patches context may be lost.
Also it is good to have no assumptions of the context loss in the
driver.

Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
---
 arch/arm/mach-omap2/hsmmc.c |    6 ------
 1 files changed, 0 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index b0268ea..2361f24 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -32,17 +32,11 @@ static u16 control_mmc1;

 #define HSMMC_NAME_LEN 9

-#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
-
 static int hsmmc_get_context_loss(struct device *dev)
 {
        return omap_pm_get_dev_context_loss_count(dev);
 }

-#else
-#define hsmmc_get_context_loss NULL
-#endif
-
 static void omap_hsmmc1_before_set_reg(struct device *dev, int slot,
                                  int power_on, int vdd)
 {
--
1.7.0.4

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

* Re: [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
  2012-04-20  9:33   ` Tero Kristo
@ 2012-04-23 16:09     ` Jon Hunter
  -1 siblings, 0 replies; 126+ messages in thread
From: Jon Hunter @ 2012-04-23 16:09 UTC (permalink / raw)
  To: Tero Kristo
  Cc: linux-omap, khilman, paul, Nishanth Menon, Rajendra Nayak,
	Santosh Shilimkar, linux-arm-kernel

Hi Tero,

On 04/20/2012 04:33 AM, Tero Kristo wrote:

[...]

> +/**
> + * omap4_dpll_print_reg - dump out a single DPLL register value
> + * @dpll_reg: register to dump
> + * @name: name of the register
> + * @tuple: content of the register
> + *
> + * Helper dump function to print out a DPLL register value in case
> + * of restore failures.
> + */
> +static void omap4_dpll_print_reg(struct omap4_dpll_regs *dpll_reg, char *name,
> +				 struct dpll_reg *tuple)
> +{
> +	if (tuple->offset)
> +		pr_warn("%s - Address offset = 0x%08x, value=0x%08x\n", name,
> +			tuple->offset, tuple->val);

Minor nit-pick here ...

1. Offset is 16-bits and so we can just have "offset = 0x%04x"
2. Consider dropping "Address" from "Address offset"
3. Can we be consistent in our spaces for "offset = " and "value="?

> +}
> +
> +/*
> + * omap4_dpll_dump_regs - dump out DPLL registers
> + * @dpll_reg: DPLL to dump
> + *
> + * Dump out the contents of the registers for a DPLL. Called if a
> + * restore for DPLL fails to lock.
> + */
> +static void omap4_dpll_dump_regs(struct omap4_dpll_regs *dpll_reg)
> +{
> +	pr_warn("%s: Unable to lock dpll %s[part=%x inst=%x]:\n",
> +		__func__, dpll_reg->name, dpll_reg->mod_partition,
> +		dpll_reg->mod_inst);
> +	omap4_dpll_print_reg(dpll_reg, "clksel", &dpll_reg->clksel);
> +	omap4_dpll_print_reg(dpll_reg, "div_m2", &dpll_reg->div_m2);
> +	omap4_dpll_print_reg(dpll_reg, "div_m3", &dpll_reg->div_m3);
> +	omap4_dpll_print_reg(dpll_reg, "div_m4", &dpll_reg->div_m4);
> +	omap4_dpll_print_reg(dpll_reg, "div_m5", &dpll_reg->div_m5);
> +	omap4_dpll_print_reg(dpll_reg, "div_m6", &dpll_reg->div_m6);
> +	omap4_dpll_print_reg(dpll_reg, "div_m7", &dpll_reg->div_m7);
> +	omap4_dpll_print_reg(dpll_reg, "clkdcoldo", &dpll_reg->clkdcoldo);
> +	omap4_dpll_print_reg(dpll_reg, "clkmode", &dpll_reg->clkmode);
> +	omap4_dpll_print_reg(dpll_reg, "autoidle", &dpll_reg->autoidle);
> +	if (dpll_reg->idlest.offset)
> +		pr_warn("idlest - Address offset = 0x%08x, before val=0x%08x"
> +			" after = 0x%08x\n", dpll_reg->idlest.offset,
> +			dpll_reg->idlest.val,
> +			omap4_dpll_read_reg(dpll_reg, &dpll_reg->idlest));

Nit-pick ...

1. Same comments as above
2. Consider dropping "Address offset" altogether here as we print
"idlest" the offset should be implied.
3. Also can we be consistent in our naming of "before val and "after"?
For example, "val before =" and "val now = ".

Cheers
Jon

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

* [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
@ 2012-04-23 16:09     ` Jon Hunter
  0 siblings, 0 replies; 126+ messages in thread
From: Jon Hunter @ 2012-04-23 16:09 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tero,

On 04/20/2012 04:33 AM, Tero Kristo wrote:

[...]

> +/**
> + * omap4_dpll_print_reg - dump out a single DPLL register value
> + * @dpll_reg: register to dump
> + * @name: name of the register
> + * @tuple: content of the register
> + *
> + * Helper dump function to print out a DPLL register value in case
> + * of restore failures.
> + */
> +static void omap4_dpll_print_reg(struct omap4_dpll_regs *dpll_reg, char *name,
> +				 struct dpll_reg *tuple)
> +{
> +	if (tuple->offset)
> +		pr_warn("%s - Address offset = 0x%08x, value=0x%08x\n", name,
> +			tuple->offset, tuple->val);

Minor nit-pick here ...

1. Offset is 16-bits and so we can just have "offset = 0x%04x"
2. Consider dropping "Address" from "Address offset"
3. Can we be consistent in our spaces for "offset = " and "value="?

> +}
> +
> +/*
> + * omap4_dpll_dump_regs - dump out DPLL registers
> + * @dpll_reg: DPLL to dump
> + *
> + * Dump out the contents of the registers for a DPLL. Called if a
> + * restore for DPLL fails to lock.
> + */
> +static void omap4_dpll_dump_regs(struct omap4_dpll_regs *dpll_reg)
> +{
> +	pr_warn("%s: Unable to lock dpll %s[part=%x inst=%x]:\n",
> +		__func__, dpll_reg->name, dpll_reg->mod_partition,
> +		dpll_reg->mod_inst);
> +	omap4_dpll_print_reg(dpll_reg, "clksel", &dpll_reg->clksel);
> +	omap4_dpll_print_reg(dpll_reg, "div_m2", &dpll_reg->div_m2);
> +	omap4_dpll_print_reg(dpll_reg, "div_m3", &dpll_reg->div_m3);
> +	omap4_dpll_print_reg(dpll_reg, "div_m4", &dpll_reg->div_m4);
> +	omap4_dpll_print_reg(dpll_reg, "div_m5", &dpll_reg->div_m5);
> +	omap4_dpll_print_reg(dpll_reg, "div_m6", &dpll_reg->div_m6);
> +	omap4_dpll_print_reg(dpll_reg, "div_m7", &dpll_reg->div_m7);
> +	omap4_dpll_print_reg(dpll_reg, "clkdcoldo", &dpll_reg->clkdcoldo);
> +	omap4_dpll_print_reg(dpll_reg, "clkmode", &dpll_reg->clkmode);
> +	omap4_dpll_print_reg(dpll_reg, "autoidle", &dpll_reg->autoidle);
> +	if (dpll_reg->idlest.offset)
> +		pr_warn("idlest - Address offset = 0x%08x, before val=0x%08x"
> +			" after = 0x%08x\n", dpll_reg->idlest.offset,
> +			dpll_reg->idlest.val,
> +			omap4_dpll_read_reg(dpll_reg, &dpll_reg->idlest));

Nit-pick ...

1. Same comments as above
2. Consider dropping "Address offset" altogether here as we print
"idlest" the offset should be implied.
3. Also can we be consistent in our naming of "before val and "after"?
For example, "val before =" and "val now = ".

Cheers
Jon

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

* Re: [PATCH 05/19] ARM: OMAP4: PM: Add SAR backup support towards device OFF
  2012-04-20  9:33   ` Tero Kristo
@ 2012-04-24 16:35     ` Tony Lindgren
  -1 siblings, 0 replies; 126+ messages in thread
From: Tony Lindgren @ 2012-04-24 16:35 UTC (permalink / raw)
  To: Tero Kristo
  Cc: linux-omap, khilman, paul, linux-arm-kernel, Santosh Shilimkar

* Tero Kristo <t-kristo@ti.com> [120420 02:39]:
> +
> +static int omap4_sar_not_accessible(void)
> +{
> +	u32 usbhost_state, usbtll_state;
> +
> +	/*
> +	 * Make sure that USB host and TLL modules are not
> +	 * enabled before attempting to save the context
> +	 * registers, otherwise this will trigger an exception.
> +	 */
> +	usbhost_state = omap4_cminst_read_inst_reg(OMAP4430_CM2_PARTITION,
> +						   OMAP4430_CM2_L3INIT_INST,
> +						   OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET)
> +	    & (OMAP4430_STBYST_MASK | OMAP4430_IDLEST_MASK);
> +
> +	usbtll_state = omap4_cminst_read_inst_reg(OMAP4430_CM2_PARTITION,
> +						  OMAP4430_CM2_L3INIT_INST,
> +						  OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET)
> +	    & OMAP4430_IDLEST_MASK;

Formatting here looks bad, maybe just do it in separate steps:

	usbhost_state = omap4_cminst...
	usbhost_state &= OMAP4430_STBYST_MASK | OMAP4430_IDLEST_MASK;
...


> +	/*
> +	 * Not supported on ES1.0 silicon
> +	 */
> +	if (omap_rev() == OMAP4430_REV_ES1_0) {
> +		WARN_ONCE(1, "omap4: SAR backup not supported on ES1.0 ..\n");
> +		return -ENODEV;
> +	}

Everytime there's SoC/hardware revision detection in a non __init function, 
something is most likely wrong.


> +void omap4_sar_overwrite(void)
> +{
> +	u32 val = 0;
> +	u32 offset = 0;
> +
> +	if (cpu_is_omap446x())
> +		offset = 0x04;

Here too.


> +static int __init omap4_sar_ram_init(void)
> +{
> +	/*
> +	 * To avoid code running on other OMAPs in
> +	 * multi-omap builds
> +	 */
> +	if (!cpu_is_omap44xx())
> +		return -ENODEV;

You should configure things here instead by setting function
pointers or variables.

Regards,

Tony

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

* [PATCH 05/19] ARM: OMAP4: PM: Add SAR backup support towards device OFF
@ 2012-04-24 16:35     ` Tony Lindgren
  0 siblings, 0 replies; 126+ messages in thread
From: Tony Lindgren @ 2012-04-24 16:35 UTC (permalink / raw)
  To: linux-arm-kernel

* Tero Kristo <t-kristo@ti.com> [120420 02:39]:
> +
> +static int omap4_sar_not_accessible(void)
> +{
> +	u32 usbhost_state, usbtll_state;
> +
> +	/*
> +	 * Make sure that USB host and TLL modules are not
> +	 * enabled before attempting to save the context
> +	 * registers, otherwise this will trigger an exception.
> +	 */
> +	usbhost_state = omap4_cminst_read_inst_reg(OMAP4430_CM2_PARTITION,
> +						   OMAP4430_CM2_L3INIT_INST,
> +						   OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET)
> +	    & (OMAP4430_STBYST_MASK | OMAP4430_IDLEST_MASK);
> +
> +	usbtll_state = omap4_cminst_read_inst_reg(OMAP4430_CM2_PARTITION,
> +						  OMAP4430_CM2_L3INIT_INST,
> +						  OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET)
> +	    & OMAP4430_IDLEST_MASK;

Formatting here looks bad, maybe just do it in separate steps:

	usbhost_state = omap4_cminst...
	usbhost_state &= OMAP4430_STBYST_MASK | OMAP4430_IDLEST_MASK;
...


> +	/*
> +	 * Not supported on ES1.0 silicon
> +	 */
> +	if (omap_rev() == OMAP4430_REV_ES1_0) {
> +		WARN_ONCE(1, "omap4: SAR backup not supported on ES1.0 ..\n");
> +		return -ENODEV;
> +	}

Everytime there's SoC/hardware revision detection in a non __init function, 
something is most likely wrong.


> +void omap4_sar_overwrite(void)
> +{
> +	u32 val = 0;
> +	u32 offset = 0;
> +
> +	if (cpu_is_omap446x())
> +		offset = 0x04;

Here too.


> +static int __init omap4_sar_ram_init(void)
> +{
> +	/*
> +	 * To avoid code running on other OMAPs in
> +	 * multi-omap builds
> +	 */
> +	if (!cpu_is_omap44xx())
> +		return -ENODEV;

You should configure things here instead by setting function
pointers or variables.

Regards,

Tony

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

* Re: [PATCH 06/19] ARM: OMAP4: Auto generate SAR layout contents
  2012-04-20  9:33   ` Tero Kristo
@ 2012-04-24 16:37     ` Tony Lindgren
  -1 siblings, 0 replies; 126+ messages in thread
From: Tony Lindgren @ 2012-04-24 16:37 UTC (permalink / raw)
  To: Tero Kristo; +Cc: linux-omap, khilman, paul, linux-arm-kernel

* Tero Kristo <t-kristo@ti.com> [120420 02:38]:
> -void omap4_sar_overwrite(void)
> +void omap_sar_overwrite(void)
>  {
>  	u32 val = 0;
> -	u32 offset = 0;
> +	u32 usb_offset = 0x2ec;
> +	u32 usb_offset2 = 0x91c;
>  
> -	if (cpu_is_omap446x())
> -		offset = 0x04;
> +	if (cpu_is_omap446x()) {
> +		usb_offset = 0x2f4;
> +		usb_offset2 = 0x920;
> +	}

Here too you should initialized these during __init. Otherwise
we'll end up piling more and more if else cpu_is_omapxxxx for
future omaps that again might change the offsets.

Tony

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

* [PATCH 06/19] ARM: OMAP4: Auto generate SAR layout contents
@ 2012-04-24 16:37     ` Tony Lindgren
  0 siblings, 0 replies; 126+ messages in thread
From: Tony Lindgren @ 2012-04-24 16:37 UTC (permalink / raw)
  To: linux-arm-kernel

* Tero Kristo <t-kristo@ti.com> [120420 02:38]:
> -void omap4_sar_overwrite(void)
> +void omap_sar_overwrite(void)
>  {
>  	u32 val = 0;
> -	u32 offset = 0;
> +	u32 usb_offset = 0x2ec;
> +	u32 usb_offset2 = 0x91c;
>  
> -	if (cpu_is_omap446x())
> -		offset = 0x04;
> +	if (cpu_is_omap446x()) {
> +		usb_offset = 0x2f4;
> +		usb_offset2 = 0x920;
> +	}

Here too you should initialized these during __init. Otherwise
we'll end up piling more and more if else cpu_is_omapxxxx for
future omaps that again might change the offsets.

Tony

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

* Re: [PATCH 12/19] ARM: OMAP4: PM: update ROM return address for OSWR and OFF
  2012-04-20  9:33   ` Tero Kristo
@ 2012-04-24 16:39     ` Tony Lindgren
  -1 siblings, 0 replies; 126+ messages in thread
From: Tony Lindgren @ 2012-04-24 16:39 UTC (permalink / raw)
  To: Tero Kristo
  Cc: linux-omap, khilman, paul, linux-arm-kernel, Carlos Leija,
	Praneeth Bajjuri, Bryan Buckley

* Tero Kristo <t-kristo@ti.com> [120420 02:39]:
> @@ -384,6 +386,17 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
>  	set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON);
>  
>  	if (omap4_mpuss_read_prev_context_state()) {
> +		/*
> +		 * Dummy dispatcher call after OSWR and OFF
> +		 * Restore the right return Kernel address (with MMU on) for
> +		 * subsequent calls to secure ROM. Otherwise the return address
> +		 * will be to a PA return address and the system will hang.
> +		 */
> +		if (omap_type() != OMAP2_DEVICE_TYPE_GP)
> +			omap_secure_dispatcher(OMAP4_PPA_SERVICE_0,
> +					       FLAG_START_CRITICAL,
> +					       0, 0, 0, 0, 0);
> +
>  		restore_ivahd_tesla_regs();
>  		restore_l3instr_regs();

This SoC test here too should be only done once during init.

Tony

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

* [PATCH 12/19] ARM: OMAP4: PM: update ROM return address for OSWR and OFF
@ 2012-04-24 16:39     ` Tony Lindgren
  0 siblings, 0 replies; 126+ messages in thread
From: Tony Lindgren @ 2012-04-24 16:39 UTC (permalink / raw)
  To: linux-arm-kernel

* Tero Kristo <t-kristo@ti.com> [120420 02:39]:
> @@ -384,6 +386,17 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
>  	set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON);
>  
>  	if (omap4_mpuss_read_prev_context_state()) {
> +		/*
> +		 * Dummy dispatcher call after OSWR and OFF
> +		 * Restore the right return Kernel address (with MMU on) for
> +		 * subsequent calls to secure ROM. Otherwise the return address
> +		 * will be to a PA return address and the system will hang.
> +		 */
> +		if (omap_type() != OMAP2_DEVICE_TYPE_GP)
> +			omap_secure_dispatcher(OMAP4_PPA_SERVICE_0,
> +					       FLAG_START_CRITICAL,
> +					       0, 0, 0, 0, 0);
> +
>  		restore_ivahd_tesla_regs();
>  		restore_l3instr_regs();

This SoC test here too should be only done once during init.

Tony

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

* Re: [PATCH 08/19] ARM: OMAP4: PM: Add device-off support
  2012-04-20  9:33   ` Tero Kristo
@ 2012-04-24 17:46     ` Jon Hunter
  -1 siblings, 0 replies; 126+ messages in thread
From: Jon Hunter @ 2012-04-24 17:46 UTC (permalink / raw)
  To: Tero Kristo
  Cc: linux-omap, khilman, paul, Santosh Shilimkar, linux-arm-kernel

Hi Tero,

On 04/20/2012 04:33 AM, Tero Kristo wrote:
> This patch adds device off support to OMAP4 device type.
> 
> OFF mode is disabled by default, however, there are two ways to enable
> OFF mode:
> a) In the board file, call omap4_pm_off_mode_enable(1)
> b) Enable OFF mode using the debugfs entry
> echo "1">/sys/kernel/debug/pm_debug/enable_off_mode
> (conversely echo '0' will disable it as well).
> 
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> [t-kristo@ti.com: largely re-structured the code]
> Signed-off-by: Tero Kristo <t-kristo@ti.com>
> ---
>  arch/arm/mach-omap2/omap-mpuss-lowpower.c |   24 ++++++++++-
>  arch/arm/mach-omap2/omap-wakeupgen.c      |   47 +++++++++++++++++++-
>  arch/arm/mach-omap2/pm-debug.c            |   17 +++++--
>  arch/arm/mach-omap2/pm.h                  |   28 ++++++++++--
>  arch/arm/mach-omap2/pm44xx.c              |   45 +++++++++++++++++++
>  arch/arm/mach-omap2/prm44xx.c             |   66 +++++++++++++++++++++++++++++
>  6 files changed, 214 insertions(+), 13 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> index e02c082..b9a2cc7 100644
> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> @@ -60,6 +60,7 @@
>  #include "prcm44xx.h"
>  #include "prm44xx.h"
>  #include "prm-regbits-44xx.h"
> +#include "cm44xx.h"
>  
>  #ifdef CONFIG_SMP
>  
> @@ -232,6 +233,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
>  {
>  	unsigned int save_state = 0;
>  	unsigned int wakeup_cpu;
> +	int ret;
>  
>  	if (omap_rev() == OMAP4430_REV_ES1_0)
>  		return -ENXIO;
> @@ -263,9 +265,21 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
>  	 * In MPUSS OSWR or device OFF, interrupt controller  contest is lost.
>  	 */
>  	mpuss_clear_prev_logic_pwrst();
> -	if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) &&
> -		(pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF))
> +	if (omap4_device_next_state_off()) {
> +		/* Save the device context to SAR RAM */
> +		ret = omap_sar_save();
> +		if (ret)
> +			return ret;

Is it safe to simply return here? I was not sure if we need to call
pwrdm_post_transition, given that we have already called
pwrdm_pre_transition on entry.

Cheers
Jon

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

* [PATCH 08/19] ARM: OMAP4: PM: Add device-off support
@ 2012-04-24 17:46     ` Jon Hunter
  0 siblings, 0 replies; 126+ messages in thread
From: Jon Hunter @ 2012-04-24 17:46 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tero,

On 04/20/2012 04:33 AM, Tero Kristo wrote:
> This patch adds device off support to OMAP4 device type.
> 
> OFF mode is disabled by default, however, there are two ways to enable
> OFF mode:
> a) In the board file, call omap4_pm_off_mode_enable(1)
> b) Enable OFF mode using the debugfs entry
> echo "1">/sys/kernel/debug/pm_debug/enable_off_mode
> (conversely echo '0' will disable it as well).
> 
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> [t-kristo at ti.com: largely re-structured the code]
> Signed-off-by: Tero Kristo <t-kristo@ti.com>
> ---
>  arch/arm/mach-omap2/omap-mpuss-lowpower.c |   24 ++++++++++-
>  arch/arm/mach-omap2/omap-wakeupgen.c      |   47 +++++++++++++++++++-
>  arch/arm/mach-omap2/pm-debug.c            |   17 +++++--
>  arch/arm/mach-omap2/pm.h                  |   28 ++++++++++--
>  arch/arm/mach-omap2/pm44xx.c              |   45 +++++++++++++++++++
>  arch/arm/mach-omap2/prm44xx.c             |   66 +++++++++++++++++++++++++++++
>  6 files changed, 214 insertions(+), 13 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> index e02c082..b9a2cc7 100644
> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> @@ -60,6 +60,7 @@
>  #include "prcm44xx.h"
>  #include "prm44xx.h"
>  #include "prm-regbits-44xx.h"
> +#include "cm44xx.h"
>  
>  #ifdef CONFIG_SMP
>  
> @@ -232,6 +233,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
>  {
>  	unsigned int save_state = 0;
>  	unsigned int wakeup_cpu;
> +	int ret;
>  
>  	if (omap_rev() == OMAP4430_REV_ES1_0)
>  		return -ENXIO;
> @@ -263,9 +265,21 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
>  	 * In MPUSS OSWR or device OFF, interrupt controller  contest is lost.
>  	 */
>  	mpuss_clear_prev_logic_pwrst();
> -	if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) &&
> -		(pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF))
> +	if (omap4_device_next_state_off()) {
> +		/* Save the device context to SAR RAM */
> +		ret = omap_sar_save();
> +		if (ret)
> +			return ret;

Is it safe to simply return here? I was not sure if we need to call
pwrdm_post_transition, given that we have already called
pwrdm_pre_transition on entry.

Cheers
Jon

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

* Re: [PATCH 10/19] ARM: OMAP4: PM: Work-around for ROM code BUG of IVAHD/TESLA
  2012-04-20  9:33   ` Tero Kristo
@ 2012-04-24 17:50     ` Jon Hunter
  -1 siblings, 0 replies; 126+ messages in thread
From: Jon Hunter @ 2012-04-24 17:50 UTC (permalink / raw)
  To: Tero Kristo
  Cc: linux-omap, khilman, paul, Rajendra Nayak, Santosh Shilimkar,
	linux-arm-kernel

Hi Tero,

On 04/20/2012 04:33 AM, Tero Kristo wrote:
> From: Santosh Shilimkar <santosh.shilimkar@ti.com>
> 
> The ROM BUG is when MPU Domain OFF wake up sequence that can compromise
> IVA and Tesla execution.
> 
> At wakeup from MPU OFF on HS device only (not GP device), when
> restoring the Secure RAM, the ROM Code reconfigures the clocks the
> same way it is done at Cold Reset.
> The IVAHD Clocks and Power Domain settings are:
> 	IVAHD_CM2 IVAHD_CLKCTRL_MODULE_MODE = DISABLE
> 	IVAHD_CM2 SL2_CLKCTRL_MODULE_MODE = DISABLE
> 	IVAHD_CM2 SL2_CLKSTCTRL_CLKTRCTRL = HW_AUTO
> 	IVAHD_PRM IVAHD_PWRSTCTRL_POWERSTATE = OFF
> The TESLA Clocks and Power Domain settings are:
> 	TESLA_CM1 TESLA_CLKCTRL_MODULE_MODE = DISABLE
> 	TESLA_CM1 TESLA_CLKSTCTRL_CLKTRCTRL = HW_AUTO
> 	TESLA_PRM TESLA_PWRSTCTRL_POWERSTATE = OFF
> 
> This patch fixes the low power OFF mode code so that the these
> registers are saved and restore across MPU OFF state.
> 
> Also because of this limitation, MPU OFF alone is not targeted without
> device OFF to avoid IVAHD and TESLA execution impact

You may wish to state which devices is impacted by this in the changelog.

> Signed-off-by: Rajendra Nayak <rnayak@ti.com>
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> [t-kristo@ti.com: added omap4 pm errata support]
> Signed-off-by: Tero Kristo <t-kristo@ti.com>
> ---
>  arch/arm/mach-omap2/omap-mpuss-lowpower.c |   53 +++++++++++++++++++++++++++++
>  arch/arm/mach-omap2/pm.h                  |    2 +
>  arch/arm/mach-omap2/pm44xx.c              |    9 +++++
>  3 files changed, 64 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> index b9a2cc7..208d4a4 100644
> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> @@ -52,6 +52,7 @@
>  
>  #include <plat/omap44xx.h>
>  
> +#include "iomap.h"
>  #include "common.h"
>  #include "omap4-sar-layout.h"
>  #include "pm.h"
> @@ -76,6 +77,24 @@ static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
>  static struct powerdomain *mpuss_pd;
>  static void __iomem *sar_base;
>  
> +struct reg_tuple {
> +	void __iomem *addr;
> +	u32 val;
> +};
> +
> +static struct reg_tuple tesla_reg[] = {
> +	{.addr = OMAP4430_CM_TESLA_CLKSTCTRL},
> +	{.addr = OMAP4430_CM_TESLA_TESLA_CLKCTRL},
> +	{.addr = OMAP4430_PM_TESLA_PWRSTCTRL},
> +};
> +
> +static struct reg_tuple ivahd_reg[] = {
> +	{.addr = OMAP4430_CM_IVAHD_CLKSTCTRL},
> +	{.addr = OMAP4430_CM_IVAHD_IVAHD_CLKCTRL},
> +	{.addr = OMAP4430_CM_IVAHD_SL2_CLKCTRL},
> +	{.addr = OMAP4430_PM_IVAHD_PWRSTCTRL}
> +};
> +
>  /*
>   * Program the wakeup routine address for the CPU0 and CPU1
>   * used for OFF or DORMANT wakeup.
> @@ -215,6 +234,34 @@ static void save_l2x0_context(void)
>  {}
>  #endif
>  
> +static inline void save_ivahd_tesla_regs(void)
> +{
> +	int i;
> +
> +	if (!IS_PM44XX_ERRATUM(PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM))
> +		return;
> +
> +	for (i = 0; i < ARRAY_SIZE(tesla_reg); i++)
> +		tesla_reg[i].val = __raw_readl(tesla_reg[i].addr);
> +
> +	for (i = 0; i < ARRAY_SIZE(ivahd_reg); i++)
> +		ivahd_reg[i].val = __raw_readl(ivahd_reg[i].addr);
> +}
> +
> +static inline void restore_ivahd_tesla_regs(void)
> +{
> +	int i;
> +
> +	if (!IS_PM44XX_ERRATUM(PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM))
> +		return;
> +
> +	for (i = 0; i < ARRAY_SIZE(tesla_reg); i++)
> +		__raw_writel(tesla_reg[i].val, tesla_reg[i].addr);
> +
> +	for (i = 0; i < ARRAY_SIZE(ivahd_reg); i++)
> +		__raw_writel(ivahd_reg[i].val, ivahd_reg[i].addr);
> +}
> +
>  /**
>   * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function
>   * The purpose of this function is to manage low power programming
> @@ -273,11 +320,14 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
>  		omap_sar_overwrite();
>  		omap4_cm_prepare_off();
>  		omap4_dpll_prepare_off();
> +		save_ivahd_tesla_regs();
>  		save_state = 3;
>  	} else if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) &&
>  		(pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF)) {
> +		save_ivahd_tesla_regs();
>  		save_state = 2;
>  	} else if (pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_OFF) {
> +		save_ivahd_tesla_regs();
>  		save_state = 3;
>  	}
>  
> @@ -302,6 +352,9 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
>  	wakeup_cpu = smp_processor_id();
>  	set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON);
>  
> +	if (omap4_mpuss_read_prev_context_state())
> +		restore_ivahd_tesla_regs();
> +
>  	if (omap4_device_prev_state_off()) {
>  		omap4_dpll_resume_off();
>  		omap4_cm_resume_off();
> diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
> index e78ec63..051aeb9 100644
> --- a/arch/arm/mach-omap2/pm.h
> +++ b/arch/arm/mach-omap2/pm.h
> @@ -131,6 +131,8 @@ extern void enable_omap3630_toggle_l2_on_restore(void);
>  static inline void enable_omap3630_toggle_l2_on_restore(void) { }
>  #endif		/* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */
>  
> +#define PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM	(1 << 0)
> +
>  #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
>  extern u16 pm44xx_errata;
>  #define IS_PM44XX_ERRATUM(id)		(pm44xx_errata & (id))
> diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
> index 8238097..67cb799 100644
> --- a/arch/arm/mach-omap2/pm44xx.c
> +++ b/arch/arm/mach-omap2/pm44xx.c
> @@ -263,6 +263,15 @@ static int __init omap4_pm_init(void)
>  
>  	(void) clkdm_for_each(omap_pm_clkdms_setup, NULL);
>  
> +	/*
> +	 * ROM code initializes IVAHD and TESLA clock registers during
> +	 * secure RAM restore phase on omap4430 EMU/HS devices, thus
> +	 * IVAHD / TESLA clock registers must be saved / restored
> +	 * during MPU OSWR / device off.
> +	 */
> +	if (cpu_is_omap443x() && omap_type() != OMAP2_DEVICE_TYPE_GP)
> +		pm44xx_errata |= PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM;

This erratum does not impact omap4430 es2.3 so the above should account
for that.

Cheers
Jon

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

* [PATCH 10/19] ARM: OMAP4: PM: Work-around for ROM code BUG of IVAHD/TESLA
@ 2012-04-24 17:50     ` Jon Hunter
  0 siblings, 0 replies; 126+ messages in thread
From: Jon Hunter @ 2012-04-24 17:50 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tero,

On 04/20/2012 04:33 AM, Tero Kristo wrote:
> From: Santosh Shilimkar <santosh.shilimkar@ti.com>
> 
> The ROM BUG is when MPU Domain OFF wake up sequence that can compromise
> IVA and Tesla execution.
> 
> At wakeup from MPU OFF on HS device only (not GP device), when
> restoring the Secure RAM, the ROM Code reconfigures the clocks the
> same way it is done at Cold Reset.
> The IVAHD Clocks and Power Domain settings are:
> 	IVAHD_CM2 IVAHD_CLKCTRL_MODULE_MODE = DISABLE
> 	IVAHD_CM2 SL2_CLKCTRL_MODULE_MODE = DISABLE
> 	IVAHD_CM2 SL2_CLKSTCTRL_CLKTRCTRL = HW_AUTO
> 	IVAHD_PRM IVAHD_PWRSTCTRL_POWERSTATE = OFF
> The TESLA Clocks and Power Domain settings are:
> 	TESLA_CM1 TESLA_CLKCTRL_MODULE_MODE = DISABLE
> 	TESLA_CM1 TESLA_CLKSTCTRL_CLKTRCTRL = HW_AUTO
> 	TESLA_PRM TESLA_PWRSTCTRL_POWERSTATE = OFF
> 
> This patch fixes the low power OFF mode code so that the these
> registers are saved and restore across MPU OFF state.
> 
> Also because of this limitation, MPU OFF alone is not targeted without
> device OFF to avoid IVAHD and TESLA execution impact

You may wish to state which devices is impacted by this in the changelog.

> Signed-off-by: Rajendra Nayak <rnayak@ti.com>
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> [t-kristo at ti.com: added omap4 pm errata support]
> Signed-off-by: Tero Kristo <t-kristo@ti.com>
> ---
>  arch/arm/mach-omap2/omap-mpuss-lowpower.c |   53 +++++++++++++++++++++++++++++
>  arch/arm/mach-omap2/pm.h                  |    2 +
>  arch/arm/mach-omap2/pm44xx.c              |    9 +++++
>  3 files changed, 64 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> index b9a2cc7..208d4a4 100644
> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> @@ -52,6 +52,7 @@
>  
>  #include <plat/omap44xx.h>
>  
> +#include "iomap.h"
>  #include "common.h"
>  #include "omap4-sar-layout.h"
>  #include "pm.h"
> @@ -76,6 +77,24 @@ static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
>  static struct powerdomain *mpuss_pd;
>  static void __iomem *sar_base;
>  
> +struct reg_tuple {
> +	void __iomem *addr;
> +	u32 val;
> +};
> +
> +static struct reg_tuple tesla_reg[] = {
> +	{.addr = OMAP4430_CM_TESLA_CLKSTCTRL},
> +	{.addr = OMAP4430_CM_TESLA_TESLA_CLKCTRL},
> +	{.addr = OMAP4430_PM_TESLA_PWRSTCTRL},
> +};
> +
> +static struct reg_tuple ivahd_reg[] = {
> +	{.addr = OMAP4430_CM_IVAHD_CLKSTCTRL},
> +	{.addr = OMAP4430_CM_IVAHD_IVAHD_CLKCTRL},
> +	{.addr = OMAP4430_CM_IVAHD_SL2_CLKCTRL},
> +	{.addr = OMAP4430_PM_IVAHD_PWRSTCTRL}
> +};
> +
>  /*
>   * Program the wakeup routine address for the CPU0 and CPU1
>   * used for OFF or DORMANT wakeup.
> @@ -215,6 +234,34 @@ static void save_l2x0_context(void)
>  {}
>  #endif
>  
> +static inline void save_ivahd_tesla_regs(void)
> +{
> +	int i;
> +
> +	if (!IS_PM44XX_ERRATUM(PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM))
> +		return;
> +
> +	for (i = 0; i < ARRAY_SIZE(tesla_reg); i++)
> +		tesla_reg[i].val = __raw_readl(tesla_reg[i].addr);
> +
> +	for (i = 0; i < ARRAY_SIZE(ivahd_reg); i++)
> +		ivahd_reg[i].val = __raw_readl(ivahd_reg[i].addr);
> +}
> +
> +static inline void restore_ivahd_tesla_regs(void)
> +{
> +	int i;
> +
> +	if (!IS_PM44XX_ERRATUM(PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM))
> +		return;
> +
> +	for (i = 0; i < ARRAY_SIZE(tesla_reg); i++)
> +		__raw_writel(tesla_reg[i].val, tesla_reg[i].addr);
> +
> +	for (i = 0; i < ARRAY_SIZE(ivahd_reg); i++)
> +		__raw_writel(ivahd_reg[i].val, ivahd_reg[i].addr);
> +}
> +
>  /**
>   * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function
>   * The purpose of this function is to manage low power programming
> @@ -273,11 +320,14 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
>  		omap_sar_overwrite();
>  		omap4_cm_prepare_off();
>  		omap4_dpll_prepare_off();
> +		save_ivahd_tesla_regs();
>  		save_state = 3;
>  	} else if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) &&
>  		(pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF)) {
> +		save_ivahd_tesla_regs();
>  		save_state = 2;
>  	} else if (pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_OFF) {
> +		save_ivahd_tesla_regs();
>  		save_state = 3;
>  	}
>  
> @@ -302,6 +352,9 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
>  	wakeup_cpu = smp_processor_id();
>  	set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON);
>  
> +	if (omap4_mpuss_read_prev_context_state())
> +		restore_ivahd_tesla_regs();
> +
>  	if (omap4_device_prev_state_off()) {
>  		omap4_dpll_resume_off();
>  		omap4_cm_resume_off();
> diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
> index e78ec63..051aeb9 100644
> --- a/arch/arm/mach-omap2/pm.h
> +++ b/arch/arm/mach-omap2/pm.h
> @@ -131,6 +131,8 @@ extern void enable_omap3630_toggle_l2_on_restore(void);
>  static inline void enable_omap3630_toggle_l2_on_restore(void) { }
>  #endif		/* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */
>  
> +#define PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM	(1 << 0)
> +
>  #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
>  extern u16 pm44xx_errata;
>  #define IS_PM44XX_ERRATUM(id)		(pm44xx_errata & (id))
> diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
> index 8238097..67cb799 100644
> --- a/arch/arm/mach-omap2/pm44xx.c
> +++ b/arch/arm/mach-omap2/pm44xx.c
> @@ -263,6 +263,15 @@ static int __init omap4_pm_init(void)
>  
>  	(void) clkdm_for_each(omap_pm_clkdms_setup, NULL);
>  
> +	/*
> +	 * ROM code initializes IVAHD and TESLA clock registers during
> +	 * secure RAM restore phase on omap4430 EMU/HS devices, thus
> +	 * IVAHD / TESLA clock registers must be saved / restored
> +	 * during MPU OSWR / device off.
> +	 */
> +	if (cpu_is_omap443x() && omap_type() != OMAP2_DEVICE_TYPE_GP)
> +		pm44xx_errata |= PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM;

This erratum does not impact omap4430 es2.3 so the above should account
for that.

Cheers
Jon

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

* Re: [PATCH 11/19] ARM: OMAP4: PM: save/restore CM L3INSTR registers when MPU hits OSWR/OFF mode
  2012-04-20  9:33   ` Tero Kristo
@ 2012-04-24 17:57     ` Jon Hunter
  -1 siblings, 0 replies; 126+ messages in thread
From: Jon Hunter @ 2012-04-24 17:57 UTC (permalink / raw)
  To: Tero Kristo
  Cc: linux-omap, khilman, paul, Rajendra Nayak, Santosh Shilimkar,
	linux-arm-kernel

Hi Tero,

On 04/20/2012 04:33 AM, Tero Kristo wrote:
> From: Rajendra Nayak <rnayak@ti.com>
> 
> On HS devices on the way out of MPU OSWR and OFF ROM code wrongly
> overwrites the CM L3INSTR registers. So to avoid this, save them and
> restore on the way out from MPU OSWR/OFF.

This appears to be an errata. So, it would be good to state explicitly
here that all revisions of all omap4 devices are impacted by this
errata. The code implies this but for documentation purposes it would be
worth stating.

Cheers
Jon

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

* [PATCH 11/19] ARM: OMAP4: PM: save/restore CM L3INSTR registers when MPU hits OSWR/OFF mode
@ 2012-04-24 17:57     ` Jon Hunter
  0 siblings, 0 replies; 126+ messages in thread
From: Jon Hunter @ 2012-04-24 17:57 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tero,

On 04/20/2012 04:33 AM, Tero Kristo wrote:
> From: Rajendra Nayak <rnayak@ti.com>
> 
> On HS devices on the way out of MPU OSWR and OFF ROM code wrongly
> overwrites the CM L3INSTR registers. So to avoid this, save them and
> restore on the way out from MPU OSWR/OFF.

This appears to be an errata. So, it would be good to state explicitly
here that all revisions of all omap4 devices are impacted by this
errata. The code implies this but for documentation purposes it would be
worth stating.

Cheers
Jon

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

* Re: [PATCH 15/19] ARM: OMAP4430: PM: workaround for DDR corruption on second CS
  2012-04-20  9:33   ` Tero Kristo
@ 2012-04-24 18:22     ` Jon Hunter
  -1 siblings, 0 replies; 126+ messages in thread
From: Jon Hunter @ 2012-04-24 18:22 UTC (permalink / raw)
  To: Tero Kristo
  Cc: linux-omap, khilman, paul, Santosh Shilimkar, linux-arm-kernel

Hi Tero,

On 04/20/2012 04:33 AM, Tero Kristo wrote:
> From: Santosh Shilimkar <santosh.shilimkar@ti.com>
> 
> Work around for Errata ID: i632 "LPDDR2 Corruption After OFF Mode
> Transition When CS1 Is Used On EMIF" which impacts OMAP443x silicon
> The issue occurs when EMIF_SDRAM_CONFIG is restored first before
> EMIF_SDRAM_CONFIG_2 is not yet restored, the register configuration
> is not set properly, we apply the required workaround allowing
> the restore sequence to work properly.
> 
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> [t-kristo@ti.com: moved workaround from omap-sar.c to pm44xx.c]
> Signed-off-by: Tero Kristo <t-kristo@ti.com>
> ---
>  .../include/mach/ctrl_module_wkup_44xx.h           |    2 +
>  arch/arm/mach-omap2/pm44xx.c                       |   24 ++++++++++++++++++++
>  2 files changed, 26 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
> index a0af9ba..b763a79 100644
> --- a/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
> +++ b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
> @@ -28,6 +28,8 @@
>  #define OMAP4_CTRL_MODULE_WKUP_IP_REVISION		0x0000
>  #define OMAP4_CTRL_MODULE_WKUP_IP_HWINFO		0x0004
>  #define OMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG		0x0010
> +#define OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG	0x0114
> +#define OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG	0x011c
>  #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0	0x0460
>  #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1	0x0464
>  #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2	0x0468
> diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
> index 0472921..d4d18d9 100644
> --- a/arch/arm/mach-omap2/pm44xx.c
> +++ b/arch/arm/mach-omap2/pm44xx.c
> @@ -17,6 +17,9 @@
>  #include <linux/err.h>
>  #include <linux/slab.h>
>  #include <asm/system_misc.h>
> +#include <linux/io.h>
> +
> +#include <mach/ctrl_module_wkup_44xx.h>
>  
>  #include "common.h"
>  #include "clockdomain.h"
> @@ -215,6 +218,27 @@ static int __init omap4_pm_init(void)
>  
>  	pr_err("Power Management for TI OMAP4.\n");
>  
> +	/*
> +	 * Work around for OMAP443x Errata i632: "LPDDR2 Corruption After OFF
> +	 * Mode Transition When CS1 Is Used On EMIF":
> +	 * Overwrite EMIF1/EMIF2
> +	 * SECURE_EMIF1_SDRAM_CONFIG2_REG
> +	 * SECURE_EMIF2_SDRAM_CONFIG2_REG
> +	 */
> +	if (cpu_is_omap443x()) {
> +		void __iomem *secure_ctrl_mod;
> +
> +		secure_ctrl_mod = ioremap(OMAP4_CTRL_MODULE_WKUP, SZ_4K);
> +		BUG_ON(!secure_ctrl_mod);
> +
> +		__raw_writel(0x10, secure_ctrl_mod +
> +			     OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG);
> +		__raw_writel(0x10, secure_ctrl_mod +
> +			     OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG);

According to the erratum description the above registers are used to
restore the EMIFx_SDRAM_CONFIG2 registers. So although the value 0x10,
maybe the value being used for EMIFx_SDRAM_CONFIG2 registers, shouldn't
we read the EMIFx_SDRAM_CONFIG2 registers and store them in the above
registers?

Cheers
Jon

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

* [PATCH 15/19] ARM: OMAP4430: PM: workaround for DDR corruption on second CS
@ 2012-04-24 18:22     ` Jon Hunter
  0 siblings, 0 replies; 126+ messages in thread
From: Jon Hunter @ 2012-04-24 18:22 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tero,

On 04/20/2012 04:33 AM, Tero Kristo wrote:
> From: Santosh Shilimkar <santosh.shilimkar@ti.com>
> 
> Work around for Errata ID: i632 "LPDDR2 Corruption After OFF Mode
> Transition When CS1 Is Used On EMIF" which impacts OMAP443x silicon
> The issue occurs when EMIF_SDRAM_CONFIG is restored first before
> EMIF_SDRAM_CONFIG_2 is not yet restored, the register configuration
> is not set properly, we apply the required workaround allowing
> the restore sequence to work properly.
> 
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> [t-kristo at ti.com: moved workaround from omap-sar.c to pm44xx.c]
> Signed-off-by: Tero Kristo <t-kristo@ti.com>
> ---
>  .../include/mach/ctrl_module_wkup_44xx.h           |    2 +
>  arch/arm/mach-omap2/pm44xx.c                       |   24 ++++++++++++++++++++
>  2 files changed, 26 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
> index a0af9ba..b763a79 100644
> --- a/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
> +++ b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
> @@ -28,6 +28,8 @@
>  #define OMAP4_CTRL_MODULE_WKUP_IP_REVISION		0x0000
>  #define OMAP4_CTRL_MODULE_WKUP_IP_HWINFO		0x0004
>  #define OMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG		0x0010
> +#define OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG	0x0114
> +#define OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG	0x011c
>  #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0	0x0460
>  #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1	0x0464
>  #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2	0x0468
> diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
> index 0472921..d4d18d9 100644
> --- a/arch/arm/mach-omap2/pm44xx.c
> +++ b/arch/arm/mach-omap2/pm44xx.c
> @@ -17,6 +17,9 @@
>  #include <linux/err.h>
>  #include <linux/slab.h>
>  #include <asm/system_misc.h>
> +#include <linux/io.h>
> +
> +#include <mach/ctrl_module_wkup_44xx.h>
>  
>  #include "common.h"
>  #include "clockdomain.h"
> @@ -215,6 +218,27 @@ static int __init omap4_pm_init(void)
>  
>  	pr_err("Power Management for TI OMAP4.\n");
>  
> +	/*
> +	 * Work around for OMAP443x Errata i632: "LPDDR2 Corruption After OFF
> +	 * Mode Transition When CS1 Is Used On EMIF":
> +	 * Overwrite EMIF1/EMIF2
> +	 * SECURE_EMIF1_SDRAM_CONFIG2_REG
> +	 * SECURE_EMIF2_SDRAM_CONFIG2_REG
> +	 */
> +	if (cpu_is_omap443x()) {
> +		void __iomem *secure_ctrl_mod;
> +
> +		secure_ctrl_mod = ioremap(OMAP4_CTRL_MODULE_WKUP, SZ_4K);
> +		BUG_ON(!secure_ctrl_mod);
> +
> +		__raw_writel(0x10, secure_ctrl_mod +
> +			     OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG);
> +		__raw_writel(0x10, secure_ctrl_mod +
> +			     OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG);

According to the erratum description the above registers are used to
restore the EMIFx_SDRAM_CONFIG2 registers. So although the value 0x10,
maybe the value being used for EMIFx_SDRAM_CONFIG2 registers, shouldn't
we read the EMIFx_SDRAM_CONFIG2 registers and store them in the above
registers?

Cheers
Jon

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

* Re: [PATCH 05/19] ARM: OMAP4: PM: Add SAR backup support towards device OFF
  2012-04-24 16:35     ` Tony Lindgren
@ 2012-04-25  7:18       ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-25  7:18 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: linux-omap, khilman, paul, linux-arm-kernel, Santosh Shilimkar

On Tue, 2012-04-24 at 09:35 -0700, Tony Lindgren wrote:
> * Tero Kristo <t-kristo@ti.com> [120420 02:39]:
> > +
> > +static int omap4_sar_not_accessible(void)
> > +{
> > +	u32 usbhost_state, usbtll_state;
> > +
> > +	/*
> > +	 * Make sure that USB host and TLL modules are not
> > +	 * enabled before attempting to save the context
> > +	 * registers, otherwise this will trigger an exception.
> > +	 */
> > +	usbhost_state = omap4_cminst_read_inst_reg(OMAP4430_CM2_PARTITION,
> > +						   OMAP4430_CM2_L3INIT_INST,
> > +						   OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET)
> > +	    & (OMAP4430_STBYST_MASK | OMAP4430_IDLEST_MASK);
> > +
> > +	usbtll_state = omap4_cminst_read_inst_reg(OMAP4430_CM2_PARTITION,
> > +						  OMAP4430_CM2_L3INIT_INST,
> > +						  OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET)
> > +	    & OMAP4430_IDLEST_MASK;
> 
> Formatting here looks bad, maybe just do it in separate steps:
> 
> 	usbhost_state = omap4_cminst...
> 	usbhost_state &= OMAP4430_STBYST_MASK | OMAP4430_IDLEST_MASK;
> ...
> 
> 
> > +	/*
> > +	 * Not supported on ES1.0 silicon
> > +	 */
> > +	if (omap_rev() == OMAP4430_REV_ES1_0) {
> > +		WARN_ONCE(1, "omap4: SAR backup not supported on ES1.0 ..\n");
> > +		return -ENODEV;
> > +	}
> 
> Everytime there's SoC/hardware revision detection in a non __init function, 
> something is most likely wrong.
> 
> 
> > +void omap4_sar_overwrite(void)
> > +{
> > +	u32 val = 0;
> > +	u32 offset = 0;
> > +
> > +	if (cpu_is_omap446x())
> > +		offset = 0x04;
> 
> Here too.
> 
> 
> > +static int __init omap4_sar_ram_init(void)
> > +{
> > +	/*
> > +	 * To avoid code running on other OMAPs in
> > +	 * multi-omap builds
> > +	 */
> > +	if (!cpu_is_omap44xx())
> > +		return -ENODEV;
> 
> You should configure things here instead by setting function
> pointers or variables.
> 
> Regards,
> 
> Tony

Okay, I can drop rest of these from this patch, most of them do not
exist in the final code (removed by later patches for autogeneration), I
just left this here for historical reasons.

-Tero


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

* [PATCH 05/19] ARM: OMAP4: PM: Add SAR backup support towards device OFF
@ 2012-04-25  7:18       ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-25  7:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 2012-04-24 at 09:35 -0700, Tony Lindgren wrote:
> * Tero Kristo <t-kristo@ti.com> [120420 02:39]:
> > +
> > +static int omap4_sar_not_accessible(void)
> > +{
> > +	u32 usbhost_state, usbtll_state;
> > +
> > +	/*
> > +	 * Make sure that USB host and TLL modules are not
> > +	 * enabled before attempting to save the context
> > +	 * registers, otherwise this will trigger an exception.
> > +	 */
> > +	usbhost_state = omap4_cminst_read_inst_reg(OMAP4430_CM2_PARTITION,
> > +						   OMAP4430_CM2_L3INIT_INST,
> > +						   OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET)
> > +	    & (OMAP4430_STBYST_MASK | OMAP4430_IDLEST_MASK);
> > +
> > +	usbtll_state = omap4_cminst_read_inst_reg(OMAP4430_CM2_PARTITION,
> > +						  OMAP4430_CM2_L3INIT_INST,
> > +						  OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET)
> > +	    & OMAP4430_IDLEST_MASK;
> 
> Formatting here looks bad, maybe just do it in separate steps:
> 
> 	usbhost_state = omap4_cminst...
> 	usbhost_state &= OMAP4430_STBYST_MASK | OMAP4430_IDLEST_MASK;
> ...
> 
> 
> > +	/*
> > +	 * Not supported on ES1.0 silicon
> > +	 */
> > +	if (omap_rev() == OMAP4430_REV_ES1_0) {
> > +		WARN_ONCE(1, "omap4: SAR backup not supported on ES1.0 ..\n");
> > +		return -ENODEV;
> > +	}
> 
> Everytime there's SoC/hardware revision detection in a non __init function, 
> something is most likely wrong.
> 
> 
> > +void omap4_sar_overwrite(void)
> > +{
> > +	u32 val = 0;
> > +	u32 offset = 0;
> > +
> > +	if (cpu_is_omap446x())
> > +		offset = 0x04;
> 
> Here too.
> 
> 
> > +static int __init omap4_sar_ram_init(void)
> > +{
> > +	/*
> > +	 * To avoid code running on other OMAPs in
> > +	 * multi-omap builds
> > +	 */
> > +	if (!cpu_is_omap44xx())
> > +		return -ENODEV;
> 
> You should configure things here instead by setting function
> pointers or variables.
> 
> Regards,
> 
> Tony

Okay, I can drop rest of these from this patch, most of them do not
exist in the final code (removed by later patches for autogeneration), I
just left this here for historical reasons.

-Tero

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

* Re: [PATCH 12/19] ARM: OMAP4: PM: update ROM return address for OSWR and OFF
  2012-04-24 16:39     ` Tony Lindgren
@ 2012-04-25  7:24       ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-25  7:24 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: linux-omap, khilman, paul, linux-arm-kernel, Carlos Leija,
	Praneeth Bajjuri, Bryan Buckley

On Tue, 2012-04-24 at 09:39 -0700, Tony Lindgren wrote:
> * Tero Kristo <t-kristo@ti.com> [120420 02:39]:
> > @@ -384,6 +386,17 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
> >  	set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON);
> >  
> >  	if (omap4_mpuss_read_prev_context_state()) {
> > +		/*
> > +		 * Dummy dispatcher call after OSWR and OFF
> > +		 * Restore the right return Kernel address (with MMU on) for
> > +		 * subsequent calls to secure ROM. Otherwise the return address
> > +		 * will be to a PA return address and the system will hang.
> > +		 */
> > +		if (omap_type() != OMAP2_DEVICE_TYPE_GP)
> > +			omap_secure_dispatcher(OMAP4_PPA_SERVICE_0,
> > +					       FLAG_START_CRITICAL,
> > +					       0, 0, 0, 0, 0);
> > +
> >  		restore_ivahd_tesla_regs();
> >  		restore_l3instr_regs();
> 
> This SoC test here too should be only done once during init.

You sure about this one? I will end up creating a variable omap_is_gp or
such, which looks somewhat silly and is going to be a duplicate (it will
not provide any extra value in addition to the existing omap_type()
check.) Also, similar checks are used elsewhere in the kernel, look at
omap-wakeupgen.c, pm34xx.c, pm44xx.c, control.c for example. Should all
of these be replaced? Well, most of these are related to secure context
saving so maybe the mechanism behind these should be changed somehow
globally.

-Tero



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

* [PATCH 12/19] ARM: OMAP4: PM: update ROM return address for OSWR and OFF
@ 2012-04-25  7:24       ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-25  7:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 2012-04-24 at 09:39 -0700, Tony Lindgren wrote:
> * Tero Kristo <t-kristo@ti.com> [120420 02:39]:
> > @@ -384,6 +386,17 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
> >  	set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON);
> >  
> >  	if (omap4_mpuss_read_prev_context_state()) {
> > +		/*
> > +		 * Dummy dispatcher call after OSWR and OFF
> > +		 * Restore the right return Kernel address (with MMU on) for
> > +		 * subsequent calls to secure ROM. Otherwise the return address
> > +		 * will be to a PA return address and the system will hang.
> > +		 */
> > +		if (omap_type() != OMAP2_DEVICE_TYPE_GP)
> > +			omap_secure_dispatcher(OMAP4_PPA_SERVICE_0,
> > +					       FLAG_START_CRITICAL,
> > +					       0, 0, 0, 0, 0);
> > +
> >  		restore_ivahd_tesla_regs();
> >  		restore_l3instr_regs();
> 
> This SoC test here too should be only done once during init.

You sure about this one? I will end up creating a variable omap_is_gp or
such, which looks somewhat silly and is going to be a duplicate (it will
not provide any extra value in addition to the existing omap_type()
check.) Also, similar checks are used elsewhere in the kernel, look at
omap-wakeupgen.c, pm34xx.c, pm44xx.c, control.c for example. Should all
of these be replaced? Well, most of these are related to secure context
saving so maybe the mechanism behind these should be changed somehow
globally.

-Tero

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

* Re: [PATCH 15/19] ARM: OMAP4430: PM: workaround for DDR corruption on second CS
  2012-04-24 18:22     ` Jon Hunter
@ 2012-04-25  7:26       ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-25  7:26 UTC (permalink / raw)
  To: Jon Hunter; +Cc: linux-omap, khilman, paul, Santosh Shilimkar, linux-arm-kernel

On Tue, 2012-04-24 at 13:22 -0500, Jon Hunter wrote:
> Hi Tero,
> 
> On 04/20/2012 04:33 AM, Tero Kristo wrote:
> > From: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > 
> > Work around for Errata ID: i632 "LPDDR2 Corruption After OFF Mode
> > Transition When CS1 Is Used On EMIF" which impacts OMAP443x silicon
> > The issue occurs when EMIF_SDRAM_CONFIG is restored first before
> > EMIF_SDRAM_CONFIG_2 is not yet restored, the register configuration
> > is not set properly, we apply the required workaround allowing
> > the restore sequence to work properly.
> > 
> > Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > [t-kristo@ti.com: moved workaround from omap-sar.c to pm44xx.c]
> > Signed-off-by: Tero Kristo <t-kristo@ti.com>
> > ---
> >  .../include/mach/ctrl_module_wkup_44xx.h           |    2 +
> >  arch/arm/mach-omap2/pm44xx.c                       |   24 ++++++++++++++++++++
> >  2 files changed, 26 insertions(+), 0 deletions(-)
> > 
> > diff --git a/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
> > index a0af9ba..b763a79 100644
> > --- a/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
> > +++ b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
> > @@ -28,6 +28,8 @@
> >  #define OMAP4_CTRL_MODULE_WKUP_IP_REVISION		0x0000
> >  #define OMAP4_CTRL_MODULE_WKUP_IP_HWINFO		0x0004
> >  #define OMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG		0x0010
> > +#define OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG	0x0114
> > +#define OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG	0x011c
> >  #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0	0x0460
> >  #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1	0x0464
> >  #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2	0x0468
> > diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
> > index 0472921..d4d18d9 100644
> > --- a/arch/arm/mach-omap2/pm44xx.c
> > +++ b/arch/arm/mach-omap2/pm44xx.c
> > @@ -17,6 +17,9 @@
> >  #include <linux/err.h>
> >  #include <linux/slab.h>
> >  #include <asm/system_misc.h>
> > +#include <linux/io.h>
> > +
> > +#include <mach/ctrl_module_wkup_44xx.h>
> >  
> >  #include "common.h"
> >  #include "clockdomain.h"
> > @@ -215,6 +218,27 @@ static int __init omap4_pm_init(void)
> >  
> >  	pr_err("Power Management for TI OMAP4.\n");
> >  
> > +	/*
> > +	 * Work around for OMAP443x Errata i632: "LPDDR2 Corruption After OFF
> > +	 * Mode Transition When CS1 Is Used On EMIF":
> > +	 * Overwrite EMIF1/EMIF2
> > +	 * SECURE_EMIF1_SDRAM_CONFIG2_REG
> > +	 * SECURE_EMIF2_SDRAM_CONFIG2_REG
> > +	 */
> > +	if (cpu_is_omap443x()) {
> > +		void __iomem *secure_ctrl_mod;
> > +
> > +		secure_ctrl_mod = ioremap(OMAP4_CTRL_MODULE_WKUP, SZ_4K);
> > +		BUG_ON(!secure_ctrl_mod);
> > +
> > +		__raw_writel(0x10, secure_ctrl_mod +
> > +			     OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG);
> > +		__raw_writel(0x10, secure_ctrl_mod +
> > +			     OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG);
> 
> According to the erratum description the above registers are used to
> restore the EMIFx_SDRAM_CONFIG2 registers. So although the value 0x10,
> maybe the value being used for EMIFx_SDRAM_CONFIG2 registers, shouldn't
> we read the EMIFx_SDRAM_CONFIG2 registers and store them in the above
> registers?

This might be a good idea, however, this patch might be tagged as TEMP
until the EMIF driver is in place, this fix should rather be located
there. I'll take a look at this if I can change the implementation a
bit.

-Tero


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

* [PATCH 15/19] ARM: OMAP4430: PM: workaround for DDR corruption on second CS
@ 2012-04-25  7:26       ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-25  7:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 2012-04-24 at 13:22 -0500, Jon Hunter wrote:
> Hi Tero,
> 
> On 04/20/2012 04:33 AM, Tero Kristo wrote:
> > From: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > 
> > Work around for Errata ID: i632 "LPDDR2 Corruption After OFF Mode
> > Transition When CS1 Is Used On EMIF" which impacts OMAP443x silicon
> > The issue occurs when EMIF_SDRAM_CONFIG is restored first before
> > EMIF_SDRAM_CONFIG_2 is not yet restored, the register configuration
> > is not set properly, we apply the required workaround allowing
> > the restore sequence to work properly.
> > 
> > Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > [t-kristo at ti.com: moved workaround from omap-sar.c to pm44xx.c]
> > Signed-off-by: Tero Kristo <t-kristo@ti.com>
> > ---
> >  .../include/mach/ctrl_module_wkup_44xx.h           |    2 +
> >  arch/arm/mach-omap2/pm44xx.c                       |   24 ++++++++++++++++++++
> >  2 files changed, 26 insertions(+), 0 deletions(-)
> > 
> > diff --git a/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
> > index a0af9ba..b763a79 100644
> > --- a/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
> > +++ b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
> > @@ -28,6 +28,8 @@
> >  #define OMAP4_CTRL_MODULE_WKUP_IP_REVISION		0x0000
> >  #define OMAP4_CTRL_MODULE_WKUP_IP_HWINFO		0x0004
> >  #define OMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG		0x0010
> > +#define OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG	0x0114
> > +#define OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG	0x011c
> >  #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0	0x0460
> >  #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1	0x0464
> >  #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2	0x0468
> > diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
> > index 0472921..d4d18d9 100644
> > --- a/arch/arm/mach-omap2/pm44xx.c
> > +++ b/arch/arm/mach-omap2/pm44xx.c
> > @@ -17,6 +17,9 @@
> >  #include <linux/err.h>
> >  #include <linux/slab.h>
> >  #include <asm/system_misc.h>
> > +#include <linux/io.h>
> > +
> > +#include <mach/ctrl_module_wkup_44xx.h>
> >  
> >  #include "common.h"
> >  #include "clockdomain.h"
> > @@ -215,6 +218,27 @@ static int __init omap4_pm_init(void)
> >  
> >  	pr_err("Power Management for TI OMAP4.\n");
> >  
> > +	/*
> > +	 * Work around for OMAP443x Errata i632: "LPDDR2 Corruption After OFF
> > +	 * Mode Transition When CS1 Is Used On EMIF":
> > +	 * Overwrite EMIF1/EMIF2
> > +	 * SECURE_EMIF1_SDRAM_CONFIG2_REG
> > +	 * SECURE_EMIF2_SDRAM_CONFIG2_REG
> > +	 */
> > +	if (cpu_is_omap443x()) {
> > +		void __iomem *secure_ctrl_mod;
> > +
> > +		secure_ctrl_mod = ioremap(OMAP4_CTRL_MODULE_WKUP, SZ_4K);
> > +		BUG_ON(!secure_ctrl_mod);
> > +
> > +		__raw_writel(0x10, secure_ctrl_mod +
> > +			     OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG);
> > +		__raw_writel(0x10, secure_ctrl_mod +
> > +			     OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG);
> 
> According to the erratum description the above registers are used to
> restore the EMIFx_SDRAM_CONFIG2 registers. So although the value 0x10,
> maybe the value being used for EMIFx_SDRAM_CONFIG2 registers, shouldn't
> we read the EMIFx_SDRAM_CONFIG2 registers and store them in the above
> registers?

This might be a good idea, however, this patch might be tagged as TEMP
until the EMIF driver is in place, this fix should rather be located
there. I'll take a look at this if I can change the implementation a
bit.

-Tero

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

* Re: [PATCH 08/19] ARM: OMAP4: PM: Add device-off support
  2012-04-24 17:46     ` Jon Hunter
@ 2012-04-25  7:30       ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-25  7:30 UTC (permalink / raw)
  To: Jon Hunter; +Cc: linux-omap, khilman, paul, Santosh Shilimkar, linux-arm-kernel

On Tue, 2012-04-24 at 12:46 -0500, Jon Hunter wrote:
> Hi Tero,
> 
> On 04/20/2012 04:33 AM, Tero Kristo wrote:
> > This patch adds device off support to OMAP4 device type.
> > 
> > OFF mode is disabled by default, however, there are two ways to enable
> > OFF mode:
> > a) In the board file, call omap4_pm_off_mode_enable(1)
> > b) Enable OFF mode using the debugfs entry
> > echo "1">/sys/kernel/debug/pm_debug/enable_off_mode
> > (conversely echo '0' will disable it as well).
> > 
> > Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > [t-kristo@ti.com: largely re-structured the code]
> > Signed-off-by: Tero Kristo <t-kristo@ti.com>
> > ---
> >  arch/arm/mach-omap2/omap-mpuss-lowpower.c |   24 ++++++++++-
> >  arch/arm/mach-omap2/omap-wakeupgen.c      |   47 +++++++++++++++++++-
> >  arch/arm/mach-omap2/pm-debug.c            |   17 +++++--
> >  arch/arm/mach-omap2/pm.h                  |   28 ++++++++++--
> >  arch/arm/mach-omap2/pm44xx.c              |   45 +++++++++++++++++++
> >  arch/arm/mach-omap2/prm44xx.c             |   66 +++++++++++++++++++++++++++++
> >  6 files changed, 214 insertions(+), 13 deletions(-)
> > 
> > diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> > index e02c082..b9a2cc7 100644
> > --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> > +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> > @@ -60,6 +60,7 @@
> >  #include "prcm44xx.h"
> >  #include "prm44xx.h"
> >  #include "prm-regbits-44xx.h"
> > +#include "cm44xx.h"
> >  
> >  #ifdef CONFIG_SMP
> >  
> > @@ -232,6 +233,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
> >  {
> >  	unsigned int save_state = 0;
> >  	unsigned int wakeup_cpu;
> > +	int ret;
> >  
> >  	if (omap_rev() == OMAP4430_REV_ES1_0)
> >  		return -ENXIO;
> > @@ -263,9 +265,21 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
> >  	 * In MPUSS OSWR or device OFF, interrupt controller  contest is lost.
> >  	 */
> >  	mpuss_clear_prev_logic_pwrst();
> > -	if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) &&
> > -		(pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF))
> > +	if (omap4_device_next_state_off()) {
> > +		/* Save the device context to SAR RAM */
> > +		ret = omap_sar_save();
> > +		if (ret)
> > +			return ret;
> 
> Is it safe to simply return here? I was not sure if we need to call
> pwrdm_post_transition, given that we have already called
> pwrdm_pre_transition on entry.

Hmm, thats a good point, I'll change the patch slightly. Anyway,
currently the potential solo pwrdm_pre_transition() will not break
anything, but in future it would, as we are planning to control AUTO_RET
feature through the pwrdm_pre / pwrdm_post calls.

-Tero


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

* [PATCH 08/19] ARM: OMAP4: PM: Add device-off support
@ 2012-04-25  7:30       ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-25  7:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 2012-04-24 at 12:46 -0500, Jon Hunter wrote:
> Hi Tero,
> 
> On 04/20/2012 04:33 AM, Tero Kristo wrote:
> > This patch adds device off support to OMAP4 device type.
> > 
> > OFF mode is disabled by default, however, there are two ways to enable
> > OFF mode:
> > a) In the board file, call omap4_pm_off_mode_enable(1)
> > b) Enable OFF mode using the debugfs entry
> > echo "1">/sys/kernel/debug/pm_debug/enable_off_mode
> > (conversely echo '0' will disable it as well).
> > 
> > Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > [t-kristo at ti.com: largely re-structured the code]
> > Signed-off-by: Tero Kristo <t-kristo@ti.com>
> > ---
> >  arch/arm/mach-omap2/omap-mpuss-lowpower.c |   24 ++++++++++-
> >  arch/arm/mach-omap2/omap-wakeupgen.c      |   47 +++++++++++++++++++-
> >  arch/arm/mach-omap2/pm-debug.c            |   17 +++++--
> >  arch/arm/mach-omap2/pm.h                  |   28 ++++++++++--
> >  arch/arm/mach-omap2/pm44xx.c              |   45 +++++++++++++++++++
> >  arch/arm/mach-omap2/prm44xx.c             |   66 +++++++++++++++++++++++++++++
> >  6 files changed, 214 insertions(+), 13 deletions(-)
> > 
> > diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> > index e02c082..b9a2cc7 100644
> > --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> > +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> > @@ -60,6 +60,7 @@
> >  #include "prcm44xx.h"
> >  #include "prm44xx.h"
> >  #include "prm-regbits-44xx.h"
> > +#include "cm44xx.h"
> >  
> >  #ifdef CONFIG_SMP
> >  
> > @@ -232,6 +233,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
> >  {
> >  	unsigned int save_state = 0;
> >  	unsigned int wakeup_cpu;
> > +	int ret;
> >  
> >  	if (omap_rev() == OMAP4430_REV_ES1_0)
> >  		return -ENXIO;
> > @@ -263,9 +265,21 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
> >  	 * In MPUSS OSWR or device OFF, interrupt controller  contest is lost.
> >  	 */
> >  	mpuss_clear_prev_logic_pwrst();
> > -	if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) &&
> > -		(pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF))
> > +	if (omap4_device_next_state_off()) {
> > +		/* Save the device context to SAR RAM */
> > +		ret = omap_sar_save();
> > +		if (ret)
> > +			return ret;
> 
> Is it safe to simply return here? I was not sure if we need to call
> pwrdm_post_transition, given that we have already called
> pwrdm_pre_transition on entry.

Hmm, thats a good point, I'll change the patch slightly. Anyway,
currently the potential solo pwrdm_pre_transition() will not break
anything, but in future it would, as we are planning to control AUTO_RET
feature through the pwrdm_pre / pwrdm_post calls.

-Tero

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

* Re: [PATCH 10/19] ARM: OMAP4: PM: Work-around for ROM code BUG of IVAHD/TESLA
  2012-04-24 17:50     ` Jon Hunter
@ 2012-04-25  7:31       ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-25  7:31 UTC (permalink / raw)
  To: Jon Hunter
  Cc: linux-omap, khilman, paul, Rajendra Nayak, Santosh Shilimkar,
	linux-arm-kernel

On Tue, 2012-04-24 at 12:50 -0500, Jon Hunter wrote:
> Hi Tero,
> 
> On 04/20/2012 04:33 AM, Tero Kristo wrote:
> > From: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > 
> > The ROM BUG is when MPU Domain OFF wake up sequence that can compromise
> > IVA and Tesla execution.
> > 
> > At wakeup from MPU OFF on HS device only (not GP device), when
> > restoring the Secure RAM, the ROM Code reconfigures the clocks the
> > same way it is done at Cold Reset.
> > The IVAHD Clocks and Power Domain settings are:
> > 	IVAHD_CM2 IVAHD_CLKCTRL_MODULE_MODE = DISABLE
> > 	IVAHD_CM2 SL2_CLKCTRL_MODULE_MODE = DISABLE
> > 	IVAHD_CM2 SL2_CLKSTCTRL_CLKTRCTRL = HW_AUTO
> > 	IVAHD_PRM IVAHD_PWRSTCTRL_POWERSTATE = OFF
> > The TESLA Clocks and Power Domain settings are:
> > 	TESLA_CM1 TESLA_CLKCTRL_MODULE_MODE = DISABLE
> > 	TESLA_CM1 TESLA_CLKSTCTRL_CLKTRCTRL = HW_AUTO
> > 	TESLA_PRM TESLA_PWRSTCTRL_POWERSTATE = OFF
> > 
> > This patch fixes the low power OFF mode code so that the these
> > registers are saved and restore across MPU OFF state.
> > 
> > Also because of this limitation, MPU OFF alone is not targeted without
> > device OFF to avoid IVAHD and TESLA execution impact
> 
> You may wish to state which devices is impacted by this in the changelog.

Okay.

> 
> > Signed-off-by: Rajendra Nayak <rnayak@ti.com>
> > Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > [t-kristo@ti.com: added omap4 pm errata support]
> > Signed-off-by: Tero Kristo <t-kristo@ti.com>
> > ---
> >  arch/arm/mach-omap2/omap-mpuss-lowpower.c |   53 +++++++++++++++++++++++++++++
> >  arch/arm/mach-omap2/pm.h                  |    2 +
> >  arch/arm/mach-omap2/pm44xx.c              |    9 +++++
> >  3 files changed, 64 insertions(+), 0 deletions(-)
> > 
> > diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> > index b9a2cc7..208d4a4 100644
> > --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> > +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> > @@ -52,6 +52,7 @@
> >  
> >  #include <plat/omap44xx.h>
> >  
> > +#include "iomap.h"
> >  #include "common.h"
> >  #include "omap4-sar-layout.h"
> >  #include "pm.h"
> > @@ -76,6 +77,24 @@ static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
> >  static struct powerdomain *mpuss_pd;
> >  static void __iomem *sar_base;
> >  
> > +struct reg_tuple {
> > +	void __iomem *addr;
> > +	u32 val;
> > +};
> > +
> > +static struct reg_tuple tesla_reg[] = {
> > +	{.addr = OMAP4430_CM_TESLA_CLKSTCTRL},
> > +	{.addr = OMAP4430_CM_TESLA_TESLA_CLKCTRL},
> > +	{.addr = OMAP4430_PM_TESLA_PWRSTCTRL},
> > +};
> > +
> > +static struct reg_tuple ivahd_reg[] = {
> > +	{.addr = OMAP4430_CM_IVAHD_CLKSTCTRL},
> > +	{.addr = OMAP4430_CM_IVAHD_IVAHD_CLKCTRL},
> > +	{.addr = OMAP4430_CM_IVAHD_SL2_CLKCTRL},
> > +	{.addr = OMAP4430_PM_IVAHD_PWRSTCTRL}
> > +};
> > +
> >  /*
> >   * Program the wakeup routine address for the CPU0 and CPU1
> >   * used for OFF or DORMANT wakeup.
> > @@ -215,6 +234,34 @@ static void save_l2x0_context(void)
> >  {}
> >  #endif
> >  
> > +static inline void save_ivahd_tesla_regs(void)
> > +{
> > +	int i;
> > +
> > +	if (!IS_PM44XX_ERRATUM(PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM))
> > +		return;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(tesla_reg); i++)
> > +		tesla_reg[i].val = __raw_readl(tesla_reg[i].addr);
> > +
> > +	for (i = 0; i < ARRAY_SIZE(ivahd_reg); i++)
> > +		ivahd_reg[i].val = __raw_readl(ivahd_reg[i].addr);
> > +}
> > +
> > +static inline void restore_ivahd_tesla_regs(void)
> > +{
> > +	int i;
> > +
> > +	if (!IS_PM44XX_ERRATUM(PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM))
> > +		return;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(tesla_reg); i++)
> > +		__raw_writel(tesla_reg[i].val, tesla_reg[i].addr);
> > +
> > +	for (i = 0; i < ARRAY_SIZE(ivahd_reg); i++)
> > +		__raw_writel(ivahd_reg[i].val, ivahd_reg[i].addr);
> > +}
> > +
> >  /**
> >   * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function
> >   * The purpose of this function is to manage low power programming
> > @@ -273,11 +320,14 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
> >  		omap_sar_overwrite();
> >  		omap4_cm_prepare_off();
> >  		omap4_dpll_prepare_off();
> > +		save_ivahd_tesla_regs();
> >  		save_state = 3;
> >  	} else if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) &&
> >  		(pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF)) {
> > +		save_ivahd_tesla_regs();
> >  		save_state = 2;
> >  	} else if (pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_OFF) {
> > +		save_ivahd_tesla_regs();
> >  		save_state = 3;
> >  	}
> >  
> > @@ -302,6 +352,9 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
> >  	wakeup_cpu = smp_processor_id();
> >  	set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON);
> >  
> > +	if (omap4_mpuss_read_prev_context_state())
> > +		restore_ivahd_tesla_regs();
> > +
> >  	if (omap4_device_prev_state_off()) {
> >  		omap4_dpll_resume_off();
> >  		omap4_cm_resume_off();
> > diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
> > index e78ec63..051aeb9 100644
> > --- a/arch/arm/mach-omap2/pm.h
> > +++ b/arch/arm/mach-omap2/pm.h
> > @@ -131,6 +131,8 @@ extern void enable_omap3630_toggle_l2_on_restore(void);
> >  static inline void enable_omap3630_toggle_l2_on_restore(void) { }
> >  #endif		/* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */
> >  
> > +#define PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM	(1 << 0)
> > +
> >  #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
> >  extern u16 pm44xx_errata;
> >  #define IS_PM44XX_ERRATUM(id)		(pm44xx_errata & (id))
> > diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
> > index 8238097..67cb799 100644
> > --- a/arch/arm/mach-omap2/pm44xx.c
> > +++ b/arch/arm/mach-omap2/pm44xx.c
> > @@ -263,6 +263,15 @@ static int __init omap4_pm_init(void)
> >  
> >  	(void) clkdm_for_each(omap_pm_clkdms_setup, NULL);
> >  
> > +	/*
> > +	 * ROM code initializes IVAHD and TESLA clock registers during
> > +	 * secure RAM restore phase on omap4430 EMU/HS devices, thus
> > +	 * IVAHD / TESLA clock registers must be saved / restored
> > +	 * during MPU OSWR / device off.
> > +	 */
> > +	if (cpu_is_omap443x() && omap_type() != OMAP2_DEVICE_TYPE_GP)
> > +		pm44xx_errata |= PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM;
> 
> This erratum does not impact omap4430 es2.3 so the above should account
> for that.

Okay, will change that.

-Tero


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

* [PATCH 10/19] ARM: OMAP4: PM: Work-around for ROM code BUG of IVAHD/TESLA
@ 2012-04-25  7:31       ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-25  7:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 2012-04-24 at 12:50 -0500, Jon Hunter wrote:
> Hi Tero,
> 
> On 04/20/2012 04:33 AM, Tero Kristo wrote:
> > From: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > 
> > The ROM BUG is when MPU Domain OFF wake up sequence that can compromise
> > IVA and Tesla execution.
> > 
> > At wakeup from MPU OFF on HS device only (not GP device), when
> > restoring the Secure RAM, the ROM Code reconfigures the clocks the
> > same way it is done at Cold Reset.
> > The IVAHD Clocks and Power Domain settings are:
> > 	IVAHD_CM2 IVAHD_CLKCTRL_MODULE_MODE = DISABLE
> > 	IVAHD_CM2 SL2_CLKCTRL_MODULE_MODE = DISABLE
> > 	IVAHD_CM2 SL2_CLKSTCTRL_CLKTRCTRL = HW_AUTO
> > 	IVAHD_PRM IVAHD_PWRSTCTRL_POWERSTATE = OFF
> > The TESLA Clocks and Power Domain settings are:
> > 	TESLA_CM1 TESLA_CLKCTRL_MODULE_MODE = DISABLE
> > 	TESLA_CM1 TESLA_CLKSTCTRL_CLKTRCTRL = HW_AUTO
> > 	TESLA_PRM TESLA_PWRSTCTRL_POWERSTATE = OFF
> > 
> > This patch fixes the low power OFF mode code so that the these
> > registers are saved and restore across MPU OFF state.
> > 
> > Also because of this limitation, MPU OFF alone is not targeted without
> > device OFF to avoid IVAHD and TESLA execution impact
> 
> You may wish to state which devices is impacted by this in the changelog.

Okay.

> 
> > Signed-off-by: Rajendra Nayak <rnayak@ti.com>
> > Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > [t-kristo at ti.com: added omap4 pm errata support]
> > Signed-off-by: Tero Kristo <t-kristo@ti.com>
> > ---
> >  arch/arm/mach-omap2/omap-mpuss-lowpower.c |   53 +++++++++++++++++++++++++++++
> >  arch/arm/mach-omap2/pm.h                  |    2 +
> >  arch/arm/mach-omap2/pm44xx.c              |    9 +++++
> >  3 files changed, 64 insertions(+), 0 deletions(-)
> > 
> > diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> > index b9a2cc7..208d4a4 100644
> > --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> > +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> > @@ -52,6 +52,7 @@
> >  
> >  #include <plat/omap44xx.h>
> >  
> > +#include "iomap.h"
> >  #include "common.h"
> >  #include "omap4-sar-layout.h"
> >  #include "pm.h"
> > @@ -76,6 +77,24 @@ static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
> >  static struct powerdomain *mpuss_pd;
> >  static void __iomem *sar_base;
> >  
> > +struct reg_tuple {
> > +	void __iomem *addr;
> > +	u32 val;
> > +};
> > +
> > +static struct reg_tuple tesla_reg[] = {
> > +	{.addr = OMAP4430_CM_TESLA_CLKSTCTRL},
> > +	{.addr = OMAP4430_CM_TESLA_TESLA_CLKCTRL},
> > +	{.addr = OMAP4430_PM_TESLA_PWRSTCTRL},
> > +};
> > +
> > +static struct reg_tuple ivahd_reg[] = {
> > +	{.addr = OMAP4430_CM_IVAHD_CLKSTCTRL},
> > +	{.addr = OMAP4430_CM_IVAHD_IVAHD_CLKCTRL},
> > +	{.addr = OMAP4430_CM_IVAHD_SL2_CLKCTRL},
> > +	{.addr = OMAP4430_PM_IVAHD_PWRSTCTRL}
> > +};
> > +
> >  /*
> >   * Program the wakeup routine address for the CPU0 and CPU1
> >   * used for OFF or DORMANT wakeup.
> > @@ -215,6 +234,34 @@ static void save_l2x0_context(void)
> >  {}
> >  #endif
> >  
> > +static inline void save_ivahd_tesla_regs(void)
> > +{
> > +	int i;
> > +
> > +	if (!IS_PM44XX_ERRATUM(PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM))
> > +		return;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(tesla_reg); i++)
> > +		tesla_reg[i].val = __raw_readl(tesla_reg[i].addr);
> > +
> > +	for (i = 0; i < ARRAY_SIZE(ivahd_reg); i++)
> > +		ivahd_reg[i].val = __raw_readl(ivahd_reg[i].addr);
> > +}
> > +
> > +static inline void restore_ivahd_tesla_regs(void)
> > +{
> > +	int i;
> > +
> > +	if (!IS_PM44XX_ERRATUM(PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM))
> > +		return;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(tesla_reg); i++)
> > +		__raw_writel(tesla_reg[i].val, tesla_reg[i].addr);
> > +
> > +	for (i = 0; i < ARRAY_SIZE(ivahd_reg); i++)
> > +		__raw_writel(ivahd_reg[i].val, ivahd_reg[i].addr);
> > +}
> > +
> >  /**
> >   * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function
> >   * The purpose of this function is to manage low power programming
> > @@ -273,11 +320,14 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
> >  		omap_sar_overwrite();
> >  		omap4_cm_prepare_off();
> >  		omap4_dpll_prepare_off();
> > +		save_ivahd_tesla_regs();
> >  		save_state = 3;
> >  	} else if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) &&
> >  		(pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF)) {
> > +		save_ivahd_tesla_regs();
> >  		save_state = 2;
> >  	} else if (pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_OFF) {
> > +		save_ivahd_tesla_regs();
> >  		save_state = 3;
> >  	}
> >  
> > @@ -302,6 +352,9 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
> >  	wakeup_cpu = smp_processor_id();
> >  	set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON);
> >  
> > +	if (omap4_mpuss_read_prev_context_state())
> > +		restore_ivahd_tesla_regs();
> > +
> >  	if (omap4_device_prev_state_off()) {
> >  		omap4_dpll_resume_off();
> >  		omap4_cm_resume_off();
> > diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
> > index e78ec63..051aeb9 100644
> > --- a/arch/arm/mach-omap2/pm.h
> > +++ b/arch/arm/mach-omap2/pm.h
> > @@ -131,6 +131,8 @@ extern void enable_omap3630_toggle_l2_on_restore(void);
> >  static inline void enable_omap3630_toggle_l2_on_restore(void) { }
> >  #endif		/* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */
> >  
> > +#define PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM	(1 << 0)
> > +
> >  #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
> >  extern u16 pm44xx_errata;
> >  #define IS_PM44XX_ERRATUM(id)		(pm44xx_errata & (id))
> > diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
> > index 8238097..67cb799 100644
> > --- a/arch/arm/mach-omap2/pm44xx.c
> > +++ b/arch/arm/mach-omap2/pm44xx.c
> > @@ -263,6 +263,15 @@ static int __init omap4_pm_init(void)
> >  
> >  	(void) clkdm_for_each(omap_pm_clkdms_setup, NULL);
> >  
> > +	/*
> > +	 * ROM code initializes IVAHD and TESLA clock registers during
> > +	 * secure RAM restore phase on omap4430 EMU/HS devices, thus
> > +	 * IVAHD / TESLA clock registers must be saved / restored
> > +	 * during MPU OSWR / device off.
> > +	 */
> > +	if (cpu_is_omap443x() && omap_type() != OMAP2_DEVICE_TYPE_GP)
> > +		pm44xx_errata |= PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM;
> 
> This erratum does not impact omap4430 es2.3 so the above should account
> for that.

Okay, will change that.

-Tero

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

* Re: [PATCH 11/19] ARM: OMAP4: PM: save/restore CM L3INSTR registers when MPU hits OSWR/OFF mode
  2012-04-24 17:57     ` Jon Hunter
@ 2012-04-25  7:31       ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-25  7:31 UTC (permalink / raw)
  To: Jon Hunter
  Cc: linux-omap, khilman, paul, Rajendra Nayak, Santosh Shilimkar,
	linux-arm-kernel

On Tue, 2012-04-24 at 12:57 -0500, Jon Hunter wrote:
> Hi Tero,
> 
> On 04/20/2012 04:33 AM, Tero Kristo wrote:
> > From: Rajendra Nayak <rnayak@ti.com>
> > 
> > On HS devices on the way out of MPU OSWR and OFF ROM code wrongly
> > overwrites the CM L3INSTR registers. So to avoid this, save them and
> > restore on the way out from MPU OSWR/OFF.
> 
> This appears to be an errata. So, it would be good to state explicitly
> here that all revisions of all omap4 devices are impacted by this
> errata. The code implies this but for documentation purposes it would be
> worth stating.

Okay, I'll add some extra beef here.

-Tero



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

* [PATCH 11/19] ARM: OMAP4: PM: save/restore CM L3INSTR registers when MPU hits OSWR/OFF mode
@ 2012-04-25  7:31       ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-25  7:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 2012-04-24 at 12:57 -0500, Jon Hunter wrote:
> Hi Tero,
> 
> On 04/20/2012 04:33 AM, Tero Kristo wrote:
> > From: Rajendra Nayak <rnayak@ti.com>
> > 
> > On HS devices on the way out of MPU OSWR and OFF ROM code wrongly
> > overwrites the CM L3INSTR registers. So to avoid this, save them and
> > restore on the way out from MPU OSWR/OFF.
> 
> This appears to be an errata. So, it would be good to state explicitly
> here that all revisions of all omap4 devices are impacted by this
> errata. The code implies this but for documentation purposes it would be
> worth stating.

Okay, I'll add some extra beef here.

-Tero

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

* Re: [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
  2012-04-23 16:09     ` Jon Hunter
@ 2012-04-25  7:33       ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-25  7:33 UTC (permalink / raw)
  To: Jon Hunter, Tony Lindgren
  Cc: linux-omap, khilman, paul, Nishanth Menon, Rajendra Nayak,
	Santosh Shilimkar, linux-arm-kernel

On Mon, 2012-04-23 at 11:09 -0500, Jon Hunter wrote:
> Hi Tero,
> 
> On 04/20/2012 04:33 AM, Tero Kristo wrote:
> 
> [...]
> 
> > +/**
> > + * omap4_dpll_print_reg - dump out a single DPLL register value
> > + * @dpll_reg: register to dump
> > + * @name: name of the register
> > + * @tuple: content of the register
> > + *
> > + * Helper dump function to print out a DPLL register value in case
> > + * of restore failures.
> > + */
> > +static void omap4_dpll_print_reg(struct omap4_dpll_regs *dpll_reg, char *name,
> > +				 struct dpll_reg *tuple)
> > +{
> > +	if (tuple->offset)
> > +		pr_warn("%s - Address offset = 0x%08x, value=0x%08x\n", name,
> > +			tuple->offset, tuple->val);
> 
> Minor nit-pick here ...
> 
> 1. Offset is 16-bits and so we can just have "offset = 0x%04x"
> 2. Consider dropping "Address" from "Address offset"
> 3. Can we be consistent in our spaces for "offset = " and "value="?
> 
> > +}
> > +
> > +/*
> > + * omap4_dpll_dump_regs - dump out DPLL registers
> > + * @dpll_reg: DPLL to dump
> > + *
> > + * Dump out the contents of the registers for a DPLL. Called if a
> > + * restore for DPLL fails to lock.
> > + */
> > +static void omap4_dpll_dump_regs(struct omap4_dpll_regs *dpll_reg)
> > +{
> > +	pr_warn("%s: Unable to lock dpll %s[part=%x inst=%x]:\n",
> > +		__func__, dpll_reg->name, dpll_reg->mod_partition,
> > +		dpll_reg->mod_inst);
> > +	omap4_dpll_print_reg(dpll_reg, "clksel", &dpll_reg->clksel);
> > +	omap4_dpll_print_reg(dpll_reg, "div_m2", &dpll_reg->div_m2);
> > +	omap4_dpll_print_reg(dpll_reg, "div_m3", &dpll_reg->div_m3);
> > +	omap4_dpll_print_reg(dpll_reg, "div_m4", &dpll_reg->div_m4);
> > +	omap4_dpll_print_reg(dpll_reg, "div_m5", &dpll_reg->div_m5);
> > +	omap4_dpll_print_reg(dpll_reg, "div_m6", &dpll_reg->div_m6);
> > +	omap4_dpll_print_reg(dpll_reg, "div_m7", &dpll_reg->div_m7);
> > +	omap4_dpll_print_reg(dpll_reg, "clkdcoldo", &dpll_reg->clkdcoldo);
> > +	omap4_dpll_print_reg(dpll_reg, "clkmode", &dpll_reg->clkmode);
> > +	omap4_dpll_print_reg(dpll_reg, "autoidle", &dpll_reg->autoidle);
> > +	if (dpll_reg->idlest.offset)
> > +		pr_warn("idlest - Address offset = 0x%08x, before val=0x%08x"
> > +			" after = 0x%08x\n", dpll_reg->idlest.offset,
> > +			dpll_reg->idlest.val,
> > +			omap4_dpll_read_reg(dpll_reg, &dpll_reg->idlest));
> 
> Nit-pick ...
> 
> 1. Same comments as above
> 2. Consider dropping "Address offset" altogether here as we print
> "idlest" the offset should be implied.
> 3. Also can we be consistent in our naming of "before val and "after"?
> For example, "val before =" and "val now = ".

Okay, I'll modify both prints slightly. Question though, do we want
these prints in the kernel in the first place? At least Tony has been
frowning upon register dumps in the kernel and this falls into that
category. What we could do is just to print the warning but drop the
register dumps out.

-Tero


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

* [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
@ 2012-04-25  7:33       ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-04-25  7:33 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 2012-04-23 at 11:09 -0500, Jon Hunter wrote:
> Hi Tero,
> 
> On 04/20/2012 04:33 AM, Tero Kristo wrote:
> 
> [...]
> 
> > +/**
> > + * omap4_dpll_print_reg - dump out a single DPLL register value
> > + * @dpll_reg: register to dump
> > + * @name: name of the register
> > + * @tuple: content of the register
> > + *
> > + * Helper dump function to print out a DPLL register value in case
> > + * of restore failures.
> > + */
> > +static void omap4_dpll_print_reg(struct omap4_dpll_regs *dpll_reg, char *name,
> > +				 struct dpll_reg *tuple)
> > +{
> > +	if (tuple->offset)
> > +		pr_warn("%s - Address offset = 0x%08x, value=0x%08x\n", name,
> > +			tuple->offset, tuple->val);
> 
> Minor nit-pick here ...
> 
> 1. Offset is 16-bits and so we can just have "offset = 0x%04x"
> 2. Consider dropping "Address" from "Address offset"
> 3. Can we be consistent in our spaces for "offset = " and "value="?
> 
> > +}
> > +
> > +/*
> > + * omap4_dpll_dump_regs - dump out DPLL registers
> > + * @dpll_reg: DPLL to dump
> > + *
> > + * Dump out the contents of the registers for a DPLL. Called if a
> > + * restore for DPLL fails to lock.
> > + */
> > +static void omap4_dpll_dump_regs(struct omap4_dpll_regs *dpll_reg)
> > +{
> > +	pr_warn("%s: Unable to lock dpll %s[part=%x inst=%x]:\n",
> > +		__func__, dpll_reg->name, dpll_reg->mod_partition,
> > +		dpll_reg->mod_inst);
> > +	omap4_dpll_print_reg(dpll_reg, "clksel", &dpll_reg->clksel);
> > +	omap4_dpll_print_reg(dpll_reg, "div_m2", &dpll_reg->div_m2);
> > +	omap4_dpll_print_reg(dpll_reg, "div_m3", &dpll_reg->div_m3);
> > +	omap4_dpll_print_reg(dpll_reg, "div_m4", &dpll_reg->div_m4);
> > +	omap4_dpll_print_reg(dpll_reg, "div_m5", &dpll_reg->div_m5);
> > +	omap4_dpll_print_reg(dpll_reg, "div_m6", &dpll_reg->div_m6);
> > +	omap4_dpll_print_reg(dpll_reg, "div_m7", &dpll_reg->div_m7);
> > +	omap4_dpll_print_reg(dpll_reg, "clkdcoldo", &dpll_reg->clkdcoldo);
> > +	omap4_dpll_print_reg(dpll_reg, "clkmode", &dpll_reg->clkmode);
> > +	omap4_dpll_print_reg(dpll_reg, "autoidle", &dpll_reg->autoidle);
> > +	if (dpll_reg->idlest.offset)
> > +		pr_warn("idlest - Address offset = 0x%08x, before val=0x%08x"
> > +			" after = 0x%08x\n", dpll_reg->idlest.offset,
> > +			dpll_reg->idlest.val,
> > +			omap4_dpll_read_reg(dpll_reg, &dpll_reg->idlest));
> 
> Nit-pick ...
> 
> 1. Same comments as above
> 2. Consider dropping "Address offset" altogether here as we print
> "idlest" the offset should be implied.
> 3. Also can we be consistent in our naming of "before val and "after"?
> For example, "val before =" and "val now = ".

Okay, I'll modify both prints slightly. Question though, do we want
these prints in the kernel in the first place? At least Tony has been
frowning upon register dumps in the kernel and this falls into that
category. What we could do is just to print the warning but drop the
register dumps out.

-Tero

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

* Re: [PATCH 15/19] ARM: OMAP4430: PM: workaround for DDR corruption on second CS
  2012-04-25  7:26       ` Tero Kristo
@ 2012-04-25  7:59         ` Shilimkar, Santosh
  -1 siblings, 0 replies; 126+ messages in thread
From: Shilimkar, Santosh @ 2012-04-25  7:59 UTC (permalink / raw)
  To: t-kristo; +Cc: Jon Hunter, linux-omap, khilman, paul, linux-arm-kernel

On Wed, Apr 25, 2012 at 12:56 PM, Tero Kristo <t-kristo@ti.com> wrote:
> On Tue, 2012-04-24 at 13:22 -0500, Jon Hunter wrote:
>> Hi Tero,
>>
>> On 04/20/2012 04:33 AM, Tero Kristo wrote:
>> > From: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> >
>> > Work around for Errata ID: i632 "LPDDR2 Corruption After OFF Mode
>> > Transition When CS1 Is Used On EMIF" which impacts OMAP443x silicon
>> > The issue occurs when EMIF_SDRAM_CONFIG is restored first before
>> > EMIF_SDRAM_CONFIG_2 is not yet restored, the register configuration
>> > is not set properly, we apply the required workaround allowing
>> > the restore sequence to work properly.
>> >
>> > Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> > [t-kristo@ti.com: moved workaround from omap-sar.c to pm44xx.c]
>> > Signed-off-by: Tero Kristo <t-kristo@ti.com>
>> > ---
>> >  .../include/mach/ctrl_module_wkup_44xx.h           |    2 +
>> >  arch/arm/mach-omap2/pm44xx.c                       |   24 ++++++++++++++++++++
>> >  2 files changed, 26 insertions(+), 0 deletions(-)
>> >
>> > diff --git a/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
>> > index a0af9ba..b763a79 100644
>> > --- a/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
>> > +++ b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
>> > @@ -28,6 +28,8 @@
>> >  #define OMAP4_CTRL_MODULE_WKUP_IP_REVISION         0x0000
>> >  #define OMAP4_CTRL_MODULE_WKUP_IP_HWINFO           0x0004
>> >  #define OMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG                0x0010
>> > +#define OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG  0x0114
>> > +#define OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG  0x011c
>> >  #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0        0x0460
>> >  #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1        0x0464
>> >  #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2        0x0468
>> > diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
>> > index 0472921..d4d18d9 100644
>> > --- a/arch/arm/mach-omap2/pm44xx.c
>> > +++ b/arch/arm/mach-omap2/pm44xx.c
>> > @@ -17,6 +17,9 @@
>> >  #include <linux/err.h>
>> >  #include <linux/slab.h>
>> >  #include <asm/system_misc.h>
>> > +#include <linux/io.h>
>> > +
>> > +#include <mach/ctrl_module_wkup_44xx.h>
>> >
>> >  #include "common.h"
>> >  #include "clockdomain.h"
>> > @@ -215,6 +218,27 @@ static int __init omap4_pm_init(void)
>> >
>> >     pr_err("Power Management for TI OMAP4.\n");
>> >
>> > +   /*
>> > +    * Work around for OMAP443x Errata i632: "LPDDR2 Corruption After OFF
>> > +    * Mode Transition When CS1 Is Used On EMIF":
>> > +    * Overwrite EMIF1/EMIF2
>> > +    * SECURE_EMIF1_SDRAM_CONFIG2_REG
>> > +    * SECURE_EMIF2_SDRAM_CONFIG2_REG
>> > +    */
>> > +   if (cpu_is_omap443x()) {
>> > +           void __iomem *secure_ctrl_mod;
>> > +
>> > +           secure_ctrl_mod = ioremap(OMAP4_CTRL_MODULE_WKUP, SZ_4K);
>> > +           BUG_ON(!secure_ctrl_mod);
>> > +
>> > +           __raw_writel(0x10, secure_ctrl_mod +
>> > +                        OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG);
>> > +           __raw_writel(0x10, secure_ctrl_mod +
>> > +                        OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG);
>>
>> According to the erratum description the above registers are used to
>> restore the EMIFx_SDRAM_CONFIG2 registers. So although the value 0x10,
>> maybe the value being used for EMIFx_SDRAM_CONFIG2 registers, shouldn't
>> we read the EMIFx_SDRAM_CONFIG2 registers and store them in the above
>> registers?
>
> This might be a good idea, however, this patch might be tagged as TEMP
> until the EMIF driver is in place, this fix should rather be located
> there. I'll take a look at this if I can change the implementation a
> bit.
>
This patch doesn't have any dependency with EMIF driver since it's more of
SAR restore BUG. If the dependency is from the regsister macro etc point
of view, PM code can to the mapping and since it is needed only once
in the init. EMIF driver is unware of SAR restore phase and that was the
purpose of the DMA bases SAR restore design.

Hope this clarifies.

Regards
Santosh
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 15/19] ARM: OMAP4430: PM: workaround for DDR corruption on second CS
@ 2012-04-25  7:59         ` Shilimkar, Santosh
  0 siblings, 0 replies; 126+ messages in thread
From: Shilimkar, Santosh @ 2012-04-25  7:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 25, 2012 at 12:56 PM, Tero Kristo <t-kristo@ti.com> wrote:
> On Tue, 2012-04-24 at 13:22 -0500, Jon Hunter wrote:
>> Hi Tero,
>>
>> On 04/20/2012 04:33 AM, Tero Kristo wrote:
>> > From: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> >
>> > Work around for Errata ID: i632 "LPDDR2 Corruption After OFF Mode
>> > Transition When CS1 Is Used On EMIF" which impacts OMAP443x silicon
>> > The issue occurs when EMIF_SDRAM_CONFIG is restored first before
>> > EMIF_SDRAM_CONFIG_2 is not yet restored, the register configuration
>> > is not set properly, we apply the required workaround allowing
>> > the restore sequence to work properly.
>> >
>> > Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> > [t-kristo at ti.com: moved workaround from omap-sar.c to pm44xx.c]
>> > Signed-off-by: Tero Kristo <t-kristo@ti.com>
>> > ---
>> > ?.../include/mach/ctrl_module_wkup_44xx.h ? ? ? ? ? | ? ?2 +
>> > ?arch/arm/mach-omap2/pm44xx.c ? ? ? ? ? ? ? ? ? ? ? | ? 24 ++++++++++++++++++++
>> > ?2 files changed, 26 insertions(+), 0 deletions(-)
>> >
>> > diff --git a/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
>> > index a0af9ba..b763a79 100644
>> > --- a/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
>> > +++ b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
>> > @@ -28,6 +28,8 @@
>> > ?#define OMAP4_CTRL_MODULE_WKUP_IP_REVISION ? ? ? ? 0x0000
>> > ?#define OMAP4_CTRL_MODULE_WKUP_IP_HWINFO ? ? ? ? ? 0x0004
>> > ?#define OMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG ? ? ? ? ? ? ? ?0x0010
>> > +#define OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG ?0x0114
>> > +#define OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG ?0x011c
>> > ?#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0 ? ? ? ?0x0460
>> > ?#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1 ? ? ? ?0x0464
>> > ?#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2 ? ? ? ?0x0468
>> > diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
>> > index 0472921..d4d18d9 100644
>> > --- a/arch/arm/mach-omap2/pm44xx.c
>> > +++ b/arch/arm/mach-omap2/pm44xx.c
>> > @@ -17,6 +17,9 @@
>> > ?#include <linux/err.h>
>> > ?#include <linux/slab.h>
>> > ?#include <asm/system_misc.h>
>> > +#include <linux/io.h>
>> > +
>> > +#include <mach/ctrl_module_wkup_44xx.h>
>> >
>> > ?#include "common.h"
>> > ?#include "clockdomain.h"
>> > @@ -215,6 +218,27 @@ static int __init omap4_pm_init(void)
>> >
>> > ? ? pr_err("Power Management for TI OMAP4.\n");
>> >
>> > + ? /*
>> > + ? ?* Work around for OMAP443x Errata i632: "LPDDR2 Corruption After OFF
>> > + ? ?* Mode Transition When CS1 Is Used On EMIF":
>> > + ? ?* Overwrite EMIF1/EMIF2
>> > + ? ?* SECURE_EMIF1_SDRAM_CONFIG2_REG
>> > + ? ?* SECURE_EMIF2_SDRAM_CONFIG2_REG
>> > + ? ?*/
>> > + ? if (cpu_is_omap443x()) {
>> > + ? ? ? ? ? void __iomem *secure_ctrl_mod;
>> > +
>> > + ? ? ? ? ? secure_ctrl_mod = ioremap(OMAP4_CTRL_MODULE_WKUP, SZ_4K);
>> > + ? ? ? ? ? BUG_ON(!secure_ctrl_mod);
>> > +
>> > + ? ? ? ? ? __raw_writel(0x10, secure_ctrl_mod +
>> > + ? ? ? ? ? ? ? ? ? ? ? ?OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG);
>> > + ? ? ? ? ? __raw_writel(0x10, secure_ctrl_mod +
>> > + ? ? ? ? ? ? ? ? ? ? ? ?OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG);
>>
>> According to the erratum description the above registers are used to
>> restore the EMIFx_SDRAM_CONFIG2 registers. So although the value 0x10,
>> maybe the value being used for EMIFx_SDRAM_CONFIG2 registers, shouldn't
>> we read the EMIFx_SDRAM_CONFIG2 registers and store them in the above
>> registers?
>
> This might be a good idea, however, this patch might be tagged as TEMP
> until the EMIF driver is in place, this fix should rather be located
> there. I'll take a look at this if I can change the implementation a
> bit.
>
This patch doesn't have any dependency with EMIF driver since it's more of
SAR restore BUG. If the dependency is from the regsister macro etc point
of view, PM code can to the mapping and since it is needed only once
in the init. EMIF driver is unware of SAR restore phase and that was the
purpose of the DMA bases SAR restore design.

Hope this clarifies.

Regards
Santosh

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

* Re: [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
  2012-04-25  7:33       ` Tero Kristo
@ 2012-04-25 15:12         ` Jon Hunter
  -1 siblings, 0 replies; 126+ messages in thread
From: Jon Hunter @ 2012-04-25 15:12 UTC (permalink / raw)
  To: t-kristo
  Cc: Tony Lindgren, linux-omap, khilman, paul, Nishanth Menon,
	Rajendra Nayak, Santosh Shilimkar, linux-arm-kernel

Hi Tero,

On 04/25/2012 02:33 AM, Tero Kristo wrote:
> On Mon, 2012-04-23 at 11:09 -0500, Jon Hunter wrote:
>> Hi Tero,
>>
>> On 04/20/2012 04:33 AM, Tero Kristo wrote:
>>
>> [...]
>>
>>> +/**
>>> + * omap4_dpll_print_reg - dump out a single DPLL register value
>>> + * @dpll_reg: register to dump
>>> + * @name: name of the register
>>> + * @tuple: content of the register
>>> + *
>>> + * Helper dump function to print out a DPLL register value in case
>>> + * of restore failures.
>>> + */
>>> +static void omap4_dpll_print_reg(struct omap4_dpll_regs *dpll_reg, char *name,
>>> +				 struct dpll_reg *tuple)
>>> +{
>>> +	if (tuple->offset)
>>> +		pr_warn("%s - Address offset = 0x%08x, value=0x%08x\n", name,
>>> +			tuple->offset, tuple->val);
>>
>> Minor nit-pick here ...
>>
>> 1. Offset is 16-bits and so we can just have "offset = 0x%04x"
>> 2. Consider dropping "Address" from "Address offset"
>> 3. Can we be consistent in our spaces for "offset = " and "value="?
>>
>>> +}
>>> +
>>> +/*
>>> + * omap4_dpll_dump_regs - dump out DPLL registers
>>> + * @dpll_reg: DPLL to dump
>>> + *
>>> + * Dump out the contents of the registers for a DPLL. Called if a
>>> + * restore for DPLL fails to lock.
>>> + */
>>> +static void omap4_dpll_dump_regs(struct omap4_dpll_regs *dpll_reg)
>>> +{
>>> +	pr_warn("%s: Unable to lock dpll %s[part=%x inst=%x]:\n",
>>> +		__func__, dpll_reg->name, dpll_reg->mod_partition,
>>> +		dpll_reg->mod_inst);
>>> +	omap4_dpll_print_reg(dpll_reg, "clksel", &dpll_reg->clksel);
>>> +	omap4_dpll_print_reg(dpll_reg, "div_m2", &dpll_reg->div_m2);
>>> +	omap4_dpll_print_reg(dpll_reg, "div_m3", &dpll_reg->div_m3);
>>> +	omap4_dpll_print_reg(dpll_reg, "div_m4", &dpll_reg->div_m4);
>>> +	omap4_dpll_print_reg(dpll_reg, "div_m5", &dpll_reg->div_m5);
>>> +	omap4_dpll_print_reg(dpll_reg, "div_m6", &dpll_reg->div_m6);
>>> +	omap4_dpll_print_reg(dpll_reg, "div_m7", &dpll_reg->div_m7);
>>> +	omap4_dpll_print_reg(dpll_reg, "clkdcoldo", &dpll_reg->clkdcoldo);
>>> +	omap4_dpll_print_reg(dpll_reg, "clkmode", &dpll_reg->clkmode);
>>> +	omap4_dpll_print_reg(dpll_reg, "autoidle", &dpll_reg->autoidle);
>>> +	if (dpll_reg->idlest.offset)
>>> +		pr_warn("idlest - Address offset = 0x%08x, before val=0x%08x"
>>> +			" after = 0x%08x\n", dpll_reg->idlest.offset,
>>> +			dpll_reg->idlest.val,
>>> +			omap4_dpll_read_reg(dpll_reg, &dpll_reg->idlest));
>>
>> Nit-pick ...
>>
>> 1. Same comments as above
>> 2. Consider dropping "Address offset" altogether here as we print
>> "idlest" the offset should be implied.
>> 3. Also can we be consistent in our naming of "before val and "after"?
>> For example, "val before =" and "val now = ".
> 
> Okay, I'll modify both prints slightly. Question though, do we want
> these prints in the kernel in the first place? At least Tony has been
> frowning upon register dumps in the kernel and this falls into that
> category. What we could do is just to print the warning but drop the
> register dumps out.

Thanks. Good question. If we are not seeing failures often, and I would
hope not, probably ok to remove. However, I will let Tony comment here  ...

Cheers
Jon

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

* [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
@ 2012-04-25 15:12         ` Jon Hunter
  0 siblings, 0 replies; 126+ messages in thread
From: Jon Hunter @ 2012-04-25 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tero,

On 04/25/2012 02:33 AM, Tero Kristo wrote:
> On Mon, 2012-04-23 at 11:09 -0500, Jon Hunter wrote:
>> Hi Tero,
>>
>> On 04/20/2012 04:33 AM, Tero Kristo wrote:
>>
>> [...]
>>
>>> +/**
>>> + * omap4_dpll_print_reg - dump out a single DPLL register value
>>> + * @dpll_reg: register to dump
>>> + * @name: name of the register
>>> + * @tuple: content of the register
>>> + *
>>> + * Helper dump function to print out a DPLL register value in case
>>> + * of restore failures.
>>> + */
>>> +static void omap4_dpll_print_reg(struct omap4_dpll_regs *dpll_reg, char *name,
>>> +				 struct dpll_reg *tuple)
>>> +{
>>> +	if (tuple->offset)
>>> +		pr_warn("%s - Address offset = 0x%08x, value=0x%08x\n", name,
>>> +			tuple->offset, tuple->val);
>>
>> Minor nit-pick here ...
>>
>> 1. Offset is 16-bits and so we can just have "offset = 0x%04x"
>> 2. Consider dropping "Address" from "Address offset"
>> 3. Can we be consistent in our spaces for "offset = " and "value="?
>>
>>> +}
>>> +
>>> +/*
>>> + * omap4_dpll_dump_regs - dump out DPLL registers
>>> + * @dpll_reg: DPLL to dump
>>> + *
>>> + * Dump out the contents of the registers for a DPLL. Called if a
>>> + * restore for DPLL fails to lock.
>>> + */
>>> +static void omap4_dpll_dump_regs(struct omap4_dpll_regs *dpll_reg)
>>> +{
>>> +	pr_warn("%s: Unable to lock dpll %s[part=%x inst=%x]:\n",
>>> +		__func__, dpll_reg->name, dpll_reg->mod_partition,
>>> +		dpll_reg->mod_inst);
>>> +	omap4_dpll_print_reg(dpll_reg, "clksel", &dpll_reg->clksel);
>>> +	omap4_dpll_print_reg(dpll_reg, "div_m2", &dpll_reg->div_m2);
>>> +	omap4_dpll_print_reg(dpll_reg, "div_m3", &dpll_reg->div_m3);
>>> +	omap4_dpll_print_reg(dpll_reg, "div_m4", &dpll_reg->div_m4);
>>> +	omap4_dpll_print_reg(dpll_reg, "div_m5", &dpll_reg->div_m5);
>>> +	omap4_dpll_print_reg(dpll_reg, "div_m6", &dpll_reg->div_m6);
>>> +	omap4_dpll_print_reg(dpll_reg, "div_m7", &dpll_reg->div_m7);
>>> +	omap4_dpll_print_reg(dpll_reg, "clkdcoldo", &dpll_reg->clkdcoldo);
>>> +	omap4_dpll_print_reg(dpll_reg, "clkmode", &dpll_reg->clkmode);
>>> +	omap4_dpll_print_reg(dpll_reg, "autoidle", &dpll_reg->autoidle);
>>> +	if (dpll_reg->idlest.offset)
>>> +		pr_warn("idlest - Address offset = 0x%08x, before val=0x%08x"
>>> +			" after = 0x%08x\n", dpll_reg->idlest.offset,
>>> +			dpll_reg->idlest.val,
>>> +			omap4_dpll_read_reg(dpll_reg, &dpll_reg->idlest));
>>
>> Nit-pick ...
>>
>> 1. Same comments as above
>> 2. Consider dropping "Address offset" altogether here as we print
>> "idlest" the offset should be implied.
>> 3. Also can we be consistent in our naming of "before val and "after"?
>> For example, "val before =" and "val now = ".
> 
> Okay, I'll modify both prints slightly. Question though, do we want
> these prints in the kernel in the first place? At least Tony has been
> frowning upon register dumps in the kernel and this falls into that
> category. What we could do is just to print the warning but drop the
> register dumps out.

Thanks. Good question. If we are not seeing failures often, and I would
hope not, probably ok to remove. However, I will let Tony comment here  ...

Cheers
Jon

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

* Re: [PATCH 15/19] ARM: OMAP4430: PM: workaround for DDR corruption on second CS
  2012-04-25  7:26       ` Tero Kristo
@ 2012-04-25 15:16         ` Jon Hunter
  -1 siblings, 0 replies; 126+ messages in thread
From: Jon Hunter @ 2012-04-25 15:16 UTC (permalink / raw)
  To: t-kristo; +Cc: linux-omap, khilman, paul, Santosh Shilimkar, linux-arm-kernel

Hi Tero,

On 04/25/2012 02:26 AM, Tero Kristo wrote:
> On Tue, 2012-04-24 at 13:22 -0500, Jon Hunter wrote:
>> Hi Tero,
>>
>> On 04/20/2012 04:33 AM, Tero Kristo wrote:
>>> From: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>>
>>> Work around for Errata ID: i632 "LPDDR2 Corruption After OFF Mode
>>> Transition When CS1 Is Used On EMIF" which impacts OMAP443x silicon
>>> The issue occurs when EMIF_SDRAM_CONFIG is restored first before
>>> EMIF_SDRAM_CONFIG_2 is not yet restored, the register configuration
>>> is not set properly, we apply the required workaround allowing
>>> the restore sequence to work properly.
>>>
>>> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>> [t-kristo@ti.com: moved workaround from omap-sar.c to pm44xx.c]
>>> Signed-off-by: Tero Kristo <t-kristo@ti.com>
>>> ---
>>>  .../include/mach/ctrl_module_wkup_44xx.h           |    2 +
>>>  arch/arm/mach-omap2/pm44xx.c                       |   24 ++++++++++++++++++++
>>>  2 files changed, 26 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
>>> index a0af9ba..b763a79 100644
>>> --- a/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
>>> +++ b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
>>> @@ -28,6 +28,8 @@
>>>  #define OMAP4_CTRL_MODULE_WKUP_IP_REVISION		0x0000
>>>  #define OMAP4_CTRL_MODULE_WKUP_IP_HWINFO		0x0004
>>>  #define OMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG		0x0010
>>> +#define OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG	0x0114
>>> +#define OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG	0x011c
>>>  #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0	0x0460
>>>  #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1	0x0464
>>>  #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2	0x0468
>>> diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
>>> index 0472921..d4d18d9 100644
>>> --- a/arch/arm/mach-omap2/pm44xx.c
>>> +++ b/arch/arm/mach-omap2/pm44xx.c
>>> @@ -17,6 +17,9 @@
>>>  #include <linux/err.h>
>>>  #include <linux/slab.h>
>>>  #include <asm/system_misc.h>
>>> +#include <linux/io.h>
>>> +
>>> +#include <mach/ctrl_module_wkup_44xx.h>
>>>  
>>>  #include "common.h"
>>>  #include "clockdomain.h"
>>> @@ -215,6 +218,27 @@ static int __init omap4_pm_init(void)
>>>  
>>>  	pr_err("Power Management for TI OMAP4.\n");
>>>  
>>> +	/*
>>> +	 * Work around for OMAP443x Errata i632: "LPDDR2 Corruption After OFF
>>> +	 * Mode Transition When CS1 Is Used On EMIF":
>>> +	 * Overwrite EMIF1/EMIF2
>>> +	 * SECURE_EMIF1_SDRAM_CONFIG2_REG
>>> +	 * SECURE_EMIF2_SDRAM_CONFIG2_REG
>>> +	 */
>>> +	if (cpu_is_omap443x()) {
>>> +		void __iomem *secure_ctrl_mod;
>>> +
>>> +		secure_ctrl_mod = ioremap(OMAP4_CTRL_MODULE_WKUP, SZ_4K);
>>> +		BUG_ON(!secure_ctrl_mod);
>>> +
>>> +		__raw_writel(0x10, secure_ctrl_mod +
>>> +			     OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG);
>>> +		__raw_writel(0x10, secure_ctrl_mod +
>>> +			     OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG);
>>
>> According to the erratum description the above registers are used to
>> restore the EMIFx_SDRAM_CONFIG2 registers. So although the value 0x10,
>> maybe the value being used for EMIFx_SDRAM_CONFIG2 registers, shouldn't
>> we read the EMIFx_SDRAM_CONFIG2 registers and store them in the above
>> registers?
> 
> This might be a good idea, however, this patch might be tagged as TEMP
> until the EMIF driver is in place, this fix should rather be located
> there. I'll take a look at this if I can change the implementation a
> bit.

By the way, I did dump the EMIF1_SDRAM_CONFIG2 register on a omap4403
and it is configured to 0x10. So I think that reading this register and
saving would be safe.

Cheers
Jon

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

* [PATCH 15/19] ARM: OMAP4430: PM: workaround for DDR corruption on second CS
@ 2012-04-25 15:16         ` Jon Hunter
  0 siblings, 0 replies; 126+ messages in thread
From: Jon Hunter @ 2012-04-25 15:16 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tero,

On 04/25/2012 02:26 AM, Tero Kristo wrote:
> On Tue, 2012-04-24 at 13:22 -0500, Jon Hunter wrote:
>> Hi Tero,
>>
>> On 04/20/2012 04:33 AM, Tero Kristo wrote:
>>> From: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>>
>>> Work around for Errata ID: i632 "LPDDR2 Corruption After OFF Mode
>>> Transition When CS1 Is Used On EMIF" which impacts OMAP443x silicon
>>> The issue occurs when EMIF_SDRAM_CONFIG is restored first before
>>> EMIF_SDRAM_CONFIG_2 is not yet restored, the register configuration
>>> is not set properly, we apply the required workaround allowing
>>> the restore sequence to work properly.
>>>
>>> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>> [t-kristo at ti.com: moved workaround from omap-sar.c to pm44xx.c]
>>> Signed-off-by: Tero Kristo <t-kristo@ti.com>
>>> ---
>>>  .../include/mach/ctrl_module_wkup_44xx.h           |    2 +
>>>  arch/arm/mach-omap2/pm44xx.c                       |   24 ++++++++++++++++++++
>>>  2 files changed, 26 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
>>> index a0af9ba..b763a79 100644
>>> --- a/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
>>> +++ b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
>>> @@ -28,6 +28,8 @@
>>>  #define OMAP4_CTRL_MODULE_WKUP_IP_REVISION		0x0000
>>>  #define OMAP4_CTRL_MODULE_WKUP_IP_HWINFO		0x0004
>>>  #define OMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG		0x0010
>>> +#define OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG	0x0114
>>> +#define OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG	0x011c
>>>  #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0	0x0460
>>>  #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1	0x0464
>>>  #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2	0x0468
>>> diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
>>> index 0472921..d4d18d9 100644
>>> --- a/arch/arm/mach-omap2/pm44xx.c
>>> +++ b/arch/arm/mach-omap2/pm44xx.c
>>> @@ -17,6 +17,9 @@
>>>  #include <linux/err.h>
>>>  #include <linux/slab.h>
>>>  #include <asm/system_misc.h>
>>> +#include <linux/io.h>
>>> +
>>> +#include <mach/ctrl_module_wkup_44xx.h>
>>>  
>>>  #include "common.h"
>>>  #include "clockdomain.h"
>>> @@ -215,6 +218,27 @@ static int __init omap4_pm_init(void)
>>>  
>>>  	pr_err("Power Management for TI OMAP4.\n");
>>>  
>>> +	/*
>>> +	 * Work around for OMAP443x Errata i632: "LPDDR2 Corruption After OFF
>>> +	 * Mode Transition When CS1 Is Used On EMIF":
>>> +	 * Overwrite EMIF1/EMIF2
>>> +	 * SECURE_EMIF1_SDRAM_CONFIG2_REG
>>> +	 * SECURE_EMIF2_SDRAM_CONFIG2_REG
>>> +	 */
>>> +	if (cpu_is_omap443x()) {
>>> +		void __iomem *secure_ctrl_mod;
>>> +
>>> +		secure_ctrl_mod = ioremap(OMAP4_CTRL_MODULE_WKUP, SZ_4K);
>>> +		BUG_ON(!secure_ctrl_mod);
>>> +
>>> +		__raw_writel(0x10, secure_ctrl_mod +
>>> +			     OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG);
>>> +		__raw_writel(0x10, secure_ctrl_mod +
>>> +			     OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG);
>>
>> According to the erratum description the above registers are used to
>> restore the EMIFx_SDRAM_CONFIG2 registers. So although the value 0x10,
>> maybe the value being used for EMIFx_SDRAM_CONFIG2 registers, shouldn't
>> we read the EMIFx_SDRAM_CONFIG2 registers and store them in the above
>> registers?
> 
> This might be a good idea, however, this patch might be tagged as TEMP
> until the EMIF driver is in place, this fix should rather be located
> there. I'll take a look at this if I can change the implementation a
> bit.

By the way, I did dump the EMIF1_SDRAM_CONFIG2 register on a omap4403
and it is configured to 0x10. So I think that reading this register and
saving would be safe.

Cheers
Jon

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

* Re: [PATCH 15/19] ARM: OMAP4430: PM: workaround for DDR corruption on second CS
  2012-04-25 15:16         ` Jon Hunter
@ 2012-04-26  6:19           ` Shilimkar, Santosh
  -1 siblings, 0 replies; 126+ messages in thread
From: Shilimkar, Santosh @ 2012-04-26  6:19 UTC (permalink / raw)
  To: Jon Hunter; +Cc: t-kristo, linux-omap, khilman, paul, linux-arm-kernel

On Wed, Apr 25, 2012 at 8:46 PM, Jon Hunter <jon-hunter@ti.com> wrote:
> Hi Tero,
>
> On 04/25/2012 02:26 AM, Tero Kristo wrote:
>> On Tue, 2012-04-24 at 13:22 -0500, Jon Hunter wrote:
>>> Hi Tero,
>>>
>>> On 04/20/2012 04:33 AM, Tero Kristo wrote:
>>>> From: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>>>
>>>> Work around for Errata ID: i632 "LPDDR2 Corruption After OFF Mode
>>>> Transition When CS1 Is Used On EMIF" which impacts OMAP443x silicon
>>>> The issue occurs when EMIF_SDRAM_CONFIG is restored first before
>>>> EMIF_SDRAM_CONFIG_2 is not yet restored, the register configuration
>>>> is not set properly, we apply the required workaround allowing
>>>> the restore sequence to work properly.
>>>>
>>>> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>>> [t-kristo@ti.com: moved workaround from omap-sar.c to pm44xx.c]
>>>> Signed-off-by: Tero Kristo <t-kristo@ti.com>
>>>> ---
>>>>  .../include/mach/ctrl_module_wkup_44xx.h           |    2 +
>>>>  arch/arm/mach-omap2/pm44xx.c                       |   24 ++++++++++++++++++++
>>>>  2 files changed, 26 insertions(+), 0 deletions(-)
>>>>
>>>> diff --git a/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
>>>> index a0af9ba..b763a79 100644
>>>> --- a/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
>>>> +++ b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
>>>> @@ -28,6 +28,8 @@
>>>>  #define OMAP4_CTRL_MODULE_WKUP_IP_REVISION         0x0000
>>>>  #define OMAP4_CTRL_MODULE_WKUP_IP_HWINFO           0x0004
>>>>  #define OMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG                0x0010
>>>> +#define OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG  0x0114
>>>> +#define OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG  0x011c
>>>>  #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0        0x0460
>>>>  #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1        0x0464
>>>>  #define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2        0x0468
>>>> diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
>>>> index 0472921..d4d18d9 100644
>>>> --- a/arch/arm/mach-omap2/pm44xx.c
>>>> +++ b/arch/arm/mach-omap2/pm44xx.c
>>>> @@ -17,6 +17,9 @@
>>>>  #include <linux/err.h>
>>>>  #include <linux/slab.h>
>>>>  #include <asm/system_misc.h>
>>>> +#include <linux/io.h>
>>>> +
>>>> +#include <mach/ctrl_module_wkup_44xx.h>
>>>>
>>>>  #include "common.h"
>>>>  #include "clockdomain.h"
>>>> @@ -215,6 +218,27 @@ static int __init omap4_pm_init(void)
>>>>
>>>>     pr_err("Power Management for TI OMAP4.\n");
>>>>
>>>> +   /*
>>>> +    * Work around for OMAP443x Errata i632: "LPDDR2 Corruption After OFF
>>>> +    * Mode Transition When CS1 Is Used On EMIF":
>>>> +    * Overwrite EMIF1/EMIF2
>>>> +    * SECURE_EMIF1_SDRAM_CONFIG2_REG
>>>> +    * SECURE_EMIF2_SDRAM_CONFIG2_REG
>>>> +    */
>>>> +   if (cpu_is_omap443x()) {
>>>> +           void __iomem *secure_ctrl_mod;
>>>> +
>>>> +           secure_ctrl_mod = ioremap(OMAP4_CTRL_MODULE_WKUP, SZ_4K);
>>>> +           BUG_ON(!secure_ctrl_mod);
>>>> +
>>>> +           __raw_writel(0x10, secure_ctrl_mod +
>>>> +                        OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG);
>>>> +           __raw_writel(0x10, secure_ctrl_mod +
>>>> +                        OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG);
>>>
>>> According to the erratum description the above registers are used to
>>> restore the EMIFx_SDRAM_CONFIG2 registers. So although the value 0x10,
>>> maybe the value being used for EMIFx_SDRAM_CONFIG2 registers, shouldn't
>>> we read the EMIFx_SDRAM_CONFIG2 registers and store them in the above
>>> registers?
>>
>> This might be a good idea, however, this patch might be tagged as TEMP
>> until the EMIF driver is in place, this fix should rather be located
>> there. I'll take a look at this if I can change the implementation a
>> bit.
>
> By the way, I did dump the EMIF1_SDRAM_CONFIG2 register on a omap4403
> and it is configured to 0x10. So I think that reading this register and
> saving would be safe.
>
That's right. The reason it is harcoded is, it will be 0x10 or 0x0. Writing 0x10
even of we use 1 chip select doesn't create any issue as such.

But go ahead and read the register and store it. That way it will
appear bit cleaner.

Regards
Santosh
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 15/19] ARM: OMAP4430: PM: workaround for DDR corruption on second CS
@ 2012-04-26  6:19           ` Shilimkar, Santosh
  0 siblings, 0 replies; 126+ messages in thread
From: Shilimkar, Santosh @ 2012-04-26  6:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 25, 2012 at 8:46 PM, Jon Hunter <jon-hunter@ti.com> wrote:
> Hi Tero,
>
> On 04/25/2012 02:26 AM, Tero Kristo wrote:
>> On Tue, 2012-04-24 at 13:22 -0500, Jon Hunter wrote:
>>> Hi Tero,
>>>
>>> On 04/20/2012 04:33 AM, Tero Kristo wrote:
>>>> From: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>>>
>>>> Work around for Errata ID: i632 "LPDDR2 Corruption After OFF Mode
>>>> Transition When CS1 Is Used On EMIF" which impacts OMAP443x silicon
>>>> The issue occurs when EMIF_SDRAM_CONFIG is restored first before
>>>> EMIF_SDRAM_CONFIG_2 is not yet restored, the register configuration
>>>> is not set properly, we apply the required workaround allowing
>>>> the restore sequence to work properly.
>>>>
>>>> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>>> [t-kristo at ti.com: moved workaround from omap-sar.c to pm44xx.c]
>>>> Signed-off-by: Tero Kristo <t-kristo@ti.com>
>>>> ---
>>>> ?.../include/mach/ctrl_module_wkup_44xx.h ? ? ? ? ? | ? ?2 +
>>>> ?arch/arm/mach-omap2/pm44xx.c ? ? ? ? ? ? ? ? ? ? ? | ? 24 ++++++++++++++++++++
>>>> ?2 files changed, 26 insertions(+), 0 deletions(-)
>>>>
>>>> diff --git a/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
>>>> index a0af9ba..b763a79 100644
>>>> --- a/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
>>>> +++ b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
>>>> @@ -28,6 +28,8 @@
>>>> ?#define OMAP4_CTRL_MODULE_WKUP_IP_REVISION ? ? ? ? 0x0000
>>>> ?#define OMAP4_CTRL_MODULE_WKUP_IP_HWINFO ? ? ? ? ? 0x0004
>>>> ?#define OMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG ? ? ? ? ? ? ? ?0x0010
>>>> +#define OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG ?0x0114
>>>> +#define OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG ?0x011c
>>>> ?#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0 ? ? ? ?0x0460
>>>> ?#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1 ? ? ? ?0x0464
>>>> ?#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2 ? ? ? ?0x0468
>>>> diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
>>>> index 0472921..d4d18d9 100644
>>>> --- a/arch/arm/mach-omap2/pm44xx.c
>>>> +++ b/arch/arm/mach-omap2/pm44xx.c
>>>> @@ -17,6 +17,9 @@
>>>> ?#include <linux/err.h>
>>>> ?#include <linux/slab.h>
>>>> ?#include <asm/system_misc.h>
>>>> +#include <linux/io.h>
>>>> +
>>>> +#include <mach/ctrl_module_wkup_44xx.h>
>>>>
>>>> ?#include "common.h"
>>>> ?#include "clockdomain.h"
>>>> @@ -215,6 +218,27 @@ static int __init omap4_pm_init(void)
>>>>
>>>> ? ? pr_err("Power Management for TI OMAP4.\n");
>>>>
>>>> + ? /*
>>>> + ? ?* Work around for OMAP443x Errata i632: "LPDDR2 Corruption After OFF
>>>> + ? ?* Mode Transition When CS1 Is Used On EMIF":
>>>> + ? ?* Overwrite EMIF1/EMIF2
>>>> + ? ?* SECURE_EMIF1_SDRAM_CONFIG2_REG
>>>> + ? ?* SECURE_EMIF2_SDRAM_CONFIG2_REG
>>>> + ? ?*/
>>>> + ? if (cpu_is_omap443x()) {
>>>> + ? ? ? ? ? void __iomem *secure_ctrl_mod;
>>>> +
>>>> + ? ? ? ? ? secure_ctrl_mod = ioremap(OMAP4_CTRL_MODULE_WKUP, SZ_4K);
>>>> + ? ? ? ? ? BUG_ON(!secure_ctrl_mod);
>>>> +
>>>> + ? ? ? ? ? __raw_writel(0x10, secure_ctrl_mod +
>>>> + ? ? ? ? ? ? ? ? ? ? ? ?OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG);
>>>> + ? ? ? ? ? __raw_writel(0x10, secure_ctrl_mod +
>>>> + ? ? ? ? ? ? ? ? ? ? ? ?OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG);
>>>
>>> According to the erratum description the above registers are used to
>>> restore the EMIFx_SDRAM_CONFIG2 registers. So although the value 0x10,
>>> maybe the value being used for EMIFx_SDRAM_CONFIG2 registers, shouldn't
>>> we read the EMIFx_SDRAM_CONFIG2 registers and store them in the above
>>> registers?
>>
>> This might be a good idea, however, this patch might be tagged as TEMP
>> until the EMIF driver is in place, this fix should rather be located
>> there. I'll take a look at this if I can change the implementation a
>> bit.
>
> By the way, I did dump the EMIF1_SDRAM_CONFIG2 register on a omap4403
> and it is configured to 0x10. So I think that reading this register and
> saving would be safe.
>
That's right. The reason it is harcoded is, it will be 0x10 or 0x0. Writing 0x10
even of we use 1 chip select doesn't create any issue as such.

But go ahead and read the register and store it. That way it will
appear bit cleaner.

Regards
Santosh

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

* RE: [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
  2012-04-20  9:33   ` Tero Kristo
@ 2012-05-02 10:10     ` Bedia, Vaibhav
  -1 siblings, 0 replies; 126+ messages in thread
From: Bedia, Vaibhav @ 2012-05-02 10:10 UTC (permalink / raw)
  To: Kristo, Tero, linux-omap, Hilman, Kevin, paul
  Cc: Menon, Nishanth, Nayak, Rajendra, Shilimkar, Santosh, linux-arm-kernel

Hi Tero,

On Fri, Apr 20, 2012 at 15:03:34, Kristo, Tero wrote:
> From: Rajendra Nayak <rnayak@ti.com>
> 
> SAR/ROM code restores only CORE DPLL to its original state
> post wakeup from OFF mode.
> The rest of the DPLL's in OMAP4 platform (MPU/IVA/ABE/USB/PER)
> are saved and restored here during an OFF transition.
> 

Most of the registers being saved and restored in the various
patches look to be contiguous. So, instead of a long list of these
contiguous registers how about having a generic API for backup and
restore of the registers contents based on the memory address range? 

Most of the registers which require save and restore are either part
of PRM, CM or Control. The PRM or CM instance could be passed as the
base and the save/restore API could work around that.

One downside is that there are some read-only registers in between but
I don't see any simple way of avoiding save and restore of those. BTW,
as per the TRM that I have, this patch is also doing save and restore
of some read-only registers.
 
> [nm@ti.com: minor cleanups]
> Signed-off-by: Nishanth Menon <nm@ti.com>
> Signed-off-by: Rajendra Nayak <rnayak@ti.com>
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Signed-off-by: Tero Kristo <t-kristo@ti.com>
> ---
>  arch/arm/mach-omap2/cm44xx.h   |    5 +
>  arch/arm/mach-omap2/dpll44xx.c |  271 ++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 276 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/cm44xx.h b/arch/arm/mach-omap2/cm44xx.h
> index 3380bee..5fba0fa 100644
> --- a/arch/arm/mach-omap2/cm44xx.h
> +++ b/arch/arm/mach-omap2/cm44xx.h
> @@ -23,4 +23,9 @@
>  #define OMAP4_CM_CLKSTCTRL				0x0000
>  #define OMAP4_CM_STATICDEP				0x0004
>  
> +#ifndef __ASSEMBLER__
> +extern void omap4_dpll_prepare_off(void);
> +extern void omap4_dpll_resume_off(void);
> +#endif
> +
>  #endif
> diff --git a/arch/arm/mach-omap2/dpll44xx.c b/arch/arm/mach-omap2/dpll44xx.c
> index 9c6a296..b411d3b 100644
> --- a/arch/arm/mach-omap2/dpll44xx.c
> +++ b/arch/arm/mach-omap2/dpll44xx.c
> @@ -14,6 +14,7 @@
>  #include <linux/clk.h>
>  #include <linux/io.h>
>  #include <linux/bitops.h>
> +#include <linux/delay.h>
>  
>  #include <plat/cpu.h>
>  #include <plat/clock.h>
> @@ -21,6 +22,96 @@
>  #include "clock.h"
>  #include "clock44xx.h"
>  #include "cm-regbits-44xx.h"
> +#include "cm1_44xx.h"
> +#include "cm2_44xx.h"
> +#include "prcm44xx.h"
> +#include "cminst44xx.h"
> +#include "cm44xx.h"
> +
> +#define MAX_DPLL_WAIT_TRIES	1000000
> +
> +struct dpll_reg {
> +	u16 offset;
> +	u32 val;
> +};
> +
> +struct omap4_dpll_regs {
> +	char *name;
> +	u32 mod_partition;
> +	u32 mod_inst;
> +	struct dpll_reg clkmode;
> +	struct dpll_reg autoidle;
> +	struct dpll_reg idlest;
> +	struct dpll_reg clksel;
> +	struct dpll_reg div_m2;
> +	struct dpll_reg div_m3;
> +	struct dpll_reg div_m4;
> +	struct dpll_reg div_m5;
> +	struct dpll_reg div_m6;
> +	struct dpll_reg div_m7;
> +	struct dpll_reg clkdcoldo;
> +};
> +
> +static struct omap4_dpll_regs dpll_regs[] = {
> +	/* MPU DPLL */
> +	{ .name		= "mpu",
> +	  .mod_partition = OMAP4430_CM1_PARTITION,
> +	  .mod_inst	= OMAP4430_CM1_CKGEN_INST,
> +	  .clkmode	= {.offset = OMAP4_CM_CLKMODE_DPLL_MPU_OFFSET},
> +	  .autoidle	= {.offset = OMAP4_CM_AUTOIDLE_DPLL_MPU_OFFSET},
> +	  .idlest	= {.offset = OMAP4_CM_IDLEST_DPLL_MPU_OFFSET},
> +	  .clksel	= {.offset = OMAP4_CM_CLKSEL_DPLL_MPU_OFFSET},
> +	  .div_m2	= {.offset = OMAP4_CM_DIV_M2_DPLL_MPU_OFFSET},
> +	},
> +	/* IVA DPLL */
> +	{ .name		= "iva",
> +	  .mod_partition = OMAP4430_CM1_PARTITION,
> +	  .mod_inst	= OMAP4430_CM1_CKGEN_INST,
> +	  .clkmode	= {.offset = OMAP4_CM_CLKMODE_DPLL_IVA_OFFSET},
> +	  .autoidle	= {.offset = OMAP4_CM_AUTOIDLE_DPLL_IVA_OFFSET},
> +	  .idlest	= {.offset = OMAP4_CM_IDLEST_DPLL_IVA_OFFSET},
> +	  .clksel	= {.offset = OMAP4_CM_CLKSEL_DPLL_IVA_OFFSET},
> +	  .div_m4	= {.offset = OMAP4_CM_DIV_M4_DPLL_IVA_OFFSET},
> +	  .div_m5	= {.offset = OMAP4_CM_DIV_M5_DPLL_IVA_OFFSET},
> +	},
> +	/* ABE DPLL */
> +	{ .name		= "abe",
> +	  .mod_partition = OMAP4430_CM1_PARTITION,
> +	  .mod_inst	= OMAP4430_CM1_CKGEN_INST,
> +	  .clkmode	= {.offset = OMAP4_CM_CLKMODE_DPLL_ABE_OFFSET},
> +	  .autoidle	= {.offset = OMAP4_CM_AUTOIDLE_DPLL_ABE_OFFSET},
> +	  .idlest	= {.offset = OMAP4_CM_IDLEST_DPLL_ABE_OFFSET},
> +	  .clksel	= {.offset = OMAP4_CM_CLKSEL_DPLL_ABE_OFFSET},
> +	  .div_m2	= {.offset = OMAP4_CM_DIV_M2_DPLL_ABE_OFFSET},
> +	  .div_m3	= {.offset = OMAP4_CM_DIV_M3_DPLL_ABE_OFFSET},
> +	},
> +	/* USB DPLL */
> +	{ .name		= "usb",
> +	  .mod_partition = OMAP4430_CM2_PARTITION,
> +	  .mod_inst	= OMAP4430_CM2_CKGEN_INST,
> +	  .clkmode	= {.offset = OMAP4_CM_CLKMODE_DPLL_USB_OFFSET},
> +	  .autoidle	= {.offset = OMAP4_CM_AUTOIDLE_DPLL_USB_OFFSET},
> +	  .idlest	= {.offset = OMAP4_CM_IDLEST_DPLL_USB_OFFSET},
> +	  .clksel	= {.offset = OMAP4_CM_CLKSEL_DPLL_USB_OFFSET},
> +	  .div_m2	= {.offset = OMAP4_CM_DIV_M2_DPLL_USB_OFFSET},
> +	  .clkdcoldo	= {.offset = OMAP4_CM_CLKDCOLDO_DPLL_USB_OFFSET},
> +	 },
> +	/* PER DPLL */
> +	{ .name		= "per",
> +	  .mod_partition = OMAP4430_CM2_PARTITION,
> +	  .mod_inst	= OMAP4430_CM2_CKGEN_INST,
> +	  .clkmode	= {.offset = OMAP4_CM_CLKMODE_DPLL_PER_OFFSET},
> +	  .autoidle	= {.offset = OMAP4_CM_AUTOIDLE_DPLL_PER_OFFSET},
> +	  .idlest	= {.offset = OMAP4_CM_IDLEST_DPLL_PER_OFFSET},
> +	  .clksel	= {.offset = OMAP4_CM_CLKSEL_DPLL_PER_OFFSET},
> +	  .div_m2	= {.offset = OMAP4_CM_DIV_M2_DPLL_PER_OFFSET},
> +	  .div_m3	= {.offset = OMAP4_CM_DIV_M3_DPLL_PER_OFFSET},
> +	  .div_m4	= {.offset = OMAP4_CM_DIV_M4_DPLL_PER_OFFSET},
> +	  .div_m5	= {.offset = OMAP4_CM_DIV_M5_DPLL_PER_OFFSET},
> +	  .div_m6	= {.offset = OMAP4_CM_DIV_M6_DPLL_PER_OFFSET},
> +	  .div_m7	= {.offset = OMAP4_CM_DIV_M7_DPLL_PER_OFFSET},
> +	},
> +};
>  
>  /* Supported only on OMAP4 */
>  int omap4_dpllmx_gatectrl_read(struct clk *clk)
> @@ -151,3 +242,183 @@ long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate)
>  
>  	return clk->dpll_data->last_rounded_rate;
>  }
> +
> +/**
> + * omap4_dpll_read_reg - reads DPLL register value
> + * @dpll_reg: DPLL register to read
> + *
> + * Reads the value of a single DPLL register.
> + */
> +static inline u32 omap4_dpll_read_reg(struct omap4_dpll_regs *dpll_reg,
> +				      struct dpll_reg *tuple)
> +{
> +	if (tuple->offset)
> +		return omap4_cminst_read_inst_reg(dpll_reg->mod_partition,
> +						  dpll_reg->mod_inst,
> +						  tuple->offset);
> +	return 0;
> +}
> +
> +/**
> + * omap4_dpll_store_reg - stores DPLL register value to memory location
> + * @dpll_reg: DPLL register to save
> + * @tuple: save address
> + *
> + * Saves a single DPLL register content to memory location defined by
> + * @tuple before entering device off mode.
> + */
> +static inline void omap4_dpll_store_reg(struct omap4_dpll_regs *dpll_reg,
> +					struct dpll_reg *tuple)
> +{
> +	tuple->val = omap4_dpll_read_reg(dpll_reg, tuple);
> +}
> +
> +/**
> + * omap4_dpll_prepare_off - stores DPLL settings before off mode
> + *
> + * Saves all DPLL register settings. This must be called before
> + * entering device off.
> + */
> +void omap4_dpll_prepare_off(void)
> +{
> +	u32 i;
> +	struct omap4_dpll_regs *dpll_reg = dpll_regs;
> +
> +	for (i = 0; i < ARRAY_SIZE(dpll_regs); i++, dpll_reg++) {
> +		omap4_dpll_store_reg(dpll_reg, &dpll_reg->clkmode);
> +		omap4_dpll_store_reg(dpll_reg, &dpll_reg->autoidle);
> +		omap4_dpll_store_reg(dpll_reg, &dpll_reg->clksel);
> +		omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m2);
> +		omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m3);
> +		omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m4);
> +		omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m5);
> +		omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m6);
> +		omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m7);
> +		omap4_dpll_store_reg(dpll_reg, &dpll_reg->clkdcoldo);
> +		omap4_dpll_store_reg(dpll_reg, &dpll_reg->idlest);
> +	}
> +}
> +
> +/**
> + * omap4_dpll_print_reg - dump out a single DPLL register value
> + * @dpll_reg: register to dump
> + * @name: name of the register
> + * @tuple: content of the register
> + *
> + * Helper dump function to print out a DPLL register value in case
> + * of restore failures.
> + */
> +static void omap4_dpll_print_reg(struct omap4_dpll_regs *dpll_reg, char *name,
> +				 struct dpll_reg *tuple)
> +{
> +	if (tuple->offset)
> +		pr_warn("%s - Address offset = 0x%08x, value=0x%08x\n", name,
> +			tuple->offset, tuple->val);
> +}
> +
> +/*
> + * omap4_dpll_dump_regs - dump out DPLL registers
> + * @dpll_reg: DPLL to dump
> + *
> + * Dump out the contents of the registers for a DPLL. Called if a
> + * restore for DPLL fails to lock.
> + */
> +static void omap4_dpll_dump_regs(struct omap4_dpll_regs *dpll_reg)
> +{
> +	pr_warn("%s: Unable to lock dpll %s[part=%x inst=%x]:\n",
> +		__func__, dpll_reg->name, dpll_reg->mod_partition,
> +		dpll_reg->mod_inst);
> +	omap4_dpll_print_reg(dpll_reg, "clksel", &dpll_reg->clksel);
> +	omap4_dpll_print_reg(dpll_reg, "div_m2", &dpll_reg->div_m2);
> +	omap4_dpll_print_reg(dpll_reg, "div_m3", &dpll_reg->div_m3);
> +	omap4_dpll_print_reg(dpll_reg, "div_m4", &dpll_reg->div_m4);
> +	omap4_dpll_print_reg(dpll_reg, "div_m5", &dpll_reg->div_m5);
> +	omap4_dpll_print_reg(dpll_reg, "div_m6", &dpll_reg->div_m6);
> +	omap4_dpll_print_reg(dpll_reg, "div_m7", &dpll_reg->div_m7);
> +	omap4_dpll_print_reg(dpll_reg, "clkdcoldo", &dpll_reg->clkdcoldo);
> +	omap4_dpll_print_reg(dpll_reg, "clkmode", &dpll_reg->clkmode);
> +	omap4_dpll_print_reg(dpll_reg, "autoidle", &dpll_reg->autoidle);
> +	if (dpll_reg->idlest.offset)
> +		pr_warn("idlest - Address offset = 0x%08x, before val=0x%08x"
> +			" after = 0x%08x\n", dpll_reg->idlest.offset,
> +			dpll_reg->idlest.val,
> +			omap4_dpll_read_reg(dpll_reg, &dpll_reg->idlest));
> +}
> +
> +/**
> + * omap4_wait_dpll_lock - wait for a DPLL lock
> + * @dpll_reg: DPLL to wait for
> + *
> + * Waits for a DPLL lock after restore.
> + */
> +static void omap4_wait_dpll_lock(struct omap4_dpll_regs *dpll_reg)
> +{
> +	int j = 0;
> +	u32 status;
> +
> +	/* Return if we dont need to lock. */
> +	if ((dpll_reg->clkmode.val & OMAP4430_DPLL_EN_MASK) !=
> +	     DPLL_LOCKED << OMAP4430_DPLL_EN_SHIFT)
> +		return;
> +
> +	while (1) {
> +		status = (omap4_dpll_read_reg(dpll_reg, &dpll_reg->idlest)
> +			  & OMAP4430_ST_DPLL_CLK_MASK)
> +			 >> OMAP4430_ST_DPLL_CLK_SHIFT;
> +		if (status == 0x1)
> +			break;
> +		if (j == MAX_DPLL_WAIT_TRIES) {
> +			/* If we are unable to lock, warn and move on.. */
> +			omap4_dpll_dump_regs(dpll_reg);
> +			break;
> +		}
> +		j++;
> +		udelay(1);
> +	}
> +}
> +
> +/**
> + * omap4_dpll_restore_reg - restores a single register for a DPLL
> + * @dpll_reg: DPLL to restore
> + * @tuple: register value to restore
> + *
> + * Restores a single register for a DPLL.
> + */
> +static inline void omap4_dpll_restore_reg(struct omap4_dpll_regs *dpll_reg,
> +					  struct dpll_reg *tuple)
> +{
> +	if (tuple->offset)
> +		omap4_cminst_write_inst_reg(tuple->val, dpll_reg->mod_partition,
> +					    dpll_reg->mod_inst, tuple->offset);
> +}
> +
> +/**
> + * omap4_dpll_resume_off - restore DPLL settings after device off
> + *
> + * Restores all DPLL settings. Must be called after wakeup from device
> + * off.
> + */
> +void omap4_dpll_resume_off(void)
> +{
> +	u32 i;
> +	struct omap4_dpll_regs *dpll_reg = dpll_regs;
> +
> +	for (i = 0; i < ARRAY_SIZE(dpll_regs); i++, dpll_reg++) {
> +		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clksel);
> +		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m2);
> +		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m3);
> +		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m4);
> +		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m5);
> +		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m6);
> +		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m7);
> +		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkdcoldo);
> +
> +		/* Restore clkmode after the above registers are restored */
> +		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkmode);
> +
> +		omap4_wait_dpll_lock(dpll_reg);
> +
> +		/* Restore autoidle settings after the dpll is locked */
> +		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->autoidle);
> +	}
> +}

If this function is placed in SRAM and PER PLL restored just after MPU
won't the exit latency be further optimized?


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

* [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
@ 2012-05-02 10:10     ` Bedia, Vaibhav
  0 siblings, 0 replies; 126+ messages in thread
From: Bedia, Vaibhav @ 2012-05-02 10:10 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tero,

On Fri, Apr 20, 2012 at 15:03:34, Kristo, Tero wrote:
> From: Rajendra Nayak <rnayak@ti.com>
> 
> SAR/ROM code restores only CORE DPLL to its original state
> post wakeup from OFF mode.
> The rest of the DPLL's in OMAP4 platform (MPU/IVA/ABE/USB/PER)
> are saved and restored here during an OFF transition.
> 

Most of the registers being saved and restored in the various
patches look to be contiguous. So, instead of a long list of these
contiguous registers how about having a generic API for backup and
restore of the registers contents based on the memory address range? 

Most of the registers which require save and restore are either part
of PRM, CM or Control. The PRM or CM instance could be passed as the
base and the save/restore API could work around that.

One downside is that there are some read-only registers in between but
I don't see any simple way of avoiding save and restore of those. BTW,
as per the TRM that I have, this patch is also doing save and restore
of some read-only registers.
 
> [nm at ti.com: minor cleanups]
> Signed-off-by: Nishanth Menon <nm@ti.com>
> Signed-off-by: Rajendra Nayak <rnayak@ti.com>
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Signed-off-by: Tero Kristo <t-kristo@ti.com>
> ---
>  arch/arm/mach-omap2/cm44xx.h   |    5 +
>  arch/arm/mach-omap2/dpll44xx.c |  271 ++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 276 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/cm44xx.h b/arch/arm/mach-omap2/cm44xx.h
> index 3380bee..5fba0fa 100644
> --- a/arch/arm/mach-omap2/cm44xx.h
> +++ b/arch/arm/mach-omap2/cm44xx.h
> @@ -23,4 +23,9 @@
>  #define OMAP4_CM_CLKSTCTRL				0x0000
>  #define OMAP4_CM_STATICDEP				0x0004
>  
> +#ifndef __ASSEMBLER__
> +extern void omap4_dpll_prepare_off(void);
> +extern void omap4_dpll_resume_off(void);
> +#endif
> +
>  #endif
> diff --git a/arch/arm/mach-omap2/dpll44xx.c b/arch/arm/mach-omap2/dpll44xx.c
> index 9c6a296..b411d3b 100644
> --- a/arch/arm/mach-omap2/dpll44xx.c
> +++ b/arch/arm/mach-omap2/dpll44xx.c
> @@ -14,6 +14,7 @@
>  #include <linux/clk.h>
>  #include <linux/io.h>
>  #include <linux/bitops.h>
> +#include <linux/delay.h>
>  
>  #include <plat/cpu.h>
>  #include <plat/clock.h>
> @@ -21,6 +22,96 @@
>  #include "clock.h"
>  #include "clock44xx.h"
>  #include "cm-regbits-44xx.h"
> +#include "cm1_44xx.h"
> +#include "cm2_44xx.h"
> +#include "prcm44xx.h"
> +#include "cminst44xx.h"
> +#include "cm44xx.h"
> +
> +#define MAX_DPLL_WAIT_TRIES	1000000
> +
> +struct dpll_reg {
> +	u16 offset;
> +	u32 val;
> +};
> +
> +struct omap4_dpll_regs {
> +	char *name;
> +	u32 mod_partition;
> +	u32 mod_inst;
> +	struct dpll_reg clkmode;
> +	struct dpll_reg autoidle;
> +	struct dpll_reg idlest;
> +	struct dpll_reg clksel;
> +	struct dpll_reg div_m2;
> +	struct dpll_reg div_m3;
> +	struct dpll_reg div_m4;
> +	struct dpll_reg div_m5;
> +	struct dpll_reg div_m6;
> +	struct dpll_reg div_m7;
> +	struct dpll_reg clkdcoldo;
> +};
> +
> +static struct omap4_dpll_regs dpll_regs[] = {
> +	/* MPU DPLL */
> +	{ .name		= "mpu",
> +	  .mod_partition = OMAP4430_CM1_PARTITION,
> +	  .mod_inst	= OMAP4430_CM1_CKGEN_INST,
> +	  .clkmode	= {.offset = OMAP4_CM_CLKMODE_DPLL_MPU_OFFSET},
> +	  .autoidle	= {.offset = OMAP4_CM_AUTOIDLE_DPLL_MPU_OFFSET},
> +	  .idlest	= {.offset = OMAP4_CM_IDLEST_DPLL_MPU_OFFSET},
> +	  .clksel	= {.offset = OMAP4_CM_CLKSEL_DPLL_MPU_OFFSET},
> +	  .div_m2	= {.offset = OMAP4_CM_DIV_M2_DPLL_MPU_OFFSET},
> +	},
> +	/* IVA DPLL */
> +	{ .name		= "iva",
> +	  .mod_partition = OMAP4430_CM1_PARTITION,
> +	  .mod_inst	= OMAP4430_CM1_CKGEN_INST,
> +	  .clkmode	= {.offset = OMAP4_CM_CLKMODE_DPLL_IVA_OFFSET},
> +	  .autoidle	= {.offset = OMAP4_CM_AUTOIDLE_DPLL_IVA_OFFSET},
> +	  .idlest	= {.offset = OMAP4_CM_IDLEST_DPLL_IVA_OFFSET},
> +	  .clksel	= {.offset = OMAP4_CM_CLKSEL_DPLL_IVA_OFFSET},
> +	  .div_m4	= {.offset = OMAP4_CM_DIV_M4_DPLL_IVA_OFFSET},
> +	  .div_m5	= {.offset = OMAP4_CM_DIV_M5_DPLL_IVA_OFFSET},
> +	},
> +	/* ABE DPLL */
> +	{ .name		= "abe",
> +	  .mod_partition = OMAP4430_CM1_PARTITION,
> +	  .mod_inst	= OMAP4430_CM1_CKGEN_INST,
> +	  .clkmode	= {.offset = OMAP4_CM_CLKMODE_DPLL_ABE_OFFSET},
> +	  .autoidle	= {.offset = OMAP4_CM_AUTOIDLE_DPLL_ABE_OFFSET},
> +	  .idlest	= {.offset = OMAP4_CM_IDLEST_DPLL_ABE_OFFSET},
> +	  .clksel	= {.offset = OMAP4_CM_CLKSEL_DPLL_ABE_OFFSET},
> +	  .div_m2	= {.offset = OMAP4_CM_DIV_M2_DPLL_ABE_OFFSET},
> +	  .div_m3	= {.offset = OMAP4_CM_DIV_M3_DPLL_ABE_OFFSET},
> +	},
> +	/* USB DPLL */
> +	{ .name		= "usb",
> +	  .mod_partition = OMAP4430_CM2_PARTITION,
> +	  .mod_inst	= OMAP4430_CM2_CKGEN_INST,
> +	  .clkmode	= {.offset = OMAP4_CM_CLKMODE_DPLL_USB_OFFSET},
> +	  .autoidle	= {.offset = OMAP4_CM_AUTOIDLE_DPLL_USB_OFFSET},
> +	  .idlest	= {.offset = OMAP4_CM_IDLEST_DPLL_USB_OFFSET},
> +	  .clksel	= {.offset = OMAP4_CM_CLKSEL_DPLL_USB_OFFSET},
> +	  .div_m2	= {.offset = OMAP4_CM_DIV_M2_DPLL_USB_OFFSET},
> +	  .clkdcoldo	= {.offset = OMAP4_CM_CLKDCOLDO_DPLL_USB_OFFSET},
> +	 },
> +	/* PER DPLL */
> +	{ .name		= "per",
> +	  .mod_partition = OMAP4430_CM2_PARTITION,
> +	  .mod_inst	= OMAP4430_CM2_CKGEN_INST,
> +	  .clkmode	= {.offset = OMAP4_CM_CLKMODE_DPLL_PER_OFFSET},
> +	  .autoidle	= {.offset = OMAP4_CM_AUTOIDLE_DPLL_PER_OFFSET},
> +	  .idlest	= {.offset = OMAP4_CM_IDLEST_DPLL_PER_OFFSET},
> +	  .clksel	= {.offset = OMAP4_CM_CLKSEL_DPLL_PER_OFFSET},
> +	  .div_m2	= {.offset = OMAP4_CM_DIV_M2_DPLL_PER_OFFSET},
> +	  .div_m3	= {.offset = OMAP4_CM_DIV_M3_DPLL_PER_OFFSET},
> +	  .div_m4	= {.offset = OMAP4_CM_DIV_M4_DPLL_PER_OFFSET},
> +	  .div_m5	= {.offset = OMAP4_CM_DIV_M5_DPLL_PER_OFFSET},
> +	  .div_m6	= {.offset = OMAP4_CM_DIV_M6_DPLL_PER_OFFSET},
> +	  .div_m7	= {.offset = OMAP4_CM_DIV_M7_DPLL_PER_OFFSET},
> +	},
> +};
>  
>  /* Supported only on OMAP4 */
>  int omap4_dpllmx_gatectrl_read(struct clk *clk)
> @@ -151,3 +242,183 @@ long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate)
>  
>  	return clk->dpll_data->last_rounded_rate;
>  }
> +
> +/**
> + * omap4_dpll_read_reg - reads DPLL register value
> + * @dpll_reg: DPLL register to read
> + *
> + * Reads the value of a single DPLL register.
> + */
> +static inline u32 omap4_dpll_read_reg(struct omap4_dpll_regs *dpll_reg,
> +				      struct dpll_reg *tuple)
> +{
> +	if (tuple->offset)
> +		return omap4_cminst_read_inst_reg(dpll_reg->mod_partition,
> +						  dpll_reg->mod_inst,
> +						  tuple->offset);
> +	return 0;
> +}
> +
> +/**
> + * omap4_dpll_store_reg - stores DPLL register value to memory location
> + * @dpll_reg: DPLL register to save
> + * @tuple: save address
> + *
> + * Saves a single DPLL register content to memory location defined by
> + * @tuple before entering device off mode.
> + */
> +static inline void omap4_dpll_store_reg(struct omap4_dpll_regs *dpll_reg,
> +					struct dpll_reg *tuple)
> +{
> +	tuple->val = omap4_dpll_read_reg(dpll_reg, tuple);
> +}
> +
> +/**
> + * omap4_dpll_prepare_off - stores DPLL settings before off mode
> + *
> + * Saves all DPLL register settings. This must be called before
> + * entering device off.
> + */
> +void omap4_dpll_prepare_off(void)
> +{
> +	u32 i;
> +	struct omap4_dpll_regs *dpll_reg = dpll_regs;
> +
> +	for (i = 0; i < ARRAY_SIZE(dpll_regs); i++, dpll_reg++) {
> +		omap4_dpll_store_reg(dpll_reg, &dpll_reg->clkmode);
> +		omap4_dpll_store_reg(dpll_reg, &dpll_reg->autoidle);
> +		omap4_dpll_store_reg(dpll_reg, &dpll_reg->clksel);
> +		omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m2);
> +		omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m3);
> +		omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m4);
> +		omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m5);
> +		omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m6);
> +		omap4_dpll_store_reg(dpll_reg, &dpll_reg->div_m7);
> +		omap4_dpll_store_reg(dpll_reg, &dpll_reg->clkdcoldo);
> +		omap4_dpll_store_reg(dpll_reg, &dpll_reg->idlest);
> +	}
> +}
> +
> +/**
> + * omap4_dpll_print_reg - dump out a single DPLL register value
> + * @dpll_reg: register to dump
> + * @name: name of the register
> + * @tuple: content of the register
> + *
> + * Helper dump function to print out a DPLL register value in case
> + * of restore failures.
> + */
> +static void omap4_dpll_print_reg(struct omap4_dpll_regs *dpll_reg, char *name,
> +				 struct dpll_reg *tuple)
> +{
> +	if (tuple->offset)
> +		pr_warn("%s - Address offset = 0x%08x, value=0x%08x\n", name,
> +			tuple->offset, tuple->val);
> +}
> +
> +/*
> + * omap4_dpll_dump_regs - dump out DPLL registers
> + * @dpll_reg: DPLL to dump
> + *
> + * Dump out the contents of the registers for a DPLL. Called if a
> + * restore for DPLL fails to lock.
> + */
> +static void omap4_dpll_dump_regs(struct omap4_dpll_regs *dpll_reg)
> +{
> +	pr_warn("%s: Unable to lock dpll %s[part=%x inst=%x]:\n",
> +		__func__, dpll_reg->name, dpll_reg->mod_partition,
> +		dpll_reg->mod_inst);
> +	omap4_dpll_print_reg(dpll_reg, "clksel", &dpll_reg->clksel);
> +	omap4_dpll_print_reg(dpll_reg, "div_m2", &dpll_reg->div_m2);
> +	omap4_dpll_print_reg(dpll_reg, "div_m3", &dpll_reg->div_m3);
> +	omap4_dpll_print_reg(dpll_reg, "div_m4", &dpll_reg->div_m4);
> +	omap4_dpll_print_reg(dpll_reg, "div_m5", &dpll_reg->div_m5);
> +	omap4_dpll_print_reg(dpll_reg, "div_m6", &dpll_reg->div_m6);
> +	omap4_dpll_print_reg(dpll_reg, "div_m7", &dpll_reg->div_m7);
> +	omap4_dpll_print_reg(dpll_reg, "clkdcoldo", &dpll_reg->clkdcoldo);
> +	omap4_dpll_print_reg(dpll_reg, "clkmode", &dpll_reg->clkmode);
> +	omap4_dpll_print_reg(dpll_reg, "autoidle", &dpll_reg->autoidle);
> +	if (dpll_reg->idlest.offset)
> +		pr_warn("idlest - Address offset = 0x%08x, before val=0x%08x"
> +			" after = 0x%08x\n", dpll_reg->idlest.offset,
> +			dpll_reg->idlest.val,
> +			omap4_dpll_read_reg(dpll_reg, &dpll_reg->idlest));
> +}
> +
> +/**
> + * omap4_wait_dpll_lock - wait for a DPLL lock
> + * @dpll_reg: DPLL to wait for
> + *
> + * Waits for a DPLL lock after restore.
> + */
> +static void omap4_wait_dpll_lock(struct omap4_dpll_regs *dpll_reg)
> +{
> +	int j = 0;
> +	u32 status;
> +
> +	/* Return if we dont need to lock. */
> +	if ((dpll_reg->clkmode.val & OMAP4430_DPLL_EN_MASK) !=
> +	     DPLL_LOCKED << OMAP4430_DPLL_EN_SHIFT)
> +		return;
> +
> +	while (1) {
> +		status = (omap4_dpll_read_reg(dpll_reg, &dpll_reg->idlest)
> +			  & OMAP4430_ST_DPLL_CLK_MASK)
> +			 >> OMAP4430_ST_DPLL_CLK_SHIFT;
> +		if (status == 0x1)
> +			break;
> +		if (j == MAX_DPLL_WAIT_TRIES) {
> +			/* If we are unable to lock, warn and move on.. */
> +			omap4_dpll_dump_regs(dpll_reg);
> +			break;
> +		}
> +		j++;
> +		udelay(1);
> +	}
> +}
> +
> +/**
> + * omap4_dpll_restore_reg - restores a single register for a DPLL
> + * @dpll_reg: DPLL to restore
> + * @tuple: register value to restore
> + *
> + * Restores a single register for a DPLL.
> + */
> +static inline void omap4_dpll_restore_reg(struct omap4_dpll_regs *dpll_reg,
> +					  struct dpll_reg *tuple)
> +{
> +	if (tuple->offset)
> +		omap4_cminst_write_inst_reg(tuple->val, dpll_reg->mod_partition,
> +					    dpll_reg->mod_inst, tuple->offset);
> +}
> +
> +/**
> + * omap4_dpll_resume_off - restore DPLL settings after device off
> + *
> + * Restores all DPLL settings. Must be called after wakeup from device
> + * off.
> + */
> +void omap4_dpll_resume_off(void)
> +{
> +	u32 i;
> +	struct omap4_dpll_regs *dpll_reg = dpll_regs;
> +
> +	for (i = 0; i < ARRAY_SIZE(dpll_regs); i++, dpll_reg++) {
> +		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clksel);
> +		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m2);
> +		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m3);
> +		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m4);
> +		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m5);
> +		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m6);
> +		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m7);
> +		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkdcoldo);
> +
> +		/* Restore clkmode after the above registers are restored */
> +		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkmode);
> +
> +		omap4_wait_dpll_lock(dpll_reg);
> +
> +		/* Restore autoidle settings after the dpll is locked */
> +		omap4_dpll_restore_reg(dpll_reg, &dpll_reg->autoidle);
> +	}
> +}

If this function is placed in SRAM and PER PLL restored just after MPU
won't the exit latency be further optimized?

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

* Re: [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
  2012-05-02 10:10     ` Bedia, Vaibhav
@ 2012-05-02 10:18       ` Shilimkar, Santosh
  -1 siblings, 0 replies; 126+ messages in thread
From: Shilimkar, Santosh @ 2012-05-02 10:18 UTC (permalink / raw)
  To: Bedia, Vaibhav
  Cc: Kristo, Tero, linux-omap, Hilman, Kevin, paul, Menon, Nishanth,
	Nayak, Rajendra, linux-arm-kernel

On Wed, May 2, 2012 at 3:40 PM, Bedia, Vaibhav <vaibhav.bedia@ti.com> wrote:
> Hi Tero,
>
> On Fri, Apr 20, 2012 at 15:03:34, Kristo, Tero wrote:
>> From: Rajendra Nayak <rnayak@ti.com>
>>
>> SAR/ROM code restores only CORE DPLL to its original state
>> post wakeup from OFF mode.
>> The rest of the DPLL's in OMAP4 platform (MPU/IVA/ABE/USB/PER)
>> are saved and restored here during an OFF transition.
>>
>
> Most of the registers being saved and restored in the various
> patches look to be contiguous. So, instead of a long list of these
> contiguous registers how about having a generic API for backup and
> restore of the registers contents based on the memory address range?
>
> Most of the registers which require save and restore are either part
> of PRM, CM or Control. The PRM or CM instance could be passed as the
> base and the save/restore API could work around that.
>
> One downside is that there are some read-only registers in between but
> I don't see any simple way of avoiding save and restore of those. BTW,
> as per the TRM that I have, this patch is also doing save and restore
> of some read-only registers.
>
You should never write to read-only registers since the behavior is
undefined.

[...]
>> +void omap4_dpll_resume_off(void)
>> +{
>> +     u32 i;
>> +     struct omap4_dpll_regs *dpll_reg = dpll_regs;
>> +
>> +     for (i = 0; i < ARRAY_SIZE(dpll_regs); i++, dpll_reg++) {
>> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clksel);
>> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m2);
>> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m3);
>> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m4);
>> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m5);
>> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m6);
>> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m7);
>> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkdcoldo);
>> +
>> +             /* Restore clkmode after the above registers are restored */
>> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkmode);
>> +
>> +             omap4_wait_dpll_lock(dpll_reg);
>> +
>> +             /* Restore autoidle settings after the dpll is locked */
>> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->autoidle);
>> +     }
>> +}
>
> If this function is placed in SRAM and PER PLL restored just after MPU
> won't the exit latency be further optimized?
>
How ?
SRAM is sower memory than DDR so I don't see how it
will reduce latency.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
@ 2012-05-02 10:18       ` Shilimkar, Santosh
  0 siblings, 0 replies; 126+ messages in thread
From: Shilimkar, Santosh @ 2012-05-02 10:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 2, 2012 at 3:40 PM, Bedia, Vaibhav <vaibhav.bedia@ti.com> wrote:
> Hi Tero,
>
> On Fri, Apr 20, 2012 at 15:03:34, Kristo, Tero wrote:
>> From: Rajendra Nayak <rnayak@ti.com>
>>
>> SAR/ROM code restores only CORE DPLL to its original state
>> post wakeup from OFF mode.
>> The rest of the DPLL's in OMAP4 platform (MPU/IVA/ABE/USB/PER)
>> are saved and restored here during an OFF transition.
>>
>
> Most of the registers being saved and restored in the various
> patches look to be contiguous. So, instead of a long list of these
> contiguous registers how about having a generic API for backup and
> restore of the registers contents based on the memory address range?
>
> Most of the registers which require save and restore are either part
> of PRM, CM or Control. The PRM or CM instance could be passed as the
> base and the save/restore API could work around that.
>
> One downside is that there are some read-only registers in between but
> I don't see any simple way of avoiding save and restore of those. BTW,
> as per the TRM that I have, this patch is also doing save and restore
> of some read-only registers.
>
You should never write to read-only registers since the behavior is
undefined.

[...]
>> +void omap4_dpll_resume_off(void)
>> +{
>> + ? ? u32 i;
>> + ? ? struct omap4_dpll_regs *dpll_reg = dpll_regs;
>> +
>> + ? ? for (i = 0; i < ARRAY_SIZE(dpll_regs); i++, dpll_reg++) {
>> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clksel);
>> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m2);
>> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m3);
>> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m4);
>> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m5);
>> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m6);
>> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m7);
>> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkdcoldo);
>> +
>> + ? ? ? ? ? ? /* Restore clkmode after the above registers are restored */
>> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkmode);
>> +
>> + ? ? ? ? ? ? omap4_wait_dpll_lock(dpll_reg);
>> +
>> + ? ? ? ? ? ? /* Restore autoidle settings after the dpll is locked */
>> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->autoidle);
>> + ? ? }
>> +}
>
> If this function is placed in SRAM and PER PLL restored just after MPU
> won't the exit latency be further optimized?
>
How ?
SRAM is sower memory than DDR so I don't see how it
will reduce latency.

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

* RE: [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
  2012-05-02 10:18       ` Shilimkar, Santosh
@ 2012-05-02 10:55         ` Bedia, Vaibhav
  -1 siblings, 0 replies; 126+ messages in thread
From: Bedia, Vaibhav @ 2012-05-02 10:55 UTC (permalink / raw)
  To: Shilimkar, Santosh
  Cc: Kristo, Tero, linux-omap, Hilman, Kevin, paul, Menon, Nishanth,
	Nayak, Rajendra, linux-arm-kernel

On Wed, May 02, 2012 at 15:48:01, Shilimkar, Santosh wrote:
> On Wed, May 2, 2012 at 3:40 PM, Bedia, Vaibhav <vaibhav.bedia@ti.com> wrote:
> > Hi Tero,
> >
> > On Fri, Apr 20, 2012 at 15:03:34, Kristo, Tero wrote:
> >> From: Rajendra Nayak <rnayak@ti.com>
> >>
> >> SAR/ROM code restores only CORE DPLL to its original state
> >> post wakeup from OFF mode.
> >> The rest of the DPLL's in OMAP4 platform (MPU/IVA/ABE/USB/PER)
> >> are saved and restored here during an OFF transition.
> >>
> >
> > Most of the registers being saved and restored in the various
> > patches look to be contiguous. So, instead of a long list of these
> > contiguous registers how about having a generic API for backup and
> > restore of the registers contents based on the memory address range?
> >
> > Most of the registers which require save and restore are either part
> > of PRM, CM or Control. The PRM or CM instance could be passed as the
> > base and the save/restore API could work around that.
> >
> > One downside is that there are some read-only registers in between but
> > I don't see any simple way of avoiding save and restore of those. BTW,
> > as per the TRM that I have, this patch is also doing save and restore
> > of some read-only registers.
> >
> You should never write to read-only registers since the behavior is
> undefined.

I was afraid of that. If all the read-only registers were clubbed together
a lot of code could have been removed. Looking more closely at the TRM
I guess we can't really ask design folks to club those read-only registers
in the future. So scratch this.

> 
> [...]
> >> +void omap4_dpll_resume_off(void)
> >> +{
> >> +     u32 i;
> >> +     struct omap4_dpll_regs *dpll_reg = dpll_regs;
> >> +
> >> +     for (i = 0; i < ARRAY_SIZE(dpll_regs); i++, dpll_reg++) {
> >> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clksel);
> >> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m2);
> >> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m3);
> >> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m4);
> >> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m5);
> >> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m6);
> >> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m7);
> >> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkdcoldo);
> >> +
> >> +             /* Restore clkmode after the above registers are restored */
> >> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkmode);
> >> +
> >> +             omap4_wait_dpll_lock(dpll_reg);
> >> +
> >> +             /* Restore autoidle settings after the dpll is locked */
> >> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->autoidle);
> >> +     }
> >> +}
> >
> > If this function is placed in SRAM and PER PLL restored just after MPU
> > won't the exit latency be further optimized?
> >
> How ?
> SRAM is sower memory than DDR so I don't see how it
> will reduce latency.
> 

I am just guessing if that's indeed the case ;) 
Haven't done any measurements to really check if that's indeed the case though.


--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
@ 2012-05-02 10:55         ` Bedia, Vaibhav
  0 siblings, 0 replies; 126+ messages in thread
From: Bedia, Vaibhav @ 2012-05-02 10:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 02, 2012 at 15:48:01, Shilimkar, Santosh wrote:
> On Wed, May 2, 2012 at 3:40 PM, Bedia, Vaibhav <vaibhav.bedia@ti.com> wrote:
> > Hi Tero,
> >
> > On Fri, Apr 20, 2012 at 15:03:34, Kristo, Tero wrote:
> >> From: Rajendra Nayak <rnayak@ti.com>
> >>
> >> SAR/ROM code restores only CORE DPLL to its original state
> >> post wakeup from OFF mode.
> >> The rest of the DPLL's in OMAP4 platform (MPU/IVA/ABE/USB/PER)
> >> are saved and restored here during an OFF transition.
> >>
> >
> > Most of the registers being saved and restored in the various
> > patches look to be contiguous. So, instead of a long list of these
> > contiguous registers how about having a generic API for backup and
> > restore of the registers contents based on the memory address range?
> >
> > Most of the registers which require save and restore are either part
> > of PRM, CM or Control. The PRM or CM instance could be passed as the
> > base and the save/restore API could work around that.
> >
> > One downside is that there are some read-only registers in between but
> > I don't see any simple way of avoiding save and restore of those. BTW,
> > as per the TRM that I have, this patch is also doing save and restore
> > of some read-only registers.
> >
> You should never write to read-only registers since the behavior is
> undefined.

I was afraid of that. If all the read-only registers were clubbed together
a lot of code could have been removed. Looking more closely at the TRM
I guess we can't really ask design folks to club those read-only registers
in the future. So scratch this.

> 
> [...]
> >> +void omap4_dpll_resume_off(void)
> >> +{
> >> + ? ? u32 i;
> >> + ? ? struct omap4_dpll_regs *dpll_reg = dpll_regs;
> >> +
> >> + ? ? for (i = 0; i < ARRAY_SIZE(dpll_regs); i++, dpll_reg++) {
> >> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clksel);
> >> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m2);
> >> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m3);
> >> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m4);
> >> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m5);
> >> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m6);
> >> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m7);
> >> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkdcoldo);
> >> +
> >> + ? ? ? ? ? ? /* Restore clkmode after the above registers are restored */
> >> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkmode);
> >> +
> >> + ? ? ? ? ? ? omap4_wait_dpll_lock(dpll_reg);
> >> +
> >> + ? ? ? ? ? ? /* Restore autoidle settings after the dpll is locked */
> >> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->autoidle);
> >> + ? ? }
> >> +}
> >
> > If this function is placed in SRAM and PER PLL restored just after MPU
> > won't the exit latency be further optimized?
> >
> How ?
> SRAM is sower memory than DDR so I don't see how it
> will reduce latency.
> 

I am just guessing if that's indeed the case ;) 
Haven't done any measurements to really check if that's indeed the case though.

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

* Re: [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
  2012-05-02 10:55         ` Bedia, Vaibhav
@ 2012-05-02 11:00           ` Shilimkar, Santosh
  -1 siblings, 0 replies; 126+ messages in thread
From: Shilimkar, Santosh @ 2012-05-02 11:00 UTC (permalink / raw)
  To: Bedia, Vaibhav
  Cc: Kristo, Tero, linux-omap, Hilman, Kevin, paul, Menon, Nishanth,
	Nayak, Rajendra, linux-arm-kernel

On Wed, May 2, 2012 at 4:25 PM, Bedia, Vaibhav <vaibhav.bedia@ti.com> wrote:
> On Wed, May 02, 2012 at 15:48:01, Shilimkar, Santosh wrote:
>> On Wed, May 2, 2012 at 3:40 PM, Bedia, Vaibhav <vaibhav.bedia@ti.com> wrote:
>> > Hi Tero,
>> >
>> > On Fri, Apr 20, 2012 at 15:03:34, Kristo, Tero wrote:
>> >> From: Rajendra Nayak <rnayak@ti.com>
>> >>
[...]

>>
>> [...]
>> >> +void omap4_dpll_resume_off(void)
>> >> +{
>> >> +     u32 i;
>> >> +     struct omap4_dpll_regs *dpll_reg = dpll_regs;
>> >> +
>> >> +     for (i = 0; i < ARRAY_SIZE(dpll_regs); i++, dpll_reg++) {
>> >> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clksel);
>> >> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m2);
>> >> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m3);
>> >> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m4);
>> >> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m5);
>> >> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m6);
>> >> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m7);
>> >> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkdcoldo);
>> >> +
>> >> +             /* Restore clkmode after the above registers are restored */
>> >> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkmode);
>> >> +
>> >> +             omap4_wait_dpll_lock(dpll_reg);
>> >> +
>> >> +             /* Restore autoidle settings after the dpll is locked */
>> >> +             omap4_dpll_restore_reg(dpll_reg, &dpll_reg->autoidle);
>> >> +     }
>> >> +}
>> >
>> > If this function is placed in SRAM and PER PLL restored just after MPU
>> > won't the exit latency be further optimized?
>> >
>> How ?
>> SRAM is sower memory than DDR so I don't see how it
>> will reduce latency.
>>
>
> I am just guessing if that's indeed the case ;)
> Haven't done any measurements to really check if that's indeed the case though.
>
You don't have to do any real measurements at least on OMAP.
OCMC RAM is interfaced over L4 and MPU has to cross two interconnect
bridges to reach to SRAM. DDR is more of direct path and much faster.

Regards
Santosh
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
@ 2012-05-02 11:00           ` Shilimkar, Santosh
  0 siblings, 0 replies; 126+ messages in thread
From: Shilimkar, Santosh @ 2012-05-02 11:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 2, 2012 at 4:25 PM, Bedia, Vaibhav <vaibhav.bedia@ti.com> wrote:
> On Wed, May 02, 2012 at 15:48:01, Shilimkar, Santosh wrote:
>> On Wed, May 2, 2012 at 3:40 PM, Bedia, Vaibhav <vaibhav.bedia@ti.com> wrote:
>> > Hi Tero,
>> >
>> > On Fri, Apr 20, 2012 at 15:03:34, Kristo, Tero wrote:
>> >> From: Rajendra Nayak <rnayak@ti.com>
>> >>
[...]

>>
>> [...]
>> >> +void omap4_dpll_resume_off(void)
>> >> +{
>> >> + ? ? u32 i;
>> >> + ? ? struct omap4_dpll_regs *dpll_reg = dpll_regs;
>> >> +
>> >> + ? ? for (i = 0; i < ARRAY_SIZE(dpll_regs); i++, dpll_reg++) {
>> >> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clksel);
>> >> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m2);
>> >> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m3);
>> >> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m4);
>> >> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m5);
>> >> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m6);
>> >> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m7);
>> >> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkdcoldo);
>> >> +
>> >> + ? ? ? ? ? ? /* Restore clkmode after the above registers are restored */
>> >> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkmode);
>> >> +
>> >> + ? ? ? ? ? ? omap4_wait_dpll_lock(dpll_reg);
>> >> +
>> >> + ? ? ? ? ? ? /* Restore autoidle settings after the dpll is locked */
>> >> + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->autoidle);
>> >> + ? ? }
>> >> +}
>> >
>> > If this function is placed in SRAM and PER PLL restored just after MPU
>> > won't the exit latency be further optimized?
>> >
>> How ?
>> SRAM is sower memory than DDR so I don't see how it
>> will reduce latency.
>>
>
> I am just guessing if that's indeed the case ;)
> Haven't done any measurements to really check if that's indeed the case though.
>
You don't have to do any real measurements at least on OMAP.
OCMC RAM is interfaced over L4 and MPU has to cross two interconnect
bridges to reach to SRAM. DDR is more of direct path and much faster.

Regards
Santosh

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

* RE: [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
  2012-05-02 11:00           ` Shilimkar, Santosh
@ 2012-05-02 11:40             ` Bedia, Vaibhav
  -1 siblings, 0 replies; 126+ messages in thread
From: Bedia, Vaibhav @ 2012-05-02 11:40 UTC (permalink / raw)
  To: Shilimkar, Santosh
  Cc: Kristo, Tero, linux-omap, Hilman, Kevin, paul, Menon, Nishanth,
	Nayak, Rajendra, linux-arm-kernel

On Wed, May 02, 2012 at 16:30:26, Shilimkar, Santosh wrote:
[...]

> >> How ?
> >> SRAM is sower memory than DDR so I don't see how it
> >> will reduce latency.
> >>
> >
> > I am just guessing if that's indeed the case ;)
> > Haven't done any measurements to really check if that's indeed the case though.
> >
> You don't have to do any real measurements at least on OMAP.
> OCMC RAM is interfaced over L4 and MPU has to cross two interconnect
> bridges to reach to SRAM. DDR is more of direct path and much faster.
> 

Hmm, I was under the impression that OCMC RAM was on L3, at least for OMAP4.
Maybe there's a extra low latency path for DDR that I am missing.

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

* [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
@ 2012-05-02 11:40             ` Bedia, Vaibhav
  0 siblings, 0 replies; 126+ messages in thread
From: Bedia, Vaibhav @ 2012-05-02 11:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 02, 2012 at 16:30:26, Shilimkar, Santosh wrote:
[...]

> >> How ?
> >> SRAM is sower memory than DDR so I don't see how it
> >> will reduce latency.
> >>
> >
> > I am just guessing if that's indeed the case ;)
> > Haven't done any measurements to really check if that's indeed the case though.
> >
> You don't have to do any real measurements at least on OMAP.
> OCMC RAM is interfaced over L4 and MPU has to cross two interconnect
> bridges to reach to SRAM. DDR is more of direct path and much faster.
> 

Hmm, I was under the impression that OCMC RAM was on L3, at least for OMAP4.
Maybe there's a extra low latency path for DDR that I am missing.

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

* Re: [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
  2012-05-02 11:40             ` Bedia, Vaibhav
@ 2012-05-02 11:46               ` Shilimkar, Santosh
  -1 siblings, 0 replies; 126+ messages in thread
From: Shilimkar, Santosh @ 2012-05-02 11:46 UTC (permalink / raw)
  To: Bedia, Vaibhav
  Cc: Kristo, Tero, linux-omap, Hilman, Kevin, paul, Menon, Nishanth,
	Nayak, Rajendra, linux-arm-kernel

On Wed, May 2, 2012 at 5:10 PM, Bedia, Vaibhav <vaibhav.bedia@ti.com> wrote:
> On Wed, May 02, 2012 at 16:30:26, Shilimkar, Santosh wrote:
> [...]
>
>> >> How ?
>> >> SRAM is sower memory than DDR so I don't see how it
>> >> will reduce latency.
>> >>
>> >
>> > I am just guessing if that's indeed the case ;)
>> > Haven't done any measurements to really check if that's indeed the case though.
>> >
>> You don't have to do any real measurements at least on OMAP.
>> OCMC RAM is interfaced over L4 and MPU has to cross two interconnect
>> bridges to reach to SRAM. DDR is more of direct path and much faster.
>>
>
> Hmm, I was under the impression that OCMC RAM was on L3, at least for OMAP4.
Nope. It's on L4 and it is same for all OMAPs including OMAP5

> Maybe there's a extra low latency path for DDR that I am missing.
Even OMAP3 DDR is faster than OCMC RAM.

Regards
Santosh

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

* [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
@ 2012-05-02 11:46               ` Shilimkar, Santosh
  0 siblings, 0 replies; 126+ messages in thread
From: Shilimkar, Santosh @ 2012-05-02 11:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 2, 2012 at 5:10 PM, Bedia, Vaibhav <vaibhav.bedia@ti.com> wrote:
> On Wed, May 02, 2012 at 16:30:26, Shilimkar, Santosh wrote:
> [...]
>
>> >> How ?
>> >> SRAM is sower memory than DDR so I don't see how it
>> >> will reduce latency.
>> >>
>> >
>> > I am just guessing if that's indeed the case ;)
>> > Haven't done any measurements to really check if that's indeed the case though.
>> >
>> You don't have to do any real measurements at least on OMAP.
>> OCMC RAM is interfaced over L4 and MPU has to cross two interconnect
>> bridges to reach to SRAM. DDR is more of direct path and much faster.
>>
>
> Hmm, I was under the impression that OCMC RAM was on L3, at least for OMAP4.
Nope. It's on L4 and it is same for all OMAPs including OMAP5

> Maybe there's a extra low latency path for DDR that I am missing.
Even OMAP3 DDR is faster than OCMC RAM.

Regards
Santosh

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

* Re: [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
  2012-05-02 11:40             ` Bedia, Vaibhav
@ 2012-05-02 11:47               ` Menon, Nishanth
  -1 siblings, 0 replies; 126+ messages in thread
From: Menon, Nishanth @ 2012-05-02 11:47 UTC (permalink / raw)
  To: Bedia, Vaibhav
  Cc: Shilimkar, Santosh, Kristo, Tero, linux-omap, Hilman, Kevin,
	paul, Nayak, Rajendra, linux-arm-kernel

On Wed, May 2, 2012 at 6:40 AM, Bedia, Vaibhav <vaibhav.bedia@ti.com> wrote:
>
> On Wed, May 02, 2012 at 16:30:26, Shilimkar, Santosh wrote:
> [...]
>
> > >> How ?
> > >> SRAM is sower memory than DDR so I don't see how it
> > >> will reduce latency.
> > >>
> > >
> > > I am just guessing if that's indeed the case ;)
> > > Haven't done any measurements to really check if that's indeed the
> > > case though.
> > >
> > You don't have to do any real measurements at least on OMAP.
> > OCMC RAM is interfaced over L4 and MPU has to cross two interconnect
> > bridges to reach to SRAM. DDR is more of direct path and much faster.
> >
>
> Hmm, I was under the impression that OCMC RAM was on L3, at least for
> OMAP4.
> Maybe there's a extra low latency path for DDR that I am missing.
have you folks considered the possibility that SRAM may be
reprogrammed by Security code to almost nothing if PA/PPA size needs
to be increased? it would be rather dumb not to support HS devices on
which real products are made, no? rule of thumb has been to avoid
usage of SRAM as it constraints security folks as well (yep, I know
they should share code with all of us etc.. but they have a different
sets of challenges that may deny them such luxury).

Regards,
Nishanth Menon

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

* [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
@ 2012-05-02 11:47               ` Menon, Nishanth
  0 siblings, 0 replies; 126+ messages in thread
From: Menon, Nishanth @ 2012-05-02 11:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 2, 2012 at 6:40 AM, Bedia, Vaibhav <vaibhav.bedia@ti.com> wrote:
>
> On Wed, May 02, 2012 at 16:30:26, Shilimkar, Santosh wrote:
> [...]
>
> > >> How ?
> > >> SRAM is sower memory than DDR so I don't see how it
> > >> will reduce latency.
> > >>
> > >
> > > I am just guessing if that's indeed the case ;)
> > > Haven't done any measurements to really check if that's indeed the
> > > case though.
> > >
> > You don't have to do any real measurements at least on OMAP.
> > OCMC RAM is interfaced over L4 and MPU has to cross two interconnect
> > bridges to reach to SRAM. DDR is more of direct path and much faster.
> >
>
> Hmm, I was under the impression that OCMC RAM was on L3, at least for
> OMAP4.
> Maybe there's a extra low latency path for DDR that I am missing.
have you folks considered the possibility that SRAM may be
reprogrammed by Security code to almost nothing if PA/PPA size needs
to be increased? it would be rather dumb not to support HS devices on
which real products are made, no? rule of thumb has been to avoid
usage of SRAM as it constraints security folks as well (yep, I know
they should share code with all of us etc.. but they have a different
sets of challenges that may deny them such luxury).

Regards,
Nishanth Menon

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

* RE: [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
  2012-05-02 11:46               ` Shilimkar, Santosh
@ 2012-05-02 11:55                 ` Bedia, Vaibhav
  -1 siblings, 0 replies; 126+ messages in thread
From: Bedia, Vaibhav @ 2012-05-02 11:55 UTC (permalink / raw)
  To: Shilimkar, Santosh
  Cc: Kristo, Tero, linux-omap, Hilman, Kevin, paul, Menon, Nishanth,
	Nayak, Rajendra, linux-arm-kernel

On Wed, May 02, 2012 at 17:16:19, Shilimkar, Santosh wrote:
> On Wed, May 2, 2012 at 5:10 PM, Bedia, Vaibhav <vaibhav.bedia@ti.com> wrote:
> > On Wed, May 02, 2012 at 16:30:26, Shilimkar, Santosh wrote:
> > [...]
> >
> >> >> How ?
> >> >> SRAM is sower memory than DDR so I don't see how it
> >> >> will reduce latency.
> >> >>
> >> >
> >> > I am just guessing if that's indeed the case ;)
> >> > Haven't done any measurements to really check if that's indeed the case though.
> >> >
> >> You don't have to do any real measurements at least on OMAP.
> >> OCMC RAM is interfaced over L4 and MPU has to cross two interconnect
> >> bridges to reach to SRAM. DDR is more of direct path and much faster.
> >>
> >
> > Hmm, I was under the impression that OCMC RAM was on L3, at least for OMAP4.
> Nope. It's on L4 and it is same for all OMAPs including OMAP5
> 
> > Maybe there's a extra low latency path for DDR that I am missing.
> Even OMAP3 DDR is faster than OCMC RAM.
> 

Ok. I guess I need to come up with some data for AM33x then.
Thanks for the clarification.

Regards,
Vaibhav

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

* [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
@ 2012-05-02 11:55                 ` Bedia, Vaibhav
  0 siblings, 0 replies; 126+ messages in thread
From: Bedia, Vaibhav @ 2012-05-02 11:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 02, 2012 at 17:16:19, Shilimkar, Santosh wrote:
> On Wed, May 2, 2012 at 5:10 PM, Bedia, Vaibhav <vaibhav.bedia@ti.com> wrote:
> > On Wed, May 02, 2012 at 16:30:26, Shilimkar, Santosh wrote:
> > [...]
> >
> >> >> How ?
> >> >> SRAM is sower memory than DDR so I don't see how it
> >> >> will reduce latency.
> >> >>
> >> >
> >> > I am just guessing if that's indeed the case ;)
> >> > Haven't done any measurements to really check if that's indeed the case though.
> >> >
> >> You don't have to do any real measurements at least on OMAP.
> >> OCMC RAM is interfaced over L4 and MPU has to cross two interconnect
> >> bridges to reach to SRAM. DDR is more of direct path and much faster.
> >>
> >
> > Hmm, I was under the impression that OCMC RAM was on L3, at least for OMAP4.
> Nope. It's on L4 and it is same for all OMAPs including OMAP5
> 
> > Maybe there's a extra low latency path for DDR that I am missing.
> Even OMAP3 DDR is faster than OCMC RAM.
> 

Ok. I guess I need to come up with some data for AM33x then.
Thanks for the clarification.

Regards,
Vaibhav

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

* RE: [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
  2012-05-02 11:47               ` Menon, Nishanth
@ 2012-05-02 11:55                 ` Bedia, Vaibhav
  -1 siblings, 0 replies; 126+ messages in thread
From: Bedia, Vaibhav @ 2012-05-02 11:55 UTC (permalink / raw)
  To: Menon, Nishanth
  Cc: Shilimkar, Santosh, Kristo, Tero, linux-omap, Hilman, Kevin,
	paul, Nayak, Rajendra, linux-arm-kernel

On Wed, May 02, 2012 at 17:17:08, Menon, Nishanth wrote:
> On Wed, May 2, 2012 at 6:40 AM, Bedia, Vaibhav <vaibhav.bedia@ti.com> wrote:
> >
> > On Wed, May 02, 2012 at 16:30:26, Shilimkar, Santosh wrote:
> > [...]
> >
> > > >> How ?
> > > >> SRAM is sower memory than DDR so I don't see how it
> > > >> will reduce latency.
> > > >>
> > > >
> > > > I am just guessing if that's indeed the case ;)
> > > > Haven't done any measurements to really check if that's indeed the
> > > > case though.
> > > >
> > > You don't have to do any real measurements at least on OMAP.
> > > OCMC RAM is interfaced over L4 and MPU has to cross two interconnect
> > > bridges to reach to SRAM. DDR is more of direct path and much faster.
> > >
> >
> > Hmm, I was under the impression that OCMC RAM was on L3, at least for
> > OMAP4.
> > Maybe there's a extra low latency path for DDR that I am missing.
> have you folks considered the possibility that SRAM may be
> reprogrammed by Security code to almost nothing if PA/PPA size needs
> to be increased? it would be rather dumb not to support HS devices on
> which real products are made, no? rule of thumb has been to avoid
> usage of SRAM as it constraints security folks as well (yep, I know
> they should share code with all of us etc.. but they have a different
> sets of challenges that may deny them such luxury).
> 

Even I would like to avoid the usage of MPUSS SRAM for this very reason.
But AFAIK the whole PPA stuff isn't applicable for OCMC RAM (not SRAM inside MPUSS).

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

* [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
@ 2012-05-02 11:55                 ` Bedia, Vaibhav
  0 siblings, 0 replies; 126+ messages in thread
From: Bedia, Vaibhav @ 2012-05-02 11:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 02, 2012 at 17:17:08, Menon, Nishanth wrote:
> On Wed, May 2, 2012 at 6:40 AM, Bedia, Vaibhav <vaibhav.bedia@ti.com> wrote:
> >
> > On Wed, May 02, 2012 at 16:30:26, Shilimkar, Santosh wrote:
> > [...]
> >
> > > >> How ?
> > > >> SRAM is sower memory than DDR so I don't see how it
> > > >> will reduce latency.
> > > >>
> > > >
> > > > I am just guessing if that's indeed the case ;)
> > > > Haven't done any measurements to really check if that's indeed the
> > > > case though.
> > > >
> > > You don't have to do any real measurements at least on OMAP.
> > > OCMC RAM is interfaced over L4 and MPU has to cross two interconnect
> > > bridges to reach to SRAM. DDR is more of direct path and much faster.
> > >
> >
> > Hmm, I was under the impression that OCMC RAM was on L3, at least for
> > OMAP4.
> > Maybe there's a extra low latency path for DDR that I am missing.
> have you folks considered the possibility that SRAM may be
> reprogrammed by Security code to almost nothing if PA/PPA size needs
> to be increased? it would be rather dumb not to support HS devices on
> which real products are made, no? rule of thumb has been to avoid
> usage of SRAM as it constraints security folks as well (yep, I know
> they should share code with all of us etc.. but they have a different
> sets of challenges that may deny them such luxury).
> 

Even I would like to avoid the usage of MPUSS SRAM for this very reason.
But AFAIK the whole PPA stuff isn't applicable for OCMC RAM (not SRAM inside MPUSS).

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

* Re: [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
  2012-05-02 11:55                 ` Bedia, Vaibhav
@ 2012-05-02 11:58                   ` Shilimkar, Santosh
  -1 siblings, 0 replies; 126+ messages in thread
From: Shilimkar, Santosh @ 2012-05-02 11:58 UTC (permalink / raw)
  To: Bedia, Vaibhav
  Cc: Menon, Nishanth, Kristo, Tero, linux-omap, Hilman, Kevin, paul,
	Nayak, Rajendra, linux-arm-kernel

On Wed, May 2, 2012 at 5:25 PM, Bedia, Vaibhav <vaibhav.bedia@ti.com> wrote:
> On Wed, May 02, 2012 at 17:17:08, Menon, Nishanth wrote:
>> On Wed, May 2, 2012 at 6:40 AM, Bedia, Vaibhav <vaibhav.bedia@ti.com> wrote:
>> >
>> > On Wed, May 02, 2012 at 16:30:26, Shilimkar, Santosh wrote:
>> > [...]
>> >
>> > > >> How ?
>> > > >> SRAM is sower memory than DDR so I don't see how it
>> > > >> will reduce latency.
>> > > >>
>> > > >
>> > > > I am just guessing if that's indeed the case ;)
>> > > > Haven't done any measurements to really check if that's indeed the
>> > > > case though.
>> > > >
>> > > You don't have to do any real measurements at least on OMAP.
>> > > OCMC RAM is interfaced over L4 and MPU has to cross two interconnect
>> > > bridges to reach to SRAM. DDR is more of direct path and much faster.
>> > >
>> >
>> > Hmm, I was under the impression that OCMC RAM was on L3, at least for
>> > OMAP4.
>> > Maybe there's a extra low latency path for DDR that I am missing.
>> have you folks considered the possibility that SRAM may be
>> reprogrammed by Security code to almost nothing if PA/PPA size needs
>> to be increased? it would be rather dumb not to support HS devices on
>> which real products are made, no? rule of thumb has been to avoid
>> usage of SRAM as it constraints security folks as well (yep, I know
>> they should share code with all of us etc.. but they have a different
>> sets of challenges that may deny them such luxury).
>>
>
> Even I would like to avoid the usage of MPUSS SRAM for this very reason.
> But AFAIK the whole PPA stuff isn't applicable for OCMC RAM (not SRAM inside MPUSS).

On OMAP, even OCMC RAM can be used by security middle-ware apart from
reserved SRAM
for HS/EMU devices.
That's what Nishant meant.

Regards
Santosh

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

* [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
@ 2012-05-02 11:58                   ` Shilimkar, Santosh
  0 siblings, 0 replies; 126+ messages in thread
From: Shilimkar, Santosh @ 2012-05-02 11:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 2, 2012 at 5:25 PM, Bedia, Vaibhav <vaibhav.bedia@ti.com> wrote:
> On Wed, May 02, 2012 at 17:17:08, Menon, Nishanth wrote:
>> On Wed, May 2, 2012 at 6:40 AM, Bedia, Vaibhav <vaibhav.bedia@ti.com> wrote:
>> >
>> > On Wed, May 02, 2012 at 16:30:26, Shilimkar, Santosh wrote:
>> > [...]
>> >
>> > > >> How ?
>> > > >> SRAM is sower memory than DDR so I don't see how it
>> > > >> will reduce latency.
>> > > >>
>> > > >
>> > > > I am just guessing if that's indeed the case ;)
>> > > > Haven't done any measurements to really check if that's indeed the
>> > > > case though.
>> > > >
>> > > You don't have to do any real measurements at least on OMAP.
>> > > OCMC RAM is interfaced over L4 and MPU has to cross two interconnect
>> > > bridges to reach to SRAM. DDR is more of direct path and much faster.
>> > >
>> >
>> > Hmm, I was under the impression that OCMC RAM was on L3, at least for
>> > OMAP4.
>> > Maybe there's a extra low latency path for DDR that I am missing.
>> have you folks considered the possibility that SRAM may be
>> reprogrammed by Security code to almost nothing if PA/PPA size needs
>> to be increased? it would be rather dumb not to support HS devices on
>> which real products are made, no? rule of thumb has been to avoid
>> usage of SRAM as it constraints security folks as well (yep, I know
>> they should share code with all of us etc.. but they have a different
>> sets of challenges that may deny them such luxury).
>>
>
> Even I would like to avoid the usage of MPUSS SRAM for this very reason.
> But AFAIK the whole PPA stuff isn't applicable for OCMC RAM (not SRAM inside MPUSS).

On OMAP, even OCMC RAM can be used by security middle-ware apart from
reserved SRAM
for HS/EMU devices.
That's what Nishant meant.

Regards
Santosh

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

* RE: [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
  2012-05-02 11:58                   ` Shilimkar, Santosh
@ 2012-05-02 12:10                     ` Bedia, Vaibhav
  -1 siblings, 0 replies; 126+ messages in thread
From: Bedia, Vaibhav @ 2012-05-02 12:10 UTC (permalink / raw)
  To: Shilimkar, Santosh
  Cc: Menon, Nishanth, Kristo, Tero, linux-omap, Hilman, Kevin, paul,
	Nayak, Rajendra, linux-arm-kernel

On Wed, May 02, 2012 at 17:28:17, Shilimkar, Santosh wrote:
> On Wed, May 2, 2012 at 5:25 PM, Bedia, Vaibhav <vaibhav.bedia@ti.com> wrote:
> > On Wed, May 02, 2012 at 17:17:08, Menon, Nishanth wrote:
> >> On Wed, May 2, 2012 at 6:40 AM, Bedia, Vaibhav <vaibhav.bedia@ti.com> wrote:
> >> >
> >> > On Wed, May 02, 2012 at 16:30:26, Shilimkar, Santosh wrote:
> >> > [...]
> >> >
> >> > > >> How ?
> >> > > >> SRAM is sower memory than DDR so I don't see how it
> >> > > >> will reduce latency.
> >> > > >>
> >> > > >
> >> > > > I am just guessing if that's indeed the case ;)
> >> > > > Haven't done any measurements to really check if that's indeed the
> >> > > > case though.
> >> > > >
> >> > > You don't have to do any real measurements at least on OMAP.
> >> > > OCMC RAM is interfaced over L4 and MPU has to cross two interconnect
> >> > > bridges to reach to SRAM. DDR is more of direct path and much faster.
> >> > >
> >> >
> >> > Hmm, I was under the impression that OCMC RAM was on L3, at least for
> >> > OMAP4.
> >> > Maybe there's a extra low latency path for DDR that I am missing.
> >> have you folks considered the possibility that SRAM may be
> >> reprogrammed by Security code to almost nothing if PA/PPA size needs
> >> to be increased? it would be rather dumb not to support HS devices on
> >> which real products are made, no? rule of thumb has been to avoid
> >> usage of SRAM as it constraints security folks as well (yep, I know
> >> they should share code with all of us etc.. but they have a different
> >> sets of challenges that may deny them such luxury).
> >>
> >
> > Even I would like to avoid the usage of MPUSS SRAM for this very reason.
> > But AFAIK the whole PPA stuff isn't applicable for OCMC RAM (not SRAM inside MPUSS).
> 
> On OMAP, even OCMC RAM can be used by security middle-ware apart from
> reserved SRAM
> for HS/EMU devices.
> That's what Nishant meant.
> 

Oh ok. I wasn't aware of this aspect.

Thanks,
Vaibhav

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

* [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
@ 2012-05-02 12:10                     ` Bedia, Vaibhav
  0 siblings, 0 replies; 126+ messages in thread
From: Bedia, Vaibhav @ 2012-05-02 12:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 02, 2012 at 17:28:17, Shilimkar, Santosh wrote:
> On Wed, May 2, 2012 at 5:25 PM, Bedia, Vaibhav <vaibhav.bedia@ti.com> wrote:
> > On Wed, May 02, 2012 at 17:17:08, Menon, Nishanth wrote:
> >> On Wed, May 2, 2012 at 6:40 AM, Bedia, Vaibhav <vaibhav.bedia@ti.com> wrote:
> >> >
> >> > On Wed, May 02, 2012 at 16:30:26, Shilimkar, Santosh wrote:
> >> > [...]
> >> >
> >> > > >> How ?
> >> > > >> SRAM is sower memory than DDR so I don't see how it
> >> > > >> will reduce latency.
> >> > > >>
> >> > > >
> >> > > > I am just guessing if that's indeed the case ;)
> >> > > > Haven't done any measurements to really check if that's indeed the
> >> > > > case though.
> >> > > >
> >> > > You don't have to do any real measurements at least on OMAP.
> >> > > OCMC RAM is interfaced over L4 and MPU has to cross two interconnect
> >> > > bridges to reach to SRAM. DDR is more of direct path and much faster.
> >> > >
> >> >
> >> > Hmm, I was under the impression that OCMC RAM was on L3, at least for
> >> > OMAP4.
> >> > Maybe there's a extra low latency path for DDR that I am missing.
> >> have you folks considered the possibility that SRAM may be
> >> reprogrammed by Security code to almost nothing if PA/PPA size needs
> >> to be increased? it would be rather dumb not to support HS devices on
> >> which real products are made, no? rule of thumb has been to avoid
> >> usage of SRAM as it constraints security folks as well (yep, I know
> >> they should share code with all of us etc.. but they have a different
> >> sets of challenges that may deny them such luxury).
> >>
> >
> > Even I would like to avoid the usage of MPUSS SRAM for this very reason.
> > But AFAIK the whole PPA stuff isn't applicable for OCMC RAM (not SRAM inside MPUSS).
> 
> On OMAP, even OCMC RAM can be used by security middle-ware apart from
> reserved SRAM
> for HS/EMU devices.
> That's what Nishant meant.
> 

Oh ok. I wasn't aware of this aspect.

Thanks,
Vaibhav

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

* Re: [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
  2012-04-25 15:12         ` Jon Hunter
@ 2012-05-04 19:22           ` Tony Lindgren
  -1 siblings, 0 replies; 126+ messages in thread
From: Tony Lindgren @ 2012-05-04 19:22 UTC (permalink / raw)
  To: Jon Hunter
  Cc: t-kristo, linux-omap, khilman, paul, Nishanth Menon,
	Rajendra Nayak, Santosh Shilimkar, linux-arm-kernel

* Jon Hunter <jon-hunter@ti.com> [120425 08:16]:
> Hi Tero,
> 
> On 04/25/2012 02:33 AM, Tero Kristo wrote:
> > On Mon, 2012-04-23 at 11:09 -0500, Jon Hunter wrote:
> >> Hi Tero,
> >>
> >> On 04/20/2012 04:33 AM, Tero Kristo wrote:
> >>
> >> [...]
> >>
> >>> +/**
> >>> + * omap4_dpll_print_reg - dump out a single DPLL register value
> >>> + * @dpll_reg: register to dump
> >>> + * @name: name of the register
> >>> + * @tuple: content of the register
> >>> + *
> >>> + * Helper dump function to print out a DPLL register value in case
> >>> + * of restore failures.
> >>> + */
> >>> +static void omap4_dpll_print_reg(struct omap4_dpll_regs *dpll_reg, char *name,
> >>> +				 struct dpll_reg *tuple)
> >>> +{
> >>> +	if (tuple->offset)
> >>> +		pr_warn("%s - Address offset = 0x%08x, value=0x%08x\n", name,
> >>> +			tuple->offset, tuple->val);
> >>
> >> Minor nit-pick here ...
> >>
> >> 1. Offset is 16-bits and so we can just have "offset = 0x%04x"
> >> 2. Consider dropping "Address" from "Address offset"
> >> 3. Can we be consistent in our spaces for "offset = " and "value="?
> >>
> >>> +}
> >>> +
> >>> +/*
> >>> + * omap4_dpll_dump_regs - dump out DPLL registers
> >>> + * @dpll_reg: DPLL to dump
> >>> + *
> >>> + * Dump out the contents of the registers for a DPLL. Called if a
> >>> + * restore for DPLL fails to lock.
> >>> + */
> >>> +static void omap4_dpll_dump_regs(struct omap4_dpll_regs *dpll_reg)
> >>> +{
> >>> +	pr_warn("%s: Unable to lock dpll %s[part=%x inst=%x]:\n",
> >>> +		__func__, dpll_reg->name, dpll_reg->mod_partition,
> >>> +		dpll_reg->mod_inst);
> >>> +	omap4_dpll_print_reg(dpll_reg, "clksel", &dpll_reg->clksel);
> >>> +	omap4_dpll_print_reg(dpll_reg, "div_m2", &dpll_reg->div_m2);
> >>> +	omap4_dpll_print_reg(dpll_reg, "div_m3", &dpll_reg->div_m3);
> >>> +	omap4_dpll_print_reg(dpll_reg, "div_m4", &dpll_reg->div_m4);
> >>> +	omap4_dpll_print_reg(dpll_reg, "div_m5", &dpll_reg->div_m5);
> >>> +	omap4_dpll_print_reg(dpll_reg, "div_m6", &dpll_reg->div_m6);
> >>> +	omap4_dpll_print_reg(dpll_reg, "div_m7", &dpll_reg->div_m7);
> >>> +	omap4_dpll_print_reg(dpll_reg, "clkdcoldo", &dpll_reg->clkdcoldo);
> >>> +	omap4_dpll_print_reg(dpll_reg, "clkmode", &dpll_reg->clkmode);
> >>> +	omap4_dpll_print_reg(dpll_reg, "autoidle", &dpll_reg->autoidle);
> >>> +	if (dpll_reg->idlest.offset)
> >>> +		pr_warn("idlest - Address offset = 0x%08x, before val=0x%08x"
> >>> +			" after = 0x%08x\n", dpll_reg->idlest.offset,
> >>> +			dpll_reg->idlest.val,
> >>> +			omap4_dpll_read_reg(dpll_reg, &dpll_reg->idlest));
> >>
> >> Nit-pick ...
> >>
> >> 1. Same comments as above
> >> 2. Consider dropping "Address offset" altogether here as we print
> >> "idlest" the offset should be implied.
> >> 3. Also can we be consistent in our naming of "before val and "after"?
> >> For example, "val before =" and "val now = ".
> > 
> > Okay, I'll modify both prints slightly. Question though, do we want
> > these prints in the kernel in the first place? At least Tony has been
> > frowning upon register dumps in the kernel and this falls into that
> > category. What we could do is just to print the warning but drop the
> > register dumps out.
> 
> Thanks. Good question. If we are not seeing failures often, and I would
> hope not, probably ok to remove. However, I will let Tony comment here  ...

Well if the register dumps really help trace the issue and don't happen
continuously I'm fine with them.

Tony

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

* [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
@ 2012-05-04 19:22           ` Tony Lindgren
  0 siblings, 0 replies; 126+ messages in thread
From: Tony Lindgren @ 2012-05-04 19:22 UTC (permalink / raw)
  To: linux-arm-kernel

* Jon Hunter <jon-hunter@ti.com> [120425 08:16]:
> Hi Tero,
> 
> On 04/25/2012 02:33 AM, Tero Kristo wrote:
> > On Mon, 2012-04-23 at 11:09 -0500, Jon Hunter wrote:
> >> Hi Tero,
> >>
> >> On 04/20/2012 04:33 AM, Tero Kristo wrote:
> >>
> >> [...]
> >>
> >>> +/**
> >>> + * omap4_dpll_print_reg - dump out a single DPLL register value
> >>> + * @dpll_reg: register to dump
> >>> + * @name: name of the register
> >>> + * @tuple: content of the register
> >>> + *
> >>> + * Helper dump function to print out a DPLL register value in case
> >>> + * of restore failures.
> >>> + */
> >>> +static void omap4_dpll_print_reg(struct omap4_dpll_regs *dpll_reg, char *name,
> >>> +				 struct dpll_reg *tuple)
> >>> +{
> >>> +	if (tuple->offset)
> >>> +		pr_warn("%s - Address offset = 0x%08x, value=0x%08x\n", name,
> >>> +			tuple->offset, tuple->val);
> >>
> >> Minor nit-pick here ...
> >>
> >> 1. Offset is 16-bits and so we can just have "offset = 0x%04x"
> >> 2. Consider dropping "Address" from "Address offset"
> >> 3. Can we be consistent in our spaces for "offset = " and "value="?
> >>
> >>> +}
> >>> +
> >>> +/*
> >>> + * omap4_dpll_dump_regs - dump out DPLL registers
> >>> + * @dpll_reg: DPLL to dump
> >>> + *
> >>> + * Dump out the contents of the registers for a DPLL. Called if a
> >>> + * restore for DPLL fails to lock.
> >>> + */
> >>> +static void omap4_dpll_dump_regs(struct omap4_dpll_regs *dpll_reg)
> >>> +{
> >>> +	pr_warn("%s: Unable to lock dpll %s[part=%x inst=%x]:\n",
> >>> +		__func__, dpll_reg->name, dpll_reg->mod_partition,
> >>> +		dpll_reg->mod_inst);
> >>> +	omap4_dpll_print_reg(dpll_reg, "clksel", &dpll_reg->clksel);
> >>> +	omap4_dpll_print_reg(dpll_reg, "div_m2", &dpll_reg->div_m2);
> >>> +	omap4_dpll_print_reg(dpll_reg, "div_m3", &dpll_reg->div_m3);
> >>> +	omap4_dpll_print_reg(dpll_reg, "div_m4", &dpll_reg->div_m4);
> >>> +	omap4_dpll_print_reg(dpll_reg, "div_m5", &dpll_reg->div_m5);
> >>> +	omap4_dpll_print_reg(dpll_reg, "div_m6", &dpll_reg->div_m6);
> >>> +	omap4_dpll_print_reg(dpll_reg, "div_m7", &dpll_reg->div_m7);
> >>> +	omap4_dpll_print_reg(dpll_reg, "clkdcoldo", &dpll_reg->clkdcoldo);
> >>> +	omap4_dpll_print_reg(dpll_reg, "clkmode", &dpll_reg->clkmode);
> >>> +	omap4_dpll_print_reg(dpll_reg, "autoidle", &dpll_reg->autoidle);
> >>> +	if (dpll_reg->idlest.offset)
> >>> +		pr_warn("idlest - Address offset = 0x%08x, before val=0x%08x"
> >>> +			" after = 0x%08x\n", dpll_reg->idlest.offset,
> >>> +			dpll_reg->idlest.val,
> >>> +			omap4_dpll_read_reg(dpll_reg, &dpll_reg->idlest));
> >>
> >> Nit-pick ...
> >>
> >> 1. Same comments as above
> >> 2. Consider dropping "Address offset" altogether here as we print
> >> "idlest" the offset should be implied.
> >> 3. Also can we be consistent in our naming of "before val and "after"?
> >> For example, "val before =" and "val now = ".
> > 
> > Okay, I'll modify both prints slightly. Question though, do we want
> > these prints in the kernel in the first place? At least Tony has been
> > frowning upon register dumps in the kernel and this falls into that
> > category. What we could do is just to print the warning but drop the
> > register dumps out.
> 
> Thanks. Good question. If we are not seeing failures often, and I would
> hope not, probably ok to remove. However, I will let Tony comment here  ...

Well if the register dumps really help trace the issue and don't happen
continuously I'm fine with them.

Tony

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

* Re: [PATCH 00/19] ARM: OMAP4 device off support
  2012-04-20  9:33 ` Tero Kristo
@ 2012-05-09 22:46   ` Kevin Hilman
  -1 siblings, 0 replies; 126+ messages in thread
From: Kevin Hilman @ 2012-05-09 22:46 UTC (permalink / raw)
  To: Tero Kristo; +Cc: linux-omap, paul, linux-arm-kernel

Tero Kristo <t-kristo@ti.com> writes:

> Hi,
>
> First version for this work. Applies on top of mainline + iochain set +
> OMAP4 core retention set. Working tree available here:
> tree: git://gitorious.org/~kristo/omap-pm/omap-pm-work.git
> branch: mainline-3.4-omap4-dev-off

FYI... seems your get repo is corrupted.  I tried fetching both with git
and https protocols:

$ git remote add tero git://gitorious.org/~kristo/omap-pm/omap-pm-work.git
$ git fetch tero
fatal: The remote end hung up unexpectedly
fatal: protocol error: bad pack heade
$ git remote rm tero
$ git remote add tero https://git.gitorious.org/~kristo/omap-pm/omap-pm-work.git
$ git fetch tero
error: Unable to find 653621e4dd02d4a2117e1b813d9c5f1ccb11c9ed under https://git.gitorious.org/~kristo/omap-pm/omap-pm-work.git
Cannot obtain needed object 653621e4dd02d4a2117e1b813d9c5f1ccb11c9ed
error: Fetch failed.

Kevin

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

* [PATCH 00/19] ARM: OMAP4 device off support
@ 2012-05-09 22:46   ` Kevin Hilman
  0 siblings, 0 replies; 126+ messages in thread
From: Kevin Hilman @ 2012-05-09 22:46 UTC (permalink / raw)
  To: linux-arm-kernel

Tero Kristo <t-kristo@ti.com> writes:

> Hi,
>
> First version for this work. Applies on top of mainline + iochain set +
> OMAP4 core retention set. Working tree available here:
> tree: git://gitorious.org/~kristo/omap-pm/omap-pm-work.git
> branch: mainline-3.4-omap4-dev-off

FYI... seems your get repo is corrupted.  I tried fetching both with git
and https protocols:

$ git remote add tero git://gitorious.org/~kristo/omap-pm/omap-pm-work.git
$ git fetch tero
fatal: The remote end hung up unexpectedly
fatal: protocol error: bad pack heade
$ git remote rm tero
$ git remote add tero https://git.gitorious.org/~kristo/omap-pm/omap-pm-work.git
$ git fetch tero
error: Unable to find 653621e4dd02d4a2117e1b813d9c5f1ccb11c9ed under https://git.gitorious.org/~kristo/omap-pm/omap-pm-work.git
Cannot obtain needed object 653621e4dd02d4a2117e1b813d9c5f1ccb11c9ed
error: Fetch failed.

Kevin

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

* Re: [PATCH 00/19] ARM: OMAP4 device off support
  2012-05-09 22:46   ` Kevin Hilman
@ 2012-05-09 23:14     ` Russell King - ARM Linux
  -1 siblings, 0 replies; 126+ messages in thread
From: Russell King - ARM Linux @ 2012-05-09 23:14 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: Tero Kristo, paul, linux-omap, linux-arm-kernel

On Wed, May 09, 2012 at 03:46:02PM -0700, Kevin Hilman wrote:
> Tero Kristo <t-kristo@ti.com> writes:
> 
> > Hi,
> >
> > First version for this work. Applies on top of mainline + iochain set +
> > OMAP4 core retention set. Working tree available here:
> > tree: git://gitorious.org/~kristo/omap-pm/omap-pm-work.git
> > branch: mainline-3.4-omap4-dev-off
> 
> FYI... seems your get repo is corrupted.  I tried fetching both with git
> and https protocols:
> 
> $ git remote add tero git://gitorious.org/~kristo/omap-pm/omap-pm-work.git
> $ git fetch tero
> fatal: The remote end hung up unexpectedly
> fatal: protocol error: bad pack heade
> $ git remote rm tero
> $ git remote add tero https://git.gitorious.org/~kristo/omap-pm/omap-pm-work.git
> $ git fetch tero
> error: Unable to find 653621e4dd02d4a2117e1b813d9c5f1ccb11c9ed under https://git.gitorious.org/~kristo/omap-pm/omap-pm-work.git
> Cannot obtain needed object 653621e4dd02d4a2117e1b813d9c5f1ccb11c9ed
> error: Fetch failed.

You will have a partially transferred pack file in your repository...

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

* [PATCH 00/19] ARM: OMAP4 device off support
@ 2012-05-09 23:14     ` Russell King - ARM Linux
  0 siblings, 0 replies; 126+ messages in thread
From: Russell King - ARM Linux @ 2012-05-09 23:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 09, 2012 at 03:46:02PM -0700, Kevin Hilman wrote:
> Tero Kristo <t-kristo@ti.com> writes:
> 
> > Hi,
> >
> > First version for this work. Applies on top of mainline + iochain set +
> > OMAP4 core retention set. Working tree available here:
> > tree: git://gitorious.org/~kristo/omap-pm/omap-pm-work.git
> > branch: mainline-3.4-omap4-dev-off
> 
> FYI... seems your get repo is corrupted.  I tried fetching both with git
> and https protocols:
> 
> $ git remote add tero git://gitorious.org/~kristo/omap-pm/omap-pm-work.git
> $ git fetch tero
> fatal: The remote end hung up unexpectedly
> fatal: protocol error: bad pack heade
> $ git remote rm tero
> $ git remote add tero https://git.gitorious.org/~kristo/omap-pm/omap-pm-work.git
> $ git fetch tero
> error: Unable to find 653621e4dd02d4a2117e1b813d9c5f1ccb11c9ed under https://git.gitorious.org/~kristo/omap-pm/omap-pm-work.git
> Cannot obtain needed object 653621e4dd02d4a2117e1b813d9c5f1ccb11c9ed
> error: Fetch failed.

You will have a partially transferred pack file in your repository...

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

* Re: [PATCH 02/19] ARM: OMAP4: PM: save/restore all CM1/2 settings in OFF mode
  2012-04-20  9:33   ` Tero Kristo
@ 2012-05-09 23:27     ` Kevin Hilman
  -1 siblings, 0 replies; 126+ messages in thread
From: Kevin Hilman @ 2012-05-09 23:27 UTC (permalink / raw)
  To: Tero Kristo
  Cc: linux-omap, paul, linux-arm-kernel, Rajendra Nayak,
	Nishanth Menon, Santosh Shilimkar, Axel Haslam

Tero Kristo <t-kristo@ti.com> writes:

> From: Rajendra Nayak <rnayak@ti.com>
>
> Restore all CM1/2 module registers as they are lost in OFF mode.

Except they are still lost since nobody calls these new functions (in
this patch.)  :)

For ease of review, it's preferred to add the *users* of new code in the
same patch as the new code.

> [nm@ti.com: minor clean ups]
> Signed-off-by: Nishanth Menon <nm@ti.com>
> Signed-off-by: Rajendra Nayak <rnayak@ti.com>
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Signed-off-by: Axel Haslam <axelhaslam@gmail.com>
> Signed-off-by: Tero Kristo <t-kristo@ti.com>
> ---
>  arch/arm/mach-omap2/cm44xx.c |  322 ++++++++++++++++++++++++++++++++++++++++++
>  arch/arm/mach-omap2/cm44xx.h |    2 +
>  2 files changed, 324 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/cm44xx.c b/arch/arm/mach-omap2/cm44xx.c
> index 535d66e..fb5465b 100644
> --- a/arch/arm/mach-omap2/cm44xx.c
> +++ b/arch/arm/mach-omap2/cm44xx.c
> @@ -21,8 +21,11 @@
>  #include "iomap.h"
>  #include "common.h"
>  #include "cm.h"
> +#include "cm44xx.h"
>  #include "cm1_44xx.h"
>  #include "cm2_44xx.h"
> +#include "cminst44xx.h"
> +#include "prcm44xx.h"
>  #include "cm-regbits-44xx.h"
>  
>  /* CM1 hardware module low-level functions */
> @@ -50,3 +53,322 @@ void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 reg)
>  {
>  	__raw_writel(val, OMAP44XX_CM2_REGADDR(inst, reg));
>  }
> +
> +#define MAX_CM_REGISTERS 51
> +
> +struct omap4_cm_reg {
> +	u16 offset;
> +	u32 val;
> +};
> +
> +struct omap4_cm_regs {
> +	u32 mod_off;
> +	u32 no_reg;

minor: do these need to be u32?

> +	struct omap4_cm_reg reg[MAX_CM_REGISTERS];
> +};
> +
> +static struct omap4_cm_regs cm1_regs[] = {
> +	/* OMAP4430_CM1_OCP_SOCKET_MOD */
> +	{ .mod_off = OMAP4430_CM1_OCP_SOCKET_INST, .no_reg = 1,
> +	{{.offset = OMAP4_CM_CM1_PROFILING_CLKCTRL_OFFSET} },

For readability sake, I'd prefer to see this line indented.  And why
the extra space before the final '}'}

> +	},

[...]

> +static void omap4_cm1_prepare_off(void)
> +{
> +	u32 i, j;
> +	struct omap4_cm_regs *cm_reg = cm1_regs;
> +
> +	for (i = 0; i < ARRAY_SIZE(cm1_regs); i++, cm_reg++) {
> +		for (j = 0; j < cm_reg->no_reg; j++) {
> +			cm_reg->reg[j].val =
> +			    omap4_cminst_read_inst_reg(OMAP4430_CM1_PARTITION,
> +						       cm_reg->mod_off,
> +						       cm_reg->reg[j].offset);
> +		}
> +	}
> +}
> +
> +static void omap4_cm2_prepare_off(void)
> +{
> +	u32 i, j;
> +	struct omap4_cm_regs *cm_reg = cm2_regs;
> +
> +	for (i = 0; i < ARRAY_SIZE(cm2_regs); i++, cm_reg++) {
> +		for (j = 0; j < cm_reg->no_reg; j++) {
> +			cm_reg->reg[j].val =
> +			    omap4_cminst_read_inst_reg(OMAP4430_CM2_PARTITION,
> +						       cm_reg->mod_off,
> +						       cm_reg->reg[j].offset);
> +		}
> +	}
> +}

> +static void omap4_cm1_resume_off(void)
> +{
> +	u32 i, j;
> +	struct omap4_cm_regs *cm_reg = cm1_regs;
> +
> +	for (i = 0; i < ARRAY_SIZE(cm1_regs); i++, cm_reg++) {
> +		for (j = 0; j < cm_reg->no_reg; j++) {
> +			omap4_cminst_write_inst_reg(cm_reg->reg[j].val,
> +						    OMAP4430_CM1_PARTITION,
> +						    cm_reg->mod_off,
> +						    cm_reg->reg[j].offset);
> +		}
> +	}
> +}
> +
> +static void omap4_cm2_resume_off(void)
> +{
> +	u32 i, j;
> +	struct omap4_cm_regs *cm_reg = cm2_regs;
> +
> +	for (i = 0; i < ARRAY_SIZE(cm2_regs); i++, cm_reg++) {
> +		for (j = 0; j < cm_reg->no_reg; j++) {
> +			omap4_cminst_write_inst_reg(cm_reg->reg[j].val,
> +						    OMAP4430_CM2_PARTITION,
> +						    cm_reg->mod_off,
> +						    cm_reg->reg[j].offset);
> +		}
> +	}
> +}

Notice the two prpare functions (and resume functions) are basically
identical, except for the partition.

How about adding a .partition field to the struct so there can be a
single function}

Kevin

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

* [PATCH 02/19] ARM: OMAP4: PM: save/restore all CM1/2 settings in OFF mode
@ 2012-05-09 23:27     ` Kevin Hilman
  0 siblings, 0 replies; 126+ messages in thread
From: Kevin Hilman @ 2012-05-09 23:27 UTC (permalink / raw)
  To: linux-arm-kernel

Tero Kristo <t-kristo@ti.com> writes:

> From: Rajendra Nayak <rnayak@ti.com>
>
> Restore all CM1/2 module registers as they are lost in OFF mode.

Except they are still lost since nobody calls these new functions (in
this patch.)  :)

For ease of review, it's preferred to add the *users* of new code in the
same patch as the new code.

> [nm at ti.com: minor clean ups]
> Signed-off-by: Nishanth Menon <nm@ti.com>
> Signed-off-by: Rajendra Nayak <rnayak@ti.com>
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Signed-off-by: Axel Haslam <axelhaslam@gmail.com>
> Signed-off-by: Tero Kristo <t-kristo@ti.com>
> ---
>  arch/arm/mach-omap2/cm44xx.c |  322 ++++++++++++++++++++++++++++++++++++++++++
>  arch/arm/mach-omap2/cm44xx.h |    2 +
>  2 files changed, 324 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/cm44xx.c b/arch/arm/mach-omap2/cm44xx.c
> index 535d66e..fb5465b 100644
> --- a/arch/arm/mach-omap2/cm44xx.c
> +++ b/arch/arm/mach-omap2/cm44xx.c
> @@ -21,8 +21,11 @@
>  #include "iomap.h"
>  #include "common.h"
>  #include "cm.h"
> +#include "cm44xx.h"
>  #include "cm1_44xx.h"
>  #include "cm2_44xx.h"
> +#include "cminst44xx.h"
> +#include "prcm44xx.h"
>  #include "cm-regbits-44xx.h"
>  
>  /* CM1 hardware module low-level functions */
> @@ -50,3 +53,322 @@ void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 reg)
>  {
>  	__raw_writel(val, OMAP44XX_CM2_REGADDR(inst, reg));
>  }
> +
> +#define MAX_CM_REGISTERS 51
> +
> +struct omap4_cm_reg {
> +	u16 offset;
> +	u32 val;
> +};
> +
> +struct omap4_cm_regs {
> +	u32 mod_off;
> +	u32 no_reg;

minor: do these need to be u32?

> +	struct omap4_cm_reg reg[MAX_CM_REGISTERS];
> +};
> +
> +static struct omap4_cm_regs cm1_regs[] = {
> +	/* OMAP4430_CM1_OCP_SOCKET_MOD */
> +	{ .mod_off = OMAP4430_CM1_OCP_SOCKET_INST, .no_reg = 1,
> +	{{.offset = OMAP4_CM_CM1_PROFILING_CLKCTRL_OFFSET} },

For readability sake, I'd prefer to see this line indented.  And why
the extra space before the final '}'}

> +	},

[...]

> +static void omap4_cm1_prepare_off(void)
> +{
> +	u32 i, j;
> +	struct omap4_cm_regs *cm_reg = cm1_regs;
> +
> +	for (i = 0; i < ARRAY_SIZE(cm1_regs); i++, cm_reg++) {
> +		for (j = 0; j < cm_reg->no_reg; j++) {
> +			cm_reg->reg[j].val =
> +			    omap4_cminst_read_inst_reg(OMAP4430_CM1_PARTITION,
> +						       cm_reg->mod_off,
> +						       cm_reg->reg[j].offset);
> +		}
> +	}
> +}
> +
> +static void omap4_cm2_prepare_off(void)
> +{
> +	u32 i, j;
> +	struct omap4_cm_regs *cm_reg = cm2_regs;
> +
> +	for (i = 0; i < ARRAY_SIZE(cm2_regs); i++, cm_reg++) {
> +		for (j = 0; j < cm_reg->no_reg; j++) {
> +			cm_reg->reg[j].val =
> +			    omap4_cminst_read_inst_reg(OMAP4430_CM2_PARTITION,
> +						       cm_reg->mod_off,
> +						       cm_reg->reg[j].offset);
> +		}
> +	}
> +}

> +static void omap4_cm1_resume_off(void)
> +{
> +	u32 i, j;
> +	struct omap4_cm_regs *cm_reg = cm1_regs;
> +
> +	for (i = 0; i < ARRAY_SIZE(cm1_regs); i++, cm_reg++) {
> +		for (j = 0; j < cm_reg->no_reg; j++) {
> +			omap4_cminst_write_inst_reg(cm_reg->reg[j].val,
> +						    OMAP4430_CM1_PARTITION,
> +						    cm_reg->mod_off,
> +						    cm_reg->reg[j].offset);
> +		}
> +	}
> +}
> +
> +static void omap4_cm2_resume_off(void)
> +{
> +	u32 i, j;
> +	struct omap4_cm_regs *cm_reg = cm2_regs;
> +
> +	for (i = 0; i < ARRAY_SIZE(cm2_regs); i++, cm_reg++) {
> +		for (j = 0; j < cm_reg->no_reg; j++) {
> +			omap4_cminst_write_inst_reg(cm_reg->reg[j].val,
> +						    OMAP4430_CM2_PARTITION,
> +						    cm_reg->mod_off,
> +						    cm_reg->reg[j].offset);
> +		}
> +	}
> +}

Notice the two prpare functions (and resume functions) are basically
identical, except for the partition.

How about adding a .partition field to the struct so there can be a
single function}

Kevin

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

* Re: [PATCH 00/19] ARM: OMAP4 device off support
  2012-05-09 23:14     ` Russell King - ARM Linux
@ 2012-05-10  9:47       ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-05-10  9:47 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: Kevin Hilman, paul, linux-omap, linux-arm-kernel

On Thu, 2012-05-10 at 00:14 +0100, Russell King - ARM Linux wrote:
> On Wed, May 09, 2012 at 03:46:02PM -0700, Kevin Hilman wrote:
> > Tero Kristo <t-kristo@ti.com> writes:
> > 
> > > Hi,
> > >
> > > First version for this work. Applies on top of mainline + iochain set +
> > > OMAP4 core retention set. Working tree available here:
> > > tree: git://gitorious.org/~kristo/omap-pm/omap-pm-work.git
> > > branch: mainline-3.4-omap4-dev-off
> > 
> > FYI... seems your get repo is corrupted.  I tried fetching both with git
> > and https protocols:
> > 
> > $ git remote add tero git://gitorious.org/~kristo/omap-pm/omap-pm-work.git
> > $ git fetch tero
> > fatal: The remote end hung up unexpectedly
> > fatal: protocol error: bad pack heade
> > $ git remote rm tero
> > $ git remote add tero https://git.gitorious.org/~kristo/omap-pm/omap-pm-work.git
> > $ git fetch tero
> > error: Unable to find 653621e4dd02d4a2117e1b813d9c5f1ccb11c9ed under https://git.gitorious.org/~kristo/omap-pm/omap-pm-work.git
> > Cannot obtain needed object 653621e4dd02d4a2117e1b813d9c5f1ccb11c9ed
> > error: Fetch failed.
> 
> You will have a partially transferred pack file in your repository...

Strange, well I pushed 1 new branch and it looks like it is cloning
properly now.

-Tero



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

* [PATCH 00/19] ARM: OMAP4 device off support
@ 2012-05-10  9:47       ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-05-10  9:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 2012-05-10 at 00:14 +0100, Russell King - ARM Linux wrote:
> On Wed, May 09, 2012 at 03:46:02PM -0700, Kevin Hilman wrote:
> > Tero Kristo <t-kristo@ti.com> writes:
> > 
> > > Hi,
> > >
> > > First version for this work. Applies on top of mainline + iochain set +
> > > OMAP4 core retention set. Working tree available here:
> > > tree: git://gitorious.org/~kristo/omap-pm/omap-pm-work.git
> > > branch: mainline-3.4-omap4-dev-off
> > 
> > FYI... seems your get repo is corrupted.  I tried fetching both with git
> > and https protocols:
> > 
> > $ git remote add tero git://gitorious.org/~kristo/omap-pm/omap-pm-work.git
> > $ git fetch tero
> > fatal: The remote end hung up unexpectedly
> > fatal: protocol error: bad pack heade
> > $ git remote rm tero
> > $ git remote add tero https://git.gitorious.org/~kristo/omap-pm/omap-pm-work.git
> > $ git fetch tero
> > error: Unable to find 653621e4dd02d4a2117e1b813d9c5f1ccb11c9ed under https://git.gitorious.org/~kristo/omap-pm/omap-pm-work.git
> > Cannot obtain needed object 653621e4dd02d4a2117e1b813d9c5f1ccb11c9ed
> > error: Fetch failed.
> 
> You will have a partially transferred pack file in your repository...

Strange, well I pushed 1 new branch and it looks like it is cloning
properly now.

-Tero

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

* Re: [PATCH 02/19] ARM: OMAP4: PM: save/restore all CM1/2 settings in OFF mode
  2012-05-09 23:27     ` Kevin Hilman
@ 2012-05-11 14:30       ` Tero Kristo
  -1 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-05-11 14:30 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: linux-omap, paul, linux-arm-kernel, Rajendra Nayak,
	Nishanth Menon, Santosh Shilimkar, Axel Haslam

On Wed, 2012-05-09 at 16:27 -0700, Kevin Hilman wrote:
> Tero Kristo <t-kristo@ti.com> writes:
> 
> > From: Rajendra Nayak <rnayak@ti.com>
> >
> > Restore all CM1/2 module registers as they are lost in OFF mode.
> 
> Except they are still lost since nobody calls these new functions (in
> this patch.)  :)
> 
> For ease of review, it's preferred to add the *users* of new code in the
> same patch as the new code.

I'll fix this for the next version. I think this same comment applies to
patch #3 also.

> 
> > [nm@ti.com: minor clean ups]
> > Signed-off-by: Nishanth Menon <nm@ti.com>
> > Signed-off-by: Rajendra Nayak <rnayak@ti.com>
> > Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > Signed-off-by: Axel Haslam <axelhaslam@gmail.com>
> > Signed-off-by: Tero Kristo <t-kristo@ti.com>
> > ---
> >  arch/arm/mach-omap2/cm44xx.c |  322 ++++++++++++++++++++++++++++++++++++++++++
> >  arch/arm/mach-omap2/cm44xx.h |    2 +
> >  2 files changed, 324 insertions(+), 0 deletions(-)
> >
> > diff --git a/arch/arm/mach-omap2/cm44xx.c b/arch/arm/mach-omap2/cm44xx.c
> > index 535d66e..fb5465b 100644
> > --- a/arch/arm/mach-omap2/cm44xx.c
> > +++ b/arch/arm/mach-omap2/cm44xx.c
> > @@ -21,8 +21,11 @@
> >  #include "iomap.h"
> >  #include "common.h"
> >  #include "cm.h"
> > +#include "cm44xx.h"
> >  #include "cm1_44xx.h"
> >  #include "cm2_44xx.h"
> > +#include "cminst44xx.h"
> > +#include "prcm44xx.h"
> >  #include "cm-regbits-44xx.h"
> >  
> >  /* CM1 hardware module low-level functions */
> > @@ -50,3 +53,322 @@ void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 reg)
> >  {
> >  	__raw_writel(val, OMAP44XX_CM2_REGADDR(inst, reg));
> >  }
> > +
> > +#define MAX_CM_REGISTERS 51
> > +
> > +struct omap4_cm_reg {
> > +	u16 offset;
> > +	u32 val;
> > +};
> > +
> > +struct omap4_cm_regs {
> > +	u32 mod_off;
> > +	u32 no_reg;
> 
> minor: do these need to be u32?

u16 should be good enough to save space I guess, I'll try changing this
and see what happens.

> 
> > +	struct omap4_cm_reg reg[MAX_CM_REGISTERS];
> > +};
> > +
> > +static struct omap4_cm_regs cm1_regs[] = {
> > +	/* OMAP4430_CM1_OCP_SOCKET_MOD */
> > +	{ .mod_off = OMAP4430_CM1_OCP_SOCKET_INST, .no_reg = 1,
> > +	{{.offset = OMAP4_CM_CM1_PROFILING_CLKCTRL_OFFSET} },
> 
> For readability sake, I'd prefer to see this line indented.  And why
> the extra space before the final '}'}

These tables are horrible, would be better to get rid of them completely
but I guess that is not possible... I'll look at the indentation.

> 
> > +	},
> 
> [...]
> 
> > +static void omap4_cm1_prepare_off(void)
> > +{
> > +	u32 i, j;
> > +	struct omap4_cm_regs *cm_reg = cm1_regs;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(cm1_regs); i++, cm_reg++) {
> > +		for (j = 0; j < cm_reg->no_reg; j++) {
> > +			cm_reg->reg[j].val =
> > +			    omap4_cminst_read_inst_reg(OMAP4430_CM1_PARTITION,
> > +						       cm_reg->mod_off,
> > +						       cm_reg->reg[j].offset);
> > +		}
> > +	}
> > +}
> > +
> > +static void omap4_cm2_prepare_off(void)
> > +{
> > +	u32 i, j;
> > +	struct omap4_cm_regs *cm_reg = cm2_regs;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(cm2_regs); i++, cm_reg++) {
> > +		for (j = 0; j < cm_reg->no_reg; j++) {
> > +			cm_reg->reg[j].val =
> > +			    omap4_cminst_read_inst_reg(OMAP4430_CM2_PARTITION,
> > +						       cm_reg->mod_off,
> > +						       cm_reg->reg[j].offset);
> > +		}
> > +	}
> > +}
> 
> > +static void omap4_cm1_resume_off(void)
> > +{
> > +	u32 i, j;
> > +	struct omap4_cm_regs *cm_reg = cm1_regs;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(cm1_regs); i++, cm_reg++) {
> > +		for (j = 0; j < cm_reg->no_reg; j++) {
> > +			omap4_cminst_write_inst_reg(cm_reg->reg[j].val,
> > +						    OMAP4430_CM1_PARTITION,
> > +						    cm_reg->mod_off,
> > +						    cm_reg->reg[j].offset);
> > +		}
> > +	}
> > +}
> > +
> > +static void omap4_cm2_resume_off(void)
> > +{
> > +	u32 i, j;
> > +	struct omap4_cm_regs *cm_reg = cm2_regs;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(cm2_regs); i++, cm_reg++) {
> > +		for (j = 0; j < cm_reg->no_reg; j++) {
> > +			omap4_cminst_write_inst_reg(cm_reg->reg[j].val,
> > +						    OMAP4430_CM2_PARTITION,
> > +						    cm_reg->mod_off,
> > +						    cm_reg->reg[j].offset);
> > +		}
> > +	}
> > +}
> 
> Notice the two prpare functions (and resume functions) are basically
> identical, except for the partition.
> 
> How about adding a .partition field to the struct so there can be a
> single function}

Yea, should be possible. I'll fix this for next rev.

-Tero


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

* [PATCH 02/19] ARM: OMAP4: PM: save/restore all CM1/2 settings in OFF mode
@ 2012-05-11 14:30       ` Tero Kristo
  0 siblings, 0 replies; 126+ messages in thread
From: Tero Kristo @ 2012-05-11 14:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 2012-05-09 at 16:27 -0700, Kevin Hilman wrote:
> Tero Kristo <t-kristo@ti.com> writes:
> 
> > From: Rajendra Nayak <rnayak@ti.com>
> >
> > Restore all CM1/2 module registers as they are lost in OFF mode.
> 
> Except they are still lost since nobody calls these new functions (in
> this patch.)  :)
> 
> For ease of review, it's preferred to add the *users* of new code in the
> same patch as the new code.

I'll fix this for the next version. I think this same comment applies to
patch #3 also.

> 
> > [nm at ti.com: minor clean ups]
> > Signed-off-by: Nishanth Menon <nm@ti.com>
> > Signed-off-by: Rajendra Nayak <rnayak@ti.com>
> > Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > Signed-off-by: Axel Haslam <axelhaslam@gmail.com>
> > Signed-off-by: Tero Kristo <t-kristo@ti.com>
> > ---
> >  arch/arm/mach-omap2/cm44xx.c |  322 ++++++++++++++++++++++++++++++++++++++++++
> >  arch/arm/mach-omap2/cm44xx.h |    2 +
> >  2 files changed, 324 insertions(+), 0 deletions(-)
> >
> > diff --git a/arch/arm/mach-omap2/cm44xx.c b/arch/arm/mach-omap2/cm44xx.c
> > index 535d66e..fb5465b 100644
> > --- a/arch/arm/mach-omap2/cm44xx.c
> > +++ b/arch/arm/mach-omap2/cm44xx.c
> > @@ -21,8 +21,11 @@
> >  #include "iomap.h"
> >  #include "common.h"
> >  #include "cm.h"
> > +#include "cm44xx.h"
> >  #include "cm1_44xx.h"
> >  #include "cm2_44xx.h"
> > +#include "cminst44xx.h"
> > +#include "prcm44xx.h"
> >  #include "cm-regbits-44xx.h"
> >  
> >  /* CM1 hardware module low-level functions */
> > @@ -50,3 +53,322 @@ void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 reg)
> >  {
> >  	__raw_writel(val, OMAP44XX_CM2_REGADDR(inst, reg));
> >  }
> > +
> > +#define MAX_CM_REGISTERS 51
> > +
> > +struct omap4_cm_reg {
> > +	u16 offset;
> > +	u32 val;
> > +};
> > +
> > +struct omap4_cm_regs {
> > +	u32 mod_off;
> > +	u32 no_reg;
> 
> minor: do these need to be u32?

u16 should be good enough to save space I guess, I'll try changing this
and see what happens.

> 
> > +	struct omap4_cm_reg reg[MAX_CM_REGISTERS];
> > +};
> > +
> > +static struct omap4_cm_regs cm1_regs[] = {
> > +	/* OMAP4430_CM1_OCP_SOCKET_MOD */
> > +	{ .mod_off = OMAP4430_CM1_OCP_SOCKET_INST, .no_reg = 1,
> > +	{{.offset = OMAP4_CM_CM1_PROFILING_CLKCTRL_OFFSET} },
> 
> For readability sake, I'd prefer to see this line indented.  And why
> the extra space before the final '}'}

These tables are horrible, would be better to get rid of them completely
but I guess that is not possible... I'll look at the indentation.

> 
> > +	},
> 
> [...]
> 
> > +static void omap4_cm1_prepare_off(void)
> > +{
> > +	u32 i, j;
> > +	struct omap4_cm_regs *cm_reg = cm1_regs;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(cm1_regs); i++, cm_reg++) {
> > +		for (j = 0; j < cm_reg->no_reg; j++) {
> > +			cm_reg->reg[j].val =
> > +			    omap4_cminst_read_inst_reg(OMAP4430_CM1_PARTITION,
> > +						       cm_reg->mod_off,
> > +						       cm_reg->reg[j].offset);
> > +		}
> > +	}
> > +}
> > +
> > +static void omap4_cm2_prepare_off(void)
> > +{
> > +	u32 i, j;
> > +	struct omap4_cm_regs *cm_reg = cm2_regs;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(cm2_regs); i++, cm_reg++) {
> > +		for (j = 0; j < cm_reg->no_reg; j++) {
> > +			cm_reg->reg[j].val =
> > +			    omap4_cminst_read_inst_reg(OMAP4430_CM2_PARTITION,
> > +						       cm_reg->mod_off,
> > +						       cm_reg->reg[j].offset);
> > +		}
> > +	}
> > +}
> 
> > +static void omap4_cm1_resume_off(void)
> > +{
> > +	u32 i, j;
> > +	struct omap4_cm_regs *cm_reg = cm1_regs;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(cm1_regs); i++, cm_reg++) {
> > +		for (j = 0; j < cm_reg->no_reg; j++) {
> > +			omap4_cminst_write_inst_reg(cm_reg->reg[j].val,
> > +						    OMAP4430_CM1_PARTITION,
> > +						    cm_reg->mod_off,
> > +						    cm_reg->reg[j].offset);
> > +		}
> > +	}
> > +}
> > +
> > +static void omap4_cm2_resume_off(void)
> > +{
> > +	u32 i, j;
> > +	struct omap4_cm_regs *cm_reg = cm2_regs;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(cm2_regs); i++, cm_reg++) {
> > +		for (j = 0; j < cm_reg->no_reg; j++) {
> > +			omap4_cminst_write_inst_reg(cm_reg->reg[j].val,
> > +						    OMAP4430_CM2_PARTITION,
> > +						    cm_reg->mod_off,
> > +						    cm_reg->reg[j].offset);
> > +		}
> > +	}
> > +}
> 
> Notice the two prpare functions (and resume functions) are basically
> identical, except for the partition.
> 
> How about adding a .partition field to the struct so there can be a
> single function}

Yea, should be possible. I'll fix this for next rev.

-Tero

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

end of thread, other threads:[~2012-05-11 14:30 UTC | newest]

Thread overview: 126+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-20  9:33 [PATCH 00/19] ARM: OMAP4 device off support Tero Kristo
2012-04-20  9:33 ` Tero Kristo
2012-04-20  9:33 ` [PATCH 01/19] ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode Tero Kristo
2012-04-20  9:33   ` Tero Kristo
2012-04-23 16:09   ` Jon Hunter
2012-04-23 16:09     ` Jon Hunter
2012-04-25  7:33     ` Tero Kristo
2012-04-25  7:33       ` Tero Kristo
2012-04-25 15:12       ` Jon Hunter
2012-04-25 15:12         ` Jon Hunter
2012-05-04 19:22         ` Tony Lindgren
2012-05-04 19:22           ` Tony Lindgren
2012-05-02 10:10   ` Bedia, Vaibhav
2012-05-02 10:10     ` Bedia, Vaibhav
2012-05-02 10:18     ` Shilimkar, Santosh
2012-05-02 10:18       ` Shilimkar, Santosh
2012-05-02 10:55       ` Bedia, Vaibhav
2012-05-02 10:55         ` Bedia, Vaibhav
2012-05-02 11:00         ` Shilimkar, Santosh
2012-05-02 11:00           ` Shilimkar, Santosh
2012-05-02 11:40           ` Bedia, Vaibhav
2012-05-02 11:40             ` Bedia, Vaibhav
2012-05-02 11:46             ` Shilimkar, Santosh
2012-05-02 11:46               ` Shilimkar, Santosh
2012-05-02 11:55               ` Bedia, Vaibhav
2012-05-02 11:55                 ` Bedia, Vaibhav
2012-05-02 11:47             ` Menon, Nishanth
2012-05-02 11:47               ` Menon, Nishanth
2012-05-02 11:55               ` Bedia, Vaibhav
2012-05-02 11:55                 ` Bedia, Vaibhav
2012-05-02 11:58                 ` Shilimkar, Santosh
2012-05-02 11:58                   ` Shilimkar, Santosh
2012-05-02 12:10                   ` Bedia, Vaibhav
2012-05-02 12:10                     ` Bedia, Vaibhav
2012-04-20  9:33 ` [PATCH 02/19] ARM: OMAP4: PM: save/restore all CM1/2 " Tero Kristo
2012-04-20  9:33   ` Tero Kristo
2012-05-09 23:27   ` Kevin Hilman
2012-05-09 23:27     ` Kevin Hilman
2012-05-11 14:30     ` Tero Kristo
2012-05-11 14:30       ` Tero Kristo
2012-04-20  9:33 ` [PATCH 03/19] ARM: OMAP4: PM: powerdomain: Add HWSAR flag to L3INIT Tero Kristo
2012-04-20  9:33   ` Tero Kristo
2012-04-20  9:33 ` [PATCH 04/19] ARM: OMAP4: Add SAR ROM base address Tero Kristo
2012-04-20  9:33   ` Tero Kristo
2012-04-20  9:33 ` [PATCH 05/19] ARM: OMAP4: PM: Add SAR backup support towards device OFF Tero Kristo
2012-04-20  9:33   ` Tero Kristo
2012-04-24 16:35   ` Tony Lindgren
2012-04-24 16:35     ` Tony Lindgren
2012-04-25  7:18     ` Tero Kristo
2012-04-25  7:18       ` Tero Kristo
2012-04-20  9:33 ` [PATCH 06/19] ARM: OMAP4: Auto generate SAR layout contents Tero Kristo
2012-04-20  9:33   ` Tero Kristo
2012-04-24 16:37   ` Tony Lindgren
2012-04-24 16:37     ` Tony Lindgren
2012-04-20  9:33 ` [PATCH 07/19] ARM: OMAP4: SAR: generate overwrite data based on SAR ROM contents Tero Kristo
2012-04-20  9:33   ` Tero Kristo
2012-04-20  9:33 ` [PATCH 08/19] ARM: OMAP4: PM: Add device-off support Tero Kristo
2012-04-20  9:33   ` Tero Kristo
2012-04-24 17:46   ` Jon Hunter
2012-04-24 17:46     ` Jon Hunter
2012-04-25  7:30     ` Tero Kristo
2012-04-25  7:30       ` Tero Kristo
2012-04-20  9:33 ` [PATCH 09/19] ARM: OMAP4: PM: add errata support Tero Kristo
2012-04-20  9:33   ` Tero Kristo
2012-04-20  9:33 ` [PATCH 10/19] ARM: OMAP4: PM: Work-around for ROM code BUG of IVAHD/TESLA Tero Kristo
2012-04-20  9:33   ` Tero Kristo
2012-04-24 17:50   ` Jon Hunter
2012-04-24 17:50     ` Jon Hunter
2012-04-25  7:31     ` Tero Kristo
2012-04-25  7:31       ` Tero Kristo
2012-04-20  9:33 ` [PATCH 11/19] ARM: OMAP4: PM: save/restore CM L3INSTR registers when MPU hits OSWR/OFF mode Tero Kristo
2012-04-20  9:33   ` Tero Kristo
2012-04-24 17:57   ` Jon Hunter
2012-04-24 17:57     ` Jon Hunter
2012-04-25  7:31     ` Tero Kristo
2012-04-25  7:31       ` Tero Kristo
2012-04-20  9:33 ` [PATCH 12/19] ARM: OMAP4: PM: update ROM return address for OSWR and OFF Tero Kristo
2012-04-20  9:33   ` Tero Kristo
2012-04-24 16:39   ` Tony Lindgren
2012-04-24 16:39     ` Tony Lindgren
2012-04-25  7:24     ` Tero Kristo
2012-04-25  7:24       ` Tero Kristo
2012-04-20  9:33 ` [PATCH 13/19] ARM: OMAP4: PM: Mark the PPI and SPI interrupts as non-secure for GP Tero Kristo
2012-04-20  9:33   ` Tero Kristo
2012-04-20  9:33 ` [PATCH 14/19] ARM: OMAP4: wakeupgen: enable clocks for save_secure_all Tero Kristo
2012-04-20  9:33   ` Tero Kristo
2012-04-20  9:33 ` [PATCH 15/19] ARM: OMAP4430: PM: workaround for DDR corruption on second CS Tero Kristo
2012-04-20  9:33   ` Tero Kristo
2012-04-24 18:22   ` Jon Hunter
2012-04-24 18:22     ` Jon Hunter
2012-04-25  7:26     ` Tero Kristo
2012-04-25  7:26       ` Tero Kristo
2012-04-25  7:59       ` Shilimkar, Santosh
2012-04-25  7:59         ` Shilimkar, Santosh
2012-04-25 15:16       ` Jon Hunter
2012-04-25 15:16         ` Jon Hunter
2012-04-26  6:19         ` Shilimkar, Santosh
2012-04-26  6:19           ` Shilimkar, Santosh
2012-04-20  9:33 ` [PATCH 16/19] TEMP: ARM: OMAP4: prevent voltage transitions Tero Kristo
2012-04-20  9:33   ` Tero Kristo
2012-04-20  9:33 ` [PATCH 17/19] ARM: OMAP4: put cpu1 back to sleep if no wake request Tero Kristo
2012-04-20  9:33   ` Tero Kristo
2012-04-20  9:33 ` [PATCH 18/19] ARM: OMAP4460: wakeupgen: set GIC_CPU0 backup status flag always Tero Kristo
2012-04-20  9:33   ` Tero Kristo
2012-04-20  9:33 ` [PATCH 19/19] ARM: OMAP4: powerdomain: update mpu / core off counters during device off Tero Kristo
2012-04-20  9:33   ` Tero Kristo
2012-04-20 12:20 ` [PATCH 00/19] ARM: OMAP4 device off support T Krishnamoorthy, Balaji
2012-04-20 12:20   ` T Krishnamoorthy, Balaji
2012-04-20 12:58   ` Tero Kristo
2012-04-20 12:58     ` Tero Kristo
2012-04-20 13:55     ` Kevin Hilman
2012-04-20 13:55       ` Kevin Hilman
2012-04-20 14:43       ` Tero Kristo
2012-04-20 14:43         ` Tero Kristo
2012-04-20 14:51         ` Datta, Shubhrajyoti
2012-04-20 14:51           ` Datta, Shubhrajyoti
2012-04-20 15:07           ` Tero Kristo
2012-04-20 15:07             ` Tero Kristo
2012-04-23  6:28             ` Shubhrajyoti Datta
2012-04-23  6:28               ` Shubhrajyoti Datta
2012-05-09 22:46 ` Kevin Hilman
2012-05-09 22:46   ` Kevin Hilman
2012-05-09 23:14   ` Russell King - ARM Linux
2012-05-09 23:14     ` Russell King - ARM Linux
2012-05-10  9:47     ` Tero Kristo
2012-05-10  9:47       ` Tero Kristo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.